Restructure student tracks by cross-reference chains, add project rules
Student tracks restructured based on document cross-reference analysis: - Track 1 "Gemalen & CRC Keten": Grace→Kevin→Robin→Adriaan (chain) - Track 2 "Condition Monitoring": Kevin→Yamai (fork from Track 1) - Track 3 "Zuivering & Beluchting": Noa‖Elise (parallel, same problem) - Track 4 "EVOLV Reactor Model": Pieter (standalone, no student cross-refs) - Track 5 "IoT & ICT Infra": Bart→Fontys ICT→Fontys TOGAF (chain) Inter-student dependencies added (7 new): - Grace→Kevin, Kevin→Robin, Robin→Adriaan (Track 1 chain) - Kevin→Yamai (Track 2 fork) - Bart→Fontys ICT→Fontys TOGAF (Track 5 chain) CLAUDE.md: Added "Metro Map Data Rules" section documenting: - Thema=line, Project=station, speerpunt=track grouping - Student work rules: cross-references determine track sharing - Identified chains with evidence (reference counts from source docs) - Grid alignment requirements MetroCanvas: Truncate long station labels to prevent overlap (max ~20 chars based on grid spacing, with ellipsis) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
31
CLAUDE.md
31
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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user