Nederlandse vertaling

Architecturale guardrail.

Een volledige vertaling over productieklare apps bouwen met AI, patronen en architecturale controle.

Architecturale Guardrail — Nederlandse Vertaling

Introductie

In deze video leer je een eenvoudige, herhaalbare werkwijze om apps uitsluitend met AI te bouwen. Je hebt geen honderden vaardigheden, gespecialiseerde agents en allerlei ingewikkelde mechanismen en strategieën nodig.

Dit is het enige wat je nodig hebt. Na deze video kun je vol vertrouwen productieklare apps bouwen met uitsluitend AI.

We weten allemaal dat het moeilijke deel niet is om AI code te laten schrijven. Het moeilijke deel is om goede code te blijven schrijven terwijl je app groeit. Misschien ben je eerder tegen bekende problemen aangelopen bij het bouwen met AI, zoals:

  • je contextvensters en sessielimieten bereiken;
  • AI die bestanden verzint;
  • AI die van het doel afwijkt;
  • AI die de architectuur niet volgt;
  • AI die geen veilige code bouwt;
  • bouwen met AI dat meer voelt als vibe coding, waarbij je door prompts simpelweg een hele app probeert te creëren.

Dat is de slechtst mogelijke manier om een applicatie te bouwen. Als je moeite hebt om de code die AI genereert te vertrouwen, dan zou deze video je problemen moeten oplossen.

Je leert een systeem om met AI te bouwen dat ik guardrail coding noem, oftewel de architecturale guardrail. Dit is precies het systeem dat ik heb gebruikt om Fun AI en Mochi uitsluitend met AI te bouwen.

Om dit in perspectief te plaatsen: Mochi heeft 1.200 functies die in vier maanden productieklaar zijn gebouwd met precies de architecturale guardrail die je vandaag leert.

Resultaten van leden

Om te bewijzen dat het systeem doet waarvoor het bedoeld is, zie je hier echte mensen die de architecturale guardrail hebben getest.

Sunny heeft vier apps gebouwd in minder dan 21 dagen. Hij zegt dat zijn tokenverbruik drastisch is gedaald en dat hij zijn kosten heeft verlaagd door van Cloud Max 20 over te stappen naar het 5x-plan. Dat komt doordat tokenoptimalisatie in de architecturale guardrail is ingebouwd.

Deze strategie werkt ongeacht of je Claude Code, Codex of Cursor gebruikt. Het is een systeem. Eén lid zegt dat hij iets heeft geleerd wat hij kan blijven gebruiken, ongeacht welke AI-tool morgen nog bestaat.

Een ander lid bouwde zijn volledige LinkedIn-publisher zonder AI voortdurend te begeleiden. Damian bouwde in tien uur een applicatie vanuit een leeg repository en voegde screenshots als bewijs toe. Hij schreef geen enkele prompt, omdat de architecturale guardrail alle benodigde onderdelen al bevatte. Daardoor kon hij zijn aandacht richten op de belangrijkste functie van zijn app: audio. Dat is de reden waarom dit één dag duurde in plaats van een maand.

In minder dan twee dagen bouwde iemand zijn volledige LinkedIn-DM-SaaS. In negen uur werkte de hele pipeline al. De kern van Ruby’s app werkt ook. Michelle deelde haar app en haar resultaat. Jan bracht zijn eerste functie met de architecturale guardrail uit voor een complexere multi-tenant modelleerapplicatie. Dat bewijst dat het systeem op iedere schaal werkt.

AI bouwde Jans app correct, precies zoals hij had gevraagd. Hij typte in gewoon Engels en AI bouwde het via de guardrail correct.

Stephen schreef na ongeveer een week dat de methodologie hem hielp een app te bouwen die kan meegroeien wanneer nieuwe functies worden toegevoegd. Ido loste binnen twee uur een knelpunt op waar hij al een tijd last van had. Jethan bracht de tweede functie van zijn app uit.

Dit bewijst dat het systeem werkt.

Wat je gaat leren

Elke module is één onderdeel van een laag binnen de architecturale guardrail. De architecturale guardrail omvat meerdere concepten en architectuurlagen. Het is een systeem waarin al deze onderdelen samenwerken om betere apps te bouwen.

De mindset

Om te laten zien wat er mogelijk is met de architecturale guardrail, laat ik Mochi zien. Mochi is onderdeel van Funnelmazi.ai, mijn eigen bedrijf.

Het bijzondere is dat de website van Funnelmazi.ai binnen Funnelmazi.ai zelf is gebouwd. Dat laat zien wat er in de app mogelijk is.

De app heeft een dashboard, een inboxpagina voor alle e-mails, producten, websitebouwers, formulierbouwers, CMS-tabellen, leads, leadlijsten, tracking, aangepaste gegevens, marketing, e-mailsjablonen, pipelines en automatiseringen.

