Brent Ceulemans
Al het werk

Case 02 · Onder NDA

Het systeem waar een bedrijf zijn dag in doorbrengt

Een installatiebedrijf groeide uit zijn Excel-bestanden en ontdekte daarna dat kant-en-klare software niet past op de manier waarop het echt werkt. Dit kwam ervoor in de plaats: één platform voor verkoop, planning, uitvoering op de werf, logistiek, boekhouding en een klantenportaal — en de keuzes die eronder liggen.

Rol
Enige developer — van datamodel tot deploy
Draait sinds
Begin 2026, dagelijks in productie
Gebruikers
Tientallen mensen per dag, plus een klantenportaal
Stack
React · TypeScript · Postgres · Supabase

Context

Wat het verving

Elk bedrijf dat een bepaalde grootte bereikt heeft dezelfde drie werktuigen: een Excel-bestand dat niemand durft aanraken, een gedeelde mailbox, en één persoon die nog weet hoe alles in elkaar past. Dat werkt tot het niet meer werkt — meestal net op de dag dat die persoon met verlof is.

Het voor de hand liggende antwoord is iets kopen. Dat mislukt om een specifieke reden: een standaard-CRM gaat uit van een verkoopproces, een standaard-ERP van een fabriek, en een bedrijf dat dingen plaatst bij mensen thuis is geen van beide. Je buigt het bedrijf naar de software, en het Excel-bestand komt stilletjes terug voor alles wat er niet in paste.

De opdracht was dus niet “digitaliseer dit”. Ze was: modelleer wat dit bedrijf echt doet, en maak de dag van elke rol korter in plaats van beter gedocumenteerd.

Omvang

Vijf lagen, één database

elke laag heeft zijn kleur

  1. Leads

    • kwalificatie
    • bronherkomst
    • opvolging
  2. Offertes

    • regelprijzen
    • btw-regimes
    • digitaal tekenen
  3. Werf

    • planning
    • uitvoering
    • voorraad
  4. Facturen

    • afpunten
    • btw-aangiftes
    • invordering
  5. Portaal

    • klant & partner
    • rollen & rechten
    • row-level security

Een opdracht schuift van links naar rechts door deze lagen, en elke overdracht is een plek waar vroeger een Excel-bestand stond. Ze op één database zetten is wat het overtypen wegneemt — en wat toegangscontrole meteen het moeilijkste probleem op deze pagina maakt.

Techniek

Keuzes die telden

en wat het alternatief kost

Een offerte is een contract, dus haar regels liggen vast

Een getekende offerte kan niet meer veranderen — niet haar prijzen, niet haar btw-regime, niet de volgorde van de regels. Ze aanpassen maakt een nieuwe revisie en laat de getekende versie exact zoals de klant ze zag. De factuur wordt daarna opgebouwd uit de getekende regels, niet opnieuw berekend met de huidige prijzen.

Waarom niet andersom

Het alternatief lijkt ongeveer een jaar lang eenvoudiger, tot een update van de prijslijst stilletjes herschrijft waarmee een klant akkoord ging. Zo’n bug vind je niet bij het testen; je vindt hem in een discussie.

Het portaal staat op dezelfde database, dus RLS is de bodem

Klanten en partners lezen hun eigen projecten uit dezelfde tabellen waarin de boekhouding werkt. Er is geen spiegeldatabase en geen sync-job. Elke tabel die het portaal raakt draagt een row-level policy, en die policy — niet de query, niet de component — bepaalt wat er terugkomt.

Waarom niet andersom

Een apart leesmodel is een tweede bron van waarheid, en een tweede bron van waarheid loopt scheef. Eén database houden betekent dat een policy het enige is dat tussen een klant en de rest van het bedrijf staat, en dat is precies de druk die er op hoort te staan. Ik test ze door als de verkeerde gebruiker in te loggen en het request te zien falen.

Geldinvarianten worden door de database gecontroleerd, volgens schema

Factuurtotalen moeten gelijk zijn aan de som van hun regels. De btw moet overeenkomen met het regime op de getekende offerte. Een betaling mag nooit afgepunt worden tegen een factuur van een andere klant. Dat zijn geplande checks op de echte data, en ze alarmeren alleen wanneer de toestand verandert — één keer bij het foutlopen, en opnieuw wanneer het weer klopt.

Waarom niet andersom

Financiële bugs zijn stil. Er wordt niets gegooid; een getal is gewoon verkeerd, en blijft verkeerd tot iemand met de hand hertelt. Een alarm dat elk kwartier afgaat staat binnen een dag op stil en is daarna waardeloos, dus het gaat af op overgangen.

Elke rol krijgt een eigen scherm, geen gefilterde versie van één scherm

De planner, de ploeg op de werf, het magazijn en de boekhouder kijken naar hetzelfde project via vier verschillende schermen. De werf-app toont vandaag, dit adres, dit materiaal, deze foto. De boekhouder ziet nooit een planningsraster.

Waarom niet andersom

Eén scherm met alles verstopt achter rechten is precies hoe bedrijfssoftware iets wordt dat mensen vermijden. Vier gerichte schermen bouwen kost echt geld; één scherm dat niemand wil openen kost meer, en dat zie je terug als een Excel-bestand dat opnieuw op iemands bureaublad verschijnt.

Werkwijze

Hoe het werk verloopt

  1. 01

    Eerst meelopen, dan pas modelleren

    Het datamodel komt uit kijken hoe een opdracht echt beweegt, niet uit een lastenboek. De woorden die mensen al gebruiken worden de tabelnamen.

  2. 02

    Eén laag volledig live zetten

    Offertes, helemaal van lead tot getekende pdf, voor er iets anders begint. Een laag die live staat leert je in een week meer dan een kwartaal plannen.

  3. 03

    De regels in de database zetten

    Constraints, policies en invariant-checks, want applicatiecode is waar regels vergeten raken. Als iets belangrijk is, moet het de schrijfactie weigeren.

  4. 04

    Zelf de deploy én het zaterdagtelefoontje dragen

    Architectuur, migraties, deploys en het incident zijn hetzelfde werk. Weten dat jij degene bent die gebeld wordt verandert wat je bereid bent te shippen.

Draai de check, lees de output, en dan pas zeggen dat het werkt.