Leer hoe je Claude Code-stijlgids-prompts schrijft die naamgeving, lagen, foutafhandeling en logging afdwingen en schendingen vroeg opsporen met eenvoudige controles.

Stijlafwijkingen verschijnen zelden als één grote fout. Ze beginnen als kleine “goed genoeg” keuzes die onschuldig lijken in een pull request, en stapelen zich dan op totdat de codebase ongelijkmatig aanvoelt en moeilijker te lezen is.
Stijlverschuiving ziet er vaak zo uit: één bestand gebruikt userID, een ander userId, een derde uid. De ene handler retourneert { error: "..." }, een ander gooit een exception, weer een ander logt en geeft null terug. Elke wijziging is klein, maar samen creëren ze een repo waar patronen onvoorspelbaar worden.
Snelle iteratie en meerdere bijdragers maken het erger. Mensen kopiëren wat ze zien, vooral onder tijdsdruk. Als de meest recente code in de repo een snelkoppeling gebruikte, wordt die snelkoppeling het sjabloon voor de volgende wijziging. Na een paar weken is de “standaardstijl” niet je geschreven gids meer. Het is wat er het laatst gebeurde.
Daarom moet het doel consistente conventies zijn, niet persoonlijke voorkeuren. De vraag is niet "Vind ik deze naam mooi?" maar "Komt dit overeen met de regels die we hebben afgesproken zodat de volgende persoon het zonder nadenken kan volgen?"
Schendingen vroeg vangen betekent slechte patronen stoppen voordat ze copy-paste-brandstof worden. Focus op nieuwe en gewijzigde code, repareer de eerste verschijning van een nieuwe inconsistentie, en blokkeer merges die nieuwe drift introduceren. Wanneer je een probleem meldt, voeg dan een kort voorbeeld van de voorkeursoplossing toe zodat mensen het de volgende keer kunnen nadoen.
Een realistisch voorbeeld: een ontwikkelaar voegt een nieuw API-endpoint toe en logt ruwe request bodies “alleen voor debugging”. Landa dit, dan kopieert het volgende endpoint het, en al snel verschijnen gevoelige gegevens in logs. Het in de eerste PR vangen is goedkoop. Het vangen nadat het zich heeft verspreid is pijnlijk en riskant.
Een stijlguide werkt alleen in reviews als hij leest als een checklist, niet als een verzameling voorkeuren. Herschrijf elke richtlijn als een regel die op een diff gecontroleerd kan worden.
Organiseer regels in vier bakken zodat ze moeilijk te missen zijn: naamgeving, lagen, foutafhandeling en logging. Schrijf voor elke bak twee dingen: wat waar moet zijn en wat verboden is.
Bepaal vooraf de sterkte van elke regel:
Stel scope in zodat reviews niet veranderen in eindeloze refactors. Een simpele regel werkt goed: “nieuwe en gewijzigde code moet voldoen; bestaande onaangeraakte code wordt niet herschreven tenzij het een fix blokkeert.” Als je cleanup wil, timebox het dan als een aparte taak.
Definieer ook de output die je van een review wilt zodat het gemakkelijk is om te handelen: een pass/fail-uitspraak, een lijst met overtredingen met bestand- en lijnverwijzingen, voorgestelde fixes geschreven als concrete edits, en een korte risiconotitie wanneer iets bugs of lekken kan veroorzaken.
Voorbeeld: als een PR ruwe gebruikers-tokens logt, moet de review falen onder “logging: nooit geheimen loggen” en voorstellen om in plaats daarvan een request ID te loggen.
Stijlprompts falen wanneer ze als voorkeuren klinken. Een goede reviewprompt leest als een contract: duidelijke non-negotiables, duidelijk benoemde uitzonderingen en een voorspelbare output.
Begin met twee korte blokken: wat waar moet zijn en wat buigbaar is. Voeg daarna een beslisregel toe: “Als onduidelijk, markeer als Needs Clarification. Raad nooit.”
Eis bewijs. Wanneer het hulpmiddel een overtreding markeert, verplicht het dan het exacte identifier en bestandspad te citeren, niet een vage omschrijving. Die enkele eis voorkomt veel heen en weer.
Houd de scope strak: commentaar alleen op gewijzigde regels en rechtstreeks beïnvloede codepaden. Als je niet-gerelateerde refactors toestaat, verandert stijlhandhaving in “schrijf het bestand opnieuw”, en mensen gaan het vertrouwen in de feedback verliezen.
Hier is een structuur die je kunt hergebruiken:
Role: strict style guide reviewer.
Input: diff (or files changed) + style guide rules.
Non-negotiables: [list].
Allowed exceptions: [list].
Scope: ONLY comment on changed lines and directly impacted code paths. No unrelated refactors.
Evidence: Every finding MUST include (a) file path, (b) exact identifier(s), (c) short quote.
Output: structured compliance report with pass/fail per category + minimal fixes.
Eis dat het rapport elke keer dezelfde secties behoudt, zelfs als sommige “No issues found” zijn: Naming, Layering, Error handling, Logging.
Als er staat “service layer leaking DB details”, moet het iets citeren als internal/orders/service/order_service.go en de exacte call (bijvoorbeeld db.QueryContext) zodat je het lek kunt repareren zonder te discussiëren wat het bedoelde.
Een stijlguide blijft hangen als het proces herhaalbaar is. Het doel is het model regels te laten checken, niet smaak te laten bediscussiëren, en het elke keer op dezelfde manier te doen.
Gebruik een eenvoudige twee-pas workflow:
Voorbeeld: een PR voegt een nieuw endpoint toe. Pass 1 markeert dat de handler direct naar PostgreSQL praat (layering), gemengde naamgeving gebruikt voor request structs (naming), en volledige e-mails logt (logging). Pass 2 maakt minimale fixes: verplaats de DB-call naar een service of repository, hernoem de struct en mask de e-mail in logs. Niets anders verandert.
Naamgevingsissues voelen klein, maar veroorzaken echte kosten: mensen lezen intent verkeerd, zoeken wordt moeilijker en “bijna hetzelfde” namen vermenigvuldigen zich.
Stel de naamgevingsregels die de reviewer moet afdwingen over de hele wijziging vast: bestandsnamen, geëxporteerde types, functies, variabelen, constanten en tests. Wees expliciet over casing (camelCase, PascalCase, snake_case) en kies één acroniemregel (bijvoorbeeld APIClient vs ApiClient). Eis dat overal.
Standaardiseer ook gedeelde woordenschat: fouttypes, logvelden en config-sleutels. Als logs request_id gebruiken, sta dan niet toe dat iemand reqId in één bestand en requestId in een ander gebruikt.
Een praktische reviewer-instructie:
Check every new or renamed identifier. Enforce casing + acronym rules.
Flag vague names (data, info, handler), near-duplicates (userId vs userID), and names that contradict behavior.
Prefer domain language: business terms over generic tech words.
Vraag om een kort rapport: de drie meest verwarrende namen, eventuele near-duplicates en welke je behoudt, plus log/config/error-namen die niet aan de standaard voldoen.
Lagenregels werken het beste in gewone taal: handlers praten HTTP, services bevatten business rules, repositories praten met de database.
Vergrendel afhankelijkheidsrichting. Handlers mogen services aanroepen. Services mogen repositories aanroepen. Repositories mogen geen services of handlers aanroepen. Handlers mogen geen databasecode, SQL-helpers of ORM-modellen importeren. Als je gedeelde pakketten gebruikt (config, time, IDs), houd die vrij van applicatielogica.
Wijs cross-cutting werk een thuis toe. Validatie hoort meestal aan de grens voor request-shape en in de service voor businessregels. Autorisatie begint vaak in de handler (identity, scopes), maar de service moet de uiteindelijke beslissing afdwingen. Mapping hoort aan de lagenranden: handler map HTTP naar domeininput, repository map DB-rows naar domeintypen.
Plaats dit in een prompt om reviews concreet te houden:
Check layering: handler -> service -> repository only.
Report any leaks:
- DB types/queries in handlers or services
- HTTP request/response types inside services or repositories
- repository returning DB models instead of domain objects
- auth/validation mixed into repository
For each leak, propose the smallest fix: move function, add interface, or rename package.
Maak het rapport expliciet: benoem het bestand, de laag waar het thuis hoort, de import of call die de regel breekt en de minimale verandering die voorkomt dat het patroon zich verspreidt.
De meeste stijldebatten worden luid wanneer iets in productie faalt. Een duidelijke foutafhandelingspolicy houdt fixes rustig omdat iedereen weet hoe “goed” eruitziet.
Formuleer de filosofie en handhaaf die. Bijvoorbeeld: “Wrap errors om context toe te voegen; creëer een nieuwe error alleen wanneer je betekenis verandert of een user message mapt. Retourneer ruwe errors alleen op de systeemgrens.” Die ene zin voorkomt dat willekeurige patronen zich verspreiden.
Scheid user-facing tekst van interne details. Gebruikersberichten moeten kort en veilig zijn. Interne errors kunnen de operatie-naam en sleutelidentificatoren bevatten, maar geen geheimen.
Controleer in reviews op een paar veelvoorkomende fouten: swallowed errors (gelogd maar niet geretourneerd), ambigue returns (nil waarde met nil error na een mislukking), en user-facing messages die stacktraces, query-tekst, tokens of PII lekken. Als je retries of timeouts ondersteunt, vereist dat ze expliciet zijn.
Voorbeeld: een checkout call time-out. De gebruiker ziet “Payment service is taking too long.” Intern wrap je de timeout en voeg je op=checkout.charge en het order-ID toe zodat het doorzoekbaar en actiegericht is.
Logs helpen alleen als iedereen ze hetzelfde schrijft. Als elke ontwikkelaar eigen bewoordingen, levels en velden kiest, wordt zoeken giswerk.
Maak loglevels non-negotiable: debug voor ontwikkelingsdetails, info voor normale mijlpalen, warn voor onverwachte maar afgehandelde situaties, en error wanneer de user-facing actie faalt of aandacht nodig heeft. Houd “fatal” of “panic” zeldzaam en gekoppeld aan een duidelijke crashpolicy.
Gestructureerde logs zijn belangrijker dan perfecte zinnen. Eis stabiele sleutelnamen zodat dashboards en alerts niet breken. Bepaal een kleine kernset (bijvoorbeeld event, component, action, status, duration_ms) en houd die consistent.
Behandel gevoelige data als een harde stop. Wees expliciet over wat nooit gelogd mag worden: wachtwoorden, auth-tokens, volledige creditcards, geheimen en ruwe persoonsgegevens. Wijs ook op dingen die onschuldig lijken maar dat niet zijn, zoals password reset links, session IDs en volledige request bodies.
Correlatie-IDs maken debugging mogelijk over lagen heen. Vereis een request_id in elke logregel binnen een request. Als je user_id logt, definieer wanneer dat toegestaan is en hoe je ontbrekende of anonieme gebruikers representeert.
Een herbruikbaar promptblok:
Review the changes for logging conventions:
- Check level usage (debug/info/warn/error). Flag any level that does not match impact.
- Verify structured fields: require stable keys and avoid free-form context in the message.
- Confirm correlation identifiers: request_id on all request-bound logs; user_id only when allowed.
- Flag any sensitive data risk (tokens, secrets, personal data, request/response bodies).
- Identify noisy logs (in loops, per-item logs, repeated success messages) and missing context.
Return: (1) violations with file/line, (2) suggested rewrite examples, (3) what to add or remove.
Voordat je merge, doe een snelle “safety pass”: nieuwe logs zonder request_id voor requestwerk, nieuwe keys die bestaande namen veranderen (userId vs user_id), error logs zonder wat faalde (operatie, resource, status), high-volume logs die bij elk request afgaan, en elke kans dat geheimen of persoonlijke data in velden of messages verschijnen.
Behandel stijldrift als een build break, niet als een suggestie. Voeg een strikte poort toe die draait vóór merge en een duidelijk pass of fail teruggeeft. Als een mandatory regel gebroken is (naamgeving, laaggrenzen, loggingveiligheid, foutafhandeling), faalt het en wijst het op exacte bestanden en regels.
Houd de poort kort. Een praktische truc is een JA/NEE-checklist per regel te vereisen en goedkeuring te weigeren als een item NEE is.
Een PR-size checklist die de meeste problemen vangt:
Wanneer het hulpmiddel fixes voorstelt, vereist dan een klein compliant snippet voor elke regel die het aanraakt. Dat voorkomt vage feedback zoals “hernoem voor duidelijkheid”.
De snelste manier waarop een stijlguide faalt, is ruimte laten voor interpretatie. Als twee reviewers dezelfde regel kunnen lezen en tot verschillende conclusies komen, zal het hulpmiddel smaak afdwingen, niet standaarden.
Naamgeving is een veelvoorkomend voorbeeld. “Gebruik duidelijke namen” is niet testbaar. Verscherp het naar iets wat je kunt verifiëren: “functies zijn werkwoorden (bijv. createInvoice), booleans beginnen met is/has/can, geëxporteerde types zijn PascalCase.”
Een andere valkuil is alles tegelijk vragen. Als één prompt probeert naamgeving, lagen, fouten, logging, tests en performance te dekken, wordt de feedback oppervlakkig. Splits reviews op in gefocuste passen als je diepte nodig hebt, of houd de gate-prompt beperkt tot mandatory regels.
De problemen die handhaving meestal laten afdrijven:
Als je prompts als tests behandelt, krijg je voorspelbare handhaving. Als je ze als advies behandelt, sluipen overtredingen binnen en vermenigvuldigen zich.
Doe een snelle pass over de diff (niet de hele repo) en bevestig:
Houd een klein prompttemplate bij de hand en plak het bij elke wijziging:
Review ONLY the changed code against our rules for naming, layering, errors, and logging.
List mandatory violations first (with file + line if available). Then list optional suggestions.
End with either: “no mandatory violations found” or “mandatory violations found”.
Voorbeeld: een nieuwe functie procUsr() in een handler die direct naar PostgreSQL schrijft moet falen op naamgeving en layering, ook al werkt de feature. Het hier vangen voorkomt dat de fout via copy-paste verspreidt.
Een teammate voegt een nieuw endpoint toe: POST /v1/invoices/{id}/send. Het raakt een handler, een service en storage.
Op de eerste pass wil je een rapport, geen rewrite:
Pass 1 (report only)
You are a strict style checker. Read the patch.
Rules: naming must match our guide, handlers call services only, services call storage only, no SQL in handlers,
errors must be wrapped with context, logs must be structured and not leak PII.
Output: a numbered list of violations with file:line, rule name, and one-sentence impact. Do not propose fixes.
If a rule might be intentionally broken, ask one clarification question.
Typische bevindingen: SendInvoiceNow() vs SendInvoice naamingsmismatch, de handler die db.QueryRow direct aanroept, raw err retourneren zonder context, en noisy logs zoals log.Printf("sending invoice %v", invoice) die volledige objecten dumpen.
De tweede pass vraagt om minimale, veilige changes:
Pass 2 (minimal fix suggestions)
Using the violations list, propose the smallest code edits to comply.
Constraints: keep behavior the same, no refactors beyond what is needed, show suggested function names and where code should move.
For each fix, include 1-2 lines of example code.
Als het breken van een regel is toegestaan, vermeld dat dan vooraf: “Exceptions are permitted only if you add a short comment explaining why, and you add a follow-up task to remove the exception.”
Na de fix wordt de handler een dunne adapter, de service beheert de workflow, storage bevat de query, errors worden fmt.Errorf("send invoice: %w", err), en logs worden één nette regel met veilige velden (invoice ID, niet de volledige invoice).
Kies één team-goedgekeurde prompt en behandel die als een gedeeld hulpmiddel. Begin met wat het meest irriteert in jullie reviews (naamgevingsdrift, lekkende lagen, inconsistente errors, onveilige logs). Werk de prompt alleen bij wanneer je een echte overtreding in echte code ziet.
Houd een klein regelsblok bovenaan de prompt en plak het ongewijzigd in elke review. Als iedereen de regels elke keer aanpast, heb je geen standaard. Je hebt een debat.
Een eenvoudige cadence helpt: één persoon verzamelt de topstijl-missers van de week en je voegt precies één duidelijkere regel of één beter voorbeeld toe.
Als je in een chat-gedreven buildflow werkt zoals Koder.ai (koder.ai), is het de moeite waard dezelfde gate checks tijdens wijzigingen te draaien, niet alleen aan het einde. Features zoals planning, snapshots en rollback kunnen helpen stijlfixes klein en omkeerbaar te houden voordat je broncode exporteert.