Alles op de prijspagina is ingevoerd in een CMS-builder die gekoppeld is aan een CMS-lijst met componenten. Daardoor ziet alles er hetzelfde uit, kan alles opnieuw worden gebruikt en kunnen de gegevens per onderdeel verschillen.

Wanneer ik tussen de pagina’s navigeer, is alles extreem snel. Na de eerste weergave is er vrijwel geen laadtijd. Een wijziging wordt onmiddellijk bijgewerkt. Dit is een optimistische gebruikersinterface.

Al deze architecturale werkwijzen en goede programmeerpraktijken maken deel uit van de architecturale guardrail. Je kunt zelf, of met behulp van AI, iets zoals dit bouwen. Dat is het doel van deze video: je inspireren om AI en Claude Code te gebruiken om apps productieklaar te bouwen.

Je leert coderen en je leert sturen.

Als technische vaardigheid het enige vereiste was, zouden leden zonder webontwikkelingservaring geen apps kunnen bouwen. De belangrijkste vaardigheid bij het bouwen met AI is daarom het geven van richting. Webontwikkelingskennis helpt als hefboom, maar je moet vooral leren hoe je AI aanwijzingen geeft en in de juiste richting wijst. Dat noemen we patroonherkenning.

AI hoeft niet iedere schrijfhandeling voorgeschreven te krijgen. Wanneer je iedere functie afzonderlijk van begin tot eind zou moeten plannen en AI bij iedere stap zou moeten begeleiden, zou deze app waarschijnlijk twee jaar hebben gekost. Hij is in minder dan vier maanden gebouwd.

Denk aan code, processen en herbruikbaarheid. Verbind echte situaties aan je idee en geef AI een analogie. Daardoor begrijpt AI wat je bouwt en hoe nieuwe functies op bestaande functies aansluiten.

De functies van Mochi zijn afzonderlijk gebouwd. Daarna werd Mochi AI toegevoegd: een AI-agent waarmee je alles binnen de software kunt besturen. Mochi is daardoor een door agentische AI aangedreven CRM.

Hoe konden al die afzonderlijke functies met één prompt aan Mochi AI worden gekoppeld? Omdat ik vooraf op mondiaal niveau had nagedacht. Mijn prompts hielden rekening met functies die later zouden worden toegevoegd.

De belangrijkste les is deze:

Prompt naar de toekomst, niet naar het heden.

Stel je de functies voor die uiteindelijk in je app aanwezig zijn. Wat wil je bereiken? Wanneer je nu een functie bouwt, denk dan één stap hoger: wat kun je nu doen om deze functie later opnieuw bruikbaar te maken?

Je kunt AI vragen een probleem of functie volgens dit principe op te delen. Bij het Prisma-schema van Mochi vroeg ik AI om gegevens bij te houden die ik nu nog niet had en in de toekomst mogelijk nodig zou hebben. Daardoor ontstonden nieuwe mogelijkheden, zoals affiliate marketing.

Dit is een belangrijke periode voor webontwikkelaars. Ongeveer eens in de drie jaar ontstaat er een enorme golf rond een onderwerp. Sommige mensen begrijpen die ontwikkeling en bouwen er grote bedrijven mee.

Dit is het eerste moment waarop webontwikkelaars zichzelf in feite kunnen vervangen. Vroeger was tijd onze grootste beperking. We verdienden geld door onze tijd uit te wisselen. Door AI is tijd op een bepaalde manier onze hefboom geworden.

Coderen met AI wordt dit jaar en de komende jaren een van de belangrijkste vaardigheden.

Als je de code in je eigen applicatie niet kunt begrijpen zonder documentatie te lezen, kan AI die code ook niet begrijpen. Kijk naar een bestand met list, update en delete. Zonder documentatie zie je dat dit iets met het wijzigen of beheren van gegevens te maken heeft.

Je ziet ook terugkerende patronen, zoals protected procedure en required permission. Wanneer je later een update-, list- of API-endpoint bouwt, weet je daardoor welke structuur je moet volgen. Dat is de ervaring die je voor AI moet creëren wanneer AI je code leest of nieuwe functies toevoegt.

Claude instellen

Open de website van Claude, ga naar de prijspagina en selecteer het plan dat je nodig hebt. Het plan van 100 dollar per maand wordt aanbevolen. De meeste leden die dit hebben getest gebruiken dat plan. Je hebt niet het twintigvoudige gebruik nodig.

Klik op “Try Claude”, maak een account aan en installeer Claude daarna in de terminal. Sommige mensen gebruiken de desktopapp. Voor coderen wordt de terminalversie aanbevolen; de desktopapp kan worden gebruikt voor onderzoek, brainstormen en gesprekken.

Open de snelstartgids van Claude Code. Zoek “Install Claude Code”, kopieer het commando voor je besturingssysteem en druk op Enter. Controleer daarna of Claude is geïnstalleerd. Wanneer Claude niet verschijnt, sluit je de terminal, start je hem opnieuw en voer je het commando opnieuw uit.

