Een webapp die elke tandartsnota automatisch toetst aan de officiële NZa-tarieven
Notacheckers is een webapp die Nederlandse tandartsnota's automatisch controleert. Een gebruiker uploadt een PDF of foto, AI leest de declaratieregels uit, en elke regel wordt vergeleken met 772 officiële NZa-tarieven uit 2026. Mogelijke overschrijdingen worden direct gemarkeerd. Volledig anoniem en serverless op Cloudflare, door mij solo gebouwd.

De uitdaging.
Een tandartsnota controleren is voor de meeste mensen vrijwel onmogelijk. De officiële NZa-tarieven zijn openbaar, maar verspreid over losse documenten per zorgsoort, en een nota staat vol codes zoals C11, M03 of V30 zonder uitleg. Tegelijk was er volop nieuws over te hoge mondzorgrekeningen. De opdracht: bouw een gratis, laagdrempelige tool waar iemand zijn nota (PDF of foto) uploadt en meteen ziet of die klopt.
De moeilijkheid zit in de keten. Een ongestructureerd document moet betrouwbaar worden omgezet naar gestructureerde regels, rommelig uitgelezen codes moeten matchen met een officiële catalogus, en elke regel moet worden getoetst aan een regelgebonden dataset met randgevallen zoals variabele tarieven en verplichte combinatiecodes. Dat alles moet strikt anoniem gebeuren en goedkoop kunnen draaien bij onvoorspelbare bezoekersaantallen. Geen accounts, geen persoonsgegevens, geen serverpark om te beheren.
De aanpak.
De kern is een flow van vier stappen met een mens in de lus: uploaden, controleren, checken, resultaat. De gebruiker uploadt een bestand, AI leest de factuur uit tot gestructureerde data, en de gebruiker bevestigt of corrigeert wat is uitgelezen voordat er iets wordt gevalideerd. Pas daarna draait de validatie elke bevestigde regel langs de NZa-catalogus en berekent eventuele overschrijdingen.
Privacy zit in het ontwerp, niet als bijzaak: elke controle is anoniem, krijgt automatisch een vervaldatum van 30 dagen en wordt door een dagelijkse cron opgeruimd. Elke stap schrijft naar een append-only gebeurtenissenlog, zodat de status en de audittrail altijd herleidbaar zijn. De hele oplossing is test-gedreven gebouwd: 249 testcases dekken de extractie, de validatieregels, de betaling, de retentie en de beveiliging af.
Architectuur en keuzes.
- ·
SvelteKit op Cloudflare Workers. Een gratis publiekstool met onvoorspelbaar verkeer moet goedkoop aan de rand draaien, zonder server om te beheren en zonder koude opstart.
- ·
Neon Postgres met Drizzle ORM. De controle is een toestandsmachine (uploaded, review_required, validated, failed) die relationele integriteit vraagt. Cloudflare Hyperdrive lost de connection-pooling op vanuit een Workers-isolate.
- ·
OpenAI met een strikt JSON-schema, geen klassieke OCR. Tandartsnota's verschillen enorm in lay-out. Een visueel model met een afgedwongen schema (bedragen als integer-centen, codes in hoofdletters, nullable velden) levert schonere data dan template-OCR.
- ·
Stripe en de PDF-generator met de hand gebouwd. Stripe draait op fetch plus Web Crypto HMAC voor webhookverificatie, de PDF wordt byte voor byte geschreven. Node-gebaseerde SDK's en PDF-bibliotheken draaien namelijk niet op Workers-isolates.
- ·
Zod, magic-byte validatie en een HMAC-fingerprint. Dekken payload-validatie, bestandsveiligheid en dubbeldetectie af, zonder de inhoud identificeerbaar op te slaan.
De moeilijkste problemen, opgelost.
- 1
Codes ontwarren van hoeveelheden. AI leverde soms codes als M03X6 aan, waarbij de 6 eigenlijk een aantal is. Een canonicalisatie-functie matcht tegen de 772-catalogus via langste-match, haalt de hoeveelheid eruit en herstelt de echte code. Het systeemprompt instrueert het model bovendien expliciet om de vermenigvuldiger nooit aan de code te plakken.
- 2
Variabele tarieven niet raden. 49 orthodontiecodes hebben meerdere geldige A/B/C-tarieven, afhankelijk van welke lijst van toepassing is. In plaats van een bedrag te gokken, markeert de tool die als context vereist. Eerlijkheid boven schijnprecisie: een valse “klopt niet” is erger dan geen oordeel.
- 3
Stripe en PDF op Workers zonder SDK. Webhookhandtekeningen worden geverifieerd met een eigen, timing-safe HMAC-vergelijking (300 seconden tolerantie), en het betaalde rapport wordt als rauwe PDF-bytes opgebouwd. Beide omzeilen dat de gangbare bibliotheken niet aan de rand draaien.
- 4
Privacy by design. Geen naam, adres of IP in de controle, alleen een anonieme kopie met praktijknaam, een vervaldatum van 30 dagen en een dagelijkse opruimcron. Misbruik wordt geremd met rate limiting (16 uploads per 10 minuten) zonder het IP-adres in de controle vast te leggen.
Resultaat.
Het resultaat is een werkende, geteste en privacy-first webapp die 772 officiële NZa-codes over drie zorgsoorten dekt, met 249 testcases en 651 assertions, solo gebouwd in ongeveer 4,5 week. Een gebruiker ziet per regel of die klopt, of er mogelijk te veel is gerekend en met hoeveel, en kan optioneel een uitgebreid PDF-rapport ontgrendelen en laten mailen.
Voor een ondernemer is de brug recht: dezelfde keten, AI leest een document uit en een regelmotor toetst elke regel aan jouw eigen regels of dataset, past op vrijwel elk documentzwaar proces. Denk aan inkoopfacturen tegen contractprijzen, polisvoorwaarden, declaraties of compliance-checks tegen een wettelijk kader. Legt jouw team stapels PDF's handmatig langs een set regels, dan is dit precies de capaciteit die dat werk automatiseert. Het draait serverless, dus de kosten schalen mee met het gebruik in plaats van met vaste infrastructuur.
Onder de motorkap.
Veelgestelde vragen.
Iets wat hier niet bij staat? Mail rechtstreeks.
Kan dit ook voor mijn facturen of processen? +
Ja. De opzet is generiek: AI leest een document uit tot gestructureerde velden, en een regelmotor toetst die aan jouw dataset of regels. De tandartsnota is hier de casus, maar dezelfde keten werkt voor inkoopfacturen, leveranciersbonnen, contracten, polissen of compliance-controles. Wat verandert is het schema en de regels, niet de architectuur.
Hoe lang duurde dit om te bouwen? +
Ongeveer 4,5 week door één ontwikkelaar. Dat omvat de volledige keten: upload, AI-extractie, bevestiging door de gebruiker, validatie, resultaatpagina, betaalde-rapport-flow, e-mailbezorging en de privacy- en retentielogica, met 249 geautomatiseerde tests.
Wat kost zoiets ongeveer? +
Een gefocuste eerste versie in deze stijl start doorgaans in de lage vier cijfers en groeit met de scope (AI-extractie, betalingen, rapportage en AVG-logica voegen elk werk toe). De exacte prijs hangt af van het aantal documenttypes, de complexiteit van je regels en de integraties. Voor een concrete inschatting kijken we samen naar jouw documenten en proces.
Is AI-extractie betrouwbaar genoeg om op te bouwen? +
De tool vertrouwt niet blind op het model. Het AI-antwoord wordt afgedwongen via een strikt JSON-schema, de gebruiker bevestigt of corrigeert de uitgelezen data voordat er iets wordt gevalideerd, en codes die niet in de officiële lijst staan worden expliciet als niet automatisch gecontroleerd gemarkeerd. Die mens-in-de-lus en het bewust niet-raden zijn ontwerpkeuzes, geen toeval.
Hoe zit het met privacy en AVG? +
Privacy is in het datamodel ingebouwd. Geen account, geen naam of adres, geen IP-adres in de controle. Er wordt een anonieme kopie met praktijknaam bewaard voor de controle en statistiek, elke controle vervalt na 30 dagen en wordt automatisch gewist. Een e-mailadres wordt alleen opgeslagen als de gebruiker er zelf om vraagt om het PDF-rapport te ontvangen.