Eindgebruiker-documentatie (userdocs)
Userdocs zijn de Nederlandstalige uitleg die een klant te zien krijgt voor
een Tapster-feature: niet voor het ontwikkelteam, maar voor de gebruiker,
beheerder of admin die in de app zit. Ze wonen naast de feature-code in de
repo, ze worden in dezelfde PR gereviewd als de code, en na merge naar
main verschijnen ze automatisch als KB-artikel in Freescout onder
mailbox 1.
Deze pagina legt het mentale model uit. Voor de stappen om er één toe te
voegen, zie Voeg eindgebruiker-documentatie toe.
Voor de CI-workflows die userdocs bewaken en publiceren, zie
Documentatie-pipeline.
Wat een userdoc is en wat niet
Een userdoc is een markdown-bestand met frontmatter, in een userdocs/-map
naast de feature-code:
apps/frontend/src/app/features/<scope>/<feature>/
└── userdocs/
├── index.md (verplicht als de feature user-facing is)
├── how-to-<verb>.md (optioneel, voor afgebakende deeltaken)
└── assets/ (optioneel, screenshots)
Voor backend-modules in apps/api/src/modules/<module>/ werkt het op
dezelfde manier, mits het gedrag iets is dat een eindgebruiker (vaak een
beheerder of admin) ziet of merkt.
Wat een userdoc niet is:
- Geen developer-uitleg (“hoe is het geïmplementeerd”): dat hoort in
docs/of in code-commentaar. - Geen API-documentatie: die genereert de backend zelf via OpenAPI.
- Geen release-notes: die komen uit
docs/releases/, gegenereerd per minor of major release.
Het verschil tussen userdocs en docs/ staat ook in
CONTRIBUTING-DOCS.
Eén audience per feature-folder
De top-level folder onder features/ bepaalt voor wie de userdoc is. Dat
zorgt dat de juiste categorie-prefix in Freescout vanzelf klopt.
| Folder | audience |
Category-prefix |
|---|---|---|
apps/frontend/src/app/features/user/... |
gebruiker |
Gebruiker > ... |
apps/frontend/src/app/features/backoffice/... |
beheerder |
Beheerder > ... |
apps/frontend/src/app/features/admin/... |
admin |
Admin > ... |
apps/frontend/src/app/features/global/... |
passend bij wie het ziet | matchend |
apps/api/src/modules/... |
passend bij wie het raakt | matchend |
De levenscyclus
schrijven valideren publiceren bijwerken
───────── ───────── ────────── ─────────
/generate- ─► userdocs-check ─► freescout-sync ─► slash-command
userdocs (pull request) (push naar main) opnieuw, content
+ review hash detecteert
wijziging
- Schrijven. De slash-command
/generate-userdocs <pad>leest routes, page-templates, components en i18n; past de Tapster-stijlregels toe (Nederlands, geen em-dashes, korte zinnen, tweede persoon); en schrijft eenindex.mdmet geldige frontmatter. Je reviewt de tekst zelf voor commit, want de AI mag niets verzinnen maar misinterpreteren kan altijd. - Valideren. De CI-check
userdocs-check.ymldraaitnpm run userdocs:validateop elke PR. Een kapotte frontmatter (volgens het Zod-schema intools/freescout-sync/src/frontmatter.ts) faalt hard. Daarnaast plaatst dezelfde workflow een zachte waarschuwing als feature-code wijzigt zonder bijbehorende userdocs-mutatie. - Publiceren. Bij elke push naar
mainwaarbij iets onderapps/**/userdocs/**wijzigt, draaitfreescout-sync.yml. Die rendert markdown naar HTML, regelt het categorie-pad in Freescout idempotent aan (categorieën worden aangemaakt als ze nog niet bestaan), maakt of updatet het artikel via de Freescout-API, en commit de toegekendefreescout_article_id/freescout_category_id/content_hashterug naar de repo. - Bijwerken. Wijzigt de tekst, dan verandert de
content_hashen detecteert sync dat. Wijzigt er niets, dan skipt sync via die hash. Zetstatus: draftom een artikel weer in te trekken (DELETEop de Freescout-API); het bronbestand blijft staan voor traceability.
Het volledige CI-mechanisme (loop guards, draft-PR’s, safety-rails staat
in detail uitgelegd in
Documentatie-pipeline.
Waarom naast de code
Drie redenen om userdocs niet in een aparte repo of in Freescout-zelf te beheren:
- Eén review, één merge. Wie het UI-gedrag verandert, raakt vrijwel altijd ook de uitleg. Door beide in dezelfde PR te zetten merk je verstoringen meteen (label hernoemd, knop verplaatst, flow gewijzigd).
- Versiebeheer en blame. Een userdoc is gewoon markdown in git. Geschiedenis, branches en revert werken zoals bij code, en niet zoals in een ad-hoc WYSIWYG-editor in een KB.
- AI-genereerbaar maar mensgereviewd. De slash-command kan een goede eerste versie schrijven omdat de bronnen (routes, templates, i18n) letterlijk naast het document liggen. Een mens reviewt voor commit. Een losse repo of CMS zou dat vertragen.
Het frontmatter-contract
Elke userdoc begint met YAML-frontmatter. Drie soorten velden:
| Veld | Wie zet ‘m | Mag muteren? |
|---|---|---|
title, slug, category, audience, visibility, status, last_reviewed |
jij, bij creatie of update | ja, behalve slug (zie hieronder) |
freescout_article_id, freescout_category_id |
de sync-workflow, na eerste publicatie | nee, hand-aanpassen breekt idempotentie |
content_hash |
de sync-workflow, na elke succesvolle sync | nee, automatisch beheerd |
slug is de stabiele ID over de levensduur van het document: aanpassen
geeft een nieuw artikel in Freescout en laat het oude wezen-bestaan.
status: draft is de standaard voor nieuw werk; published als de tekst
geschikt is voor live KB. Setting status terug op draft na publicatie
trekt het artikel in.
Het volledige schema en welke velden waarom verplicht zijn, staat in
tools/freescout-sync/src/frontmatter.ts.
Wat je als developer doet
Concreet, op een normale feature-PR:
- Maak of update de feature-code.
- Roep
/generate-userdocs apps/frontend/src/app/features/<scope>/<feature>(of het backend-equivalent) aan in Claude Code. - Lees de gegenereerde tekst. Klopt elke UI-label met wat in de templates
staat? Klopt de
audiencemet de feature-folder? Zetstatusoppublishedzodra de tekst geschikt is voor live KB. - Draai lokaal
npm run userdocs:validate. Verwacht✓ N userdoc(s) valide. - Commit beide (feature + userdocs) in dezelfde PR en push.
- Na merge naar
mainpubliceertfreescout-sync.ymlhet artikel automatisch binnen seconden.
De stap-voor-stap-versie met commando’s en branche-conventies staat in
Voeg eindgebruiker-documentatie toe.
Wanneer hoort er een userdoc bij een PR?
Korte vuistregel: als een eindgebruiker iets nieuws of anders ziet, ja.
Voor het volledige beslisschema (refactor, styling-tweak, bug-fix, admin-
feature in apps/api/) zie de tabel in de
how-to.
De CI-check is een waarschuwing, geen blocker. Onderdrukken met label
docs: not-needed of de checkbox in de PR-body als er bewust geen userdoc
nodig is.
Veelgemaakte verwarring
- Userdocs valideren vs userdocs sync.
npm run userdocs:validatecontroleert frontmatter lokaal of in CI;npm run freescout:syncpubliceert naar Freescout. De PR-check valideert alleen; de post-merge workflow publiceert. status: draftvs niet committen.draftbetekent “wel in git, nog niet geschikt voor klanten”. Sync slaat draft-docs over voor publicatie en trekt eerder gepubliceerde docs in als hun status terug naardraftspringt. Wil je een artikel echt nooit publiceren, commit dan niet./generate-userdocsvs hand-schrijven. Beide mag. De slash-command geeft een consistente eerste versie omdat hij routes/templates/i18n leest; hand-aanpassen na review is altijd toegestaan. Wijzig welslug,freescout_article_idofcontent_hashniet hand-matig (zie frontmatter-contract).
Zie ook
- Voeg eindgebruiker-documentatie toe - stappen per PR.
- Documentatie-pipeline (CI-workflows) - hoe
userdocs-checkenfreescout-syncwerken. - Documentatie bijdragen - waar hoort welke doc.
apps/frontend/AGENTS.md#eindgebruiker-documentatie-userdocs- volledige conventie voor AI-agents.tools/freescout-sync/README.md- sync-CLI met--dry-run,--full-scanen safety-rails..claude/commands/generate-userdocs.md- bron van de slash-command.