Open je project in Visual Studio Code en voer Claude uit vanuit de terminal, zodat Claude toegang heeft tot de bestanden.

Let op: de optie dangerously skip permissions is een destructieve handeling. Hiermee krijgt Claude volledige bypass-toegang en vraagt het niet telkens om goedkeuring. Gebruik dit bewust.

De eerste projectregels

Het belangrijkste bestand in je build is CLAUDE.md. Maak dit bestand in een Claude-map. Skills en subagents zijn niet noodzakelijk. Dit is het minimale systeem waarmee je goede productiecode kunt bouwen.

Voeg onderaan CLAUDE.md deze regel toe:

Gebruik git niet.

Claude probeert anders soms sessiegeschiedenis en commits te lezen. Het kan dan besluiten eerdere wijzigingen ongedaan te maken en alles opnieuw op te bouwen. Maak daarom expliciet duidelijk dat Claude git niet mag gebruiken zonder jouw verzoek.

Iedere functie krijgt een eigen branch. Open een tweede terminal en gebruik bijvoorbeeld:

git checkout -b nieuwe-branchnaam

Zo blijft je main-branch beschermd en kun je meerdere versies van een functie naast elkaar uitproberen. Voor een websitebuilder werden bijvoorbeeld branches als V5.1 en V5.2 gebruikt totdat de juiste versie was gevonden.

Overzicht van 10.000 voet

De oude aanpak is dat je in iedere prompt de functies, architectuur, permissies, organisatiecontroles, teamleden, organisatiescope, rate limiting en gebruikscontroles opnieuw beschrijft.

Vaak wordt dit daarna in een docs-map gezet. Die map wordt dan de bron van waarheid. Het probleem is dat AI nog steeds volledig afhankelijk is van context. Zodra het contextvenster vol raakt of AI hallucineert, volgt AI niet langer het bedoelde systeem en patroon.

De oplossing is om deze onderdelen in één vooraf gebouwd blok te plaatsen. Dat blok is de bron van waarheid. De architecturale planning in iedere prompt richt zich dan uitsluitend op de functie die op dat moment wordt gebouwd.

In plaats van volledig op context te vertrouwen, vertrouw je op fouten. Dat betekent lintingfouten, compilatiefouten, TypeScript-fouten en andere signalen die AI tijdens het bouwen vertellen wat er moet gebeuren.

Deze signalen geven AI kleine stukjes context. Ze geven patronen, structuur en aanwijzingen terwijl de code wordt gegenereerd. Wanneer een permissie ontbreekt, kan het blok een fout opwerpen en voorkomen dat de code compileert.

De app wordt dan productieklaar door systemen en controles, niet door een enorme documentatiemap die AI uit het hoofd moet onthouden.

De architectuur bevat een bron van waarheid, Zod-schema’s, permissies, linting, TypeScript, compilatiecontroles, een routerlaag en een servicelaag. De routerlaag bevat bedrijfslogica. De servicelaag benadert de server en kan uitsluitend server-side worden gebruikt.

Patroonherkenning

Wanneer je nadenkt over een productieve dag, herinner je je de volgorde van je handelingen: wat je ’s ochtends deed, wat daarna kwam en wat je later op de dag deed. Herhaling creëert patronen.

AI werkt op dezelfde manier. AI volgt een lineair pad. Wanneer je AI vraagt een functie te bouwen, kijkt AI naar wat al eerder is gedaan: hoe authenticatie is gebouwd, hoe andere functies zijn opgebouwd en welk patroon wordt gebruikt.

Wanneer de codebase geen duidelijk patroon bevat, zoekt AI tussen inconsistente voorbeelden en kiest het zelf een patroon. Daardoor ontstaat code drift en technische schuld.

Alles wat je bouwt moet daarom een herkenbaar patroon volgen. In een TRPC-router zie je bijvoorbeeld overal protected procedure en required permission. AI herkent die structuur en weet dat een nieuw API-endpoint dezelfde aanpak moet gebruiken.

Wanneer een permissiefunctie een fout geeft omdat er geen permissie is meegegeven, vertelt het echoesignaal AI precies wat moet worden toegevoegd. Je hoeft de volledige code niet te kennen om de structuur te begrijpen.

Dit is patroonimplementatie in combinatie met een aanpak die op fouten en controles vertrouwt.


Globalisatie

Globalisatie maakt het voor AI eenvoudiger om te begrijpen wat in je app opnieuw kan worden gebruikt. De verschillende modules vormen samen het grotere plaatje: de architecturale guardrail bestaat uit meerdere lagen en concepten die samen één systeem vormen.

Denk aan een sleutel van een garagedeur. Je bewaart die op één vaste plek, samen met andere sleutels. Daardoor hoef je niet meerdere locaties te onthouden. In code betekent globalisatie dat je onderdelen die op verschillende plaatsen nodig zijn uit de afzonderlijke functies haalt en als standaard beschikbaar maakt.

