Branch handles: Added all 6 directions (→ ← ↑ ↓ ↘ ↗) so an entire metro map can grow from a single starting node. Cardinal directions (0/90/180/270°) extend the same line, diagonals (45/315°) fork to new tracks. Documents seeded from 6 architecture diagrams: - EVOLV Digital Twin Hierarchy (ISA-88 tracks) → Gemaal 3.0 - Pumping Station dependency chain → Gemaal 3.0 - PLC/EDGE VLAN network architecture → BRIDGE - R&D Stack topology (Cloud/EDGE/OT) → BRIDGE - CoreSync network setup → BRIDGE - R&D Timeline gitflow tracks → Governance Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
628 lines
31 KiB
PHP
628 lines
31 KiB
PHP
<?php
|
||
|
||
namespace Database\Seeders;
|
||
|
||
use App\Enums\CommitmentStatus;
|
||
use App\Enums\FaseStatus;
|
||
use App\Enums\FaseType;
|
||
use App\Enums\Prioriteit;
|
||
use App\Enums\ProjectRol;
|
||
use App\Enums\ProjectStatus;
|
||
use App\Enums\SpeerpuntStatus;
|
||
use App\Models\Afhankelijkheid;
|
||
use App\Models\Commitment;
|
||
use App\Models\Document;
|
||
use App\Models\Fase;
|
||
use App\Models\Project;
|
||
use App\Models\Role;
|
||
use App\Models\Speerpunt;
|
||
use App\Models\Thema;
|
||
use App\Models\User;
|
||
use Illuminate\Database\Seeder;
|
||
use Illuminate\Support\Facades\Hash;
|
||
|
||
class DatabaseSeeder extends Seeder
|
||
{
|
||
/**
|
||
* Seed the application's database.
|
||
*
|
||
* Planning 2026 – R&D Lab Waterschap Brabantse Delta
|
||
* Source: Planning 2026.pptx
|
||
*/
|
||
public function run(): void
|
||
{
|
||
// ──────────────────────────────────────────────────────────────
|
||
// 1. System roles
|
||
// ──────────────────────────────────────────────────────────────
|
||
$roleAdmin = Role::create([
|
||
'naam' => 'admin',
|
||
'beschrijving' => 'Volledige toegang tot het platform',
|
||
'permissies' => ['*'],
|
||
]);
|
||
|
||
$roleProjectOwner = Role::create([
|
||
'naam' => 'project_owner',
|
||
'beschrijving' => 'Kan projecten beheren en bewerken',
|
||
'permissies' => ['projects.manage', 'commitments.manage', 'documents.manage'],
|
||
]);
|
||
|
||
$roleTeamMember = Role::create([
|
||
'naam' => 'team_member',
|
||
'beschrijving' => 'Kan bijdragen aan toegewezen projecten',
|
||
'permissies' => ['projects.view', 'commitments.edit', 'documents.upload'],
|
||
]);
|
||
|
||
Role::create([
|
||
'naam' => 'viewer',
|
||
'beschrijving' => 'Alleen-lezen toegang',
|
||
'permissies' => ['projects.view', 'documents.view'],
|
||
]);
|
||
|
||
// ──────────────────────────────────────────────────────────────
|
||
// 2. Users (R&D team)
|
||
// ──────────────────────────────────────────────────────────────
|
||
$admin = User::create([
|
||
'name' => 'Admin',
|
||
'email' => 'admin@innovatieplatform.nl',
|
||
'password' => Hash::make('password'),
|
||
'functie' => 'Platform Beheerder',
|
||
'afdeling' => 'R&D Lab',
|
||
'email_verified_at' => now(),
|
||
]);
|
||
$admin->roles()->attach($roleAdmin);
|
||
|
||
$rene = User::create([
|
||
'name' => 'Rene de Ren',
|
||
'email' => 'rene@wbd-rd.nl',
|
||
'password' => Hash::make('password'),
|
||
'functie' => 'R&D Engineer / Teamlead',
|
||
'afdeling' => 'R&D Lab',
|
||
'email_verified_at' => now(),
|
||
]);
|
||
$rene->roles()->attach($roleProjectOwner);
|
||
|
||
$pim = User::create([
|
||
'name' => 'Pim Moerman',
|
||
'email' => 'p.moerman@wbd-rd.nl',
|
||
'password' => Hash::make('password'),
|
||
'functie' => 'Technisch Adviseur OT/IT',
|
||
'afdeling' => 'R&D Lab',
|
||
'email_verified_at' => now(),
|
||
]);
|
||
$pim->roles()->attach($roleTeamMember);
|
||
|
||
$sjoerd = User::create([
|
||
'name' => 'Sjoerd Fijnje',
|
||
'email' => 's.fijnje@wbd-rd.nl',
|
||
'password' => Hash::make('password'),
|
||
'functie' => 'Werktuigbouwkundige / Elektro',
|
||
'afdeling' => 'R&D Lab',
|
||
'email_verified_at' => now(),
|
||
]);
|
||
$sjoerd->roles()->attach($roleTeamMember);
|
||
|
||
// ──────────────────────────────────────────────────────────────
|
||
// 3. Themas – 2026 strategic themes
|
||
//
|
||
// Kaders: geen nieuwe ML-modellen, geen nieuwe digital twins,
|
||
// focus op werkend krijgen, architectuur aantonen, overdragen.
|
||
// ──────────────────────────────────────────────────────────────
|
||
$themaArchitectuur = Thema::create([
|
||
'naam' => 'Architectuur & Veiligheid',
|
||
'beschrijving' => 'Aantonen dat de EDGE-laag architectuur veilig, betrouwbaar en schaalbaar is. OT/IT-scheiding, Siemens-koppeling, CI/CD implementatie.',
|
||
'prioriteit' => Prioriteit::Hoog,
|
||
'periode_start' => '2026-01-01',
|
||
'periode_eind' => '2026-12-31',
|
||
]);
|
||
|
||
$themaProductie = Thema::create([
|
||
'naam' => 'Productiewaardig Maken',
|
||
'beschrijving' => 'Bestaande innovaties werkend, overdraagbaar en schaalbaar maken. Begeleiding van aanbestedingen en overdracht naar Bouwen/Beheer.',
|
||
'prioriteit' => Prioriteit::Hoog,
|
||
'periode_start' => '2026-01-01',
|
||
'periode_eind' => '2026-12-31',
|
||
]);
|
||
|
||
$themaLab = Thema::create([
|
||
'naam' => 'Lab & Prototyping',
|
||
'beschrijving' => 'Fysieke opstellingen valideren, uitbreiden en koppelen tot een realistische testomgeving voor afvlakkingsregelingen.',
|
||
'prioriteit' => Prioriteit::Midden,
|
||
'periode_start' => '2026-01-01',
|
||
'periode_eind' => '2026-12-31',
|
||
]);
|
||
|
||
$themaGovernance = Thema::create([
|
||
'naam' => 'Governance & Teamborging',
|
||
'beschrijving' => 'R&D minder persoonsafhankelijk maken. Projectstructuur, documentatie, besluitvorming en rolafbakening vastleggen.',
|
||
'prioriteit' => Prioriteit::Midden,
|
||
'periode_start' => '2026-01-01',
|
||
'periode_eind' => '2026-12-31',
|
||
]);
|
||
|
||
// ──────────────────────────────────────────────────────────────
|
||
// 4. Speerpunten (2 per thema)
|
||
// ──────────────────────────────────────────────────────────────
|
||
|
||
// Architectuur & Veiligheid
|
||
$spEdge = Speerpunt::create([
|
||
'thema_id' => $themaArchitectuur->id,
|
||
'naam' => 'EDGE-laag & OT/IT-scheiding',
|
||
'beschrijving' => 'Implementatie en validatie van de EDGE-architectuur met beveiligde OT/IT-scheiding op pilotlocatie.',
|
||
'eigenaar_id' => $rene->id,
|
||
'status' => SpeerpuntStatus::Actief,
|
||
]);
|
||
|
||
$spCicd = Speerpunt::create([
|
||
'thema_id' => $themaArchitectuur->id,
|
||
'naam' => 'CI/CD & DevOps R&D-stack',
|
||
'beschrijving' => 'Continuous Integration en Deployment implementeren in de R&D-stack voor maximale efficiëntie en herhaalbaarheid.',
|
||
'eigenaar_id' => $rene->id,
|
||
'status' => SpeerpuntStatus::Concept,
|
||
]);
|
||
|
||
// Productiewaardig Maken
|
||
$spOverdracht = Speerpunt::create([
|
||
'thema_id' => $themaProductie->id,
|
||
'naam' => 'Overdracht naar Bouwen/Beheer',
|
||
'beschrijving' => 'Innovaties begeleiden van R&D naar productie: documentatie, oplevering, kennisoverdracht.',
|
||
'eigenaar_id' => $rene->id,
|
||
'status' => SpeerpuntStatus::Actief,
|
||
]);
|
||
|
||
$spAanbesteding = Speerpunt::create([
|
||
'thema_id' => $themaProductie->id,
|
||
'naam' => 'Aanbesteding & TCO-toetsing',
|
||
'beschrijving' => 'Technische toetsing van aanbestedingen op prestatie-eisen, energie-efficiëntie en inpasbaarheid.',
|
||
'eigenaar_id' => $pim->id,
|
||
'status' => SpeerpuntStatus::Actief,
|
||
]);
|
||
|
||
// Lab & Prototyping
|
||
$spDtValidatie = Speerpunt::create([
|
||
'thema_id' => $themaLab->id,
|
||
'naam' => 'Digital Twin Validatie',
|
||
'beschrijving' => 'Valideren van 2025-ontwikkelingen (Measurement, Rotating Machine, Aeration Tank, MGC, Diffuser) op het fysieke prototype.',
|
||
'eigenaar_id' => $rene->id,
|
||
'status' => SpeerpuntStatus::Actief,
|
||
]);
|
||
|
||
$spGemalenketen = Speerpunt::create([
|
||
'thema_id' => $themaLab->id,
|
||
'naam' => 'Gemalenketen Testomgeving',
|
||
'beschrijving' => 'Realiseren van een volledige gemalenketen in het lab voor experimentele afvlakkingsregelingen.',
|
||
'eigenaar_id' => $sjoerd->id,
|
||
'status' => SpeerpuntStatus::Concept,
|
||
]);
|
||
|
||
// Governance & Teamborging
|
||
$spProjectstructuur = Speerpunt::create([
|
||
'thema_id' => $themaGovernance->id,
|
||
'naam' => 'Projectstructuur & Documentatie',
|
||
'beschrijving' => 'Afspraken vastleggen over projectstructuur, documentatie, besluitvorming en beleid.',
|
||
'eigenaar_id' => $rene->id,
|
||
'status' => SpeerpuntStatus::Actief,
|
||
]);
|
||
|
||
$spRolafbakening = Speerpunt::create([
|
||
'thema_id' => $themaGovernance->id,
|
||
'naam' => 'Rolafbakening R&D ↔ Organisatie',
|
||
'beschrijving' => 'Verduidelijken wat R&D wel en niet doet. Afbakening richting Beheer, Bouwen, ICT en Datalab.',
|
||
'eigenaar_id' => $rene->id,
|
||
'status' => SpeerpuntStatus::Concept,
|
||
]);
|
||
|
||
// ──────────────────────────────────────────────────────────────
|
||
// 5. Projects – 2026 planning (6 projects from the presentation)
|
||
// ──────────────────────────────────────────────────────────────
|
||
|
||
// --- B.R.I.D.G.E (Bidirectional Real-time Interface for Data & Grid Exchange) ---
|
||
$bridge = $this->createProject([
|
||
'speerpunt_id' => $spEdge->id,
|
||
'naam' => 'B.R.I.D.G.E – Pilot Klundert',
|
||
'beschrijving' => 'Aantonen dat de nieuwe EDGE-laag veilig en betrouwbaar assets kan uitlezen en aansturen, en correct kan koppelen met Siemens-omgevingen. Implementatie Ubuntu LTS, Node-RED orkestratie, OPC UA communicatie met Siemens PLC (T-serie).',
|
||
'eigenaar_id' => $rene->id,
|
||
'status' => ProjectStatus::Pilot,
|
||
'prioriteit' => Prioriteit::Hoog,
|
||
'startdatum' => '2026-01-15',
|
||
'streef_einddatum' => '2026-09-30',
|
||
], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment, FaseType::Pilot]);
|
||
|
||
// --- C.R.I.S.P (Compressor Replacement for Immediate System Performance) ---
|
||
$crisp = $this->createProject([
|
||
'speerpunt_id' => $spAanbesteding->id,
|
||
'naam' => 'C.R.I.S.P – Compressor Aanbesteding',
|
||
'beschrijving' => 'Technische toetsing van aanbestedingsmethodiek voor compressorvervanging Nieuwveer. Prestatie-eisen, energie-efficiëntie, inpasbaarheid in procesautomatisering. R&D als inhoudelijke sparringpartner voor Bouwen.',
|
||
'eigenaar_id' => $pim->id,
|
||
'status' => ProjectStatus::Verkenning,
|
||
'prioriteit' => Prioriteit::Hoog,
|
||
'startdatum' => '2026-02-01',
|
||
'streef_einddatum' => '2026-08-31',
|
||
], [FaseType::Signaal, FaseType::Verkenning]);
|
||
|
||
// --- W.I.S.E (Weather and Influent Sampling Engine) ---
|
||
$wise = $this->createProject([
|
||
'speerpunt_id' => $spOverdracht->id,
|
||
'naam' => 'W.I.S.E – Monsternamekast Overdracht',
|
||
'beschrijving' => 'Overdracht monsternamekast naar Bouwen. Opleveren Node-RED flows, documentatie, afbakening R&D vs beheer. Samenwerking met Datalab (data & integratie voorspellend model) en Beheer/Operatie.',
|
||
'eigenaar_id' => $rene->id,
|
||
'status' => ProjectStatus::OverdrachtBouwen,
|
||
'prioriteit' => Prioriteit::Hoog,
|
||
'startdatum' => '2025-06-01',
|
||
'streef_einddatum' => '2026-06-30',
|
||
], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment, FaseType::Pilot, FaseType::Besluitvorming, FaseType::OverdrachtBouwen]);
|
||
|
||
// --- Gemaal 3.0 – Prototype Validatie ---
|
||
$gemaal = $this->createProject([
|
||
'speerpunt_id' => $spDtValidatie->id,
|
||
'naam' => 'Gemaal 3.0 – Prototype Validatie',
|
||
'beschrijving' => 'Valideren dat het recent gebouwde prototype functioneel correct is. Testen van alle elektrische aansluitingen, I/O-functionaliteit en randapparatuur. Go/no-go voor verdere uitrol naar 2 kopieën.',
|
||
'eigenaar_id' => $sjoerd->id,
|
||
'status' => ProjectStatus::Experiment,
|
||
'prioriteit' => Prioriteit::Midden,
|
||
'startdatum' => '2026-03-01',
|
||
'streef_einddatum' => '2026-07-31',
|
||
], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment]);
|
||
|
||
// --- Afvlakkingsregeling – Lab Gemalenketen ---
|
||
$afvlak = $this->createProject([
|
||
'speerpunt_id' => $spGemalenketen->id,
|
||
'naam' => 'Afvlakkingsregeling – Lab Keten',
|
||
'beschrijving' => 'Nabootsen van een volledige gemalenketen in het lab, klaarstomen voor afvlakkingsregeling. Realiseren 2 extra opstellingen, koppelen tot keten, basissoftware testen op ketengedrag.',
|
||
'eigenaar_id' => $sjoerd->id,
|
||
'status' => ProjectStatus::Concept,
|
||
'prioriteit' => Prioriteit::Midden,
|
||
'startdatum' => '2026-06-01',
|
||
'streef_einddatum' => '2026-12-31',
|
||
], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept]);
|
||
|
||
// --- Structuur & Borging R&D-team ---
|
||
$governance = $this->createProject([
|
||
'speerpunt_id' => $spProjectstructuur->id,
|
||
'naam' => 'Structuur & Borging R&D',
|
||
'beschrijving' => 'R&D minder persoonsafhankelijk en beter voorspelbaar maken. Afspraken over projectstructuur, documentatie, besluitvorming, beleid. Inrichten ICT in Bouvigne voor R&D en Datanetwerkteam.',
|
||
'eigenaar_id' => $rene->id,
|
||
'status' => ProjectStatus::Verkenning,
|
||
'prioriteit' => Prioriteit::Midden,
|
||
'startdatum' => '2026-01-01',
|
||
'streef_einddatum' => '2026-12-31',
|
||
], [FaseType::Signaal, FaseType::Verkenning]);
|
||
|
||
// ──────────────────────────────────────────────────────────────
|
||
// 6. Assign team members
|
||
// ──────────────────────────────────────────────────────────────
|
||
$bridge->teamleden()->attach($pim->id, ['rol' => ProjectRol::Lid->value]);
|
||
$bridge->teamleden()->attach($sjoerd->id, ['rol' => ProjectRol::Lid->value]);
|
||
$crisp->teamleden()->attach($rene->id, ['rol' => ProjectRol::Reviewer->value]);
|
||
$wise->teamleden()->attach($pim->id, ['rol' => ProjectRol::Lid->value]);
|
||
$gemaal->teamleden()->attach($rene->id, ['rol' => ProjectRol::Reviewer->value]);
|
||
$afvlak->teamleden()->attach($rene->id, ['rol' => ProjectRol::Reviewer->value]);
|
||
$governance->teamleden()->attach($pim->id, ['rol' => ProjectRol::Lid->value]);
|
||
$governance->teamleden()->attach($sjoerd->id, ['rol' => ProjectRol::Lid->value]);
|
||
|
||
// ──────────────────────────────────────────────────────────────
|
||
// 7. Commitments
|
||
// ──────────────────────────────────────────────────────────────
|
||
|
||
// BRIDGE
|
||
Commitment::create([
|
||
'project_id' => $bridge->id,
|
||
'beschrijving' => 'Architectuur validatiedocument opleveren conform stackKlundertPilot.pdf',
|
||
'eigenaar_id' => $rene->id,
|
||
'deadline' => '2026-04-30',
|
||
'status' => CommitmentStatus::InUitvoering,
|
||
'bron' => 'Planning 2026 – slide 3',
|
||
]);
|
||
|
||
Commitment::create([
|
||
'project_id' => $bridge->id,
|
||
'beschrijving' => 'OT/IT beveiligingsassessment en scheidingsrapport',
|
||
'eigenaar_id' => $pim->id,
|
||
'deadline' => '2026-06-30',
|
||
'status' => CommitmentStatus::Open,
|
||
'bron' => 'Planning 2026 – slide 3',
|
||
]);
|
||
|
||
Commitment::create([
|
||
'project_id' => $bridge->id,
|
||
'beschrijving' => 'Beslisdocument voor opschaling EDGE-laag naar andere locaties',
|
||
'eigenaar_id' => $rene->id,
|
||
'deadline' => '2026-09-30',
|
||
'status' => CommitmentStatus::Open,
|
||
'bron' => 'Planning 2026 – slide 3',
|
||
]);
|
||
|
||
// CRISP
|
||
Commitment::create([
|
||
'project_id' => $crisp->id,
|
||
'beschrijving' => 'TCO-onderbouwde aanbestedingsdocumenten technisch getoetst vóór marktgang',
|
||
'eigenaar_id' => $pim->id,
|
||
'deadline' => '2026-05-31',
|
||
'status' => CommitmentStatus::Open,
|
||
'bron' => 'Planning 2026 – slide 4',
|
||
]);
|
||
|
||
// WISE
|
||
Commitment::create([
|
||
'project_id' => $wise->id,
|
||
'beschrijving' => 'Node-RED flows opleveren aan Bouwen / uitvoerende partij',
|
||
'eigenaar_id' => $rene->id,
|
||
'deadline' => '2026-03-31',
|
||
'status' => CommitmentStatus::InUitvoering,
|
||
'bron' => 'Planning 2026 – slide 5',
|
||
]);
|
||
|
||
Commitment::create([
|
||
'project_id' => $wise->id,
|
||
'beschrijving' => 'Overdracht- en documentatiepakket compleet (afbakening R&D vs beheer)',
|
||
'eigenaar_id' => $rene->id,
|
||
'deadline' => '2026-06-30',
|
||
'status' => CommitmentStatus::Open,
|
||
'bron' => 'Planning 2026 – slide 5',
|
||
]);
|
||
|
||
// Gemaal 3.0
|
||
Commitment::create([
|
||
'project_id' => $gemaal->id,
|
||
'beschrijving' => 'Go/no-go besluit voor uitrol naar 2 kopieën op basis van testresultaten',
|
||
'eigenaar_id' => $sjoerd->id,
|
||
'deadline' => '2026-06-30',
|
||
'status' => CommitmentStatus::Open,
|
||
'bron' => 'Planning 2026 – slide 6',
|
||
]);
|
||
|
||
Commitment::create([
|
||
'project_id' => $gemaal->id,
|
||
'beschrijving' => 'Overzicht software/hardware functionaliteiten en validatie digital twins',
|
||
'eigenaar_id' => $rene->id,
|
||
'deadline' => '2026-07-31',
|
||
'status' => CommitmentStatus::Open,
|
||
'bron' => 'Planning 2026 – slide 6',
|
||
]);
|
||
|
||
// Afvlakkingsregeling
|
||
Commitment::create([
|
||
'project_id' => $afvlak->id,
|
||
'beschrijving' => '2 extra opstellingen gerealiseerd en gekoppeld tot keten',
|
||
'eigenaar_id' => $sjoerd->id,
|
||
'deadline' => '2026-10-31',
|
||
'status' => CommitmentStatus::Open,
|
||
'bron' => 'Planning 2026 – slide 7',
|
||
]);
|
||
|
||
// Governance
|
||
Commitment::create([
|
||
'project_id' => $governance->id,
|
||
'beschrijving' => 'Projectstructuur- en documentatieafspraken vastgelegd',
|
||
'eigenaar_id' => $rene->id,
|
||
'deadline' => '2026-03-31',
|
||
'status' => CommitmentStatus::InUitvoering,
|
||
'bron' => 'Planning 2026 – slide 8',
|
||
]);
|
||
|
||
Commitment::create([
|
||
'project_id' => $governance->id,
|
||
'beschrijving' => 'Rolafbakening R&D ↔ Beheer ↔ Bouwen vastgelegd en gecommuniceerd',
|
||
'eigenaar_id' => $rene->id,
|
||
'deadline' => '2026-06-30',
|
||
'status' => CommitmentStatus::Open,
|
||
'bron' => 'Planning 2026 – slide 8',
|
||
]);
|
||
|
||
// ──────────────────────────────────────────────────────────────
|
||
// 8. Documents
|
||
// ──────────────────────────────────────────────────────────────
|
||
Document::create([
|
||
'project_id' => $bridge->id,
|
||
'titel' => 'Stack Architectuur Klundert Pilot',
|
||
'type' => 'technisch_ontwerp',
|
||
'inhoud' => 'Systeemarchitectuur EDGE-laag: Ubuntu LTS, Node-RED orkestratie, OPC UA communicatie met Siemens PLC T-serie, InfluxDB/Grafana datastromen.',
|
||
'versie' => 1,
|
||
'auteur_id' => $rene->id,
|
||
]);
|
||
|
||
Document::create([
|
||
'project_id' => $wise->id,
|
||
'titel' => 'Overdrachtsprotocol Monsternamekast',
|
||
'type' => 'protocol',
|
||
'inhoud' => 'Opleverdocument voor de overdracht van de monsternamekast naar Bouwen. Bevat: Node-RED flow specificaties, integratie voorspellend model, afbakening verantwoordelijkheden.',
|
||
'versie' => 1,
|
||
'auteur_id' => $rene->id,
|
||
]);
|
||
|
||
Document::create([
|
||
'project_id' => $crisp->id,
|
||
'titel' => 'Technische Toetsing Aanbesteding Compressoren',
|
||
'type' => 'technisch_rapport',
|
||
'inhoud' => 'Q&A en technische beoordeling van aanbestedingsdocumenten voor compressorvervanging Nieuwveer. TCO-analyse, prestatie-eisen, energie-efficiëntie.',
|
||
'versie' => 1,
|
||
'auteur_id' => $pim->id,
|
||
]);
|
||
|
||
Document::create([
|
||
'project_id' => $gemaal->id,
|
||
'titel' => 'Testrapport Prototype Gemaal 3.0',
|
||
'type' => 'technisch_rapport',
|
||
'inhoud' => 'Bevindingen en verbeterpunten uit validatie van het prototype: elektrische aansluitingen, I/O-functionaliteit, randapparatuur, digital twin koppelingen.',
|
||
'versie' => 1,
|
||
'auteur_id' => $sjoerd->id,
|
||
]);
|
||
|
||
Document::create([
|
||
'project_id' => $governance->id,
|
||
'titel' => 'R&D Projectstructuur & Beleidskader',
|
||
'type' => 'projectplan',
|
||
'inhoud' => 'Afspraken over projectstructuur, documentatiestandaarden, besluitvormingsproces en beleid voor het R&D-lab.',
|
||
'versie' => 1,
|
||
'auteur_id' => $rene->id,
|
||
]);
|
||
|
||
// --- Documents extracted from architecture diagrams (raw/*.drawio.png) ---
|
||
|
||
// EVOLV-Tracks-Maintracks: full ISA-88 node hierarchy
|
||
Document::create([
|
||
'project_id' => $gemaal->id,
|
||
'titel' => 'EVOLV Digital Twin Hiërarchie (ISA-88 Tracks)',
|
||
'type' => 'technisch_ontwerp',
|
||
'inhoud' => "EVOLV node-hiërarchie conform ISA-88 (S88) batch control standaard.\n\n"
|
||
. "**Control Module**: measurement, diffuser, healthCompact, filterController\n"
|
||
. "**Equipment**: Rotating Machine, sump (gepland)\n"
|
||
. "**Unit**: machineGroupControl, valve, hydraulic network (gepland)\n"
|
||
. "**Process Cell**: Pumping Station\n"
|
||
. "**Area**: Sewage Pumping Group Control\n"
|
||
. "**Complex models**: Influent Prediction\n"
|
||
. "**Utilities**: generalFunctions, coreSync, convert, dashboardAPI\n"
|
||
. "**Data manipulation**: onderste laag\n\n"
|
||
. "Verticale tracks per asset-keten. Horizontale vertakkingen per ISA-88 niveau. "
|
||
. "Stippellijncirkels = geplande maar nog niet gebouwde nodes. "
|
||
. "Bron: EVOLV-Tracks-Maintracks.drawio.png",
|
||
'versie' => 1,
|
||
'auteur_id' => $rene->id,
|
||
]);
|
||
|
||
// EVOLV-Tracks-PumpingStation: vertical dependency chain
|
||
Document::create([
|
||
'project_id' => $gemaal->id,
|
||
'titel' => 'Pumping Station Afhankelijkheidsketen',
|
||
'type' => 'technisch_ontwerp',
|
||
'inhoud' => "Verticale afhankelijkheidsketen voor de Pumping Station track:\n\n"
|
||
. "measurement (Control Module) → Rotating Machine (Equipment) → "
|
||
. "machineGroupControl (Unit) → Sewage Pumping Station (Process Cell) → "
|
||
. "Sewage Pumping Group Control (Area) → Influent Prediction (Complex) → "
|
||
. "generalFunctions + coreSync + convert + dashboardAPI (Utilities)\n\n"
|
||
. "Elke laag is afhankelijk van de laag erboven. Equipment-nodes die als stippellijn staan "
|
||
. "(sump) zijn gepland maar nog niet ontwikkeld.\n"
|
||
. "Bron: EVOLV-Tracks-PumpingStation.drawio.png",
|
||
'versie' => 1,
|
||
'auteur_id' => $rene->id,
|
||
]);
|
||
|
||
// PLCEdge: network architecture VLAN separation
|
||
Document::create([
|
||
'project_id' => $bridge->id,
|
||
'titel' => 'PLC/EDGE Netwerk Architectuur (VLAN-scheiding)',
|
||
'type' => 'technisch_ontwerp',
|
||
'inhoud' => "Netwerkarchitectuur voor de BRIDGE pilot met VLAN-scheiding:\n\n"
|
||
. "**Extern Serverpark** (Internet): Digital Twin + Integratielaag op Edem expert system\n"
|
||
. "**Bouvigne Serverpark** (VLAN 1): Linux Server met Digital Twin + Integratielaag\n"
|
||
. "**On-site Gemaal/RWZI** (VLAN 2 + 3):\n"
|
||
. " - VLAN 3: Linux EDGE met Digital Twin + Integratielaag\n"
|
||
. " - VLAN 2: Siemens 1500 PLC (Typical) + Remote IO modules → Pomp\n\n"
|
||
. "Communicatie: HTTPS tussen extern en Bouvigne, tunnel naar EDGE, OPC UA naar PLC.\n"
|
||
. "Bron: PLCEdge-Page-1.drawio.png",
|
||
'versie' => 2,
|
||
'auteur_id' => $pim->id,
|
||
]);
|
||
|
||
// Stack: full R&D software stack
|
||
Document::create([
|
||
'project_id' => $bridge->id,
|
||
'titel' => 'R&D Stack Topologie (Cloud / EDGE / OT)',
|
||
'type' => 'technisch_ontwerp',
|
||
'inhoud' => "Drielaagse R&D stack architectuur:\n\n"
|
||
. "**Cloud/Central Layer**: nginx-proxy, Nodered, Portainer, SSL CertResolver, "
|
||
. "jenkins, influx-db, Grafana, Mosquitto, MQTT Broker, Fluffle (MQTT OUT ONLY broker), "
|
||
. "ESL dit (single port only)\n\n"
|
||
. "**EDGE Layer**: Mosquitto/VPN bridge, Nodered, Portainer, influx-db, "
|
||
. "Grafana, CoreSync, Mosquitto, MQTT SX\n\n"
|
||
. "**OT Layer**: OPCua Server → PLC\n\n"
|
||
. "Tunnel-verbinding tussen Cloud en EDGE. OPC UA van EDGE naar OT.\n"
|
||
. "Bron: Stack.drawio (2).png",
|
||
'versie' => 1,
|
||
'auteur_id' => $rene->id,
|
||
]);
|
||
|
||
// CoreSync: local/central sync topology
|
||
Document::create([
|
||
'project_id' => $bridge->id,
|
||
'titel' => 'CoreSync Netwerk Setup (Single Level)',
|
||
'type' => 'technisch_ontwerp',
|
||
'inhoud' => "CoreSync single-level configuratie:\n\n"
|
||
. "**R&D lokaal ZRG (LVL 1)**: Apparaat 1 + Apparaat 2 met measurement nodes, "
|
||
. "verbonden via Apparaat 3 (Node-Red container) met GR Bridge flows\n\n"
|
||
. "**R&D Centraal (LVL 1)**: Apparaat 4 (Node-Red container) met GR Bridge flows, "
|
||
. "verbonden via HTTPS naar lokaal\n\n"
|
||
. "Notitie: Elk netwerk dat UR, DR en 1RG bijv de edges zijn dit simpel. "
|
||
. "Ga through AZURE. Per net tekent voor edge = 1 à 1 b/u to net. "
|
||
. "PI flow at Bouvigne.\n"
|
||
. "Bron: CoreSync-Single level.drawio.png",
|
||
'versie' => 1,
|
||
'auteur_id' => $pim->id,
|
||
]);
|
||
|
||
// Complex gitflow: R&D timeline with branching tracks
|
||
Document::create([
|
||
'project_id' => $governance->id,
|
||
'titel' => 'R&D Tijdlijn & Releasebeleid (Gitflow)',
|
||
'type' => 'projectplan',
|
||
'inhoud' => "R&D release-tijdlijn als metro-tracks (gitflow model):\n\n"
|
||
. "**Tracks**: Bestuurlijk, Hotfix, Release, Release Fixes, Studenten, Yellowchess, Budget\n\n"
|
||
. "**Tijdlijn**:\n"
|
||
. "- 7/'21: R&D start PRO\n"
|
||
. "- 8/'21: Introductie met minor avans\n"
|
||
. "- 9/'21: Start minor PA avans, Opbouw partytent\n"
|
||
. "- 8/'21: Budget 40k\n"
|
||
. "- Pilot v0.1 → Verhuizing loods hardenberg → Pilot v0.2\n"
|
||
. "- Release 2.0 → 2.1\n\n"
|
||
. "Vertakkingen tonen hoe R&D-werk splitst en samenkomt.\n"
|
||
. "Bron: EVOLV-Tracks-complex gitflow.drawio.png",
|
||
'versie' => 1,
|
||
'auteur_id' => $rene->id,
|
||
]);
|
||
|
||
// ──────────────────────────────────────────────────────────────
|
||
// 9. Dependencies between projects
|
||
// ──────────────────────────────────────────────────────────────
|
||
|
||
// Afvlakkingsregeling hangt af van Gemaal 3.0 (prototype moet gevalideerd zijn)
|
||
Afhankelijkheid::create([
|
||
'project_id' => $afvlak->id,
|
||
'afhankelijk_van_project_id' => $gemaal->id,
|
||
'type' => 'technisch',
|
||
'beschrijving' => 'De afvlakkingsregeling vereist gevalideerde prototypes van Gemaal 3.0 (× 2 kopieën) als basis voor de ketenopstelling.',
|
||
'status' => 'open',
|
||
]);
|
||
|
||
// WISE overdracht profiteert van BRIDGE architectuur (gedeelde EDGE-infrastructuur)
|
||
Afhankelijkheid::create([
|
||
'project_id' => $wise->id,
|
||
'afhankelijk_van_project_id' => $bridge->id,
|
||
'type' => 'infrastructuur',
|
||
'beschrijving' => 'De monsternamekast draait op dezelfde EDGE-architectuur die BRIDGE valideert.',
|
||
'status' => 'open',
|
||
]);
|
||
|
||
// Gemaal 3.0 validatie van digital twins hangt samen met BRIDGE architectuur
|
||
Afhankelijkheid::create([
|
||
'project_id' => $gemaal->id,
|
||
'afhankelijk_van_project_id' => $bridge->id,
|
||
'type' => 'technisch',
|
||
'beschrijving' => 'Digital twin validatie in Gemaal 3.0 gebruikt dezelfde EDGE-laag als bewezen in BRIDGE.',
|
||
'status' => 'open',
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* Helper: create a project with its completed and active phases.
|
||
*/
|
||
private function createProject(array $attributes, array $faseTypes): Project
|
||
{
|
||
$project = Project::create($attributes);
|
||
|
||
$project->teamleden()->attach($attributes['eigenaar_id'], ['rol' => ProjectRol::Eigenaar->value]);
|
||
|
||
foreach ($faseTypes as $index => $faseType) {
|
||
$isLast = $index === count($faseTypes) - 1;
|
||
|
||
Fase::create([
|
||
'project_id' => $project->id,
|
||
'type' => $faseType,
|
||
'status' => $isLast ? FaseStatus::Actief : FaseStatus::Afgerond,
|
||
'startdatum' => now()->subMonths(count($faseTypes) - 1 - $index),
|
||
'einddatum' => $isLast ? null : now()->subMonths(count($faseTypes) - 2 - $index),
|
||
]);
|
||
}
|
||
|
||
return $project;
|
||
}
|
||
}
|