docs(trim): extract MCP integration into runbook

This commit is contained in:
Janpeter Visser 2026-05-03 01:03:55 +02:00
parent df649ee1bd
commit d469b4018a
3 changed files with 67 additions and 331 deletions

View file

@ -6,41 +6,8 @@ language: en
last_updated: 2026-05-03
---
<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know
# Agent Instructions — Scrum4Me
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->
This file is a redirect stub. All agent instructions live in **[CLAUDE.md](./CLAUDE.md)**.
# Scrum4Me Codex Rules
Read `CLAUDE.md` and the relevant files in `docs/` before changing behavior. The same product and security rules apply to Codex work.
## Access Control
- Product-scoped access is owner-or-member: use `productAccessFilter(userId)` from `lib/product-access.ts`.
- Use owner-only `user_id` checks only for actions that truly require ownership, such as product archiving and team management.
- Never trust client-provided IDs by themselves. For reorder, promotion, completion, or bulk updates, fetch the records with both `id in (...)` and the parent scope (`product_id`, `pbi_id`, `sprint_id`, or `story_id`) before writing.
- Reject duplicate IDs in ordered lists or decision payloads.
- Derive denormalized fields from database parents, for example `pbi.product_id`, not from form data or JSON bodies.
- Demo users and demo API tokens must receive 403 on write operations.
## Documentation Sync
When changing behavior, API responses, dependencies, environment variables, deployment behavior, or analytics, update the matching docs in the same change:
- `README.md` for setup, dependencies, deployment, and API overview.
- `docs/specs/functional.md` for user-facing/API requirements.
- `docs/architecture.md` for stack, access model, data model, env vars, and deployment.
- `docs/patterns/` when a reusable implementation rule changes.
- `CLAUDE.md` and this file when an agent instruction would have prevented the issue.
## Verification
Before handing work back, run:
```bash
npm run lint
npm test
npm run build
```
For Claude Code specifically, CLAUDE.md is loaded automatically. Start there.

356
CLAUDE.md
View file