Aan de clientzijde heb je pagina’s en componenten. Aan de serverzijde heb je functies. Een feature gate kan bijvoorbeeld op beide kanten nodig zijn. Wanneer een gebruiker onvoldoende credits heeft, mag hij een pagina niet zien en mogen knoppen zoals “Add project” geen nieuw project aanmaken. Diezelfde regel moet overal gelden.

Wanneer je zulke logica telkens opnieuw bouwt voor de client, de server en afzonderlijke componenten, ontstaat code drift. De oplossing is een herbruikbare helper die bepaalt of een gebruiker op basis van zijn plan toegang heeft. De client en de server kunnen dezelfde helper gebruiken en er eventueel hun eigen wrapper omheen plaatsen.

In mijn app is de feature-gatefunctie opgebroken in een client-side helper en een resource map. Die resource map is de bron van waarheid voor de volledige applicatie. Ze bepaalt welke plannen toegang hebben tot welke functies.

Ik heb plan-sleutels voor free, starter, pro en enterprise, plus een intern portal-plan dat betalingen kan omzeilen. Met TypeScript wordt de structuur van die plannen vastgelegd. Wanneer AI een verkeerde plannaam gebruikt, ontstaat een fout. Dat is microcontextinjectie: de fout vertelt AI welke naam en structuur vereist zijn.

De resource map bevat resources zoals members, invitations, organization, roles, testgegevens en custom branding. Iedere resource heeft een naam, beschrijving, upgradebericht, limiet en bijbehorende planregels. Dezelfde informatie wordt ook gebruikt voor navigatie.

Wanneer een gebruiker een product probeert te maken, controleert de helper welke resource wordt aangesproken, welk plan de gebruiker heeft en hoeveel hij al heeft gebruikt. Die gegevens komen uit een cache die op de server en client beschikbaar is. Wanneer de limiet is bereikt, kan de app een upgrade-modal tonen.

Deze controle is één herbruikbare functie. Ze ontvangt de resource en de gecachte plan- en gebruiksgegevens. Wanneer de voorwaarden niet kloppen, wordt een fout opgegooid. De functie kan op de server en de client worden gebruikt.

In de protected procedure worden permissies uit de organisatie-rol gehaald. Die verwijzen naar permission constants, die weer rechtstreeks naar de resource entries verwijzen. Daardoor hoef je de structuur op slechts één plek te wijzigen om het gedrag van de hele app aan te passen.

Dezelfde resources worden gebruikt voor sidebar-navigatie. Wanneer een gebruiker de pagina vernieuwt, worden de navigatie-items aan dezelfde feature gates gekoppeld. Ook wanneer AI een fout maakt, blijft de app daardoor beschermd.

TypeScript lock-in

TypeScript ondersteunt IntelliSense en dwingt code streng af. AI krijgt een fout wanneer het iets probeert te bundelen of bouwen dat niet aan de regels voldoet. De build voert de Next.js-build, ESLint en andere controles uit.

De eerste functie van TypeScript is de bron van waarheid. Wanneer de structuur verandert, ontstaat een lintingfout. Zo ontdek je dat een sleutel of richtlijn niet wordt gebruikt.

Alle TypeScript-types moeten dynamisch worden gegenereerd. Je mag dezelfde types niet steeds opnieuw hardcoderen of opnieuw opbouwen. De permission constructor leidt bijvoorbeeld alle permissietypes af uit de resourcestructuur.

Wanneer aan de resource map een onbekende resource wordt toegevoegd, ontstaat een fout. De fout controleert de ontwikkelaar en voorkomt dat AI de code verder bouwt zonder de juiste structuur.

Dynamisch gegenereerde types moeten strikt zijn. Gebruik geen any, unknown of andere bypasses. Een type mag op geen enkele manier kunnen worden geschonden.

Gebruik types die al in de app bestaan. Wanneer je AI vertelt dat bestaande types eerst moeten worden gebruikt, gaat AI op zoek naar die types voordat het nieuwe types maakt. Prisma is daarbij de bron van waarheid voor databasetypes. Maak geen tweede user-object met opnieuw een ID en naam wanneer Prisma al het juiste user-type genereert.

Een belangrijke oefening is het afdwingen van een regel zoals use server of server only op bestanden met serveracties. Alleen een instructie in CLAUDE.md is niet betrouwbaar genoeg. Wanneer bestaande bestanden de regel niet volgen, neemt AI dat verkeerde patroon over.

De oplossing is ESLint. Maak een configuratie die controleert dat servicebestanden met de juiste regel beginnen. Wanneer de regel ontbreekt, geeft ESLint een fout. Die fout wordt aan AI doorgegeven en AI kan de regel tijdens het bouwen toevoegen. Zo wordt de regel door de code zelf afgedwongen.

Identiteit normaliseren

In echte apps gebruik je vaak externe bibliotheken voor authenticatie, formulieren en andere functies. Gebruik zulke bibliotheken. Ze zijn breed gebruikt en er is veel informatie beschikbaar over goede implementaties.

