docs: AI-optimized docs restructure (Phases 1–8) (#61)
* docs(dialog-pattern): add generic entity-dialog spec Introduceert docs/patterns/dialog.md als bron-of-truth voor elke create/edit/detail-dialog in Scrum4Me, ongeacht het achterliggende dataobject. Bevat 14 secties: uitgangspunten, stack, component- architectuur, layout, validatie, drielaagse demo-policy, submission, dialog-gedrag, theming, footer, triggers/URL-state, per-entiteit profile-template, out-of-scope, en een verificatie-checklist. Registreert het patroon in CLAUDE.md "Implementatiepatronen"-tabel zodat Claude (en mensen) de spec verplicht raadplegen voor elke nieuwe dialog. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(dialog-pattern): convert task spec + add pbi/story entity-profiles Reduceert docs/scrum4me-task-dialog.md van 507 naar ~140 regels: alle gedeelde regels verhuisd naar docs/patterns/dialog.md, dit document bevat nu alleen Task-specifieke velden, URL-pattern, status-veld, server actions, triggers en bewuste out-of-scope-keuzes. Voegt twee nieuwe entity-profielen toe voor bestaande dialogen: - docs/scrum4me-pbi-dialog.md (PbiDialog: state-based, code+title-rij, PbiStatusSelect, geen delete in v1) - docs/scrum4me-story-dialog.md (StoryDialog: state-based, header met status/priority badges, inline activity-log, demo-readonly-fallback, inline-delete-confirm i.p.v. AlertDialog) Beide profielen documenteren expliciet de "Bekende gaps t.o.v. generieke spec" zodat opvolgende PR's de afwijkingen kunnen rechtzetten of bewust kunnen accorderen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Added pdevelopment docs * docs(plans): add docs-restructure plan for AI-optimized lookup Audit of existing 39 doc files (~10.700 lines) and a phased restructure proposal aimed at minimising the tokens an AI agent has to read to find the right reference. Captures resolved decisions on language (English), ADR template (Nygard default with MADR escape-hatch), index generator (node script), and folder taxonomy. Proposal status — fase 1 to follow. * docs(adr): add ADR scaffolding (templates, README, meta-ADR) Set up docs/adr/ as the canonical home for architecture decisions: - templates/nygard.md — default four-section format (Status, Context, Decision, Consequences) for one-way-door decisions. - templates/madr.md — MADR v4 with YAML front-matter and explicit Considered Options for decisions where rejected alternatives matter. - README.md — naming convention (NNNN-kebab-case), template-selection guidance (Nygard default; MADR for auth, queue mechanics, agent integration), status lifecycle, and ADR roster. - 0000-record-architecture-decisions.md — meta-ADR establishing the practice itself, in Nygard format. Backfilling existing implicit decisions (base-ui-over-radix, float sort_order, demo-user three-layer policy, etc.) is fase 6 of the docs-restructure plan. * feat(docs): add docs index generator + initial INDEX.md scripts/generate-docs-index.mjs walks docs/**/*.md, parses YAML front-matter (or first H1 fallback) and a Nygard-style ## Status section, then writes docs/INDEX.md with grouped tables for ADRs, Specs, Plans (with archive subsection), Patterns, and Other. Pure Node 20 (no external deps); idempotent — running it twice produces byte-identical output. Excludes adr/templates/, the ADR README, INDEX.md itself, and any *_*.md sidecar file. Wire-up: - package.json: docs:index → node scripts/generate-docs-index.mjs Initial run indexed 35 docs across the existing structure; the generated INDEX.md is committed so the table is reviewable in the PR before hooking generation into a pre-commit step. * chore: ignore Obsidian vault and personal sidecar files Add .obsidian/ (Obsidian vault config) and _*.md (personal sidecar notes) to .gitignore so the docs/ tree can serve as canonical source of truth while still being usable as an Obsidian vault for personal authoring. The docs index generator already excludes the same _*.md pattern from INDEX.md. * docs(plans): add PBI bulk-create spec for docs-restructure Machine-parseable spec for an executor that calls the scrum4me MCP (create_pbi → create_story → create_task) to seed the docs-restructure work into the DB. - Section 1 (Context) is the PBI description; serves as task-context via mcp__scrum4me__get_claude_context. - Section 2 lists the 6 resolved decisions (English, MD3+styling merged, solo-paneel merged, .Plans archived, Nygard ADR default, node index script). - Section 3 records what already shipped on this branch so the executor doesn't duplicate the ADR scaffolding or index generator. - Section 4 carries the structured YAML graph: 1 PBI, 8 stories (one per phase), 39 tasks. product_id is REPLACE_ME — fill before running. - YAML validated with PyYAML; field schema sanity-checked. * docs(junk-cleanup): remove stub patterns/test.md * docs(junk-cleanup): archive .Plans/ to docs/plans/archive/ * docs(front-matter): add YAML front-matter to docs/ root * docs(front-matter): add YAML front-matter to patterns/ * docs(front-matter): add YAML front-matter to plans + agent files * docs(index): regenerate INDEX.md after front-matter pass * docs(naming): drop scrum4me- prefix from doc filenames * docs(naming): lowercase API.md and MD3 filenames * docs(naming): rename plan file to kebab-case ASCII * docs(naming): rename middleware.md to proxy.md (next 16) * docs(naming): polish CLAUDE.md doc-index after renames * docs(taxonomy): scaffold topical folders under docs/ * docs(taxonomy): move spec files into docs/specs/ * docs(taxonomy): move design/api/qa/backlog/assets into folders * docs(taxonomy): move agent-instruction-audit into decisions/ * docs(split): break architecture.md into 6 topical files * docs(split): merge solo-paneel-spec into specs/functional.md * docs(split): merge md3-color-scheme into design/styling * docs(trim): extract branch/commit rules into runbook * docs(trim): extract MCP integration into runbook * docs(adr): add 0001-base-ui-over-radix * docs(adr): add 0002-float-sort-order * docs(adr): add 0003-one-branch-per-milestone * docs(adr): add 0004-status-enum-mapping * docs(adr): add 0005-iron-session-over-nextauth * docs(adr): add 0006-demo-user-three-layer-policy * docs(adr): add 0007-claude-question-channel-design * docs(adr): add 0008-agent-instructions-in-claude-md + update README index * docs(index): regenerate after ADR 0001-0008 * docs(glossary): add docs/glossary.md * chore(docs): regenerate INDEX.md in pre-commit hook * docs(readme): link INDEX + glossary + agent instructions * feat(docs): add doc-link checker script * chore(docs): wire docs:check-links and docs npm scripts * ci(docs): block merge on broken doc links * docs(links): fix broken cross-references after restructure --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
289bcf9bf0
commit
7e45bbdbc0
81 changed files with 12364 additions and 3154 deletions
396
CLAUDE.md
396
CLAUDE.md
|
|
@ -1,372 +1,114 @@
|
|||
---
|
||||
title: "CLAUDE.md — Scrum4Me"
|
||||
status: active
|
||||
audience: [ai-agent]
|
||||
language: nl
|
||||
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/functional.md` | Acceptatiecriteria, randgevallen, user flows |
|
||||
| `docs/architecture.md` | Stack, datamodel, Prisma schema, Zustand stores |
|
||||
| `docs/backlog.md` | Welke task bouwen, volgorde, "done when"-criteria |
|
||||
| `docs/personas.md` | Lars (primair), Dina, Remi — gebruik bij UI-beslissingen |
|
||||
| `docs/product-backlog.md` | Historische domein-backlog (referentie); seed wordt sinds ST-004 gegenereerd uit `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/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/<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-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
|
||||
**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/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 middleware (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/task-dialog.md`) |
|
||||
| **Story met UI-component (verplicht 3-task-patroon: Helper / Component / Integration)** | `docs/patterns/story-with-ui-component.md` — elke story met een `*-component.tsx` vereist een afsluitende Integration-task die de component in `page.tsx` wirt |
|
||||
| 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 |
|
||||
|
||||
---
|
||||
|
||||
## Integration-task verificatie (smoke-test)
|
||||
|
||||
Voor stories met `*-component.tsx`: de Integration-task moet vóór
|
||||
`update_job_status(done)` een smoke-test draaien op de daadwerkelijke
|
||||
HTML-render:
|
||||
|
||||
```bash
|
||||
# In de worktree — pas ROUTE en SECTIONS aan per story
|
||||
ROUTE="/insights"
|
||||
SECTIONS=("Sprint Health" "Plan-quality" "Agent throughput" "Velocity" "Backlog health")
|
||||
|
||||
npm run dev > /tmp/dev.log 2>&1 &
|
||||
DEV_PID=$!
|
||||
sleep 8 # wacht tot Next.js compiled
|
||||
|
||||
curl -s http://localhost:3000${ROUTE} > /tmp/page.html
|
||||
|
||||
SMOKE_FAIL=
|
||||
for section in "${SECTIONS[@]}"; do
|
||||
grep -q "$section" /tmp/page.html || { echo "MISSING: $section"; SMOKE_FAIL=1; }
|
||||
done
|
||||
|
||||
kill $DEV_PID
|
||||
[ -z "$SMOKE_FAIL" ] # exit-code 1 als iets miste
|
||||
```
|
||||
|
||||
Als de smoke-test faalt: pas `page.tsx` aan zodat alle secties renderen, herhaal.
|
||||
Markeer Integration-task DONE pas wanneer alle verwachte sections in de HTML zitten.
|
||||
| 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.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 |
|
||||
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 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/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
|
||||
```bash
|
||||
npm run lint && npm test && npm run build
|
||||
```
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue