# CLAUDE.md — Scrum4Me Dit is het centrale instructiedocument voor Claude Code. Lees dit volledig voordat je iets bouwt. --- ## Wat is Scrum4Me? 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 | |---|---| | `docs/scrum4me-functional-spec.md` | Acceptatiecriteria, randgevallen, user flows | | `docs/scrum4me-architecture.md` | Stack, datamodel, Prisma schema, Zustand stores | | `docs/scrum4me-backlog.md` | Welke task bouwen, volgorde, "done when"-criteria | | `docs/scrum4me-personas.md` | Lars (primair), Dina, Remi — gebruik bij UI-beslissingen | | `docs/scrum4me-product-backlog.md` | Historische domein-backlog (referentie); seed wordt sinds ST-004 gegenereerd uit `scrum4me-backlog.md` via `prisma/seed-data/parse-backlog.ts` | | `docs/API.md` | REST-API contract voor Claude Code — endpoints, status-enums, foutcodes, voorbeeld-curls | | `docs/scrum4me-styling.md` | **Lees dit voor elk component** — MD3-kleuren, shadcn patronen | | `docs/agent-instruction-audit.md` | Waarom de agent-instructies zijn aangescherpt; checklist voor toekomstige wijzigingen | | `docs/plans/-*.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 | --- ## Waar te beginnen Volg de backlog strikt op volgorde. Start bij **ST-001**. Sla geen milestone over. ``` M0 (ST-001–008) → M1 (ST-101–110) → M2 (ST-201–210) → M3 (ST-301–312) → M4 (ST-401–410) → M5 (ST-501–506) → M6 (ST-601–612) ``` 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 4. Verifieer: `npm run lint && npm test && npm run build` 5. Commit per laag (zie Commit Strategy) ### Track B — manueel (Codex of zonder MCP) 1. Lees de task in `scrum4me-backlog.md` 2. Zoek de bijbehorende feature-spec in `scrum4me-functional-spec.md` 3. Lees het relevante patroon in `docs/patterns/` en styling in `docs/scrum4me-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 --- ## Tech stack ``` 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 `scrum4me-styling.md` voor alle patronen. > ⚠️ **Next.js-versie:** Lees `node_modules/next/dist/docs/` bij twijfel — API's kunnen afwijken van trainingsdata. --- ## UI Library Conventions - 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`: - ✅ `}>...` - ❌ `` — 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 --- ## Implementatiepatronen Lees het relevante patroon vóór je begint. Nooit uit het hoofd schrijven. | 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` | | Middleware (route protection) | `docs/patterns/middleware.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` | | 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 | --- ## 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) ``` Volledige Zod-schema in `lib/env.ts`. `.env.example` is de canonieke lijst voor nieuwe checkouts. --- ## 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:** elke Server Action controleert `session.isDemo` vóór schrijven - **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.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/agent-instruction-audit.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 | --- ## MCP-integratie 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 (13) **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 **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` - `mcp__scrum4me__create_todo` **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 ### 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 scrum4me-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.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/scrum4me-backlog.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.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