Toch kan een externe provider later beperkingen opleveren. Daarom is een adapterlaag nuttig. In mijn boilerplate heb ik bijvoorbeeld Clerk en Better Auth als mogelijke providers. Better Auth biedt flexibiliteit en open source. Clerk richt zich op snelheid, dashboards, sessiebeheer en audits.

Clerk beperkte in mijn geval het aantal rollen. Mochi heeft aangepaste rollen nodig voor teamleden. Daarom heb ik een adapterlaag gemaakt. Clerk regelt authenticatie en accountleden. De adapter voegt een role-property en aanvullende helpers toe.

De adapterlaag is een plug-insysteem. Wanneer ik later van authenticatieprovider wissel, hoef ik alleen de adapter te vervangen. De rest van de app blijft dezelfde gestandaardiseerde laag gebruiken.

Hetzelfde idee gebruik ik voor de teksteditor. Ik wilde een editor zoals Notion bouwen, met blokken, invoervelden, handtekeningen en dynamische variabelen. Zo’n editor volledig vanaf nul bouwen zou veel tijd kosten. Daarom gebruik ik Lexical, een open-source editor met een plug-inarchitectuur en server-side rendering.

Ik bouw mijn eigen uitbreidingen boven op Lexical. Dezelfde editor wordt gebruikt in tickets, de websitebuilder, facturen en contracten. Dynamische variabelen kunnen bijvoorbeeld een voornaam, e-mailadres, lead of ontvanger invoegen.

De algemene regel is: begin met een goede externe bibliotheek en bouw je eigen functionaliteit erbovenop via een adapterlaag. In de app staat een gedeelde adapter met gedeelde permissies en afzonderlijke verbindingen voor de verschillende providers.

Alleen server-side

Server-only beschermt je app. AI kan vrijwel alles doen wat je toestaat, dus je moet een patroon afdwingen dat eerder is getest.

Een veelvoorkomende fout in AI-apps is een API-endpoint dat wijzigingen uitvoert. Ontwikkelaars maken een serveractie en denken dat die uitsluitend op de server kan worden aangeroepen. In Next.js kunnen serveracties echter ook vanaf de client worden aangeroepen. De serveractie wordt in de clientbundel opgenomen en kan met de juiste bundel-ID rechtstreeks worden aangeroepen.

Wanneer de beveiliging alleen in een ander API-endpoint zit, kan iemand de serveractie omzeilen. De kleinste effectieve stap is daarom voorkomen dat de functie in de clientbundel terechtkomt.

Importeer server-only bovenaan ieder servicebestand. Daardoor kan de code alleen op de server worden uitgevoerd. De app gebruikt daarnaast ESLint om af te dwingen dat alle services met deze regel beginnen.

Zo is het patroon vooraf ingebouwd. AI hoeft alleen de bestaande servicevorm te volgen en kan geen onbeveiligde clienttoegang creëren.

Het blok

Het blok is het hart van de architecturale guardrail. Het brengt patroonherkenning, globalisatie, beveiliging, TypeScript en een genormaliseerd toegangspunt samen.

Ik wilde dat Mochi snel aanvoelde. De eerste render hangt altijd af van de netwerksnelheid, maar optimistic updates, servercache, clientcache en invalidatie maken navigatie daarna snel.

Alle verkeersstromen naar de backend moeten door één blok gaan. Dat verkeer kan afkomstig zijn van een gebruikersactie, een directe aanval op een endpoint of AI die een nieuwe functie bouwt.

Het blok bevat sessiebeheer, plan-cache, resources, auditlogs, permissiecontroles en rate limiting. De naam van het herbruikbare patroon is protected procedure. AI hoeft alleen die naam te herkennen. Alles wat daarachter zit, gebeurt automatisch.

Dat maakt controle eenvoudig. In de gitwijzigingen zie je een resource en een API-endpoint. Je controleert of het endpoint de protected procedure gebruikt. Daarna test je de functie als QA: klik op de knoppen en test afwijkende situaties.

Productieklaar betekent niet dat er nooit een bug kan bestaan. Bugs zijn oplosbaar. Een datalek, verkeerde organisatiescope of vermenging van gegevens tussen organisaties is veel ernstiger. Wanneer drie organisaties klantgegevens opslaan en een query geen organisatie-ID gebruikt, kan de ene organisatie de gegevens van een andere zien.

Daarom moet iedere datatoegang correct worden gescoord op de organisatie. Het blok dwingt de belangrijkste controles af voordat de service de database benadert.

Database-isolatie is eveneens belangrijk. Gebruik Prisma als tussenlaag. Daarmee kun je PostgreSQL-providers zoals Supabase en Neon gebruiken en later wisselen zonder de hele app opnieuw te schrijven.

De servicelaag is de enige laag die rechtstreeks met Prisma en de database communiceert. De router bevat bedrijfslogica. De procedure vormt het beschermende blok daartussen.

