Files
innovatieplatform/database/seeders/DatabaseSeeder.php
znetsixe d03fe15542 Sprint 1: Auth, metro map canvas, services, and retro UI
Authentication:
- Laravel Fortify + Sanctum with Inertia views
- RBAC middleware (admin, project_owner, team_member, viewer)
- Retro terminal-styled login/register/forgot-password pages

Metro Map (core UI):
- D3.js zoomable SVG canvas with metro line rendering
- Station nodes with glow-on-hover, status coloring, tooltips
- Breadcrumb navigation for multi-level drill-down
- Node preview panel with zoom-in action
- C64-style CLI bar with blinking cursor at bottom

Backend services:
- ProjectService (CRUD, phase transitions, park/stop, audit logging)
- ThemaService (CRUD with audit)
- MapDataService (strategy map L1, project map L2)
- Thin controllers: MapController, ProjectController, ThemaController
- 32 routes total (auth + app + API)

Style foundation:
- Retro-futurism theme: VT323, Press Start 2P, IBM Plex Mono fonts
- Dark palette with cyan/orange/green/purple neon accents
- Comprehensive seed data (4 themes, 12 projects, commitments, deps)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:52:35 +02:00

553 lines
27 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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.
*/
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
// ──────────────────────────────────────────────────────────────
$adminUser = User::create([
'name' => 'Admin Gebruiker',
'email' => 'admin@innovatieplatform.nl',
'password' => Hash::make('password'),
'functie' => 'Platform Beheerder',
'afdeling' => 'R&D Lab',
'email_verified_at' => now(),
]);
$adminUser->roles()->attach($roleAdmin);
$testUser = User::create([
'name' => 'Rene de Ren',
'email' => 'rene@wbd-rd.nl',
'password' => Hash::make('password'),
'functie' => 'R&D Engineer',
'afdeling' => 'R&D Lab',
'email_verified_at' => now(),
]);
$testUser->roles()->attach($roleProjectOwner);
$analyst = User::create([
'name' => 'Lisanne Bakker',
'email' => 'l.bakker@wbd-rd.nl',
'password' => Hash::make('password'),
'functie' => 'Data Analist',
'afdeling' => 'Watermanagement',
'email_verified_at' => now(),
]);
$analyst->roles()->attach($roleTeamMember);
$engineer = User::create([
'name' => 'Joris van Dam',
'email' => 'j.vandam@wbd-rd.nl',
'password' => Hash::make('password'),
'functie' => 'Senior Technisch Adviseur',
'afdeling' => 'Infrastructuur',
'email_verified_at' => now(),
]);
$engineer->roles()->attach($roleTeamMember);
// ──────────────────────────────────────────────────────────────
// 3. Themas (4 strategic themes)
// ──────────────────────────────────────────────────────────────
$themaWater = Thema::create([
'naam' => 'Waterkwaliteit',
'beschrijving' => 'Verbetering van de kwaliteit van oppervlaktewater en grondwater door innovatieve monitoring- en zuiveringstechnieken.',
'prioriteit' => Prioriteit::Hoog,
'periode_start' => '2025-01-01',
'periode_eind' => '2028-12-31',
]);
$themaInfra = Thema::create([
'naam' => 'Slimme Infrastructuur',
'beschrijving' => 'Digitalisering en automatisering van waterkeringen, gemalen en sluizen voor efficiënter beheer en snellere responstijden.',
'prioriteit' => Prioriteit::Hoog,
'periode_start' => '2025-01-01',
'periode_eind' => '2028-12-31',
]);
$themaData = Thema::create([
'naam' => 'Data-gedreven Beheer',
'beschrijving' => 'Inzet van data-analyse, AI en digitale tweelingen voor betere besluitvorming in waterbeheer.',
'prioriteit' => Prioriteit::Midden,
'periode_start' => '2025-06-01',
'periode_eind' => '2029-06-30',
]);
$themaDuurzaam = Thema::create([
'naam' => 'Duurzaamheid & Klimaatadaptatie',
'beschrijving' => 'Innovaties gericht op energieneutraliteit, circulaire waterketens en klimaatrobuuste inrichting van het beheergebied.',
'prioriteit' => Prioriteit::Midden,
'periode_start' => '2025-01-01',
'periode_eind' => '2030-12-31',
]);
// ──────────────────────────────────────────────────────────────
// 4. Speerpunten (2 per thema)
// ──────────────────────────────────────────────────────────────
// Waterkwaliteit
$spWaterMonitoring = Speerpunt::create([
'thema_id' => $themaWater->id,
'naam' => 'Real-time Watermonitoring',
'beschrijving' => 'Continue meting van waterkwaliteitsparameters via IoT-sensoren in het beheergebied.',
'eigenaar_id' => $testUser->id,
'status' => SpeerpuntStatus::Actief,
]);
$spMicropollution = Speerpunt::create([
'thema_id' => $themaWater->id,
'naam' => 'Microverontreinigingen',
'beschrijving' => 'Detectie en verwijdering van opkomende stoffen zoals medicijnresten en PFAS.',
'eigenaar_id' => $engineer->id,
'status' => SpeerpuntStatus::Concept,
]);
// Slimme Infrastructuur
$spDigitaalBeheer = Speerpunt::create([
'thema_id' => $themaInfra->id,
'naam' => 'Digitaal Kunstwerkenregister',
'beschrijving' => 'Volledig digitaal beheer van kunstwerken met BIM-koppeling en conditiebewaking.',
'eigenaar_id' => $engineer->id,
'status' => SpeerpuntStatus::Actief,
]);
$spSmartGemaal = Speerpunt::create([
'thema_id' => $themaInfra->id,
'naam' => 'Slimme Gemaalbesturing',
'beschrijving' => 'Predictieve sturing van gemalen op basis van weersvoorspelling en waterstanden.',
'eigenaar_id' => $testUser->id,
'status' => SpeerpuntStatus::Actief,
]);
// Data-gedreven Beheer
$spDigitaalTwin = Speerpunt::create([
'thema_id' => $themaData->id,
'naam' => 'Digitale Tweeling Watersysteem',
'beschrijving' => 'Virtueel model van het watersysteem voor scenario-analyse en operationele ondersteuning.',
'eigenaar_id' => $analyst->id,
'status' => SpeerpuntStatus::Concept,
]);
$spAIVoorspelling = Speerpunt::create([
'thema_id' => $themaData->id,
'naam' => 'AI-gestuurde Waterstandsvoorspelling',
'beschrijving' => 'Machine learning modellen voor nauwkeurige korte- en middellangetermijnwaterstanden.',
'eigenaar_id' => $analyst->id,
'status' => SpeerpuntStatus::Actief,
]);
// Duurzaamheid
$spEnergieneutraal = Speerpunt::create([
'thema_id' => $themaDuurzaam->id,
'naam' => 'Energieneutrale Zuivering',
'beschrijving' => 'Zelfvoorzienende rwzi\'s door terugwinning van energie uit afvalwater.',
'eigenaar_id' => $engineer->id,
'status' => SpeerpuntStatus::Actief,
]);
$spCirculaireWater = Speerpunt::create([
'thema_id' => $themaDuurzaam->id,
'naam' => 'Circulaire Waterketen',
'beschrijving' => 'Terugwinning van grondstoffen (fosfaat, cellulose, warmte) uit afvalwater.',
'eigenaar_id' => $testUser->id,
'status' => SpeerpuntStatus::Concept,
]);
// ──────────────────────────────────────────────────────────────
// 5. Projects (1012 spread across themes and lifecycle phases)
// ──────────────────────────────────────────────────────────────
$projects = [];
// --- Waterkwaliteit projects ---
$p1 = $this->createProject([
'speerpunt_id' => $spWaterMonitoring->id,
'naam' => 'LoRaWAN Sensornetwerk Biesbosch',
'beschrijving' => 'Uitrol van een draadloos sensornetwerk in het Biesbosch-gebied voor real-time meting van waterkwaliteitsparameters (pH, DO, troebelheid, geleidbaarheid).',
'eigenaar_id' => $testUser->id,
'status' => ProjectStatus::Pilot,
'prioriteit' => Prioriteit::Hoog,
'startdatum' => '2025-03-01',
'streef_einddatum' => '2025-12-31',
], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment, FaseType::Pilot]);
$p2 = $this->createProject([
'speerpunt_id' => $spWaterMonitoring->id,
'naam' => 'Drone-inspectie Waterbodem',
'beschrijving' => 'Onderzoek naar de inzet van autonome onderwaterdrones voor sedimentkartering en vervuilingdetectie in kanalen en sloten.',
'eigenaar_id' => $engineer->id,
'status' => ProjectStatus::Experiment,
'prioriteit' => Prioriteit::Midden,
'startdatum' => '2025-06-01',
'streef_einddatum' => '2026-06-30',
], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment]);
$p3 = $this->createProject([
'speerpunt_id' => $spMicropollution->id,
'naam' => 'PFAS Detectiemethode Ontwikkeling',
'beschrijving' => 'Ontwikkeling van een snelle en goedkope veldmethode voor PFAS-detectie in oppervlaktewater, als alternatief voor kostbare laboratoriumanalyse.',
'eigenaar_id' => $analyst->id,
'status' => ProjectStatus::Verkenning,
'prioriteit' => Prioriteit::Hoog,
'startdatum' => '2025-09-01',
'streef_einddatum' => '2026-09-30',
], [FaseType::Signaal, FaseType::Verkenning]);
// --- Slimme Infrastructuur projects ---
$p4 = $this->createProject([
'speerpunt_id' => $spDigitaalBeheer->id,
'naam' => 'BIM-model Gemaal De Donge',
'beschrijving' => 'Digitale driedimensionale representatie van gemaal De Donge inclusief alle technische installaties, leidingen en elektrotechnische componenten.',
'eigenaar_id' => $engineer->id,
'status' => ProjectStatus::OverdrachtBouwen,
'prioriteit' => Prioriteit::Midden,
'startdatum' => '2024-09-01',
'streef_einddatum' => '2025-06-30',
], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment, FaseType::Pilot, FaseType::Besluitvorming, FaseType::OverdrachtBouwen]);
$p5 = $this->createProject([
'speerpunt_id' => $spSmartGemaal->id,
'naam' => 'Predictieve Gemaalbesturing Mark-Vliet',
'beschrijving' => 'Implementatie van een ML-algoritme dat op basis van KNMI-weerdata en historische afvoerpatronen de optimale pompsturing berekent voor het Mark-Vliet systeem.',
'eigenaar_id' => $testUser->id,
'status' => ProjectStatus::Besluitvorming,
'prioriteit' => Prioriteit::Hoog,
'startdatum' => '2025-01-01',
'streef_einddatum' => '2025-12-31',
], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment, FaseType::Pilot, FaseType::Besluitvorming]);
$p6 = $this->createProject([
'speerpunt_id' => $spSmartGemaal->id,
'naam' => 'Remote Monitoring Waterkeringen',
'beschrijving' => 'Continuemonitoring van primaire waterkeringen met IoT-sensoren voor zakking, piping-detectie en grondwaterstand.',
'eigenaar_id' => $engineer->id,
'status' => ProjectStatus::Signaal,
'prioriteit' => Prioriteit::Laag,
'startdatum' => '2026-01-01',
'streef_einddatum' => null,
], [FaseType::Signaal]);
// --- Data-gedreven Beheer projects ---
$p7 = $this->createProject([
'speerpunt_id' => $spDigitaalTwin->id,
'naam' => 'Digitale Tweeling Pilot Roosendaalse Vliet',
'beschrijving' => 'Eerste proof-of-concept van een digitale tweeling voor het deelgebied Roosendaalse Vliet, gekoppeld aan het SOBEK-hydraulisch model.',
'eigenaar_id' => $analyst->id,
'status' => ProjectStatus::Concept,
'prioriteit' => Prioriteit::Hoog,
'startdatum' => '2025-07-01',
'streef_einddatum' => '2026-12-31',
], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept]);
$p8 = $this->createProject([
'speerpunt_id' => $spAIVoorspelling->id,
'naam' => 'AI Waterstandsmodel Hollandsch Diep',
'beschrijving' => 'Training en validatie van een LSTM-neuraal netwerk voor 48-uurs waterstandsvoorspellingen op het Hollandsch Diep, ter vervanging van het huidige regressiemodel.',
'eigenaar_id' => $analyst->id,
'status' => ProjectStatus::Experiment,
'prioriteit' => Prioriteit::Hoog,
'startdatum' => '2025-04-01',
'streef_einddatum' => '2026-03-31',
], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment]);
$p9 = $this->createProject([
'speerpunt_id' => $spAIVoorspelling->id,
'naam' => 'Open Data Platform Waterschap',
'beschrijving' => 'Ontwikkeling van een publiekstoegankelijk data-portaal voor het ontsluiten van historische en actuele meetdata van het waterschap.',
'eigenaar_id' => $testUser->id,
'status' => ProjectStatus::Geparkeerd,
'prioriteit' => Prioriteit::Laag,
'startdatum' => '2024-06-01',
'streef_einddatum' => '2025-12-31',
], [FaseType::Signaal, FaseType::Verkenning]);
// --- Duurzaamheid projects ---
$p10 = $this->createProject([
'speerpunt_id' => $spEnergieneutraal->id,
'naam' => 'Biogasopwaardering RWZI Bath',
'beschrijving' => 'Opwaardering van slibvergistingsgas naar groengas-kwaliteit voor invoeding op het gasnet en verkoop aan een energiemaatschappij.',
'eigenaar_id' => $engineer->id,
'status' => ProjectStatus::Evaluatie,
'prioriteit' => Prioriteit::Midden,
'startdatum' => '2024-01-01',
'streef_einddatum' => '2025-06-30',
], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment, FaseType::Pilot, FaseType::Besluitvorming, FaseType::OverdrachtBouwen, FaseType::OverdrachtBeheer, FaseType::Evaluatie]);
$p11 = $this->createProject([
'speerpunt_id' => $spCirculaireWater->id,
'naam' => 'Fosfaatterugwinning Struviet',
'beschrijving' => 'Implementatie van struvietkristallisatie-technologie op RWZI Nieuw-Vossemeer voor de terugwinning van fosfaat als meststof.',
'eigenaar_id' => $testUser->id,
'status' => ProjectStatus::Pilot,
'prioriteit' => Prioriteit::Midden,
'startdatum' => '2025-02-01',
'streef_einddatum' => '2026-02-28',
], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment, FaseType::Pilot]);
$p12 = $this->createProject([
'speerpunt_id' => $spEnergieneutraal->id,
'naam' => 'Warmteterugwinning Afvalwater Centrum',
'beschrijving' => 'Pilotinstallatie voor warmtewisselaars op het rioolstelsel in Breda-centrum om warmte terug te winnen voor stadsverwarming.',
'eigenaar_id' => $engineer->id,
'status' => ProjectStatus::Verkenning,
'prioriteit' => Prioriteit::Midden,
'startdatum' => '2025-10-01',
'streef_einddatum' => '2027-03-31',
], [FaseType::Signaal, FaseType::Verkenning]);
$projects = [$p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9, $p10, $p11, $p12];
// ──────────────────────────────────────────────────────────────
// 6. Assign team members
// ──────────────────────────────────────────────────────────────
$p1->teamleden()->attach($analyst->id, ['rol' => ProjectRol::Lid->value]);
$p2->teamleden()->attach($testUser->id, ['rol' => ProjectRol::Reviewer->value]);
$p5->teamleden()->attach($analyst->id, ['rol' => ProjectRol::Lid->value]);
$p5->teamleden()->attach($engineer->id, ['rol' => ProjectRol::Reviewer->value]);
$p8->teamleden()->attach($engineer->id, ['rol' => ProjectRol::Lid->value]);
// ──────────────────────────────────────────────────────────────
// 7. Commitments
// ──────────────────────────────────────────────────────────────
Commitment::create([
'project_id' => $p1->id,
'beschrijving' => 'Installatie van 20 sensorknooppunten in het veld vóór einde Q3 2025',
'eigenaar_id' => $testUser->id,
'deadline' => '2025-09-30',
'status' => CommitmentStatus::InUitvoering,
'bron' => 'Stuurgroep Waterkwaliteit — 12 maart 2025',
]);
Commitment::create([
'project_id' => $p1->id,
'beschrijving' => 'Validatierapport sensornauwkeurigheid opleveren aan dataplatformteam',
'eigenaar_id' => $analyst->id,
'deadline' => '2025-11-30',
'status' => CommitmentStatus::Open,
'bron' => 'Stuurgroep Waterkwaliteit — 12 maart 2025',
]);
Commitment::create([
'project_id' => $p5->id,
'beschrijving' => 'Afstemming met Rijkswaterstaat over databeschikbaarheid afvoermetingen',
'eigenaar_id' => $engineer->id,
'deadline' => '2025-07-31',
'status' => CommitmentStatus::Afgerond,
'bron' => 'Projectstartup 15 januari 2025',
]);
Commitment::create([
'project_id' => $p5->id,
'beschrijving' => 'Businesscase energiebesparing opstellen voor directie',
'eigenaar_id' => $testUser->id,
'deadline' => '2025-10-15',
'status' => CommitmentStatus::Open,
'bron' => 'Besluitvormingsrapport fase 5',
]);
Commitment::create([
'project_id' => $p8->id,
'beschrijving' => 'Trainingsdata leveren: minimaal 5 jaar uurlijkse waterstandsmetingen',
'eigenaar_id' => $analyst->id,
'deadline' => '2025-08-01',
'status' => CommitmentStatus::Afgerond,
'bron' => 'Projectplan AI Waterstandsmodel v1.0',
]);
Commitment::create([
'project_id' => $p10->id,
'beschrijving' => 'Eindrapportage energieopbrengst en milieuprestatie biogasinstallatie',
'eigenaar_id' => $engineer->id,
'deadline' => '2025-05-31',
'status' => CommitmentStatus::Afgerond,
'bron' => 'Evaluatieprogramma RWZI Bath',
]);
Commitment::create([
'project_id' => $p11->id,
'beschrijving' => 'Technische specificaties struvietreactor aanleveren aan leverancier',
'eigenaar_id' => $testUser->id,
'deadline' => '2025-05-01',
'status' => CommitmentStatus::Afgerond,
'bron' => 'Pilotopzet Fosfaatterugwinning',
]);
// ──────────────────────────────────────────────────────────────
// 8. Documents
// ──────────────────────────────────────────────────────────────
Document::create([
'project_id' => $p1->id,
'titel' => 'Technisch Ontwerp LoRaWAN Netwerk',
'type' => 'technisch_ontwerp',
'inhoud' => 'Systeemarchitectuur, gatewaylocaties, frequentieplan en databeheerprotocol voor het LoRaWAN sensornetwerk in het Biesboschgebied.',
'versie' => 2,
'auteur_id' => $engineer->id,
]);
Document::create([
'project_id' => $p1->id,
'titel' => 'Projectplan Fase Pilot',
'type' => 'projectplan',
'inhoud' => 'Doelstellingen, activiteiten, planning en risico\'s voor de pilotfase van het LoRaWAN sensornetwerk.',
'versie' => 1,
'auteur_id' => $testUser->id,
]);
Document::create([
'project_id' => $p5->id,
'titel' => 'Businesscase Predictieve Gemaalbesturing',
'type' => 'businesscase',
'inhoud' => 'Kosten-batenanalyse voor de implementatie van ML-gestuurde pompsturing, inclusief energiebesparingspotentieel en investeringskosten.',
'versie' => 3,
'auteur_id' => $testUser->id,
]);
Document::create([
'project_id' => $p8->id,
'titel' => 'Modelarchitectuur LSTM Waterstandsvoorspelling',
'type' => 'technisch_rapport',
'inhoud' => 'Gedetailleerde beschrijving van de LSTM-netwerkarchitectuur, feature engineering, trainingsopzet en validatiemethodiek.',
'versie' => 1,
'auteur_id' => $analyst->id,
]);
Document::create([
'project_id' => $p10->id,
'titel' => 'Evaluatierapport Biogasopwaardering RWZI Bath',
'type' => 'evaluatierapport',
'inhoud' => 'Eindresultaten van de biogasopwaarderingsinstallatie: energieproductie, CH4-gehalte, opbrengst en geleerde lessen.',
'versie' => 1,
'auteur_id' => $engineer->id,
]);
Document::create([
'project_id' => $p4->id,
'titel' => 'BIM-protocol Kunstwerken v2.0',
'type' => 'protocol',
'inhoud' => 'Afspraken voor objectcodering, LOD-niveaus, attribuutvelden en uitwisselformaten (IFC) voor het BIM-model van kunstwerken.',
'versie' => 2,
'auteur_id' => $engineer->id,
]);
// ──────────────────────────────────────────────────────────────
// 9. Dependencies between projects
// ──────────────────────────────────────────────────────────────
// AI Waterstandsmodel is afhankelijk van LoRaWAN Sensornetwerk (databron)
Afhankelijkheid::create([
'project_id' => $p8->id,
'afhankelijk_van_project_id' => $p1->id,
'type' => 'data',
'beschrijving' => 'Het AI-model heeft real-time sensordata nodig uit het LoRaWAN netwerk als input feature.',
'status' => 'actief',
]);
// Digitale Tweeling is afhankelijk van AI Waterstandsmodel
Afhankelijkheid::create([
'project_id' => $p7->id,
'afhankelijk_van_project_id' => $p8->id,
'type' => 'technisch',
'beschrijving' => 'De digitale tweeling integreert de voorspellingsmodule van het AI waterstandsmodel.',
'status' => 'actief',
]);
// Predictieve Gemaalbesturing is afhankelijk van AI Waterstandsmodel
Afhankelijkheid::create([
'project_id' => $p5->id,
'afhankelijk_van_project_id' => $p8->id,
'type' => 'technisch',
'beschrijving' => 'De predictieve besturing gebruikt de 48-uurs waterstandsvoorspellingen als stuurinput.',
'status' => 'actief',
]);
// Remote Monitoring Waterkeringen is afhankelijk van LoRaWAN Sensornetwerk
Afhankelijkheid::create([
'project_id' => $p6->id,
'afhankelijk_van_project_id' => $p1->id,
'type' => 'infrastructuur',
'beschrijving' => 'Het monitoring-project maakt gebruik van de LoRaWAN-infrastructuur voor datatransport.',
'status' => 'gepland',
]);
}
/**
* Helper: create a project with its completed and active phases.
*
* @param array<string, mixed> $attributes
* @param FaseType[] $faseTypes All phase types in chronological order; the last one is the active phase.
*/
private function createProject(array $attributes, array $faseTypes): Project
{
$project = Project::create($attributes);
// Attach the project owner as eigenaar in the pivot table
$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;
}
}