W27 | Van submodules naar monorepo: toegeven dat dag 1 niet klopte
Build AI. Run AI. Own AI. — Week W27 · 29 juni-5 juli 2026
Build AI. Run AI. Own AI.
Ik bouw dit niet in een lab, maar middenin mijn eigen leven als zzp'er en vader — en toch ontwerp ik elke keuze alsof er een enterprise-klant op leunt: multi-tenant vanaf dag 1, secrets die nooit een mens ziet, migraties die nooit terug kunnen. Dit is het logboek van die combinatie: zelf bouwen, zelf draaiend houden, zelf eigenaar blijven — inclusief de aanname, de misser en de prijs van elke keuze.
Op dag 1 van dit platform koos ik ervoor om de belangrijkste onderdelen — de n8n-laag, de database — als losse Git-submodules te behandelen: elk onderdeel zijn eigen repository, bij elkaar gebracht in één overkoepelend project. Vier maanden later draaide ik die beslissing terug.
Het probleem dat opdook
3 juli 2026, na opnieuw een falende `git-finish`-run. De root-repo was op dat moment een Git-superproject met meerdere submodules, en dat type probleem kwam steeds terug: detached HEADs, verouderde refs, gitlink-pointers die niet klopten, half afgeronde finish-runs. Niet één keer, maar structureel.
De makkelijke weg die ik had kunnen nemen
De scripts zelf nog beter maken. Dat was ook letterlijk de eerste stap van mijn eigen plan: de git-hulpscripts "dual-mode" maken, zodat ze zowel met nog-bestaande submodules als met al-geabsorbeerde gewone mappen konden omgaan. Elke keer dat er een nieuwe edge case opdook, kon ik de scripts weer een beetje slimmer maken. Dat loste steeds één symptoom op — maar de onderliggende complexiteit, meerdere git-histories die met elkaar moesten kloppen, bleef gewoon bestaan.
De keuze die ik maakte en de strategie erachter
Erkennen dat het probleem niet in de scripts zat, maar in de submodule-structuur zelf. De keuze: PA-service wordt een gewone monorepo, zonder Git-submodules. Niet in één big-bang-overstap, maar gefaseerd — eerst de kleine services migreren om het patroon te bewijzen, dan de infra-kritische onderdelen, dan de losse klantproducten. En pas ná het weghalen van de laatste submodule de mapnamen opschonen, zodat een submodule-migratie en een hernoeming nooit tegelijk door elkaar heen liepen. Eén submodule bleef bewust, met een expliciete reden, tijdelijk een uitzondering: de n8n-workflows, omdat die een eigen beschermingsmechanisme hadden dat nog niet was overgezet.
Wat het kostte
Dit was geen klein opruimklusje. Het was twaalf losse migratiestappen, één voor één, over bijna elk onderdeel van het platform heen. En de ongemakkelijkste kost was niet technisch: het was erkennen dat dit mijn eigen dag-1-beslissing was, vier maanden eerder, die ik nu zelf terugdraaide. Geen externe aanleiding, geen klant die erom vroeg — gewoon mijn eigen eerdere keuze die niet bleek te werken.
Wat het nu oplevert en wat ik ervan leerde
Een directe, blijvende afspraak: vanaf nu geen nieuwe submodules meer toevoegen, en als een extern repo echt tijdelijk nodig is, leg dat dan expliciet vast als uitzondering met een einddatum. Maar belangrijker: dit is de stap die alles wat ik sindsdien heb gebouwd pas mogelijk maakte — één repo, waarin meerdere AI-agents naast elkaar kunnen werken zonder dat submodule-gedoe daar nog eens dwars doorheen loopt.