De lineaire route is:

  1. router;
  2. protected procedure;
  3. service;
  4. Prisma;
  5. database.

TRPC maakt deze structuur mogelijk. Routers worden vanuit één routerindex gekoppeld. Een member-router maakt een TRPC-router en bevat methodes zoals list, update en delete. Elk endpoint gebruikt de protected procedure.

De procedure bouwt de context op. Die context bevat onder andere de organisatie, actieve organisatie en gebruikerspermissies. De stappen zijn request setup, organizationscope, onboarding gate, membership check, role gate, permission gate, path resolution, rate limiting per resource, planlimiet, feature flag, paginering, contextverrijking en een gebruiksteller.

Daarna volgen exception handlers, succesregistratie en auditlogs. AI hoeft deze onderdelen niet telkens opnieuw te prompten. Het hoeft alleen de protected procedure te gebruiken en de verplichte opties mee te geven.

De routerlaag bevat bedrijfslogica. Bij een websitebuilder kan bijvoorbeeld maximaal drie mensen tegelijk aan dezelfde pagina werken. De router controleert hoeveel mensen verbonden zijn en weigert een vierde verbinding.

Bij automatiseringen kan een endpoint een Zod-schema als input gebruiken. Daardoor blijft de invoer consistent, ook wanneer AI de resource op een andere pagina gebruikt. De router roept vervolgens een server-only service aan. De businesslogica blijft gescheiden van de databaselogica.

De organisatie-ID moet dynamisch uit de context komen. AI mag die ID niet raden of zelf uit een website afleiden. De context bevat de sessie van de ingelogde gebruiker en wordt rechtstreeks in de API-aanroep gebruikt. Zelfs wanneer een prompt een verkeerde organisatie-ID noemt, blijft de server de correcte organisatie gebruiken.

Daardoor kan Mochi AI meerdere acties aan elkaar koppelen: een formulier maken, kwalificatievragen toevoegen, aangepaste gegevens maken, de website opbouwen en automatiseringen instellen. De organisatiescope blijft veilig omdat die in de API-endpointcontext wordt geïnjecteerd.

Handhaving

De planlimiet wordt automatisch uit de resources afgeleid. De resources bevatten plannen, limieten, feature gates en permissies. Wanneer je een nieuwe resource toevoegt, hoef je alleen de bron van waarheid aan te passen.

Rate limiting hoort op blokniveau te gebeuren. Sommige services hebben een hogere of lagere limiet nodig, dus er is een basisprocedure met rate-limitmiddleware. De protected procedure gebruikt die basisprocedure ook.

Openbare pagina’s moeten eveneens rate limiting hebben. Een miljoen verzoeken op een publieke pagina kan een DDoS-achtig patroon vormen. De rate limiter gebruikt de client-IP en de ingestelde limiet. Tijdens lokale ontwikkeling kan een uitzondering nodig zijn, omdat hot reload soms veel verzoeken veroorzaakt.

Auditlogs gebruiken hetzelfde principe. De resource, gebruiker en organisatie zijn al bekend. De protected procedure registreert de actie automatisch. AI hoeft niet in iedere router afzonderlijk een auditlogregel te schrijven.

De clientspiegel

Wanneer je alle patronen uit deze cursus in je codebase bouwt, ontstaat een clientspiegel. De server- en clientlogica gebruiken dezelfde globale functies en interfaces. Patronen worden daardoor voortdurend herhaald en AI herkent ze sneller.

De kloof

Alle beveiliging werkt alleen wanneer iedere route door het blok gaat. Een derde-partijcomponent, zoals Clerk Billing, kan buiten de TRPC-procedure vallen. Dan wordt de rest van de app beschermd, terwijl de billingpagina rechtstreeks bereikbaar blijft.

De oplossing is geen extra router voor ieder extern component. Plaats een controle in de layout. Gebruik dezelfde resources en permissies om de route te controleren. De layout kan het pad en de navigatie-informatie vergelijken met de rol van de gebruiker en toegang weigeren wanneer dat nodig is.

Inline-injectie

Inline-injectie geeft AI kleine stukjes context op het moment dat die nodig zijn. In plaats van een grote documentatiemap te laden, plaats je boven ieder belangrijk codeblok een inline commentaar.

Het commentaar beantwoordt:

  • wat doet dit?
  • waarom bestaat het?
  • hoe werkt het?
  • waar wordt het gebruikt?

Je hoeft niet iedere regel te documenteren. Plaats het commentaar boven functies en belangrijke blokken. Het doel is AI-ontwikkeling zo eenvoudig mogelijk te maken.

Een docs-map kan nuttig zijn voor leden en menselijke uitleg. Die map is geen architecturale bron van waarheid voor AI. Inline comments, TypeScript, linting en foutafhandeling zijn sterker gebleken dan verouderde externe documentatie.

Grep eerst

