Compare commits
5 commits
main
...
feat/story
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee05e4775e | ||
|
|
e9d6b8a255 | ||
|
|
c4ce3d7885 | ||
|
|
685f0dd32e | ||
|
|
29597e96a7 |
27 changed files with 101 additions and 101 deletions
|
|
@ -22,8 +22,8 @@ Read `CLAUDE.md` and the relevant files in `docs/` before changing behavior. The
|
||||||
When changing behavior, API responses, dependencies, environment variables, deployment behavior, or analytics, update the matching docs in the same change:
|
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.
|
- `README.md` for setup, dependencies, deployment, and API overview.
|
||||||
- `docs/scrum4me-functional-spec.md` for user-facing/API requirements.
|
- `docs/functional.md` for user-facing/API requirements.
|
||||||
- `docs/scrum4me-architecture.md` for stack, access model, data model, env vars, and deployment.
|
- `docs/architecture.md` for stack, access model, data model, env vars, and deployment.
|
||||||
- `docs/patterns/` when a reusable implementation rule changes.
|
- `docs/patterns/` when a reusable implementation rule changes.
|
||||||
- `CLAUDE.md` and this file when an agent instruction would have prevented the issue.
|
- `CLAUDE.md` and this file when an agent instruction would have prevented the issue.
|
||||||
|
|
||||||
|
|
|
||||||
36
CLAUDE.md
36
CLAUDE.md
|
|
@ -16,13 +16,13 @@ Lees het relevante document voordat je aan een feature begint. Nooit gokken over
|
||||||
|
|
||||||
| Document | Gebruik voor |
|
| Document | Gebruik voor |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `docs/scrum4me-functional-spec.md` | Acceptatiecriteria, randgevallen, user flows |
|
| `docs/functional.md` | Acceptatiecriteria, randgevallen, user flows |
|
||||||
| `docs/scrum4me-architecture.md` | Stack, datamodel, Prisma schema, Zustand stores |
|
| `docs/architecture.md` | Stack, datamodel, Prisma schema, Zustand stores |
|
||||||
| `docs/scrum4me-backlog.md` | Welke task bouwen, volgorde, "done when"-criteria |
|
| `docs/backlog.md` | Welke task bouwen, volgorde, "done when"-criteria |
|
||||||
| `docs/scrum4me-personas.md` | Lars (primair), Dina, Remi — gebruik bij UI-beslissingen |
|
| `docs/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/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/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/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/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`, …). |
|
| `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 |
|
| [`madhura68/scrum4me-mcp`](https://github.com/madhura68/scrum4me-mcp) | MCP-server repo: native tools voor Claude Code, schema-sync via git submodule |
|
||||||
|
|
@ -51,9 +51,9 @@ Werken aan een task kan via twee tracks. Track A heeft de voorkeur als je in Cla
|
||||||
|
|
||||||
### Track B — manueel (Codex of zonder MCP)
|
### Track B — manueel (Codex of zonder MCP)
|
||||||
|
|
||||||
1. Lees de task in `scrum4me-backlog.md`
|
1. Lees de task in `backlog.md`
|
||||||
2. Zoek de bijbehorende feature-spec in `scrum4me-functional-spec.md`
|
2. Zoek de bijbehorende feature-spec in `functional.md`
|
||||||
3. Lees het relevante patroon in `docs/patterns/` en styling in `docs/scrum4me-styling.md` als dat van toepassing is
|
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
|
4. Bouw — test — verifieer de "Done when"-criteria
|
||||||
5. Vraag of de code correct is
|
5. Vraag of de code correct is
|
||||||
6. Commit (zie Commit Strategy hieronder)
|
6. Commit (zie Commit Strategy hieronder)
|
||||||
|
|
@ -79,7 +79,7 @@ Vercel Analytics (@vercel/analytics/next)
|
||||||
|
|
||||||
> ⚠️ **Stylingregel:** Gebruik **nooit** `bg-blue-500` of willekeurige Tailwind-kleuren.
|
> ⚠️ **Stylingregel:** Gebruik **nooit** `bg-blue-500` of willekeurige Tailwind-kleuren.
|
||||||
> Gebruik altijd semantische MD3-tokens: `bg-primary`, `bg-status-done`, `bg-priority-critical`.
|
> Gebruik altijd semantische MD3-tokens: `bg-primary`, `bg-status-done`, `bg-priority-critical`.
|
||||||
> Zie `scrum4me-styling.md` voor alle patronen.
|
> Zie `styling.md` voor alle patronen.
|
||||||
|
|
||||||
> ⚠️ **Next.js-versie:** Lees `node_modules/next/dist/docs/` bij twijfel — API's kunnen afwijken van trainingsdata.
|
> ⚠️ **Next.js-versie:** Lees `node_modules/next/dist/docs/` bij twijfel — API's kunnen afwijken van trainingsdata.
|
||||||
|
|
||||||
|
|
@ -108,10 +108,10 @@ Lees het relevante patroon vóór je begint. Nooit uit het hoofd schrijven.
|
||||||
| Route Handler (REST API) | `docs/patterns/route-handler.md` |
|
| Route Handler (REST API) | `docs/patterns/route-handler.md` |
|
||||||
| Zustand optimistische update + rollback | `docs/patterns/zustand-optimistic.md` |
|
| Zustand optimistische update + rollback | `docs/patterns/zustand-optimistic.md` |
|
||||||
| Float sort_order drag-and-drop | `docs/patterns/sort-order.md` |
|
| Float sort_order drag-and-drop | `docs/patterns/sort-order.md` |
|
||||||
| Middleware (route protection) | `docs/patterns/middleware.md` |
|
| Proxy middleware (route protection) | `docs/patterns/proxy.md` |
|
||||||
| QR-pairing (unauth-SSE + pre-auth cookie) | `docs/patterns/qr-login.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` |
|
| 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/scrum4me-task-dialog.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 |
|
| **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` |
|
| 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 |
|
| 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 |
|
||||||
|
|
@ -170,13 +170,13 @@ Volledige Zod-schema in `lib/env.ts`. `.env.example` is de canonieke lijst voor
|
||||||
- **Toegangsmodel:** product-scoped resources gebruiken `productAccessFilter(userId)` tenzij het expliciet een eigenaarsactie is
|
- **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
|
- **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
|
- **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/scrum4me-architecture.md#demo-user-policy` en `docs/plans/ST-1110-demo-readonly.md`
|
- **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
|
- **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`
|
- **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
|
- **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`
|
- **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
|
- **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`
|
- **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"
|
- **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
|
- **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
|
||||||
|
|
||||||
|
|
@ -352,7 +352,7 @@ Wekelijks (maandag 08:00 Amsterdam) draait de remote agent `trig_015FFUnxjz9WMuh
|
||||||
|
|
||||||
- **Sharp** moet Linux-binaries hebben voor de Vercel-runtime: `npm i --include=optional sharp` of platform-specifieke deps configureren in `package.json`
|
- **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
|
- **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
|
- **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
|
- **`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)
|
- **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)
|
||||||
|
|
||||||
|
|
@ -360,11 +360,11 @@ Wekelijks (maandag 08:00 Amsterdam) draait de remote agent `trig_015FFUnxjz9WMuh
|
||||||
|
|
||||||
## Definition of Done (MVP)
|
## Definition of Done (MVP)
|
||||||
|
|
||||||
M7 (MCP-server) is post-MVP en heeft eigen acceptatie in `docs/scrum4me-backlog.md`.
|
M7 (MCP-server) is post-MVP en heeft eigen acceptatie in `docs/backlog.md`.
|
||||||
|
|
||||||
- [ ] Alle 62 tasks (ST-001 t/m ST-612) afgerond
|
- [ ] Alle 62 tasks (ST-001 t/m ST-612) afgerond
|
||||||
- [ ] Volledige Lars-flow zonder fouten (ST-612)
|
- [ ] Volledige Lars-flow zonder fouten (ST-612)
|
||||||
- [ ] Alle gedocumenteerde API-endpoints werken via curl (zie `docs/API.md`)
|
- [ ] Alle gedocumenteerde API-endpoints werken via curl (zie `docs/api.md`)
|
||||||
- [ ] Demo-gebruiker heeft geen schrijfrechten
|
- [ ] Demo-gebruiker heeft geen schrijfrechten
|
||||||
- [ ] App opzetbaar via README zonder extra hulp
|
- [ ] App opzetbaar via README zonder extra hulp
|
||||||
- [ ] CI/CD actief — falende build blokkeert merge
|
- [ ] CI/CD actief — falende build blokkeert merge
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ Verwacht: alle 69 tests slagen, 0 failures.
|
||||||
bash scripts/test-api.sh
|
bash scripts/test-api.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
De curl-tests dekken alle 7 API-endpoints: auth (401), demo-blokkering (403), inputvalidatie (400) en happy paths. Zie `docs/scrum4me-test-plan.md` voor het volledige testplan.
|
De curl-tests dekken alle 7 API-endpoints: auth (401), demo-blokkering (403), inputvalidatie (400) en happy paths. Zie `docs/test-plan.md` voor het volledige testplan.
|
||||||
|
|
||||||
## Database
|
## Database
|
||||||
|
|
||||||
|
|
@ -279,7 +279,7 @@ De productieomgeving is gericht op Vercel + Neon.
|
||||||
|
|
||||||
### Documentatie
|
### Documentatie
|
||||||
|
|
||||||
- [Functionele specificatie](docs/scrum4me-functional-spec.md)
|
- [Functionele specificatie](docs/functional.md)
|
||||||
- [Technische architectuur](docs/scrum4me-architecture.md)
|
- [Technische architectuur](docs/architecture.md)
|
||||||
- [Backlog](docs/scrum4me-backlog.md)
|
- [Backlog](docs/backlog.md)
|
||||||
- [Agent-instructie audit](docs/agent-instruction-audit.md)
|
- [Agent-instructie audit](docs/agent-instruction-audit.md)
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@ Dit document legt vast welke wijzigingen zijn gecontroleerd, welke documentatie
|
||||||
|
|
||||||
| Wijziging | Code-locatie | Documentatie bijgewerkt |
|
| Wijziging | Code-locatie | Documentatie bijgewerkt |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Reorder-acties valideren alle IDs binnen de juiste parent-scope | `actions/stories.ts`, `actions/sprints.ts` | `docs/scrum4me-architecture.md`, `docs/patterns/server-action.md`, `docs/patterns/sort-order.md`, `CLAUDE.md`, `AGENTS.md` |
|
| Reorder-acties valideren alle IDs binnen de juiste parent-scope | `actions/stories.ts`, `actions/sprints.ts` | `docs/architecture.md`, `docs/patterns/server-action.md`, `docs/patterns/sort-order.md`, `CLAUDE.md`, `AGENTS.md` |
|
||||||
| Sprint afronden accepteert alleen stories uit de actieve sprint | `actions/sprints.ts` | `docs/scrum4me-architecture.md`, `docs/patterns/server-action.md`, `AGENTS.md` |
|
| Sprint afronden accepteert alleen stories uit de actieve sprint | `actions/sprints.ts` | `docs/architecture.md`, `docs/patterns/server-action.md`, `AGENTS.md` |
|
||||||
| Todo-promotie gebruikt scoped todo lookup en `pbi.product_id` als bron van waarheid | `actions/todos.ts` | `docs/scrum4me-architecture.md`, `docs/patterns/server-action.md`, `CLAUDE.md`, `AGENTS.md` |
|
| Todo-promotie gebruikt scoped todo lookup en `pbi.product_id` als bron van waarheid | `actions/todos.ts` | `docs/architecture.md`, `docs/patterns/server-action.md`, `CLAUDE.md`, `AGENTS.md` |
|
||||||
| `GET /api/products` retourneert ook gedeelde producten via `product_members` | `app/api/products/route.ts` | `README.md`, `docs/scrum4me-functional-spec.md`, `docs/scrum4me-backlog.md`, `docs/patterns/route-handler.md` |
|
| `GET /api/products` retourneert ook gedeelde producten via `product_members` | `app/api/products/route.ts` | `README.md`, `docs/functional.md`, `docs/backlog.md`, `docs/patterns/route-handler.md` |
|
||||||
| `sharp` is directe runtime dependency | `package.json`, `package-lock.json` | `README.md`, `docs/scrum4me-architecture.md`, `CLAUDE.md` |
|
| `sharp` is directe runtime dependency | `package.json`, `package-lock.json` | `README.md`, `docs/architecture.md`, `CLAUDE.md` |
|
||||||
| Vercel Analytics is toegevoegd aan de root layout | `app/layout.tsx`, `package.json`, `package-lock.json` | `README.md`, `docs/scrum4me-architecture.md`, `CLAUDE.md` |
|
| Vercel Analytics is toegevoegd aan de root layout | `app/layout.tsx`, `package.json`, `package-lock.json` | `README.md`, `docs/architecture.md`, `CLAUDE.md` |
|
||||||
| `.env.example` ontbrak ondanks verwijzingen in architectuurdocs | `.env.example` | `README.md`, `docs/scrum4me-architecture.md` |
|
| `.env.example` ontbrak ondanks verwijzingen in architectuurdocs | `.env.example` | `README.md`, `docs/architecture.md` |
|
||||||
|
|
||||||
## Preventieve regels
|
## Preventieve regels
|
||||||
|
|
||||||
|
|
@ -44,9 +44,9 @@ Concrete regels:
|
||||||
Een codewijziging is niet klaar als de documentatie een oud contract beschrijft. Agents moeten bij elke wijziging nagaan of deze plekken geraakt worden:
|
Een codewijziging is niet klaar als de documentatie een oud contract beschrijft. Agents moeten bij elke wijziging nagaan of deze plekken geraakt worden:
|
||||||
|
|
||||||
- `README.md`: setup, scripts, dependencies, deployment, API-overzicht.
|
- `README.md`: setup, scripts, dependencies, deployment, API-overzicht.
|
||||||
- `docs/scrum4me-functional-spec.md`: functionele eisen en API-contracten.
|
- `docs/functional.md`: functionele eisen en API-contracten.
|
||||||
- `docs/scrum4me-architecture.md`: stack, datamodel, securitymodel, env vars, deployment.
|
- `docs/architecture.md`: stack, datamodel, securitymodel, env vars, deployment.
|
||||||
- `docs/scrum4me-backlog.md`: "done when"-criteria en scope van backlog-items.
|
- `docs/backlog.md`: "done when"-criteria en scope van backlog-items.
|
||||||
- `docs/patterns/`: herbruikbare implementatiepatronen.
|
- `docs/patterns/`: herbruikbare implementatiepatronen.
|
||||||
- `CLAUDE.md` en `AGENTS.md`: agent-regels die de fout in de toekomst voorkomen.
|
- `CLAUDE.md` en `AGENTS.md`: agent-regels die de fout in de toekomst voorkomen.
|
||||||
|
|
||||||
|
|
@ -100,7 +100,7 @@ Sinds ronde 1 (2026-04-25) is er substantieel werk geland dat de agent-workflow
|
||||||
- **ST-509** Todo description (max 2000)
|
- **ST-509** Todo description (max 2000)
|
||||||
- **ST-511** Entity codes voor Product/PBI/Story (auto-default + manual override + retry op race condition)
|
- **ST-511** Entity codes voor Product/PBI/Story (auto-default + manual override + retry op race condition)
|
||||||
- **ST-512** REST API uitgebreid met `code`, `description`, `implementation_plan` in alle endpoints
|
- **ST-512** REST API uitgebreid met `code`, `description`, `implementation_plan` in alle endpoints
|
||||||
- **ST-513** API hardening voor Claude Code: `GET /api/health`, `GET /api/products/:id/claude-context`, lowercase status-enums op de API-grens, `StoryLog.metadata` JSONB, validatie-fouten van `400` → `422`, nieuwe `docs/API.md`
|
- **ST-513** API hardening voor Claude Code: `GET /api/health`, `GET /api/products/:id/claude-context`, lowercase status-enums op de API-grens, `StoryLog.metadata` JSONB, validatie-fouten van `400` → `422`, nieuwe `docs/api.md`
|
||||||
- **PR #2 Codex-review-saga** — 8 testbestanden faalden bij de contract-flip; tests werden niet meebijgewerkt. Twee P2-issues van Codex: malformed JSON moet `400` blijven (P2.1), en `status: review` werd geaccepteerd terwijl de sprint-UI er niet mee om kan gaan (P2.2)
|
- **PR #2 Codex-review-saga** — 8 testbestanden faalden bij de contract-flip; tests werden niet meebijgewerkt. Twee P2-issues van Codex: malformed JSON moet `400` blijven (P2.1), en `status: review` werd geaccepteerd terwijl de sprint-UI er niet mee om kan gaan (P2.2)
|
||||||
- **M7: scrum4me-mcp** — aparte MCP-server repo (`madhura68/scrum4me-mcp`) met 9 tools en 1 prompt voor Claude Code, schema gedeeld via git submodule
|
- **M7: scrum4me-mcp** — aparte MCP-server repo (`madhura68/scrum4me-mcp`) met 9 tools en 1 prompt voor Claude Code, schema gedeeld via git submodule
|
||||||
- **lib/code.ts vs lib/code-server.ts** — gesplitst om client-bundle vrij te houden van `pg` (gaf eerst `Module not found: 'dns'` build-error)
|
- **lib/code.ts vs lib/code-server.ts** — gesplitst om client-bundle vrij te houden van `pg` (gaf eerst `Module not found: 'dns'` build-error)
|
||||||
|
|
@ -110,13 +110,13 @@ Sinds ronde 1 (2026-04-25) is er substantieel werk geland dat de agent-workflow
|
||||||
|
|
||||||
| Wijziging | Code-locatie | Documentatie bijgewerkt |
|
| Wijziging | Code-locatie | Documentatie bijgewerkt |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Lowercase status-enums op REST-grens, mappers naar DB-enum | `lib/task-status.ts`, `app/api/tasks/[id]/route.ts`, `app/api/sprints/[id]/tasks/route.ts`, `app/api/products/[id]/next-story/route.ts` | `docs/API.md`, `CLAUDE.md` |
|
| Lowercase status-enums op REST-grens, mappers naar DB-enum | `lib/task-status.ts`, `app/api/tasks/[id]/route.ts`, `app/api/sprints/[id]/tasks/route.ts`, `app/api/products/[id]/next-story/route.ts` | `docs/api.md`, `CLAUDE.md` |
|
||||||
| 400 (malformed JSON) gescheiden van 422 (zod-validatie) | `app/api/tasks/[id]/route.ts`, `app/api/stories/[id]/tasks/reorder/route.ts`, `app/api/todos/route.ts`, `app/api/stories/[id]/log/route.ts` | `docs/API.md`, `CLAUDE.md` |
|
| 400 (malformed JSON) gescheiden van 422 (zod-validatie) | `app/api/tasks/[id]/route.ts`, `app/api/stories/[id]/tasks/reorder/route.ts`, `app/api/todos/route.ts`, `app/api/stories/[id]/log/route.ts` | `docs/api.md`, `CLAUDE.md` |
|
||||||
| `status: review` geweigerd door PATCH `/api/tasks/:id` zolang sprint-UI geen REVIEW rendert | `app/api/tasks/[id]/route.ts` | `docs/API.md` |
|
| `status: review` geweigerd door PATCH `/api/tasks/:id` zolang sprint-UI geen REVIEW rendert | `app/api/tasks/[id]/route.ts` | `docs/api.md` |
|
||||||
| Entity codes (Product/PBI/Story) met auto-default + retry-on-P2002 | `actions/products.ts`, `actions/pbis.ts`, `actions/stories.ts`, `lib/code.ts`, `lib/code-server.ts` | `docs/scrum4me-backlog.md` (ST-511) |
|
| Entity codes (Product/PBI/Story) met auto-default + retry-on-P2002 | `actions/products.ts`, `actions/pbis.ts`, `actions/stories.ts`, `lib/code.ts`, `lib/code-server.ts` | `docs/backlog.md` (ST-511) |
|
||||||
| `StoryLog.metadata` JSONB | `prisma/schema.prisma`, `prisma/migrations/20260426214905_add_story_log_metadata/`, `app/api/stories/[id]/log/route.ts` | `docs/API.md` |
|
| `StoryLog.metadata` JSONB | `prisma/schema.prisma`, `prisma/migrations/20260426214905_add_story_log_metadata/`, `app/api/stories/[id]/log/route.ts` | `docs/api.md` |
|
||||||
| Health- en bundled-context endpoints voor Claude Code | `app/api/health/route.ts`, `app/api/products/[id]/claude-context/route.ts` | `docs/API.md`, `CLAUDE.md` |
|
| Health- en bundled-context endpoints voor Claude Code | `app/api/health/route.ts`, `app/api/products/[id]/claude-context/route.ts` | `docs/api.md`, `CLAUDE.md` |
|
||||||
| MCP-server gepubliceerd als aparte repo | `madhura68/scrum4me-mcp` (extern) | `CLAUDE.md` (sectie MCP-integratie), `docs/scrum4me-backlog.md` (M7) |
|
| MCP-server gepubliceerd als aparte repo | `madhura68/scrum4me-mcp` (extern) | `CLAUDE.md` (sectie MCP-integratie), `docs/backlog.md` (M7) |
|
||||||
|
|
||||||
## Nieuwe preventieve regels
|
## Nieuwe preventieve regels
|
||||||
|
|
||||||
|
|
@ -140,7 +140,7 @@ API exposeert lowercase, DB houdt UPPER_SNAKE. Conversie uitsluitend via `lib/ta
|
||||||
- `400`: parse-fout op `request.json()` — wikkel altijd in `try/catch`
|
- `400`: parse-fout op `request.json()` — wikkel altijd in `try/catch`
|
||||||
- `422`: zod-validatie of well-formed-maar-niet-acceptabel (bv. `task_id` van andere story)
|
- `422`: zod-validatie of well-formed-maar-niet-acceptabel (bv. `task_id` van andere story)
|
||||||
- `403`: demo-token op write
|
- `403`: demo-token op write
|
||||||
- Documenteer per endpoint in `docs/API.md`
|
- Documenteer per endpoint in `docs/api.md`
|
||||||
|
|
||||||
### Client/server module-boundary
|
### Client/server module-boundary
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -393,13 +393,13 @@ curl -N -i -b /tmp/jar http://localhost:3000/api/auth/pair/stream/<pairingId>
|
||||||
### `POST /api/auth/pair/claim`
|
### `POST /api/auth/pair/claim`
|
||||||
|
|
||||||
Cookie-auth. Atomisch consume van een approved pairing → schrijft de echte
|
Cookie-auth. Atomisch consume van een approved pairing → schrijft de echte
|
||||||
`scrum4me-session` cookie zodat de desktop is ingelogd.
|
`session` cookie zodat de desktop is ingelogd.
|
||||||
|
|
||||||
**Auth:** `s4m_pair`-cookie.
|
**Auth:** `s4m_pair`-cookie.
|
||||||
**Body:** `{ "pairingId": "cmoh..." }`.
|
**Body:** `{ "pairingId": "cmoh..." }`.
|
||||||
|
|
||||||
**Response 200:** `{ "ok": true }` plus
|
**Response 200:** `{ "ok": true }` plus
|
||||||
- `Set-Cookie: scrum4me-session=...; HttpOnly; SameSite=Lax` — paired-sessie met `paired: true` en `pairedExpiresAt = now + 8h` payload-velden.
|
- `Set-Cookie: session=...; HttpOnly; SameSite=Lax` — paired-sessie met `paired: true` en `pairedExpiresAt = now + 8h` payload-velden.
|
||||||
- `Set-Cookie: s4m_pair=...; Max-Age=0` — pre-auth cookie wordt gewist.
|
- `Set-Cookie: s4m_pair=...; Max-Age=0` — pre-auth cookie wordt gewist.
|
||||||
|
|
||||||
**Foutcodes:**
|
**Foutcodes:**
|
||||||
|
|
@ -564,7 +564,7 @@ sequenceDiagram
|
||||||
D->>S: POST /api/auth/pair/claim<br/>Cookie: s4m_pair, body: { pairingId }
|
D->>S: POST /api/auth/pair/claim<br/>Cookie: s4m_pair, body: { pairingId }
|
||||||
S->>S: atomic UPDATE WHERE status=approved AND token-hash<br/>→ status=consumed
|
S->>S: atomic UPDATE WHERE status=approved AND token-hash<br/>→ status=consumed
|
||||||
S->>S: getIronSession.save { userId, paired: true, pairedExpiresAt }
|
S->>S: getIronSession.save { userId, paired: true, pairedExpiresAt }
|
||||||
S-->>D: 200, Set-Cookie: scrum4me-session<br/>+ s4m_pair cleared
|
S-->>D: 200, Set-Cookie: session<br/>+ s4m_pair cleared
|
||||||
D->>D: redirect /dashboard
|
D->>D: redirect /dashboard
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -409,8 +409,8 @@ De MVP is klaar wanneer Lars — de primaire persona — de volledige cyclus kan
|
||||||
- **`PATCH /api/tasks/:id`:** accepteert lowercase `status` via mapper; retourneert lowercase
|
- **`PATCH /api/tasks/:id`:** accepteert lowercase `status` via mapper; retourneert lowercase
|
||||||
- **Story-log metadata:** nieuwe optionele `metadata Json?` kolom op `StoryLog`; `POST /api/stories/:id/log` accepteert per type een optioneel `metadata`-veld (bv. `{ branch: 'feat/x' }`); bestaande velden ongewijzigd → backwards-compatible
|
- **Story-log metadata:** nieuwe optionele `metadata Json?` kolom op `StoryLog`; `POST /api/stories/:id/log` accepteert per type een optioneel `metadata`-veld (bv. `{ branch: 'feat/x' }`); bestaande velden ongewijzigd → backwards-compatible
|
||||||
- **Foutcodes:** Zod-validatie geeft `422` (was `400`); `400` blijft voor malformed body; `401`/`403`/`404`/`500` ongewijzigd
|
- **Foutcodes:** Zod-validatie geeft `422` (was `400`); `400` blijft voor malformed body; `401`/`403`/`404`/`500` ongewijzigd
|
||||||
- **API-documentatie:** nieuwe `docs/API.md` met endpoints, request/response, foutcodes, status-enums en curl-voorbeelden; `CLAUDE.md` verwijst ernaar
|
- **API-documentatie:** nieuwe `docs/api.md` met endpoints, request/response, foutcodes, status-enums en curl-voorbeelden; `CLAUDE.md` verwijst ernaar
|
||||||
- Done when: `curl /api/health` werkt zonder auth; `curl /api/products/:id/claude-context` retourneert bundled JSON; PATCH/PUT routes accepteren lowercase status en geven 422 bij ongeldige body; story-log POST bewaart `metadata`; `docs/API.md` is gepubliceerd
|
- Done when: `curl /api/health` werkt zonder auth; `curl /api/products/:id/claude-context` retourneert bundled JSON; PATCH/PUT routes accepteren lowercase status en geven 422 bij ongeldige body; story-log POST bewaart `metadata`; `docs/api.md` is gepubliceerd
|
||||||
- **`GET /api/products`:** voeg `code` toe (naast `id`, `name`, `repo_url`); optioneel `description` en `definition_of_done`
|
- **`GET /api/products`:** voeg `code` toe (naast `id`, `name`, `repo_url`); optioneel `description` en `definition_of_done`
|
||||||
- **`GET /api/products/:id/next-story`:** voeg `code` toe op story; voeg per task `code` (derived `${story.code}.${index_in_story}`) en `implementation_plan` toe
|
- **`GET /api/products/:id/next-story`:** voeg `code` toe op story; voeg per task `code` (derived `${story.code}.${index_in_story}`) en `implementation_plan` toe
|
||||||
- **`GET /api/sprints/:id/tasks`:** voeg `description`, `implementation_plan` en `story_code` toe per task; voeg een derived `code`-veld per task toe (`${story.code}.${index_in_story}`)
|
- **`GET /api/sprints/:id/tasks`:** voeg `description`, `implementation_plan` en `story_code` toe per task; voeg een derived `code`-veld per task toe (`${story.code}.${index_in_story}`)
|
||||||
|
|
@ -547,7 +547,7 @@ Filtering server-side: alleen events binnen de actieve sprint van een product wa
|
||||||
- Done when: twee tabs van Solo Paneel — mutatie in tab A komt binnen 1–2s in tab B zonder refresh
|
- Done when: twee tabs van Solo Paneel — mutatie in tab A komt binnen 1–2s in tab B zonder refresh
|
||||||
|
|
||||||
- [x] **ST-806** Documentatie + acceptatietest
|
- [x] **ST-806** Documentatie + acceptatietest
|
||||||
- Sectie "Realtime updates" in `docs/scrum4me-architecture.md` met diagram en filtering-regels; vermelding in `CLAUDE.md`; korte note over `/api/realtime/solo` in `docs/API.md`; handmatig E2E-scenario's gedraaid (zelfde gebruiker twee tabs, MCP-write, REST-write, story-claim, network-flap)
|
- Sectie "Realtime updates" in `docs/architecture.md` met diagram en filtering-regels; vermelding in `CLAUDE.md`; korte note over `/api/realtime/solo` in `docs/api.md`; handmatig E2E-scenario's gedraaid (zelfde gebruiker twee tabs, MCP-write, REST-write, story-claim, network-flap)
|
||||||
- Done when: alle scenario's lopen door zonder onverwachte gedragingen
|
- Done when: alle scenario's lopen door zonder onverwachte gedragingen
|
||||||
|
|
||||||
Volledig plan in `.Plans/2026-04-27-m8-realtime-solo.md` (lokaal, niet gecommit).
|
Volledig plan in `.Plans/2026-04-27-m8-realtime-solo.md` (lokaal, niet gecommit).
|
||||||
|
|
@ -641,13 +641,13 @@ Volledige flow + threat-model: `docs/patterns/qr-login.md` (op te leveren in ST-
|
||||||
- [ ] **ST-1007** Desktop UI: QR-render + SSE-listener op `/login`
|
- [ ] **ST-1007** Desktop UI: QR-render + SSE-listener op `/login`
|
||||||
- **Dependency:** `qrcode.react` (client SVG; mobileSecret blijft op desktop in JS-geheugen)
|
- **Dependency:** `qrcode.react` (client SVG; mobileSecret blijft op desktop in JS-geheugen)
|
||||||
- **`app/login/qr-login-button.tsx`:** Client Component; klik → POST `pair/start` (`credentials: 'same-origin'` zodat `s4m_pair`-cookie wordt geaccepteerd) → render QR met `qrUrl` (fragment-URL) → open `EventSource('/api/auth/pair/stream/<pairingId>', { withCredentials: true })` → bij `approved` event POST `pair/claim` (cookie-only) → bij succes `router.push('/dashboard')`; aftellende timer (2 min); bij timeout "Vernieuwen"-knop; cleanup bij unmount/redirect
|
- **`app/login/qr-login-button.tsx`:** Client Component; klik → POST `pair/start` (`credentials: 'same-origin'` zodat `s4m_pair`-cookie wordt geaccepteerd) → render QR met `qrUrl` (fragment-URL) → open `EventSource('/api/auth/pair/stream/<pairingId>', { withCredentials: true })` → bij `approved` event POST `pair/claim` (cookie-only) → bij succes `router.push('/dashboard')`; aftellende timer (2 min); bij timeout "Vernieuwen"-knop; cleanup bij unmount/redirect
|
||||||
- **`app/login/page.tsx`:** knop "Inloggen via mobiel" naast bestaande wachtwoord-form (MD3-tokens uit `docs/scrum4me-styling.md`)
|
- **`app/login/page.tsx`:** knop "Inloggen via mobiel" naast bestaande wachtwoord-form (MD3-tokens uit `docs/styling.md`)
|
||||||
- A11y: QR heeft alt-tekst met de URL voor screenreaders/copy-paste (de hash-suffix is onderdeel van die alt-tekst, niet van de page-URL die in browsergeschiedenis komt)
|
- A11y: QR heeft alt-tekst met de URL voor screenreaders/copy-paste (de hash-suffix is onderdeel van die alt-tekst, niet van de page-URL die in browsergeschiedenis komt)
|
||||||
- Done when: end-to-end happy path werkt op localhost (twee browsers): A toont QR → B scant + bevestigt → A redirect naar `/dashboard` met `session.paired === true`; QR vernieuwt na expiry; geen secret zichtbaar in DevTools Network-tab onder URL-kolommen
|
- Done when: end-to-end happy path werkt op localhost (twee browsers): A toont QR → B scant + bevestigt → A redirect naar `/dashboard` met `session.paired === true`; QR vernieuwt na expiry; geen secret zichtbaar in DevTools Network-tab onder URL-kolommen
|
||||||
|
|
||||||
- [ ] **ST-1008** Documentatie + acceptatietest
|
- [ ] **ST-1008** Documentatie + acceptatietest
|
||||||
- **`docs/API.md`:** drie nieuwe endpoints (start/stream/claim) met request/response, cookie-mechaniek, foutcodes (400/401/403/404/410/422/429), curl-voorbeelden inclusief `--cookie-jar`
|
- **`docs/api.md`:** drie nieuwe endpoints (start/stream/claim) met request/response, cookie-mechaniek, foutcodes (400/401/403/404/410/422/429), curl-voorbeelden inclusief `--cookie-jar`
|
||||||
- **`docs/scrum4me-architecture.md`:** sectie "QR-pairing flow" met sequence-diagram + threat-model; expliciete subsectie *"Waarom geen secret in URL"* — fragments worden niet naar server gestuurd; SSE/claim authenticeren via HttpOnly cookie zodat secret-materiaal niet in access logs / reverse-proxy logs / observability-tools / browsergeschiedenis kan belanden
|
- **`docs/architecture.md`:** sectie "QR-pairing flow" met sequence-diagram + threat-model; expliciete subsectie *"Waarom geen secret in URL"* — fragments worden niet naar server gestuurd; SSE/claim authenticeren via HttpOnly cookie zodat secret-materiaal niet in access logs / reverse-proxy logs / observability-tools / browsergeschiedenis kan belanden
|
||||||
- **`docs/patterns/qr-login.md`:** nieuw pattern-doc voor toekomstige features die hetzelfde unauth-SSE-via-pre-auth-cookie-patroon willen hergebruiken
|
- **`docs/patterns/qr-login.md`:** nieuw pattern-doc voor toekomstige features die hetzelfde unauth-SSE-via-pre-auth-cookie-patroon willen hergebruiken
|
||||||
- **`CLAUDE.md`:** verwijzing naar het nieuwe pattern-doc in de patterns-tabel
|
- **`CLAUDE.md`:** verwijzing naar het nieuwe pattern-doc in de patterns-tabel
|
||||||
- **Acceptatietest:** zeven scenario's handmatig: happy path, demo-block, replay, expiry tijdens pending, expiry tussen approve+claim, ontbrekende cookie op SSE/claim, secret niet aanwezig in `nginx`/Vercel access logs (controle via runtime-logs MCP-tool)
|
- **Acceptatietest:** zeven scenario's handmatig: happy path, demo-block, replay, expiry tijdens pending, expiry tussen approve+claim, ontbrekende cookie op SSE/claim, secret niet aanwezig in `nginx`/Vercel access logs (controle via runtime-logs MCP-tool)
|
||||||
|
|
@ -694,7 +694,7 @@ Persistent vraag-antwoord-kanaal tussen Claude Code (via MCP) en de actieve Scru
|
||||||
- **`stores/notifications-store.ts`** — Zustand store volgens `solo-store.ts`-patroon: `init`, `add`, `update`, `remove`, `optimisticAnswer`, `rollbackAnswer`; selectors `openCount`, `forYouCount`
|
- **`stores/notifications-store.ts`** — Zustand store volgens `solo-store.ts`-patroon: `init`, `add`, `update`, `remove`, `optimisticAnswer`, `rollbackAnswer`; selectors `openCount`, `forYouCount`
|
||||||
- **`lib/realtime/use-notifications-realtime.ts`** — analoog aan `useSoloRealtime`; EventSource op `/api/realtime/notifications` met reconnect-backoff
|
- **`lib/realtime/use-notifications-realtime.ts`** — analoog aan `useSoloRealtime`; EventSource op `/api/realtime/notifications` met reconnect-backoff
|
||||||
- **`components/notifications/notifications-bridge.tsx`** — Server Component die initial-data fetcht en aan store geeft; mount in `app/(app)/layout.tsx` naast `<SoloRealtimeBridge />`
|
- **`components/notifications/notifications-bridge.tsx`** — Server Component die initial-data fetcht en aan store geeft; mount in `app/(app)/layout.tsx` naast `<SoloRealtimeBridge />`
|
||||||
- **`components/shared/notifications-bell.tsx`** — Bell-icon (Lucide) met badge in NavBar (links van avatar); MD3-tokens uit `docs/scrum4me-styling.md`
|
- **`components/shared/notifications-bell.tsx`** — Bell-icon (Lucide) met badge in NavBar (links van avatar); MD3-tokens uit `docs/styling.md`
|
||||||
- **`components/notifications/notifications-sheet.tsx`** — shadcn Sheet van rechts; lijst gegroepeerd per product; story-assignee krijgt visuele *"wacht op jou"*-emphase
|
- **`components/notifications/notifications-sheet.tsx`** — shadcn Sheet van rechts; lijst gegroepeerd per product; story-assignee krijgt visuele *"wacht op jou"*-emphase
|
||||||
- **`components/notifications/answer-modal.tsx`** — shadcn Dialog; story-context-link, vraag-tekst, RadioGroup (als options) of Textarea (free-text), submit via `useTransition` + Server Action; demo-blok met tooltip
|
- **`components/notifications/answer-modal.tsx`** — shadcn Dialog; story-context-link, vraag-tekst, RadioGroup (als options) of Textarea (free-text), submit via `useTransition` + Server Action; demo-blok met tooltip
|
||||||
- Done when: bell + badge zichtbaar; klik opent Sheet met items; submit verwijdert item optimistisch; tweede tab van zelfde user ziet nieuwe vraag binnen 1-2s; demo-modus rendert maar Verstuur disabled
|
- Done when: bell + badge zichtbaar; klik opent Sheet met items; submit verwijdert item optimistisch; tweede tab van zelfde user ziet nieuwe vraag binnen 1-2s; demo-modus rendert maar Verstuur disabled
|
||||||
|
|
@ -713,8 +713,8 @@ Persistent vraag-antwoord-kanaal tussen Claude Code (via MCP) en de actieve Scru
|
||||||
- Done when: handmatige `curl -X POST` met secret expireert oude rijen; Vercel-dashboard toont cron-config na deploy; onbevoegde call → 401
|
- Done when: handmatige `curl -X POST` met secret expireert oude rijen; Vercel-dashboard toont cron-config na deploy; onbevoegde call → 401
|
||||||
|
|
||||||
- [ ] **ST-1108** Documentatie + acceptatietest
|
- [ ] **ST-1108** Documentatie + acceptatietest
|
||||||
- **`docs/API.md`:** secties "SSE — Notifications" + "Cron — Expire questions" met curl-voorbeelden
|
- **`docs/api.md`:** secties "SSE — Notifications" + "Cron — Expire questions" met curl-voorbeelden
|
||||||
- **`docs/scrum4me-architecture.md`:** sectie "Vraag-antwoord-kanaal Claude ↔ user" met Mermaid sequence-diagram + threat-model + "Waarom hergebruik scrum4me_changes-kanaal"
|
- **`docs/architecture.md`:** sectie "Vraag-antwoord-kanaal Claude ↔ user" met Mermaid sequence-diagram + threat-model + "Waarom hergebruik scrum4me_changes-kanaal"
|
||||||
- **`docs/patterns/claude-question-channel.md`:** nieuw herbruikbaar pattern-doc voor toekomstige bidirectionele async-communicatie tussen MCP-agents en interactieve users
|
- **`docs/patterns/claude-question-channel.md`:** nieuw herbruikbaar pattern-doc voor toekomstige bidirectionele async-communicatie tussen MCP-agents en interactieve users
|
||||||
- **`CLAUDE.md`:** rij in Implementatiepatronen-tabel voor het nieuwe pattern
|
- **`CLAUDE.md`:** rij in Implementatiepatronen-tabel voor het nieuwe pattern
|
||||||
- **Acceptatietest** zes scenario's: sync happy (wait_seconds), async happy (geen wait), demo-block, access-isolation, expiry via cron, race op double-submit
|
- **Acceptatietest** zes scenario's: sync happy (wait_seconds), async happy (geen wait), demo-block, access-isolation, expiry via cron, race op double-submit
|
||||||
|
|
@ -137,9 +137,9 @@ Specifiek voor M11. Kopieer en pas aan:
|
||||||
|
|
||||||
## Referenties
|
## Referenties
|
||||||
|
|
||||||
- Volledige flow + threat-model: `docs/scrum4me-architecture.md` § Vraag-
|
- Volledige flow + threat-model: `docs/architecture.md` § Vraag-
|
||||||
antwoord-kanaal Claude ↔ user
|
antwoord-kanaal Claude ↔ user
|
||||||
- Endpoint-contract: `docs/API.md` § Notifications + Cron
|
- Endpoint-contract: `docs/api.md` § Notifications + Cron
|
||||||
- LISTEN/NOTIFY-pattern: `app/api/realtime/solo/route.ts` (M8 ST-802) — zelfde
|
- LISTEN/NOTIFY-pattern: `app/api/realtime/solo/route.ts` (M8 ST-802) — zelfde
|
||||||
ReadableStream + heartbeat + hard-close + abort-cleanup
|
ReadableStream + heartbeat + hard-close + abort-cleanup
|
||||||
- M10 vs M11 keuze tussen eigen/gedeeld kanaal: zie threat-model-tabel
|
- M10 vs M11 keuze tussen eigen/gedeeld kanaal: zie threat-model-tabel
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ Deze pagina is **bindend** voor elke create/edit/detail-dialog in Scrum4Me, onge
|
||||||
|
|
||||||
> **Doel:** elke dialog voelt identiek aan voor de gebruiker, hergebruikt dezelfde primitives, en heeft de drielaagse demo-policy + auth-scoping standaard ingebakken.
|
> **Doel:** elke dialog voelt identiek aan voor de gebruiker, hergebruikt dezelfde primitives, en heeft de drielaagse demo-policy + auth-scoping standaard ingebakken.
|
||||||
|
|
||||||
Voor entity-specifieke afwijkingen of velden: schrijf één begeleidende doc per entiteit (zie sectie [§ Per-entiteit profile](#per-entiteit-profile-verplicht)). Voorbeeld: `docs/scrum4me-task-dialog.md` is het Task-profiel.
|
Voor entity-specifieke afwijkingen of velden: schrijf één begeleidende doc per entiteit (zie sectie [§ Per-entiteit profile](#per-entiteit-profile-verplicht)). Voorbeeld: `docs/task-dialog.md` is het Task-profiel.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -16,10 +16,10 @@ Voor entity-specifieke afwijkingen of velden: schrijf één begeleidende doc per
|
||||||
| 1.2 | Gebruik composition via de **`render`-prop** (zie `CLAUDE.md` "UI Library Conventions"). Nooit Radix' `asChild`. | Project gebruikt `@base-ui/react`, niet Radix |
|
| 1.2 | Gebruik composition via de **`render`-prop** (zie `CLAUDE.md` "UI Library Conventions"). Nooit Radix' `asChild`. | Project gebruikt `@base-ui/react`, niet Radix |
|
||||||
| 1.3 | Mode (`create` vs `edit` vs `detail`) wordt afgeleid uit één input — een prop, een `state`-object of een `searchParam`. **Niet** twee aparte componenten. | Voorkomt code-duplicatie en inconsistente labels/footer-layouts |
|
| 1.3 | Mode (`create` vs `edit` vs `detail`) wordt afgeleid uit één input — een prop, een `state`-object of een `searchParam`. **Niet** twee aparte componenten. | Voorkomt code-duplicatie en inconsistente labels/footer-layouts |
|
||||||
| 1.4 | Auth-scoping op elke server action via `productAccessFilter(userId)` (of het scope-helper-equivalent). Cross-tenant writes mogen onmogelijk zijn. | `CLAUDE.md` "Toegangsmodel" + `docs/patterns/server-action.md` |
|
| 1.4 | Auth-scoping op elke server action via `productAccessFilter(userId)` (of het scope-helper-equivalent). Cross-tenant writes mogen onmogelijk zijn. | `CLAUDE.md` "Toegangsmodel" + `docs/patterns/server-action.md` |
|
||||||
| 1.5 | **Drielaagse demo-policy** (verplicht — zie § 6) op elke write-actie. | `CLAUDE.md` "Demo-check" + `docs/scrum4me-architecture.md#demo-user-policy` |
|
| 1.5 | **Drielaagse demo-policy** (verplicht — zie § 6) op elke write-actie. | `CLAUDE.md` "Demo-check" + `docs/architecture.md#demo-user-policy` |
|
||||||
| 1.6 | Validatie via één gedeeld zod-schema (`lib/schemas/<entity>.ts`) — gebruikt door zowel form als server action. | `CLAUDE.md` "Validatie" |
|
| 1.6 | Validatie via één gedeeld zod-schema (`lib/schemas/<entity>.ts`) — gebruikt door zowel form als server action. | `CLAUDE.md` "Validatie" |
|
||||||
| 1.7 | Foutcodes volgen de project-conventie (§ 5). | `CLAUDE.md` "Foutcodes API" |
|
| 1.7 | Foutcodes volgen de project-conventie (§ 5). | `CLAUDE.md` "Foutcodes API" |
|
||||||
| 1.8 | Geen willekeurige Tailwind-kleuren (`bg-blue-500` etc.). Alleen MD3-tokens uit `app/styles/theme.css`. | `docs/scrum4me-styling.md` |
|
| 1.8 | Geen willekeurige Tailwind-kleuren (`bg-blue-500` etc.). Alleen MD3-tokens uit `app/styles/theme.css`. | `docs/styling.md` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -295,7 +295,7 @@ Voor state-based pattern: het record komt al uit de parent (in-memory store of s
|
||||||
|
|
||||||
## 12 — Per-entiteit profile (verplicht)
|
## 12 — Per-entiteit profile (verplicht)
|
||||||
|
|
||||||
Voor elke entiteit met een dialog hoort één profiel-doc te bestaan: `docs/<scrum4me-<entity>-dialog>.md` (of vergelijkbaar). Het profiel **vult de generieke spec aan** en bevat **alleen** de entity-specifieke onderdelen.
|
Voor elke entiteit met een dialog hoort één profiel-doc te bestaan: `docs/<<entity>-dialog>.md` (of vergelijkbaar). Het profiel **vult de generieke spec aan** en bevat **alleen** de entity-specifieke onderdelen.
|
||||||
|
|
||||||
### Verplichte secties van het entity-profile
|
### Verplichte secties van het entity-profile
|
||||||
|
|
||||||
|
|
@ -380,8 +380,8 @@ Reviewer en bouwer lopen deze door vóór merge:
|
||||||
## 15 — Referenties
|
## 15 — Referenties
|
||||||
|
|
||||||
- `CLAUDE.md` — UI Library Conventions, Demo-check, Foutcodes API, Validatie
|
- `CLAUDE.md` — UI Library Conventions, Demo-check, Foutcodes API, Validatie
|
||||||
- `docs/scrum4me-styling.md` — MD3-tokens, kleurklassen
|
- `docs/styling.md` — MD3-tokens, kleurklassen
|
||||||
- `docs/scrum4me-architecture.md` — Demo user policy, scope-helpers
|
- `docs/architecture.md` — Demo user policy, scope-helpers
|
||||||
- `docs/patterns/server-action.md` — Server Action template (auth + Zod)
|
- `docs/patterns/server-action.md` — Server Action template (auth + Zod)
|
||||||
- `docs/patterns/zustand-optimistic.md` — voor lijst-views die de dialog aanroepen
|
- `docs/patterns/zustand-optimistic.md` — voor lijst-views die de dialog aanroepen
|
||||||
- `docs/scrum4me-task-dialog.md` — voorbeeld-profile voor entiteit "Task"
|
- `docs/task-dialog.md` — voorbeeld-profile voor entiteit "Task"
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export interface SessionData {
|
||||||
|
|
||||||
export const sessionOptions: SessionOptions = {
|
export const sessionOptions: SessionOptions = {
|
||||||
password: process.env.SESSION_SECRET!,
|
password: process.env.SESSION_SECRET!,
|
||||||
cookieName: 'scrum4me-session',
|
cookieName: 'session',
|
||||||
cookieOptions: {
|
cookieOptions: {
|
||||||
secure: process.env.NODE_ENV === 'production',
|
secure: process.env.NODE_ENV === 'production',
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ Drie tijden in escalerende volgorde, alle korter dan de reguliere sessie:
|
||||||
|
|
||||||
## Referenties
|
## Referenties
|
||||||
|
|
||||||
- Volledige flow + threat-model: `docs/scrum4me-architecture.md` § QR-pairing flow
|
- Volledige flow + threat-model: `docs/architecture.md` § QR-pairing flow
|
||||||
- Endpoint-contract: `docs/API.md` § Auth — QR-pairing
|
- Endpoint-contract: `docs/api.md` § Auth — QR-pairing
|
||||||
- LISTEN/NOTIFY-pattern: `app/api/realtime/solo/route.ts` (M8 ST-802) — zelfde
|
- LISTEN/NOTIFY-pattern: `app/api/realtime/solo/route.ts` (M8 ST-802) — zelfde
|
||||||
ReadableStream + heartbeat + hard-close + abort-cleanup, alleen ander channel
|
ReadableStream + heartbeat + hard-close + abort-cleanup, alleen ander channel
|
||||||
|
|
|
||||||
|
|
@ -116,5 +116,5 @@ Specifiek voor PbiDialog (boven op de algemene out-of-scope-lijst in `docs/patte
|
||||||
- `components/shared/pbi-status-select.tsx` — PBI-status-select
|
- `components/shared/pbi-status-select.tsx` — PBI-status-select
|
||||||
- `lib/task-status.ts` — `PbiStatusApi`-mapper
|
- `lib/task-status.ts` — `PbiStatusApi`-mapper
|
||||||
- `docs/patterns/dialog.md` — generieke spec (bron-of-truth)
|
- `docs/patterns/dialog.md` — generieke spec (bron-of-truth)
|
||||||
- `docs/scrum4me-architecture.md` — datamodel `Pbi`
|
- `docs/architecture.md` — datamodel `Pbi`
|
||||||
- `docs/scrum4me-styling.md` — MD3-tokens, status- en priority-kleuren
|
- `docs/styling.md` — MD3-tokens, status- en priority-kleuren
|
||||||
|
|
@ -7,8 +7,8 @@ Inloggen op een (publieke) desktop zonder wachtwoord: desktop toont QR, telefoon
|
||||||
- `desktopToken` reist alleen via HttpOnly cookie `s4m_pair` met `Path=/api/auth/pair`, `Max-Age=120`, `SameSite=Lax`
|
- `desktopToken` reist alleen via HttpOnly cookie `s4m_pair` met `Path=/api/auth/pair`, `Max-Age=120`, `SameSite=Lax`
|
||||||
- Twee gescheiden hashes in DB scheiden mobiel-bewijs (`secret_hash`) van desktop-bewijs (`desktop_token_hash`)
|
- Twee gescheiden hashes in DB scheiden mobiel-bewijs (`secret_hash`) van desktop-bewijs (`desktop_token_hash`)
|
||||||
|
|
||||||
Backlog-entries: zie [scrum4me-backlog.md § M10](../scrum4me-backlog.md#m10-password-loze-inlog-via-qr-pairing).
|
Backlog-entries: zie [backlog.md § M10](../backlog.md#m10-password-loze-inlog-via-qr-pairing).
|
||||||
Functional spec: zie [scrum4me-functional-spec.md § F-01b](../scrum4me-functional-spec.md#f-01b-inloggen-via-mobiel-qr-pairing).
|
Functional spec: zie [functional.md § F-01b](../functional.md#f-01b-inloggen-via-mobiel-qr-pairing).
|
||||||
|
|
||||||
**Implementatie-volgorde** (commit-strategy uit CLAUDE.md):
|
**Implementatie-volgorde** (commit-strategy uit CLAUDE.md):
|
||||||
|
|
||||||
|
|
@ -652,7 +652,7 @@ ST-1006 staat bij de API-laag (niet bij UI) omdat het een Route Handler is; ST-1
|
||||||
- De `session.isDemo` check overneemt: als de approver een demo-user is — wat ST-1005 al blokkeert — komen we hier niet eens, maar `is_demo` doorzetten is een extra vangnet.
|
- De `session.isDemo` check overneemt: als de approver een demo-user is — wat ST-1005 al blokkeert — komen we hier niet eens, maar `is_demo` doorzetten is een extra vangnet.
|
||||||
|
|
||||||
**Verificatie**
|
**Verificatie**
|
||||||
- Handmatig: na approve in mobiele tab, POST naar `/api/auth/pair/claim` met de cookie van start → 200 + `Set-Cookie: scrum4me-session=...`
|
- Handmatig: na approve in mobiele tab, POST naar `/api/auth/pair/claim` met de cookie van start → 200 + `Set-Cookie: session=...`
|
||||||
- `curl -X POST` zonder cookie → 401
|
- `curl -X POST` zonder cookie → 401
|
||||||
- Tweede claim → 410
|
- Tweede claim → 410
|
||||||
|
|
||||||
|
|
@ -767,7 +767,7 @@ ST-1006 staat bij de API-laag (niet bij UI) omdat het een Route Handler is; ST-1
|
||||||
<QrLoginButton />
|
<QrLoginButton />
|
||||||
```
|
```
|
||||||
|
|
||||||
MD3-tokens uit `docs/scrum4me-styling.md`; geen willekeurige Tailwind-kleuren.
|
MD3-tokens uit `docs/styling.md`; geen willekeurige Tailwind-kleuren.
|
||||||
|
|
||||||
4. **A11y**: QR-component krijgt `aria-label="QR-code voor mobiel inloggen"` en de URL wordt visueel als kopieer-bare tekst onder de QR getoond zodat screenreaders en gebruikers met cameraproblemen de URL handmatig kunnen openen.
|
4. **A11y**: QR-component krijgt `aria-label="QR-code voor mobiel inloggen"` en de URL wordt visueel als kopieer-bare tekst onder de QR getoond zodat screenreaders en gebruikers met cameraproblemen de URL handmatig kunnen openen.
|
||||||
|
|
||||||
|
|
@ -788,17 +788,17 @@ ST-1006 staat bij de API-laag (niet bij UI) omdat het een Route Handler is; ST-1
|
||||||
## ST-1008 — Documentatie + acceptatietest
|
## ST-1008 — Documentatie + acceptatietest
|
||||||
|
|
||||||
**Bestanden**
|
**Bestanden**
|
||||||
- `docs/API.md` — drie nieuwe endpoints
|
- `docs/api.md` — drie nieuwe endpoints
|
||||||
- `docs/scrum4me-architecture.md` — sectie "QR-pairing flow" + threat-model
|
- `docs/architecture.md` — sectie "QR-pairing flow" + threat-model
|
||||||
- `docs/patterns/qr-login.md` — nieuw pattern-doc
|
- `docs/patterns/qr-login.md` — nieuw pattern-doc
|
||||||
- `CLAUDE.md` — verwijzing naar het pattern-doc in de patterns-tabel
|
- `CLAUDE.md` — verwijzing naar het pattern-doc in de patterns-tabel
|
||||||
- `__tests__/integration/qr-pairing-e2e.test.ts` — optioneel, alleen als de test-infra het toelaat
|
- `__tests__/integration/qr-pairing-e2e.test.ts` — optioneel, alleen als de test-infra het toelaat
|
||||||
|
|
||||||
**Stappen**
|
**Stappen**
|
||||||
|
|
||||||
1. **`docs/API.md`** — drie endpoints documenteren met request/response, foutcodes (400/401/403/404/410/422/429), curl-voorbeelden inclusief `--cookie-jar`. Voeg een sectie *"Cookie-mechaniek"* toe die uitlegt dat `s4m_pair` een tijdelijke pre-auth cookie is, anders dan de iron-session cookie.
|
1. **`docs/api.md`** — drie endpoints documenteren met request/response, foutcodes (400/401/403/404/410/422/429), curl-voorbeelden inclusief `--cookie-jar`. Voeg een sectie *"Cookie-mechaniek"* toe die uitlegt dat `s4m_pair` een tijdelijke pre-auth cookie is, anders dan de iron-session cookie.
|
||||||
|
|
||||||
2. **`docs/scrum4me-architecture.md`** — sectie *"QR-pairing flow"* met:
|
2. **`docs/architecture.md`** — sectie *"QR-pairing flow"* met:
|
||||||
- Sequence-diagram (mermaid of ASCII analoog aan M8)
|
- Sequence-diagram (mermaid of ASCII analoog aan M8)
|
||||||
- Threat-model:
|
- Threat-model:
|
||||||
- **Replay**: atomic `updateMany` met `status='approved'` voorkomt dubbele claim
|
- **Replay**: atomic `updateMany` met `status='approved'` voorkomt dubbele claim
|
||||||
|
|
@ -826,7 +826,7 @@ ST-1006 staat bij de API-laag (niet bij UI) omdat het een Route Handler is; ST-1
|
||||||
7. **Secret niet in access logs** — controleer Vercel runtime-logs (via `mcp__a1fa0fcf-…__get_runtime_logs`) en lokale dev-logs; zoek op de secret-string en op `s=`-substrings; verwacht: 0 hits
|
7. **Secret niet in access logs** — controleer Vercel runtime-logs (via `mcp__a1fa0fcf-…__get_runtime_logs`) en lokale dev-logs; zoek op de secret-string en op `s=`-substrings; verwacht: 0 hits
|
||||||
|
|
||||||
**Aandachtspunten**
|
**Aandachtspunten**
|
||||||
- Zorg dat de runtime-logs MCP-controle in `docs/scrum4me-test-plan.md` belandt zodat hij bij elke release herhaalbaar is.
|
- Zorg dat de runtime-logs MCP-controle in `docs/test-plan.md` belandt zodat hij bij elke release herhaalbaar is.
|
||||||
- `docs/patterns/qr-login.md` mag refereren naar bestaande pattern-docs (iron-session, route-handler) zonder ze te dupliceren.
|
- `docs/patterns/qr-login.md` mag refereren naar bestaande pattern-docs (iron-session, route-handler) zonder ze te dupliceren.
|
||||||
|
|
||||||
**Verificatie**
|
**Verificatie**
|
||||||
|
|
@ -857,7 +857,7 @@ feat(ST-1005): add mobile pair confirmation page with hash-fragment client islan
|
||||||
feat(ST-1006): add /api/auth/pair/claim with atomic consume
|
feat(ST-1006): add /api/auth/pair/claim with atomic consume
|
||||||
chore(ST-1007): add qrcode.react dependency
|
chore(ST-1007): add qrcode.react dependency
|
||||||
feat(ST-1007): add QR login button on /login with SSE listener
|
feat(ST-1007): add QR login button on /login with SSE listener
|
||||||
docs(ST-1008): document QR-pairing endpoints in API.md
|
docs(ST-1008): document QR-pairing endpoints in api.md
|
||||||
docs(ST-1008): add QR-pairing flow and threat-model to architecture
|
docs(ST-1008): add QR-pairing flow and threat-model to architecture
|
||||||
docs(ST-1008): add qr-login pattern doc
|
docs(ST-1008): add qr-login pattern doc
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ Persistent vraag-antwoord-kanaal tussen Claude Code (via MCP) en de actieve Scru
|
||||||
|
|
||||||
Eerste concrete uitwerking van strategische **richting B** (verdiepen van de unieke AI-driven dev-flow).
|
Eerste concrete uitwerking van strategische **richting B** (verdiepen van de unieke AI-driven dev-flow).
|
||||||
|
|
||||||
Backlog-entries: zie [scrum4me-backlog.md § M11](../scrum4me-backlog.md#m11-claude-vraagt-gebruiker-antwoordt) (op te leveren in ST-1108).
|
Backlog-entries: zie [backlog.md § M11](../backlog.md#m11-claude-vraagt-gebruiker-antwoordt) (op te leveren in ST-1108).
|
||||||
|
|
||||||
**Beveiligingsuitgangspunten:**
|
**Beveiligingsuitgangspunten:**
|
||||||
- Atomic answer via `updateMany WHERE status='open'` — concurrent dubbele submit kan niet
|
- Atomic answer via `updateMany WHERE status='open'` — concurrent dubbele submit kan niet
|
||||||
|
|
@ -279,7 +279,7 @@ Backlog-entries: zie [scrum4me-backlog.md § M11](../scrum4me-backlog.md#m11-cla
|
||||||
|
|
||||||
**Aandachtspunten**
|
**Aandachtspunten**
|
||||||
- Bell-icon en avatar moeten visueel balanceren — hoogte/padding gelijktrekken
|
- Bell-icon en avatar moeten visueel balanceren — hoogte/padding gelijktrekken
|
||||||
- MD3-tokens uit `docs/scrum4me-styling.md`: badge `bg-error text-error-foreground` voor critical-count, `bg-primary` voor neutraal. Geen willekeurige Tailwind-kleuren
|
- MD3-tokens uit `docs/styling.md`: badge `bg-error text-error-foreground` voor critical-count, `bg-primary` voor neutraal. Geen willekeurige Tailwind-kleuren
|
||||||
- Optimistic-answer in store: voor het Server Action-resultaat zet item op pending; bij error rollback met sonner-error-toast
|
- Optimistic-answer in store: voor het Server Action-resultaat zet item op pending; bij error rollback met sonner-error-toast
|
||||||
- Sheet-content blijft open zodat de user meerdere vragen achter elkaar kan beantwoorden (zelfde patroon als ST-358 openstaande-stories-sheet)
|
- Sheet-content blijft open zodat de user meerdere vragen achter elkaar kan beantwoorden (zelfde patroon als ST-358 openstaande-stories-sheet)
|
||||||
- ARIA: bell-icon heeft `aria-label="Notificaties — N open vragen"`, badge `role="status"`
|
- ARIA: bell-icon heeft `aria-label="Notificaties — N open vragen"`, badge `role="status"`
|
||||||
|
|
@ -369,18 +369,18 @@ Backlog-entries: zie [scrum4me-backlog.md § M11](../scrum4me-backlog.md#m11-cla
|
||||||
## ST-1108 — Documentatie + acceptatietest
|
## ST-1108 — Documentatie + acceptatietest
|
||||||
|
|
||||||
**Bestanden**
|
**Bestanden**
|
||||||
- `docs/API.md` — secties "SSE — Notifications" + "Cron — Expire questions"
|
- `docs/api.md` — secties "SSE — Notifications" + "Cron — Expire questions"
|
||||||
- `docs/scrum4me-architecture.md` — sectie "Vraag-antwoord-kanaal" met sequence-diagram
|
- `docs/architecture.md` — sectie "Vraag-antwoord-kanaal" met sequence-diagram
|
||||||
- `docs/patterns/claude-question-channel.md` — herbruikbaar pattern-doc
|
- `docs/patterns/claude-question-channel.md` — herbruikbaar pattern-doc
|
||||||
- `docs/scrum4me-backlog.md` — M11-tabel-rij + M11-sectie
|
- `docs/backlog.md` — M11-tabel-rij + M11-sectie
|
||||||
- `prisma/seed-data/parse-backlog.ts` — `M11: 'ACTIVE'`, `M10: 'COMPLETED'`, `M3.5: 'COMPLETED'`
|
- `prisma/seed-data/parse-backlog.ts` — `M11: 'ACTIVE'`, `M10: 'COMPLETED'`, `M3.5: 'COMPLETED'`
|
||||||
- `CLAUDE.md` — pattern-doc verwijzing in Implementatiepatronen-tabel
|
- `CLAUDE.md` — pattern-doc verwijzing in Implementatiepatronen-tabel
|
||||||
|
|
||||||
**Stappen**
|
**Stappen**
|
||||||
|
|
||||||
1. Backlog-tabel-rij + M11-sectie in `docs/scrum4me-backlog.md` (mirror M10-format met **Implementatieplan:** verwijzing naar dit doc)
|
1. Backlog-tabel-rij + M11-sectie in `docs/backlog.md` (mirror M10-format met **Implementatieplan:** verwijzing naar dit doc)
|
||||||
|
|
||||||
2. `docs/scrum4me-architecture.md` § "Vraag-antwoord-kanaal":
|
2. `docs/architecture.md` § "Vraag-antwoord-kanaal":
|
||||||
- Mermaid sequence-diagram: Claude → MCP → DB → trigger → SSE → user → Server Action → DB → trigger → polling-tool
|
- Mermaid sequence-diagram: Claude → MCP → DB → trigger → SSE → user → Server Action → DB → trigger → polling-tool
|
||||||
- Threat-model-tabel (replay, demo-block, access-leak, expiry, race)
|
- Threat-model-tabel (replay, demo-block, access-leak, expiry, race)
|
||||||
- "Waarom hergebruik scrum4me_changes-kanaal" sub-sectie
|
- "Waarom hergebruik scrum4me_changes-kanaal" sub-sectie
|
||||||
|
|
@ -430,7 +430,7 @@ feat(ST-1105): add NotificationsBell + Sheet + AnswerModal
|
||||||
chore(ST-1107): add CRON_SECRET to env schema
|
chore(ST-1107): add CRON_SECRET to env schema
|
||||||
feat(ST-1107): add /api/cron/expire-questions handler
|
feat(ST-1107): add /api/cron/expire-questions handler
|
||||||
feat(ST-1107): wire vercel.ts cron entry
|
feat(ST-1107): wire vercel.ts cron entry
|
||||||
docs(ST-1108): document notifications SSE + cron in API.md
|
docs(ST-1108): document notifications SSE + cron in api.md
|
||||||
docs(ST-1108): add vraag-antwoord-kanaal flow to architecture
|
docs(ST-1108): add vraag-antwoord-kanaal flow to architecture
|
||||||
docs(ST-1108): add claude-question-channel pattern doc
|
docs(ST-1108): add claude-question-channel pattern doc
|
||||||
chore(ST-1108): backlog M11 + parser ACTIVE-flip
|
chore(ST-1108): backlog M11 + parser ACTIVE-flip
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Eén "actief Product Backlog" per gebruiker, persistent op `User.active_product_id`. NavBar wordt: Producten | Product Backlog | Sprint | Solo | Todo's. Zonder actief PB zijn Backlog/Sprint/Solo disabled. Sprint is alleen klikbaar als er een sprint met status `ACTIVE` bestaat. Vervangt de bestaande `last_product`-cookieflow.
|
Eén "actief Product Backlog" per gebruiker, persistent op `User.active_product_id`. NavBar wordt: Producten | Product Backlog | Sprint | Solo | Todo's. Zonder actief PB zijn Backlog/Sprint/Solo disabled. Sprint is alleen klikbaar als er een sprint met status `ACTIVE` bestaat. Vervangt de bestaande `last_product`-cookieflow.
|
||||||
|
|
||||||
Backlog-entries: zie [scrum4me-backlog.md § M9](../scrum4me-backlog.md#m9-actief-product-backlog).
|
Backlog-entries: zie [backlog.md § M9](../backlog.md#m9-actief-product-backlog).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ Drie-laagse bescherming:
|
||||||
| ST-1110.5 | `feat(ST-1110.5)` | 12 component/pagina-bestanden |
|
| ST-1110.5 | `feat(ST-1110.5)` | 12 component/pagina-bestanden |
|
||||||
| ST-1110.5 tests | `test(ST-1110.5)` | `__tests__/api/pair-claim.test.ts`, `__tests__/api/pair-start.test.ts` |
|
| ST-1110.5 tests | `test(ST-1110.5)` | `__tests__/api/pair-claim.test.ts`, `__tests__/api/pair-start.test.ts` |
|
||||||
| ST-1110.6 | `test(ST-1110.6)` | `__tests__/proxy/demo-guard.test.ts` |
|
| ST-1110.6 | `test(ST-1110.6)` | `__tests__/proxy/demo-guard.test.ts` |
|
||||||
| ST-1110.7 | `docs(ST-1110.7)` | `docs/scrum4me-architecture.md`, dit bestand |
|
| ST-1110.7 | `docs(ST-1110.7)` | `docs/architecture.md`, dit bestand |
|
||||||
|
|
||||||
## Aandachtspunten toekomstige stories
|
## Aandachtspunten toekomstige stories
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -202,10 +202,10 @@ Korte prompt-flow:
|
||||||
1. `wait_for_job({ accept_kinds: ['PLANNING'], wait_seconds: 600 })` — claim
|
1. `wait_for_job({ accept_kinds: ['PLANNING'], wait_seconds: 600 })` — claim
|
||||||
2. Lees `planning_target` uit response (PBI of STORY) + `existing_*`
|
2. Lees `planning_target` uit response (PBI of STORY) + `existing_*`
|
||||||
3. **Lees lokale docs uit Scrum4Me-checkout:**
|
3. **Lees lokale docs uit Scrum4Me-checkout:**
|
||||||
- `docs/scrum4me-functional-spec.md` (functioneel kader)
|
- `docs/functional.md` (functioneel kader)
|
||||||
- `docs/scrum4me-architecture.md` (technisch kader)
|
- `docs/architecture.md` (technisch kader)
|
||||||
- `docs/patterns/*.md` (relevante patterns op basis van target-titel/-beschrijving)
|
- `docs/patterns/*.md` (relevante patterns op basis van target-titel/-beschrijving)
|
||||||
- `docs/scrum4me-styling.md` als target UI-werk betreft
|
- `docs/styling.md` als target UI-werk betreft
|
||||||
4. Bedenk children:
|
4. Bedenk children:
|
||||||
- Voor `STORY`-target: 3-7 taken met titel, korte beschrijving, `implementation_plan` (verwijst naar relevante patterns + bestanden), priority
|
- Voor `STORY`-target: 3-7 taken met titel, korte beschrijving, `implementation_plan` (verwijst naar relevante patterns + bestanden), priority
|
||||||
- Voor `PBI`-target: 2-5 stories met titel, beschrijving in user-story-format, acceptance_criteria, priority
|
- Voor `PBI`-target: 2-5 stories met titel, beschrijving in user-story-format, acceptance_criteria, priority
|
||||||
|
|
@ -251,10 +251,10 @@ MCP-tools testen in `scrum4me-mcp` repo (aparte PR).
|
||||||
| `components/backlog/pbi-list.tsx` | MODIFY | Status-pill op pbi-card |
|
| `components/backlog/pbi-list.tsx` | MODIFY | Status-pill op pbi-card |
|
||||||
| `components/shared/planning-job-pill.tsx` | NEW | Generic pill-component |
|
| `components/shared/planning-job-pill.tsx` | NEW | Generic pill-component |
|
||||||
| `docs/patterns/claude-agent-roles.md` | NEW | Pattern-doc: één table, kind-enum, accept_kinds-arg, lokale agent-prompts |
|
| `docs/patterns/claude-agent-roles.md` | NEW | Pattern-doc: één table, kind-enum, accept_kinds-arg, lokale agent-prompts |
|
||||||
| `docs/scrum4me-architecture.md` | MODIFY | Sectie "Claude Agents" uitbreiden — twee rollen, schema, queue, prompts |
|
| `docs/architecture.md` | MODIFY | Sectie "Claude Agents" uitbreiden — twee rollen, schema, queue, prompts |
|
||||||
| `docs/scrum4me-pbi-dialog.md` | MODIFY | Sectie "Speciale gedragingen → Planning-trigger" toevoegen |
|
| `docs/pbi-dialog.md` | MODIFY | Sectie "Speciale gedragingen → Planning-trigger" toevoegen |
|
||||||
| `docs/scrum4me-story-dialog.md` | MODIFY | Idem |
|
| `docs/story-dialog.md` | MODIFY | Idem |
|
||||||
| `docs/scrum4me-task-dialog.md` | MODIFY | Vermelden dat tasks ook door planning-agent kunnen ontstaan |
|
| `docs/task-dialog.md` | MODIFY | Vermelden dat tasks ook door planning-agent kunnen ontstaan |
|
||||||
| `__tests__/actions/claude-jobs-planning.test.ts` | NEW | |
|
| `__tests__/actions/claude-jobs-planning.test.ts` | NEW | |
|
||||||
| `__tests__/lib/claude-job-status.test.ts` | MODIFY | `kind`-mapping testen |
|
| `__tests__/lib/claude-job-status.test.ts` | MODIFY | `kind`-mapping testen |
|
||||||
| `__tests__/api/realtime-solo-planning.test.ts` | NEW | |
|
| `__tests__/api/realtime-solo-planning.test.ts` | NEW | |
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
>
|
>
|
||||||
> **Scope v1:** geen REVIEW-status, geen multi-product aggregatie, geen taak-level overrides. Story-level assignment volstaat. Desktop-first conform ST-606 — onder 1024px tonen we dezelfde "te smal scherm"-melding als de rest van de app.
|
> **Scope v1:** geen REVIEW-status, geen multi-product aggregatie, geen taak-level overrides. Story-level assignment volstaat. Desktop-first conform ST-606 — onder 1024px tonen we dezelfde "te smal scherm"-melding als de rest van de app.
|
||||||
>
|
>
|
||||||
> **Versie:** v2 — verwerkt antwoorden uit `scrum4me-backlog.md` over sessie-flag, bestaande Server Actions en desktop-first scope.
|
> **Versie:** v2 — verwerkt antwoorden uit `backlog.md` over sessie-flag, bestaande Server Actions en desktop-first scope.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -159,5 +159,5 @@ Specifiek voor StoryDialog (boven op de algemene out-of-scope-lijst in `docs/pat
|
||||||
- `components/markdown.tsx` — gedeelde markdown-wrapper
|
- `components/markdown.tsx` — gedeelde markdown-wrapper
|
||||||
- `lib/task-status.ts` — status-enum-mapper
|
- `lib/task-status.ts` — status-enum-mapper
|
||||||
- `docs/patterns/dialog.md` — generieke spec (bron-of-truth)
|
- `docs/patterns/dialog.md` — generieke spec (bron-of-truth)
|
||||||
- `docs/scrum4me-architecture.md` — datamodel `Story`
|
- `docs/architecture.md` — datamodel `Story`
|
||||||
- `docs/scrum4me-styling.md` — MD3-tokens, status- en priority-kleuren
|
- `docs/styling.md` — MD3-tokens, status- en priority-kleuren
|
||||||
|
|
@ -122,6 +122,6 @@ Specifiek voor TaskDialog (boven op de algemene out-of-scope-lijst in `docs/patt
|
||||||
## Referenties
|
## Referenties
|
||||||
|
|
||||||
- `docs/patterns/dialog.md` — generieke spec (bron-of-truth voor alles wat hier niet beschreven is)
|
- `docs/patterns/dialog.md` — generieke spec (bron-of-truth voor alles wat hier niet beschreven is)
|
||||||
- `docs/scrum4me-architecture.md` — datamodel `Task`
|
- `docs/architecture.md` — datamodel `Task`
|
||||||
- `docs/scrum4me-styling.md` — MD3-tokens, status- en priority-kleuren
|
- `docs/styling.md` — MD3-tokens, status- en priority-kleuren
|
||||||
- `lib/task-status.ts` — enum-mapper DB ↔ API
|
- `lib/task-status.ts` — enum-mapper DB ↔ API
|
||||||
Loading…
Add table
Add a link
Reference in a new issue