Architectuur op hoofdlijnen
Een pragmatisch opgezette multi-tenant SaaS-applicatie: één webapplicatie, serverless functies voor het zware werk, en een Postgres-database waarin autorisatie op rijniveau is afgedwongen.
De stack
| Laag | Invulling |
|---|---|
| Frontend | React 19, opgebouwd als single-page applicatie en gebouwd met Vite, met Tailwind CSS voor de opmaak |
| Serverfuncties | Serverless functies op Vercel — alle AI-aanroepen, exports en beheeracties lopen hierlangs |
| Database | Supabase (PostgreSQL) met row-level security op elke tabel |
| Vectorzoeken | pgvector binnen dezelfde database — geen aparte vectordienst |
| Authenticatie | Supabase Auth, uitsluitend op uitnodiging |
| Documentrendering | Server-side headless browser voor PDF-export |
| Foutmonitoring | Sentry, aan zowel client- als serverzijde |
Waarom deze opzet
Twee keuzes verdienen toelichting.
Alle AI-aanroepen via serverfuncties, nooit vanuit de browser. Sleutels voor AI-leveranciers en de service-rol van de database bestaan uitsluitend serverside. De browser kan geen AI-aanroep doen die niet eerst langs de eigen gateway gaat, waar autorisatie, budgetbewaking en promptresolutie plaatsvinden.
Geen aparte vectordatabase. De embeddings staan in dezelfde Postgres als de canvasdata. Daardoor geldt dezelfde row-level security voor het zoeken naar bewijs als voor de gewone data — tenant-isolatie hoeft niet in twee systemen apart kloppend gehouden te worden.
Omgevingen
Er zijn twee volwaardige omgevingen:
- Staging — schemakopie van productie met wegwerpbare inhoud. Elke databasewijziging wordt hier eerst bewezen.
- Productie — krijgt schemawijzigingen uitsluitend via een migratiebestand dat al op staging is toegepast en geverifieerd.
Die volgorde is geen afspraak maar een geautomatiseerde poort in de uitleverstraat; zie Kwaliteit en delivery.
Schaal van de codebase
| Onderdeel | Hoe het is geborgd |
|---|---|
| Databasemigraties | één basisbestand van 47.108 regels plus 26 migraties erna (stand 30 oktober 2026), elk een versiebeheerd bestand, op volgorde toegepast en eerst op staging bewezen |
| Component- en unittests | bij elke wijziging, verplicht vóór samenvoegen; 2.816 testbestanden |
| Testsuites voor tenant-isolatie | 134 reeksen, bij elke wijziging die de database raakt en elke nacht tegen een echte database |
| Nachtelijke controles | volledige reizen door de applicatie, de scheidingstoets, de modellijst en de scan op kwetsbare pakketten |
| Tabellen | 162 in het public-schema, op elke tabel rijbeveiliging |
| Architectuurbesluiten | 39, met alternatieven en de voorwaarden voor heroverweging |