AI moet eerst de juiste bestanden vinden voordat het context gaat lezen. De codebase wordt daarom eerst via een grep-script doorzocht. Source-of-truth-keywords staan bovenaan de relevante bestanden. Denk aan woorden zoals permissions, resources, plans en database.

AI gebruikt het script om een korte lijst met relevante bestanden te vinden. Daarna wordt alleen de beste locatie verder gelezen. Zo wordt het contextvenster niet gevuld met alle bestanden die toevallig hetzelfde woord bevatten.

In CLAUDE.md moet daarom staan dat AI vóór het maken van types, functies, constanten of componenten eerst met het grep-script moet zoeken. De snelle route naar de bron van waarheid houdt contextvervuiling laag en vermindert het verbruik van sessielimieten.

CLAUDE.md als orkestrator

CLAUDE.md verbindt alle concepten. Het bestand hoeft niet lang te zijn. Mijn versie was 86 regels; in Mochi waren het ongeveer 25 regels.

De belangrijkste regels zijn:

  • alles volgt bestaande patronen;
  • AI verzint geen eigen architectuur;
  • de app gebruikt een globale bron van waarheid;
  • nieuwe code wordt in de bestaande architectuur gebouwd;
  • globaliseer herbruikbare code;
  • gebruik eerst grep om de juiste bestanden te vinden;
  • voeg source-of-truth-keywords toe aan nieuwe onderdelen;
  • maak geen dubbele functies;
  • routers gebruiken de protected procedure;
  • routers bevatten bedrijfslogica en orkestratie;
  • services zijn de enige laag die de database rechtstreeks aanraakt;
  • permissies moeten worden aangesloten;
  • servicebestanden zijn server-only;
  • gebruik geen any, unknown of TypeScript-bypasses;
  • gebruik dynamische types en Prisma als bron van waarheid;
  • valideer invoer met Zod;
  • gebruik inline contextinjectie;
  • hergebruik bestaande componenten;
  • plaats globale componenten in de globale map;
  • plaats routegebonden componenten in de routegebonden componentenmap;
  • ontwerp componenten voor hergebruik;
  • volg bestaande design tokens en thema’s;
  • hardcode geen kleuren of waarden die als Tailwind-token bestaan;
  • voer vóór iedere oplevering een TypeScript-controle uit;
  • gebruik barrel exports wanneer die AI helpen de structuur te begrijpen;
  • laat geen functies onvoltooid achter;
  • laat AI nooit git gebruiken.

Barrel exports zijn voor menselijke productiecode niet altijd ideaal. Voor AI vormen indexbestanden een snelle kaart van alle beschikbare onderdelen. Een websitebuilder-index kan bijvoorbeeld herbruikbare componenten, eigen secties en toolbaronderdelen tonen.

Voor componenten geldt: wanneer je een patroon van een andere component kopieert, is dat een signaal om de functionaliteit te globaliseren. Een header kan bijvoorbeeld slots gebruiken. De basisheader blijft hetzelfde, terwijl iedere pagina eigen knoppen of inhoud in de slot kan plaatsen.

Gebruik design tokens uit Tailwind. Hardcoded kleuren kunnen dark mode en globale stijlaanpassingen breken. Een token past zich aan wanneer het globale stylesheet verandert.

Sessielimieten

Het bereiken van een sessielimiet is geen teken dat het systeem slecht werkt. Het betekent dat je de aangeschafte capaciteit gebruikt. Met de extra architectuurlagen krijg je mogelijk een veel grotere output dan iemand zonder deze aanpak.

Hoe je prompt

Er zijn eenvoudige en complexe functies.

Een eenvoudige functie prompt je in gewoon Engels. Beschrijf de grote functie en de kleine onderdelen. Een leadlijst kan bijvoorbeeld bestaan uit filters, leads verplaatsen en een lijst verwijderen. Wanneer de functie klein genoeg is, kun je alles in één prompt bouwen.

Een complexe functie moet je iteratief bouwen. Een websitebuilder bevat bijvoorbeeld een canvas, frames, drag-and-drop, stijlen en vooraf gebouwde componenten. Breek deze onderdelen op en bepaal de volgorde waarin de voorwaarden moeten worden gebouwd.

Wanneer een kalender als vooraf gebouwde component in de websitebuilder moet verschijnen, bouw je de kalender eerst. Daarna bouw je de canvas, frames, drag-and-drop en stijlen. De volgorde wordt een lineaire workflow.

Denk eerst globaal. Voor een canvas moet je nadenken over state management, de structuur van de state en de manier waarop de state wordt gewijzigd. Redux kan de centrale opslag vormen.

Je kunt bijvoorbeeld twee websites tegelijk in de Redux-store bewaren. Iedere website heeft een ID, organisatie-ID en data. De data kan een JSON-structuur bevatten met element-ID, type, naam en een array van onderliggende elementen.

Een rendering engine vertaalt die JSON-structuur naar elementen op de canvas. Voor een kalender kan een speciaal elementtype aan een kalendercomponent worden gekoppeld.