@ -8,341 +8,107 @@ last_updated: 2026-05-03
# CLAUDE.md — Scrum4Me
Dit is het centrale instructiedocument voor Claude Code. Lees dit volledig voordat je iets bouwt.
Desktop-first Scrum-app voor solo developers en kleine teams. Hiërarchie: product → PBI → story → taak. Zie [README.md](./README.md) voor setup.
---
## Wat is Scrum4Me?
## Orientatie
Een desktop-first fullstack webapplicatie voor solo developers en kleine Scrum Teams die meerdere softwareprojecten parallel beheren. De app organiseert werk hiërarchisch (product → PBI → story → taak), biedt gesplitste planningsschermen met drag-and-drop, en integreert met Claude Code via een REST API.
---
## Specificatiedocumenten
Lees het relevante document voordat je aan een feature begint. Nooit gokken over requirements.
| Document | Gebruik voor |
| Bestand | Waarvoor |
|---|---|
| `docs/specs/functional.md` | Acceptatiecriteria, randgevallen, user flows |
| `docs/architecture.md` | Stack, datamodel, Prisma schema, Zustand stores |
| `docs/backlog/index.md` | Welke task bouwen, volgorde, "done when"-criteria |
| `docs/specs/personas.md` | Lars (primair), Dina, Remi — gebruik bij UI-beslissingen |
| `docs/backlog/product-historical.md` | Historische domein-backlog (referentie); seed wordt sinds ST-004 gegenereerd uit `backlog.md` via `prisma/seed-data/parse-backlog.ts` |
| `docs/api/rest-contract.md` | REST-API contract voor Claude Code — endpoints, status-enums, foutcodes, voorbeeld-curls |
| `docs/design/styling.md` | **Lees dit voor elk component** — MD3-kleuren, shadcn patronen |
| `docs/decisions/agent-instructions-history.md` | Waarom de agent-instructies zijn aangescherpt; checklist voor toekomstige wijzigingen |
| `docs/plans/<milestone-key>-*.md` | Implementatieplan per milestone — Bestanden, Stappen, Aandachtspunten, Verificatie. Lees vóór je aan een ST begint. Milestone-key matcht backlog-header (`M9`, `M3.5`, `PBI-9`, …). |
| [`madhura68/scrum4me-mcp`](https://github.com/madhura68/scrum4me-mcp) | MCP-server repo: native tools voor Claude Code, schema-sync via git submodule |
| `docs/INDEX.md` | Gegenereerde index van alle docs — begin hier |
| `docs/specs/functional.md` | Acceptatiecriteria, user flows |
| `docs/architecture.md` | Breadcrumb → 6 topische arch-bestanden |
| `docs/backlog/index.md` | Implementatievolgorde, "done when"-criteria |
| `docs/api/rest-contract.md` | REST API contract voor Claude Code |
| `docs/design/styling.md` | **Lees vóór elk component** — MD3-tokens, shadcn |
| `docs/plans/<key>-*.md` | Implementatieplan per milestone |
---
## Waar te beginnen
## Hoe werk vinden
Volg de backlog strikt op volgorde. Start bij **ST-001**. Sla geen milestone over.
```
M0 (ST-001008) → M1 (ST-101110) → M2 (ST-201210)
→ M3 (ST-301312) → M4 (ST-401410) → M5 (ST-501506)
→ M6 (ST-601612)
```
Werken aan een task kan via twee tracks. Track A heeft de voorkeur als je in Claude Code zit; Track B is voor Codex of omgevingen zonder MCP.
### Track A — via Claude Code MCP (aanbevolen)
1. Roep `mcp__scrum4me__implement_next_story` aan met `product_id` (gebruik `mcp__scrum4me__list_products` als je het id niet weet)
2. De prompt orkestreert: `get_claude_context``log_implementation` → per task `update_task_status(in_progress)` → bouw → `update_task_status(done)``log_test_result``log_commit`
3. Bouw de tasks in volgorde van `sort_order`; lees per task de relevante pattern-doc en styling
**Track A — MCP (aanbevolen):**
1. `mcp__scrum4me__get_claude_context` → pak de next story
2. Voer taken uit in `sort_order`; update status per taak
3. Lees het relevante patroon en styling vóór je begint
4. Verifieer: `npm run lint && npm test && npm run build`
5. Commit per laag (zie Commit Strategy)
5. Commit per laag — zie [docs/runbooks/branch-and-commit.md](./docs/runbooks/branch-and-commit.md)
### Track B — manueel (Codex of zonder MCP)
**Track B — manueel:**
1. Lees taak in `docs/backlog/index.md`
2. Zoek spec in `docs/specs/functional.md`
3. Lees patroon + styling → bouw → verifieer → vraag bevestiging → commit
1. Lees de task in `backlog.md`
2. Zoek de bijbehorende feature-spec in `functional.md`
3. Lees het relevante patroon in `docs/patterns/` en styling in `docs/design/styling.md` als dat van toepassing is
4. Bouw — test — verifieer de "Done when"-criteria
5. Vraag of de code correct is
6. Commit (zie Commit Strategy hieronder)
7. Vraag of de volgende taak gedaan moet worden
Volledige MCP-tool documentatie: [docs/runbooks/mcp-integration.md](./docs/runbooks/mcp-integration.md)
---
## Tech stack
## Hardstop regels
```
Next.js 16 (App Router) + React 19
TypeScript strict
Tailwind CSS + shadcn/ui
MD3 kleurensysteem via app/styles/theme.css
Zustand (client state)
dnd-kit (drag-and-drop)
Prisma v7 + PostgreSQL (Neon)
iron-session (auth cookies)
bcryptjs + Zod + Sonner
Sharp (avatarverwerking)
Vercel Analytics (@vercel/analytics/next)
```
> ⚠️ **Stylingregel:** Gebruik **nooit** `bg-blue-500` of willekeurige Tailwind-kleuren.
> Gebruik altijd semantische MD3-tokens: `bg-primary`, `bg-status-done`, `bg-priority-critical`.
> Zie `styling.md` voor alle patronen.
> ⚠️ **Next.js-versie:** Lees `node_modules/next/dist/docs/` bij twijfel — API's kunnen afwijken van trainingsdata.
- **Styling:** nooit `bg-blue-500`; altijd MD3-tokens (`bg-primary`, `bg-status-done`, …)
- **UI:** gebruik `@base-ui/react` met `render`-prop, niet Radix `asChild`
- **Push:** nooit pushen zonder expliciete gebruikersbevestiging — zie [branch-and-commit.md](./docs/runbooks/branch-and-commit.md)
- **Demo:** drie lagen — proxy.ts + server action + UI disabled knop
- **Enum:** DB UPPER_SNAKE ↔ API lowercase — uitsluitend via `lib/task-status.ts`
- **Foutcodes:** 400 = parse-fout, 422 = Zod-validatie, 403 = demo-token
- **Server/client grens:** `*-server.ts` bevat DB/node-only; nooit importeren in client component
- **Deployment:** `npm run lint && npm test && npm run build` vóór elke PR
---
## UI Library Conventions
## Stack
- Dit project gebruikt **`@base-ui/react`**, *niet* Radix UI — ondanks dat shadcn-componenten visueel-identiek zijn
- Composition gebeurt via de **`render`-prop**, niet via Radix's `asChild`:
- ✅ `<TooltipTrigger render={<button />}>...</TooltipTrigger>`
- ❌ `<TooltipTrigger asChild><button>...</button></TooltipTrigger>` — geeft TS-errors
- Vóór je een nieuwe shadcn-/UI-primitive gebruikt: grep eerst de codebase voor bestaand gebruik en volg dat patroon (`grep -rn "PrimitiveTrigger" components/`)
- shadcn-componenten in `components/ui/` zijn dunne wrappers rond `@base-ui/react`-primitives; lees die voor de exacte prop-API
| Laag | Technologie |
|---|---|
| Framework | Next.js 16 (App Router) + React 19 |
| Taal | TypeScript strict |
| Styling | Tailwind CSS + shadcn/ui + MD3 via `app/styles/theme.css` |
| State | Zustand + dnd-kit |
| DB | Prisma v7 + PostgreSQL (Neon) |
| Auth | iron-session + bcryptjs |
| Utilities | Zod, Sonner, Sharp, Vercel Analytics |
---
## Implementatiepatronen
Lees het relevante patroon vóór je begint. Nooit uit het hoofd schrijven.
## Patterns quickref
| Patroon | Bestand |
|---|---|
| iron-session (auth cookies) | `docs/patterns/iron-session.md` |
| Prisma Client singleton | `docs/patterns/prisma-client.md` |
| Server Action (met auth + Zod) | `docs/patterns/server-action.md` |
| Route Handler (REST API) | `docs/patterns/route-handler.md` |
| Zustand optimistische update + rollback | `docs/patterns/zustand-optimistic.md` |
| Float sort_order drag-and-drop | `docs/patterns/sort-order.md` |
| Proxy (route protection) | `docs/patterns/proxy.md` |
| QR-pairing (unauth-SSE + pre-auth cookie) | `docs/patterns/qr-login.md` |
| Bidirectionele async-comms MCP-agent ↔ user | `docs/patterns/claude-question-channel.md` |
| **Entity Dialog (verplicht voor élke create/edit/detail-dialog)** | `docs/patterns/dialog.md` — bron-of-truth; per entiteit één profile-doc (bv. `docs/specs/dialogs/task.md`) |
| Status-enum mapping (DB ↔ API) | `lib/task-status.ts` |
| Client/server module-boundary | `*-server.ts` bevat DB-calls of node-only deps; `*.ts` is pure (client-safe). Nooit `import { ... } from '@/lib/foo-server'` in een client-component, anders krijg je `Module not found: 'dns'`/`'pg'`-style runtime fouten |
| iron-session | `docs/patterns/iron-session.md` |
| Prisma singleton | `docs/patterns/prisma-client.md` |
| Server Action (auth + Zod) | `docs/patterns/server-action.md` |
| Route Handler (REST) | `docs/patterns/route-handler.md` |
| Zustand optimistic update | `docs/patterns/zustand-optimistic.md` |
| Float sort_order / drag-and-drop | `docs/patterns/sort-order.md` |
| Proxy / route protection | `docs/patterns/proxy.md` |
| QR-pairing | `docs/patterns/qr-login.md` |
| Claude ↔ user vraagkanaal | `docs/patterns/claude-question-channel.md` |
| Entity Dialog (verplicht) | `docs/patterns/dialog.md` |
---
## Env vars
```bash
DATABASE_URL="" # postgresql://... (verplicht)
DIRECT_URL="" # postgresql://... — pooler-bypass voor LISTEN/NOTIFY (Neon/cloud)
SESSION_SECRET="" # min 32 chars; openssl rand -base64 32
CRON_SECRET="" # M11 — Bearer-secret voor /api/cron/*; verplicht in productie, optioneel lokaal (genereer met openssl rand -base64 32)
DATABASE_URL="" # postgresql://...
DIRECT_URL="" # pooler-bypass voor LISTEN/NOTIFY
SESSION_SECRET="" # min 32 chars
CRON_SECRET="" # Bearer-secret /api/cron/*
```
Volledige Zod-schema in `lib/env.ts`. `.env.example` is de canonieke lijst voor nieuwe checkouts.
Volledig schema: `lib/env.ts`. Canonieke lijst: `.env.example`.
---
## Conventies
- **Branches:** `feat/ST-001-scaffolding`
- **Server Actions:** altijd in `actions/[domein].ts`, nooit inline in page.tsx
- **Validatie:** altijd Zod, nooit handmatige checks
- **Toegangsmodel:** product-scoped resources gebruiken `productAccessFilter(userId)` tenzij het expliciet een eigenaarsactie is
- **Bulk-ID's:** reorder- en beslissingsacties valideren dat alle meegegeven IDs binnen dezelfde parent-scope vallen voordat er geschreven wordt
- **Foreign keys:** denormalized keys zoals `story.product_id` worden afgeleid uit de database-parent (`pbi.product_id`), nooit uit client-input
- **Demo-check (drie lagen — ST-1110):** write-acties zijn drielaags afgedekt: (1) middleware-guard in `proxy.ts` blokkeert non-GET op `/api/*` voor demo; (2) elke Server Action / Route Handler controleert `session.isDemo` vóór schrijven; (3) write-knoppen in UI zijn `disabled` met `<DemoTooltip show={isDemo}>`. Zie `docs/architecture.md#demo-user-policy` en `docs/plans/ST-1110-demo-readonly.md`
- **Foutberichten:** Nederlands voor eindgebruikers — comments in code: Engels
- **Dependencies:** elke geïmporteerde runtime package staat direct in `dependencies`, niet alleen transitief in `package-lock.json`
- **Docs-sync:** elke gedrags-, dependency-, API- of deploymentwijziging werkt README, relevante docs en patterns bij in dezelfde change
- **Entity codes:** gebruik product/PBI/story-codes in commit-titles wanneer aanwezig (`feat(ST-356.2): ...`); branchnaam blijft `feat/ST-XXX-slug`
- **Status-enums op API:** lowercase (`todo|in_progress|review|done`, `open|in_sprint|done`); DB houdt UPPER_SNAKE; conversie uitsluitend via `lib/task-status.ts`-mappers — nooit ad-hoc `.toLowerCase()` elders
- **Foutcodes API:** `400` alleen voor malformed JSON-body (parse-fout via `request.json()`); `422` voor zod-validatie en well-formed-maar-niet-acceptabel; `403` voor demo-tokens. Documenteer per endpoint in `docs/api/rest-contract.md`
- **Tests volgen contract:** bij een API-contract-wijziging (status, foutcode, response-shape) MOET in dezelfde commit ook `__tests__/api/` mee — een test die rood gaat omdat de oude waarde wordt verwacht is een onvolledige wijziging, niet een "kapotte test"
- **Dev port:** `npm run dev` draait altijd op **3000**. Een `predev`-hook killt vooraf elk proces op 3000 (stale Next.js dev-server, vorige sessie) zodat sessies, cookies en MCP-config consistent op één poort werken. Wijk hier niet van af — geen `-p 3001` o.i.d. tenzij je expliciet twee dev-servers naast elkaar wil draaien
---
## Branch & PR Strategy (STRICT — kostenbeheersing)
> **Core rule: één branch per milestone, PR alleen na gebruikerstest**
Elke `git push` naar een feature-branch triggert een Vercel preview-deployment. Op het huidige Hobby-account zijn die schaars en kosten geld; we minimaliseren preview-builds tot er werkelijk iets te reviewen valt.
### Wel doen
- Eén branch voor de hele milestone — `feat/M{N}-{slug}` (bv. `feat/M10-qr-login`); voor losse stories zonder milestone blijft `feat/ST-XXX-{slug}` geldig
- Commits accumuleren lokaal volgens de Commit Strategy hieronder — één commit per stap, ST-code in de titel
- Pushen + PR openen **pas nadat de gebruiker de milestone handmatig heeft getest en goedgekeurd** — vraag expliciet om bevestiging vóór `git push`
- Tussentijdse "klaar voor jouw test"-momenten markeren met een lokale tag of een berichtje in chat, niet met een push
### Niet doen
- Pushen na elke story of commit
- Een PR per story openen tijdens de implementatie
- "Just-in-case" pushen om backup te hebben — gebruik `git stash`, een lokale tag, of meerdere lokale branches
- `--force-push` om eerdere preview-builds "weg te toveren" (kost dezelfde build opnieuw bij hercreatie)
- **Direct pushen naar `main`** — die branch heeft protection rules; gebruik altijd een PR
### Wanneer wel commit-zonder-vragen, wanneer niet
- **Tijdens een directed sprint-flow** (Track A: `mcp__scrum4me__implement_next_story` of een expliciete *"implementeer M{N}"*-opdracht): commit-per-laag conform de Commit Strategy hieronder is impliciet geautoriseerd — niet per commit vragen
- **Bij ad-hoc / out-of-band werk** (bug-fix tussendoor, refactor, kleine wijziging op verzoek): toon de diff + voorgestelde commit-message en wacht op `"commit it"` voordat je `git commit` draait
- **`git push` is altijd expliciet** — de scope van de policy gaat over preview-builds, dus push gebeurt alleen na gebruiker-test, ongeacht commit-context
### Uitzonderingen op de push-regel
- Een **planning-PR** zonder code-wijzigingen (alleen docs in `docs/plans/` of `docs/`) mag direct gepusht worden — die triggert geen functional regressie en is goedkoop te bouwen
- Een **bugfix-hotfix** op `main` met aantoonbare productie-impact mag direct gepusht worden (via een PR — zie boven)
### Wanneer aanpassen
Zodra het Vercel-account naar Pro (of andere omgeving zonder per-build-kosten) gaat: vervang deze regel door "branch + PR per story" zoals oorspronkelijk in dit document stond. Werk deze sectie bij én documenteer de wijziging in `docs/decisions/agent-instructions-history.md`.
---
## Plan Mode
- Voor simpele, goed-afgebakende file-edits: **niet** in plan mode gaan — gewoon de wijziging maken
- Reserveer plan mode voor multi-step refactors, ambigue verzoeken, of milestone-planning waarbij design-keuzes vooraf bevestigd moeten worden
- Plannen die uit plan mode komen: opslaan als `docs/plans/M{N}-{slug}.md` (zie memory `feedback_plan_location`), niet als ephemeral systeem-bestand
---
## Commit Strategy (STRICT)
> **Core rule: één commit = één verantwoordelijkheid**
### Nooit doen
- Database + API + UI in één commit mengen
- Feature + documentatie combineren
- Grote "alles gewijzigd" commits
- Vage berichten zoals "update stuff"
### Verplichte structuur
Splits werk op in logische lagen:
1. Database / Prisma
2. API / server actions
3. UI / components
4. Config / infra
5. Documentatie
### Commit-formaat
```
feat(ST-XXX): korte beschrijving
fix(ST-XXX): korte beschrijving
chore(ST-XXX): korte beschrijving
docs(ST-XXX): korte beschrijving
```
### Voorbeeld (verplicht patroon)
In plaats van:
```bash
feat: add profile system
```
Splits altijd op in:
```bash
feat(ST-XXX): add user profile fields to Prisma schema
feat(ST-XXX): add avatar upload endpoint
feat(ST-XXX): add profile editor component
chore(ST-XXX): configure sharp for avatar processing
docs(ST-XXX): document profile feature
```
---
## Scrum-terminologie
| Correct | Niet gebruiken |
|---|---|
| Product Backlog Item (PBI) | Feature, Epic, Issue |
| Story | User Story, Ticket |
| Sprint Goal | Sprint Objective |
| Scrum Team | Team |
PBI (niet: Feature/Epic) · Story (niet: Ticket) · Sprint Goal (niet: Objective)
---
## MCP-integratie
## Verificatie
Scrum4Me heeft een eigen MCP-server in repo [`madhura68/scrum4me-mcp`](https://github.com/madhura68/scrum4me-mcp) die de REST-API als native tools voor Claude Code aanbiedt. Schema's worden gedeeld via een git submodule (`vendor/scrum4me`), niet gedupliceerd.
### Tools beschikbaar in Claude Code (18)
**Read / context:**
- `mcp__scrum4me__health` — service + DB ping
- `mcp__scrum4me__list_products` — producten waar de tokengebruiker toegang tot heeft
- `mcp__scrum4me__get_claude_context` — bundled product / actieve sprint / next story (met tasks) / open todos
**Authoring (PBI/Story/Task aanmaken):**
- `mcp__scrum4me__create_pbi``{ product_id, title, description?, priority, sort_order? }`; auto sort_order = last+1 binnen prio-groep
- `mcp__scrum4me__create_story``{ pbi_id, title, description?, acceptance_criteria?, priority, sort_order? }`; product_id afgeleid uit PBI; status=OPEN
- `mcp__scrum4me__create_task``{ story_id, title, description?, implementation_plan?, priority, sort_order? }`; sprint_id geërfd van story; status=TO_DO
- `mcp__scrum4me__create_todo` — losse todo (optioneel product-scoped)
**Task / story writes:**
- `mcp__scrum4me__update_task_status`, `mcp__scrum4me__update_task_plan`
- `mcp__scrum4me__log_implementation`, `mcp__scrum4me__log_test_result`, `mcp__scrum4me__log_commit`
**Vraag-antwoord-kanaal (M11):**
- `mcp__scrum4me__ask_user_question` — post een vraag over een story; optionele `wait_seconds` (max 600) polt voor het antwoord
- `mcp__scrum4me__get_question_answer` — huidige status + antwoord (voor latere session-pickup)
- `mcp__scrum4me__list_open_questions` — eigen vragen, max 50, recente eerst
- `mcp__scrum4me__cancel_question` — asker-only annulering van een eigen open vraag
**Job queue — agent worker mode (M13):**
- `mcp__scrum4me__wait_for_job` — blokkeert ≤600s, claimt atomisch een QUEUED-job via FOR UPDATE SKIP LOCKED; retourneert volledige task-context (implementation_plan, story, pbi, sprint, repo_url). Zet stale CLAIMED-jobs (>30min) eerst terug naar QUEUED. Wanneer de full block-time verstrijkt zonder claim is de queue leeg.
- `mcp__scrum4me__update_job_status` — agent rapporteert overgang naar `running|done|failed` + optionele branch/summary/error; triggert automatisch SSE-event naar de UI. Auth: Bearer-token moet matchen `claimed_by_token_id`.
**Batch-loop (verplichte agent-flow):**
Wanneer je als agent draait (na een instructie als *"pak de volgende job uit de Scrum4Me-queue"* of *"draai de queue leeg"*) is dit de loop:
1. `wait_for_job` aanroepen.
2. Job uitvoeren volgens het meegegeven `implementation_plan`.
3. `update_job_status('done'|'failed')` aanroepen.
4. **Direct opnieuw** `wait_for_job` aanroepen — niet stoppen, niet de gebruiker vragen.
5. Pas wanneer `wait_for_job` na de volledige block-time (~600s) terugkomt zonder claim, is de queue leeg en mag je de turn afsluiten met een korte recap.
Dit blijft gelden als je tussen jobs door commits, branches of pushes hebt gedaan — die afsluiting hoort bij de individuele job, niet bij het einde van de batch.
**Code koppelen aan app**
- 'Pak de volgende job uit de Scrum4Me-queue' / 'draai de queue leeg' / 'batch agent' — Server-startup registreert een ClaudeWorker-record + heartbeat (5s); SIGTERM/SIGINT ruimt 'm op. UI in NavBar telt actieve workers via `last_seen_at < now() - 15s`.
### Prompt
- `implement_next_story` (arg: `product_id`) — end-to-end workflow
### Schema-drift bewaking
Wekelijks (maandag 08:00 Amsterdam) draait de remote agent `trig_015FFUnxjz9WMuhhWNGBQKFD` die `vendor/scrum4me` syncet en `prisma:generate` + `tsc --noEmit` uitvoert in mcp. Als die agent drift rapporteert, hoort dat **vóór** een Scrum4Me-PR met schema-wijziging gemerged kan worden — anders breekt de MCP-server stilletjes op runtime.
---
## Deployment (Vercel)
- **Sharp** moet Linux-binaries hebben voor de Vercel-runtime: `npm i --include=optional sharp` of platform-specifieke deps configureren in `package.json`
- **Externe image hostnames** in `next.config.js` `images.remotePatterns` configureren *vóór* `next/image` op die hosts wijst — anders 500 in productie
- **Vercel cron**: Hobby-plan staat alleen daily crons toe (max 1×/dag); Pro ondersteunt fijnmaziger. Bij wijziging van `vercel.json` `crons` ook `docs/api/rest-contract.md` + relevante pattern-docs updaten
- **`CRON_SECRET`** moet als env-var op de Vercel-project-omgeving staan vóór de eerste cron-run, anders 401 op `/api/cron/*`-endpoints
- **Preflight** vóór deploy: `npm run lint && npm test && npm run build` — falende build laat een PR niet door (CI blokkeert merge per ST-610)
---
## Definition of Done (MVP)
M7 (MCP-server) is post-MVP en heeft eigen acceptatie in `docs/backlog/index.md`.
- [ ] Alle 62 tasks (ST-001 t/m ST-612) afgerond
- [ ] Volledige Lars-flow zonder fouten (ST-612)
- [ ] Alle gedocumenteerde API-endpoints werken via curl (zie `docs/api/rest-contract.md`)
- [ ] Demo-gebruiker heeft geen schrijfrechten
- [ ] App opzetbaar via README zonder extra hulp
- [ ] CI/CD actief — falende build blokkeert merge
- [ ] Beveiligingsreview API geslaagd (cross-user toegang onmogelijk)
- [ ] Documentatie is bijgewerkt voor gewijzigde API's, dependencies, deployment en agent-instructies
```bash
npm run lint && npm test && npm run build
```

View file

@ -76,3 +76,6 @@ Auto-generated on 2026-05-02 from front-matter and headings.
| [Scrum4Me — Styling & Design System](./design/styling.md) | `design/styling.md` | active | 2026-05-03 |
| [Obsidian as Personal Authoring Layer](./obsidian-authoring.md) | `obsidian-authoring.md` | active | 2026-05-02 |
| [Scrum4Me — API Test Plan](./qa/api-test-plan.md) | `qa/api-test-plan.md` | active | 2026-05-03 |
| [Branch, PR & Commit Strategy](./runbooks/branch-and-commit.md) | `runbooks/branch-and-commit.md` | active | 2026-05-03 |
| [Vercel Deployment](./runbooks/deploy-vercel.md) | `runbooks/deploy-vercel.md` | active | 2026-05-03 |
| [MCP Integration — Scrum4Me Tools](./runbooks/mcp-integration.md) | `runbooks/mcp-integration.md` | active | 2026-05-03 |