diff --git a/CLAUDE.md b/CLAUDE.md index 54dc9d6..9801c23 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -59,6 +59,37 @@ The project wiki lives in `wiki/` and follows the wiki-template schema. It is th **After making significant changes:** update relevant wiki pages, `knowledge-graph.yaml`, and `wiki/log.md`. +## Metro Map Data Rules + +The metro map is the primary navigation and knowledge structure. These rules govern how content maps to the visual metro metaphor. + +### Thema = Metro Line (Dim 1) +Each thema is a horizontal metro line at the strategy level. Keep themas to major organizational concerns: +- **R&D Planning 2026** themes (Architectuur, Productiewaardig, Lab, Governance) +- **Onderzoek** — all research work (R&D-driven and student) + +### Project = Station (Dim 1) +Each project is a station on its thema's line. Stations are zoomable into Dim 2. + +### Student Work Rules +Student projects live under the **Onderzoek** thema. Structure: +1. **Each student gets their own track (metro line) within the Onderzoek thema** — unless they build on another student's work +2. **Students who build on each other share a track** — chronological stations on the same line, earlier work first +3. **Cross-references determine track grouping**, not topic similarity. Evidence: explicit mentions of another student's work, reuse of their system/data, or continuation of their project +4. **Identified chains** (from cross-reference analysis of source documents): + - **Gemalen & CRC track**: Grace van Geel (pump curves) → Kevin Haest (CRC/IOT2050, references Grace) → Robin van Weelie (D.R.A.I.N., references CRC) → Adriaan Sol (pilot 3, references D.R.A.I.N.) + - **Monitoring branch** (forks from Kevin): Kevin Haest → Yamai van Rooij (CRC 78x, MCSA, references Kevin) + - **Zuivering track**: Noa de Groot (beluchting) ‖ Elise Nouws (algen, parallel approach to same problem) + - **EVOLV Reactor**: Pieter van der Wilt (standalone — EVOLV ASM model, no student cross-refs) + - **IoT & Infra track**: Bart van Gool (IoT-hub) → Fontys ICT (Docker/CI-CD/SOC) → Fontys TOGAF (security) +5. **Dependencies to 2026 projects** are tracked as `Afhankelijkheid` records (type: technisch/data/infrastructuur) + +### Kennis Artikelen +Standalone knowledge articles extracted from research. Not tied to a project lifecycle. Used by the AI/search engine for semantic retrieval. + +### Grid Alignment +All node positions must be multiples of GRID=50. Server-side: `MapDataService::snapToGrid()`. Client-side: `gridConstants.js`. + ## What Requires Human Validation - Architecture decisions - Domain model changes diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index a77fbf4..745eac5 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -601,50 +601,71 @@ class DatabaseSeeder extends Seeder 'status' => 'open', ]); - // ══════════════════════════════════════════════════════════════ - // 10. STUDENTEN — Thema met afstudeer-/stageprojecten + // ══════════════════════════════════════════════════════════════════ + // 10. ONDERZOEK — Research thema with student tracks // - // Source: raw/*.docx, raw/*.pdf, raw/*.pptx - // ══════════════════════════════════════════════════════════════ + // Track grouping based on cross-reference analysis of source docs. + // Students who build on each other share a track (same speerpunt). + // See CLAUDE.md "Metro Map Data Rules > Student Work Rules". + // ══════════════════════════════════════════════════════════════════ - $themaStudenten = Thema::create([ - 'naam' => 'Studenten & Onderzoek', - 'beschrijving' => 'Afstudeer-, stage- en groepsprojecten van studenten (Avans, Fontys, TU/e) binnen het R&D-lab. Kennisbasis voor toekomstige innovaties.', + $themaOnderzoek = Thema::create([ + 'naam' => 'Onderzoek', + 'beschrijving' => 'Afstudeer-, stage- en groepsprojecten (Avans, Fontys, TU/e). Tracks gegroepeerd op basis van cross-referenties: studenten die op elkaars werk voortbouwen delen een track.', 'prioriteit' => Prioriteit::Midden, 'periode_start' => '2021-07-01', 'periode_eind' => '2026-12-31', ]); - // --- Speerpunten per domein --- + // --- Speerpunten = tracks based on cross-reference chains --- + // See CLAUDE.md "Student Work Rules" for evidence - $spGemalenPompen = Speerpunt::create([ - 'thema_id' => $themaStudenten->id, - 'naam' => 'Gemalen & Pompen', - 'beschrijving' => 'Studentenonderzoek naar rioolgemalen, pompefficiëntie, regelsoftware en digitale tweelingen voor pompsystemen.', + // TRACK 1: Gemalen & CRC chain + // Grace (pump curves, refs CRC 18x) → Kevin (CRC/IOT2050, refs Grace) → Robin (D.R.A.I.N., refs CRC 3x) → Adriaan (pilot 3, refs D.R.A.I.N.) + $spGemalenCRC = Speerpunt::create([ + 'thema_id' => $themaOnderzoek->id, + 'naam' => 'Gemalen & CRC Keten', + 'beschrijving' => 'Ketensamenwerking: pompefficiëntie → CRC edge computing → regelsoftware → pilot gemaalketen. Grace → Kevin → Robin → Adriaan.', 'eigenaar_id' => $rene->id, 'status' => SpeerpuntStatus::Actief, ]); + // TRACK 2: Monitoring branch (forks from Kevin's CRC) + // Kevin → Yamai (CRC 78x, MCSA, explicitly references Kevin) + $spMonitoring = Speerpunt::create([ + 'thema_id' => $themaOnderzoek->id, + 'naam' => 'Condition Monitoring (CRC→MCSA)', + 'beschrijving' => 'Vertakking vanuit Kevin\'s CRC: Yamai bouwt voort met Motor Current Signal Analysis voor condition-based monitoring.', + 'eigenaar_id' => $rene->id, + 'status' => SpeerpuntStatus::Actief, + ]); + + // TRACK 3: Zuivering & Beluchting + // Noa (beluchting 24x) ‖ Elise (algen 289x, beluchting 92x) — parallel approaches to same problem $spZuivering = Speerpunt::create([ - 'thema_id' => $themaStudenten->id, - 'naam' => 'Zuiveringsproces & Biologie', - 'beschrijving' => 'Onderzoek naar beluchtingsoptimalisatie, algenproductie, activated sludge modellen en biologische processen.', + 'thema_id' => $themaOnderzoek->id, + 'naam' => 'Zuivering & Beluchting', + 'beschrijving' => 'Parallelle aanpak beluchtingsprobleem: Noa (mechanisch model) en Elise (biologisch via algen). Geen directe cross-refs maar zelfde onderzoeksvraag.', 'eigenaar_id' => $rene->id, 'status' => SpeerpuntStatus::Actief, ]); - $spEdgeArch = Speerpunt::create([ - 'thema_id' => $themaStudenten->id, - 'naam' => 'EDGE & Architectuur', - 'beschrijving' => 'Studentenonderzoek naar edge computing, IoT-hubs, Carbon Reducing Controller, condition-based monitoring.', - 'eigenaar_id' => $pim->id, + // TRACK 4: EVOLV Reactor (standalone) + // Pieter (EVOLV 25x, reactor 55x) — no cross-refs to other students + $spReactor = Speerpunt::create([ + 'thema_id' => $themaOnderzoek->id, + 'naam' => 'EVOLV Reactor Model', + 'beschrijving' => 'Standalone masterstage: ASM reactor model voor EVOLV. Geen cross-refs naar andere studenten, directe EVOLV-bijdrage.', + 'eigenaar_id' => $rene->id, 'status' => SpeerpuntStatus::Actief, ]); - $spIctSecurity = Speerpunt::create([ - 'thema_id' => $themaStudenten->id, - 'naam' => 'ICT & Security', - 'beschrijving' => 'Groepsprojecten over Docker, CI/CD, SOC-implementatie en TOGAF security architectuur voor edge-apparaten.', + // TRACK 5: IoT & Infrastructuur + // Bart (IoT-hub, EDGE) → Fontys ICT (Docker/CI-CD/SOC) → Fontys TOGAF (EDGE security) + $spIoTInfra = Speerpunt::create([ + 'thema_id' => $themaOnderzoek->id, + 'naam' => 'IoT & ICT Infrastructuur', + 'beschrijving' => 'Infrastructuurketen: Bart (IoT-hub integratielaag) → Fontys ICT (Docker/CI-CD/SOC) → Fontys TOGAF (security architectuur). Alle drie raken edge-infra.', 'eigenaar_id' => $pim->id, 'status' => SpeerpuntStatus::Actief, ]); @@ -653,7 +674,7 @@ class DatabaseSeeder extends Seeder // Adriaan Sol — Pilot 3 rioolgemaalketen $pAdriaan = $this->createProject([ - 'speerpunt_id' => $spGemalenPompen->id, + 'speerpunt_id' => $spGemalenCRC->id, 'naam' => 'Ontwerp Pilot 3 Rioolgemaalketen', 'beschrijving' => 'Afstudeerstage Avans Chemische Technologie. Ontwerp van pilot 3 rioolgemaalketen bij RWZI Nieuwveer. Student: Adriaan Sol (2154257).', 'eigenaar_id' => $rene->id, @@ -678,7 +699,7 @@ class DatabaseSeeder extends Seeder // Robin van Weelie — D.R.A.I.N. $pRobin = $this->createProject([ - 'speerpunt_id' => $spGemalenPompen->id, + 'speerpunt_id' => $spGemalenCRC->id, 'naam' => 'D.R.A.I.N. – Regelsoftware Rioolgemalen', 'beschrijving' => 'Afstudeeronderzoek naar data-gedreven en energie-efficiënte aansturing rioolgemalen. Technische analyse Hooge- en Lage Zwaluwe, invloed kelderhoogte en drukverschil op energetisch gedrag.', 'eigenaar_id' => $rene->id, @@ -715,7 +736,7 @@ class DatabaseSeeder extends Seeder // Grace van Geel — Pompefficiëntie $pGrace = $this->createProject([ - 'speerpunt_id' => $spGemalenPompen->id, + 'speerpunt_id' => $spGemalenCRC->id, 'naam' => 'Efficiëntie-curve Centrifugaalpompen', 'beschrijving' => 'Afstudeeronderzoek Avans naar invloed van voordruk, verschildruk en parallel werkende pompen op de efficiëntie-curve van centrifugaalpompen. Student: Grace van Geel.', 'eigenaar_id' => $rene->id, @@ -787,8 +808,9 @@ class DatabaseSeeder extends Seeder ]); // Pieter van der Wilt — Reactor model EVOLV + // TRACK 4: EVOLV Reactor (standalone, no student cross-refs) $pPieter = $this->createProject([ - 'speerpunt_id' => $spZuivering->id, + 'speerpunt_id' => $spReactor->id, 'naam' => 'Non-Ideal ASM Reactor Model (EVOLV)', 'beschrijving' => 'Masterstage: ontwikkeling van een niet-ideaal activated sludge reactor model voor het EVOLV-framework. Focus op computational setup, reaction model, transfer terms. Student: Pieter van der Wilt.', 'eigenaar_id' => $rene->id, @@ -813,7 +835,7 @@ class DatabaseSeeder extends Seeder // Kevin Haest — Carbon Reducing Controller $pKevin = $this->createProject([ - 'speerpunt_id' => $spEdgeArch->id, + 'speerpunt_id' => $spGemalenCRC->id, 'naam' => 'Carbon Reducing Controller (Siemens IOT2050)', 'beschrijving' => 'Afstudeerproject Avans E&T: CRC-systeem met edge computing op de Siemens IOT2050. Integratie IoT in afvalwaterzuivering. Samenwerking met Minor Procesautomatisering. Student: Kevin Haest.', 'eigenaar_id' => $rene->id, @@ -838,8 +860,9 @@ class DatabaseSeeder extends Seeder ]); // Yamai van Rooij — Condition-based monitoring + CRC + MCSA + // TRACK 2: Monitoring branch (forks from Kevin's CRC) $pYamai = $this->createProject([ - 'speerpunt_id' => $spEdgeArch->id, + 'speerpunt_id' => $spMonitoring->id, 'naam' => 'Condition-Based Monitoring & MCSA', 'beschrijving' => 'Stage Avans IE&M: verbetering operationele efficiëntie via CRC-systeem en Motor Current Signal Analysis. Innovatie van onderhoudspraktijken en energieverbruik reductie.', 'eigenaar_id' => $rene->id, @@ -863,8 +886,9 @@ class DatabaseSeeder extends Seeder ]); // Bart van Gool — IoT-hub integratielaag + // TRACK 5: IoT & Infrastructuur chain $pBart = $this->createProject([ - 'speerpunt_id' => $spEdgeArch->id, + 'speerpunt_id' => $spIoTInfra->id, 'naam' => 'IoT-hub Implementatie Integratielaag', 'beschrijving' => 'Afstudeerproject Avans TI: implementatie van een IoT-hub in de integratielaag van het waterschap. Koppeling R&D en integratieteam. Student: Bart van Gool. Begeleider: Pim Moerman.', 'eigenaar_id' => $pim->id, @@ -890,7 +914,7 @@ class DatabaseSeeder extends Seeder // Fontys ICT groep — Docker, CI/CD, SOC $pFontysICT = $this->createProject([ - 'speerpunt_id' => $spIctSecurity->id, + 'speerpunt_id' => $spIoTInfra->id, 'naam' => 'Fontys ICT Proftaak – Docker & CI/CD & SOC', 'beschrijving' => 'Groepsopdracht Fontys ICT: (1) Docker Swarm & load balancing, (2) Geautomatiseerde CI/CD-pijplijn ter vervanging van USB-deployments, (3) SOC-implementatie voor procesautomatisering.', 'eigenaar_id' => $pim->id, @@ -916,7 +940,7 @@ class DatabaseSeeder extends Seeder // Fontys SOC/TOGAF groep $pTOGAF = $this->createProject([ - 'speerpunt_id' => $spIctSecurity->id, + 'speerpunt_id' => $spIoTInfra->id, 'naam' => 'TOGAF Security Architectuur Edge-Devices', 'beschrijving' => 'Fontys groepsproject: beveiligingsadvies op basis van TOGAF-methodiek + NIST Cybersecurity Framework voor edge-apparaten waterschap.', 'eigenaar_id' => $pim->id, @@ -940,27 +964,72 @@ class DatabaseSeeder extends Seeder 'auteur_id' => $pim->id, ]); - // --- Dependencies: student projects that feed into 2026 work --- + // --- Inter-student dependencies (track chains) --- + + // TRACK 1 chain: Grace → Kevin → Robin → Adriaan + Afhankelijkheid::create([ + 'project_id' => $pKevin->id, + 'afhankelijk_van_project_id' => $pGrace->id, + 'type' => 'data', + 'beschrijving' => 'Kevin references Grace\'s pump efficiency curves (CRC 18x in Grace\'s report). CRC builds on pump characterization.', + 'status' => 'opgelost', + ]); + Afhankelijkheid::create([ + 'project_id' => $pRobin->id, + 'afhankelijk_van_project_id' => $pKevin->id, + 'type' => 'technisch', + 'beschrijving' => 'Robin references CRC (3x) and uses Digital Twin approach enabled by Kevin\'s edge platform.', + 'status' => 'opgelost', + ]); + Afhankelijkheid::create([ + 'project_id' => $pAdriaan->id, + 'afhankelijk_van_project_id' => $pRobin->id, + 'type' => 'technisch', + 'beschrijving' => 'Adriaan references D.R.A.I.N. (1x). Pilot 3 keten design builds on Robin\'s gemaal analysis.', + 'status' => 'opgelost', + ]); + + // TRACK 2 branch: Kevin → Yamai + Afhankelijkheid::create([ + 'project_id' => $pYamai->id, + 'afhankelijk_van_project_id' => $pKevin->id, + 'type' => 'technisch', + 'beschrijving' => 'Yamai\'s MCSA work directly extends Kevin\'s CRC system (CRC referenced 78x). Explicitly references Kevin.', + 'status' => 'opgelost', + ]); + + // TRACK 5 chain: Bart → Fontys ICT → Fontys TOGAF + Afhankelijkheid::create([ + 'project_id' => $pFontysICT->id, + 'afhankelijk_van_project_id' => $pBart->id, + 'type' => 'infrastructuur', + 'beschrijving' => 'Fontys ICT Docker/CI-CD work extends Bart\'s IoT-hub integration layer infrastructure.', + 'status' => 'open', + ]); + Afhankelijkheid::create([ + 'project_id' => $pTOGAF->id, + 'afhankelijk_van_project_id' => $pFontysICT->id, + 'type' => 'technisch', + 'beschrijving' => 'TOGAF security architecture applies to the Docker/edge infrastructure set up by Fontys ICT.', + 'status' => 'open', + ]); + + // --- Student → 2026 project dependencies --- - // Kevin's CRC work feeds into BRIDGE (edge computing proof) Afhankelijkheid::create([ 'project_id' => $bridge->id, 'afhankelijk_van_project_id' => $pKevin->id, 'type' => 'technisch', - 'beschrijving' => 'BRIDGE bouwt voort op de CRC edge computing ervaring van Kevin Haest met de Siemens IOT2050.', + 'beschrijving' => 'BRIDGE bouwt voort op Kevin\'s CRC edge computing met Siemens IOT2050.', 'status' => 'opgelost', ]); - - // Robin's D.R.A.I.N. feeds into Gemaal 3.0 / Afvlakkingsregeling Afhankelijkheid::create([ 'project_id' => $gemaal->id, 'afhankelijk_van_project_id' => $pRobin->id, 'type' => 'data', - 'beschrijving' => 'Gemaal 3.0 gebruikt de meetdata en analyse van Robin over gemalen Hooge-/Lage Zwaluwe.', + 'beschrijving' => 'Gemaal 3.0 gebruikt Robin\'s meetdata en analyse gemalen Hooge-/Lage Zwaluwe.', 'status' => 'opgelost', ]); - - // Pieter's reactor model is direct EVOLV contribution Afhankelijkheid::create([ 'project_id' => $gemaal->id, 'afhankelijk_van_project_id' => $pPieter->id, diff --git a/resources/js/Components/MetroMap/MetroCanvas.vue b/resources/js/Components/MetroMap/MetroCanvas.vue index 521067b..ffab9b6 100644 --- a/resources/js/Components/MetroMap/MetroCanvas.vue +++ b/resources/js/Components/MetroMap/MetroCanvas.vue @@ -816,15 +816,19 @@ const renderDimension = (dimData, opacity, parentGroup) => { .attr('opacity', 0.5) .text('[○]') - // Station label + // Station label (truncated to prevent overlap, max ~20 chars) nodeGroups.append('text') .attr('x', 0) .attr('y', 28) .attr('text-anchor', 'middle') .attr('fill', '#e8e8e8') .attr('font-family', "'VT323', monospace") - .attr('font-size', '14px') - .text(d => d.name) + .attr('font-size', '13px') + .text(d => { + const name = d.name ?? '' + const maxLen = Math.max(12, Math.floor(GRID_STEP_X / 10)) + return name.length > maxLen ? name.slice(0, maxLen - 1) + '…' : name + }) // Status badge nodeGroups.filter(d => d.badge)