Bouw eerst de basis: kan het systeem de datastructuur op de canvas tonen? Daarna voeg je zoom, drag-and-drop, stijlen en andere details toe. Dat is een iteratief proces.

Wanneer je geen technische ervaring hebt, spreek je je ideeën uit in eenvoudige taal of pseudocode. Vraag AI om een routekaart en architecturale blauwdruk. Jij geeft de richting en productgedachte; AI helpt met de technische uitwerking.

Rood-groen-prompting

Rood-groen-prompting heeft twee strategieën: de gap-methode en de white-lie-methode.

Bij de gap-methode laat je bewust een onderdeel open, zodat het later zichtbaar en controleerbaar kan worden toegevoegd. Een uitnodigingssysteem bestaat bijvoorbeeld uit een uitnodiging maken en een e-mail sturen. Bouw die onderdelen apart.

Een betere prompt is:

Bouw de functie om een uitnodiging te maken. Sluit e-mail nog niet aan. Maak alleen één bron-van-waarheidfunctie waar de e-mailfunctionaliteit later in komt. Log voorlopig het bericht in de console.

Zo ontstaat een gat dat later bewust wordt gevuld. Gebruik een console.warn, TODO, waarschuwing of lokale toast om te voorkomen dat het gat wordt vergeten. De guardrail moet de ontbrekende stap zichtbaar maken.

De white-lie-methode werkt met een bewering die AI dwingt eerst te zoeken. Je zegt bijvoorbeeld dat er al een bron van waarheid voor betalingen en checkout bestaat en dat AI die moet gebruiken. Wanneer de bron bestaat, vindt AI die. Wanneer ze niet bestaat, meldt AI dat of stelt AI voor de bron te bouwen.

Het uitgangspunt bepaalt de eerste actie van AI. Wanneer je zegt dat niets bestaat, begint AI meteen te schrijven. Wanneer je zegt dat iets al bestaat, gaat AI eerst zoeken.

Bij een factuurpagina is “voeg een Stripe-checkoutformulier toe” een zwakke prompt. Een betere prompt is: “Er bestaat al een bron van waarheid voor betalingen en checkout. Gebruik die eerst en verbind de factuurpagina ermee.” Daarna vraag je om die checkoutflow in de factuur te plaatsen.

Bij een Redux-probleem kun je zeggen dat er een bug bestaat waarbij websitegegevens op een andere pagina worden overschreven. AI onderzoekt dan de Redux-store, de cache en mogelijke singletonlogica en kan de onderliggende oorzaak vinden.

Hetzelfde geldt voor een oude editor die naast Lexical is blijven bestaan. Vraag AI eerst te controleren of twee editorarchitecturen door elkaar zijn gebruikt. Laat AI daarna alle verwijzingen naar de oude editor verwijderen. Zo wordt verborgen oude code zichtbaar.

Controle houden

Maak voor iedere functie een branch. Ook voor een nieuwe iteratie van dezelfde functie. Wanneer je ziet welke bestanden Claude heeft gewijzigd, behoud je overzicht en vertrouwen.

Blijf de architecturale guardrail verbeteren. Deel werkende patronen en verbeteringen met anderen.

AI Era

AI Era is een community en school voor webontwikkelaars die productieapps uitsluitend met AI willen bouwen.

Leden krijgen op dag één toegang tot dezelfde architecturale guardrail. Die wordt iedere week bijgewerkt met nieuwe strategieën voor AI-ontwikkeling.

De maker heeft tientallen apps gebouwd, waaronder Fun AI en Mochi, met meer dan 1.200 functies die in minder dan vier maanden productieklaar zijn gemaakt. Hij heeft websitebuilders, formulierbouwers, automation builders en agentische functies gebouwd.

Daarnaast heeft hij softwarelicenties verkocht en bij bedrijven met een omzet van meer dan tien cijfers geholpen apps vanaf nul op te bouwen.

De community richt zich op implementatie. Informatie staat gratis op internet; de kloof zit in het uitvoeren van het werk en het bereiken van de uitkomst.

Leden kunnen hun ideeën delen en krijgen aangepaste Loom-video’s, suggesties en coaching. De methode bestaat uit bouwen, verkopen, lanceren en schalen.

Een voorbeeld is een lid dat een app bouwde waarmee zijn broer honderden dollars per maand bespaarde en in één week 12.000 volgers kreeg.

Een ander voorbeeld gebruikt software-as-a-service. Hij vraagt 3.500 dollar per maand voor software die hij in minder dan vier dagen heeft gebouwd, terwijl vergelijkbare software vaak voor 30 dollar per maand wordt verkocht. Het verschil komt door het systems-as-a-service-model.

De community helpt leden verschillende modellen op hun app-idee toe te passen. De focus ligt op bouwen, lanceren en schalen.

Dat sluit de cursus af. Gebruik de concepten, bouw iets interessants en deel je resultaat. Vragen en suggesties kunnen onder de video worden geplaatst.

Vertaling voltooid.