* feat(PBI-74): sprint-workspace-store skelet (Story 9 / T-879)
- stores/sprint-workspace/{types,store,selectors,restore}.ts conform
product-workspace blueprint
- ContextSlice: activeProduct, activeSprintId, activeStoryId, activeTaskId
- EntitiesSlice: sprintsById, storiesById, tasksById
- RelationsSlice: sprintIdsByProduct, storyIdsBySprint, taskIdsByStory
- LoadingSlice met activeRequestId voor race-safe ensure*Loaded
- SyncSlice: realtimeStatus, lastResyncAt, resyncReason
- Realtime applyRealtimeEvent voor sprint/story/task entities + unknown-event
fallback, parent-move handling, child-cleanup bij D op sprint/story
- Optimistic mutations: sprint-story-order, sprint-task-order, entity-patch
- LocalStorage hints (storage key sprint-workspace-hints) per product/sprint
- 45 unit-tests groen — verplicht 13 cases uit workspace-store.md §Tests
* feat(PBI-74): sprint hydratie + realtime SSE (Story 9 / T-880)
- app/api/realtime/sprint/route.ts: SSE-stream LISTEN/NOTIFY op
scrum4me_changes, filter entity ∈ {sprint, story, task} per product_id;
ready-event, heartbeat 25s, hard-close 240s
- lib/realtime/use-sprint-realtime.ts: client-hook met backoff-reconnect;
ready-cycle telt; geen close op hidden; setRealtimeStatus
- lib/realtime/use-sprint-workspace-resync.ts: visibility + online triggers
resyncActiveScopes('visible' | 'reconnect')
- components/sprint/sprint-hydration-wrapper.tsx: hydrateSnapshot via
useEffect met fingerprint-check; mount realtime + resync
- app/(app)/products/[id]/sprint/[sprintId]/page.tsx: wrap SprintBoardClient
in SprintHydrationWrapper; bouw SprintWorkspaceTask-shape voor
tasksByStoryWorkspace en SprintHydrationData voor de wrapper
Schaduw-fase: useSprintStore blijft parallel werken in board components
totdat T-881 die migreert en T-883 de oude store opruimt.
* feat(PBI-74): migreer sprint-board componenten naar workspace-store (Story 9 / T-881)
- TaskList: leest tasks via selectTasksForStory met useShallow; DnD via
applyOptimisticMutation('sprint-task-order') + settle/rollback
- SprintBacklogLeft: leest stories via selectStoriesForActiveSprint met
useShallow; props 'stories' verwijderd
- SprintBoardClient: leest sprintStories uit selector i.p.v. lokale state;
add/remove via direct setState met manuele snapshot-rollback;
reorder via applyOptimisticMutation('sprint-story-order'); assignee-
change via store entity-mutation; tasksByStory en sprintStoryIdList
props weg
- app/(app)/.../sprint/[sprintId]/page.tsx: bouwt SprintHydrationData voor
wrapper; geeft alleen non-store props door aan SprintBoardClient
useSprintStore wordt nergens meer geïmporteerd — alleen comment-referentie
in SprintHydrationWrapper. Cleanup van het bestand zelf in T-883.
Verify groen (671 tests, typecheck, lint clean).
* feat(PBI-74): read-routes voor sprint-workspace + cache-headers (Story 9 / T-882)
- GET /api/products/[id]/sprints — lijst sprints per product
(ensureProductSprintsLoaded). force-dynamic, productAccessFilter,
start_date/end_date naar ISO-date string.
- GET /api/sprints/[id]/workspace — sprint snapshot met sprint-meta,
stories (incl. taskCount/doneCount/assignee), tasks gegroepeerd per
story (ensureSprintLoaded). force-dynamic, productAccessFilter via
product, status-vertaling via taskStatusToApi/storyStatusToApi.
Race-safe loaders (activeRequestId-guard), restore-flow (cascade-restore
via writeProductHint/writeSprintHint/writeStoryHint/writeTaskHint),
resync-laag (useSprintWorkspaceResync visibility + online), unknown-event
filter (isUnknownEntityEvent → resyncActiveScopes('unknown-event')) zijn
allemaal in T-879/T-880 al ingebouwd; T-882 sluit het loop met de
ontbrekende API-endpoints + cache-headers (cache: 'no-store' op fetches,
force-dynamic op routes).
* feat(PBI-74): cleanup oude sprint-store (Story 9 / T-883)
- rm stores/sprint-store.ts — alle componenten lezen nu via
useSprintWorkspaceStore (T-881 voltooide imports-migratie)
- update SprintHydrationWrapper-comment: schaduw-fase referenties
verwijderd
Verify: 671 tests groen, typecheck clean, build groen.
Grep useSprintStore = 0.
* docs(PBI-74): update Story 9 status in implementatieplan (T-884)
- Frontmatter: ready-to-execute → in-progress; revision 1 → 2;
last_updated 2026-05-09 → 2026-05-10
- Stories-tabel: kolom Status toegevoegd (Stories 1-8 DONE via PR #180,
Story 9 met T-884 op review)
- §Story 9: per-taak status + acceptatie-checklist voor T-884 manuele
staging-checks
- Aanbeveling-blokje: noteert dat Story 9 vroeger gestart is dan het
ontwerpdoc adviseerde
* feat(PBI-74): product-workspace store skelet + test-infra (Story 1)
Skelet voor de nieuwe `product-workspace-store` die op termijn de gefragmenteerde
`backlog-store`/`planner-store`/`selection-store`/`product-store` vervangt. Deze
PR levert alleen het skelet + tests; UI-consumers worden in latere stories
omgezet.
- vitest naar jsdom + tests/setup.ts (MemoryStorage, default fetch-stub) — G6/G8
- stores/product-workspace/{types,store,selectors,restore}.ts — immer-middleware,
alle slices en acties (hydrate, setActive*, ensure*Loaded met activeRequestId-
guard, applyRealtimeEvent, resyncActiveScopes/loadedScopes, optimistic
mutations). Restore-wiring in setters volgt in Story 4 (T-857/T-858).
- selectors gebruiken module-level EMPTY refs (G1) en documenteren useShallow-
vereiste (G2)
- 34 nieuwe unit-tests dekken §Testing setup-checklist uit het ontwerp:
hydrateSnapshot, selection-cascade, applyRealtimeEvent (I/U/D + parent-move +
ander-product + unknown-entity → resync), delete-cleanup, race-safe loaders,
ensureTaskLoaded _detail-flag, resyncActiveScopes ensure-keten, restore-hints
read/write/clear, optimistic mutation rollback/settle/SSE-echo idempotent
- docs/api/rest-contract.md: audit-sectie met de vier ontbrekende
ensure*Loaded-endpoints (worden toegevoegd in Story 7 / T-870)
Refs: PBI-74, ST-1318, T-837..T-843
Bron-ontwerp: docs/plans/zustand-store-rearchitecture.md
Implementatieplan: docs/plans/zustand-workspace-store-implementation.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-74): dual-dispatch hydratie + realtime naar workspace-store (Story 2)
Story 2 — schaduw-fase: BacklogHydrationWrapper en useBacklogRealtime voeden
nu ook de nieuwe product-workspace-store, terwijl de oude useBacklogStore /
useProductStore leidend blijft voor componenten. Story 3 verschuift consumers
één voor één; Story 8 ruimt de oude stores op.
- T-844: BacklogHydrationWrapper roept naast useBacklogStore.setInitialData
ook useProductWorkspaceStore.hydrateSnapshot aan. Productname-prop optioneel
toegevoegd voor activeProduct-context.
- T-845: useBacklogRealtime onmessage dispatcht events naar zowel oude store
(applyChange) als nieuwe store (applyRealtimeEvent). Geen wijziging aan
reconnect/visibility — Story 5.
- T-846: dev-only logWorkspaceFingerprint helper vergelijkt counts tussen
oude en nieuwe store na hydrate en na elk realtime-event. console.warn bij
mismatch; opt-in debug log via NEXT_PUBLIC_DEBUG_WORKSPACE_FINGERPRINT=1.
Bestand TODO-marked voor verwijdering in Story 8 (T-878).
- T-847: SetCurrentProduct schrijft naast oude useProductStore ook
useProductWorkspaceStore.setActiveProduct({id, name}); cleanup cleart beide.
setActiveProduct triggert ensureProductLoaded — fetch-stub tot Story 7
(T-870) de LIST-endpoints toevoegt.
Verify: lint+typecheck clean, 636/636 tests groen (geen UI-regressie omdat
oude store leidend blijft).
Refs: PBI-74, ST-1319, T-844..T-847
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-74): migreer backlog-componenten naar workspace-store (Story 3)
Story 3 verplaatst alle UI-consumers van de oude vier stores
(useBacklogStore/usePlannerStore/useSelectionStore/useProductStore) naar de
nieuwe product-workspace-store. De oude stores blijven nog bestaan voor
hydration-wrapper en realtime-hook (dual-dispatch); Story 8 ruimt ze op.
- T-848 backlog-split-pane.tsx: leest activePbiId/activeStoryId uit
context-slice (primitives, geen useShallow nodig).
- T-849 pbi-list.tsx: selectVisiblePbis(useShallow); DnD via
applyOptimisticMutation('pbi-order' + optionele 'entity-patch' bij
cross-priority drag), met settle/rollback per server-result.
- T-850 story-panel.tsx: selectStoriesForActivePbi(useShallow); DnD via
applyOptimisticMutation('story-order' + entity-patch bij priority change).
- T-851 task-panel.tsx: selectTasksForActiveStory(useShallow); DnD via
applyOptimisticMutation('task-order'); detail-view (ensureTaskLoaded +
isDetail) zit in de task-dialog (apart component, niet in deze lijst).
- T-852 start-sprint-button.tsx: selectActivePbi + selectStoriesForActivePbi
voor free-story count.
- T-853 set-current-product.tsx: alleen workspace-store.setActiveProduct
(oude useProductStore-import verwijderd).
- T-854 G1/G2-audit: alle nieuwe selectors gebruiken module-level EMPTY
refs (G1) en useShallow voor lijsten (G2). Geen 'Maximum update depth'-
warnings tijdens npm test.
- T-855 tests bijgewerkt: backlog-split-pane.test, task-panel.test,
integration.test gebruiken nu setState op workspace-store (helpers
resetWorkspace/setActiveStoryAndTasks/selectPbi/selectStory).
Verify: lint+typecheck clean, 636/636 tests groen. UI-consumers van
oude stores zijn nu nul (uitgezonderd dual-dispatch in hydration-wrapper en
realtime-hook + dev-fingerprint-helper, die in Story 8/T-873/T-878 verdwijnen).
Refs: PBI-74, ST-1320, T-848..T-855
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-74): race-safe loaders + restore-hints + URL-prioriteit (Story 4)
- T-856: activeRequestId-guard zat al in store.ts uit Story 1; bevestigd door
de race-safety test (in-flight ensurePbiLoaded mag niet overschrijven).
- T-857: restore-hint flow toegevoegd in setActiveProduct/setActivePbi/
setActiveStory. Async chain: await ensureXxxLoaded → guard check →
readHints → valideer hint via entities.byId → setActiveYyy(hint).
Geen setTimeout-trick — chain is alleen await-based.
- T-858: writeProductHint/writePbiHint/writeStoryHint/writeTaskHint
aangeroepen direct na set(...) zodat de hint-persistentie altijd
consistent is met de in-store selectie.
- T-859: nieuwe components/backlog/url-task-sync.tsx — leest
?editTask=<id> uit useSearchParams, schrijft de hint en roept
setActiveTask aan zodat de URL wint boven een eerder gepersisteerde
task-hint. Gemount in beide product-pages (desktop + mobile) binnen
BacklogHydrationWrapper.
- T-860: 6 nieuwe vitest-cases — 4 voor hint-persist per setter, 2 voor de
restore-flow chain (hint die niet in entities zit wordt genegeerd; hint
die wel in entities zit wordt toegepast). Bestaande race-safety test
blijft groen.
Verify: lint+typecheck clean, 642/642 tests groen.
Refs: PBI-74, ST-1321, T-856..T-860
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-74): hidden-tab + reconnect resync (Story 5)
Per ontwerp samen in één commit zodat geen vangnet wegvalt zonder vervanging.
- T-861: useBacklogRealtime sluit niet meer op visibilitychange hidden;
EventSource blijft open zolang browser/netwerk dit toelaten. Reconnect bij
netwerkfout blijft via backoff. visibilitychange fungeert nog wel als
re-connect-trigger als de stream tussentijds is gesloten (b.v. 240s
hard-close server-side).
- T-862: 'ready'-event-handler telt connect-cycles. De eerste 'ready' is de
initial connect (geen resync). Bij latere 'ready' (post-reconnect) wordt
resyncActiveScopes('reconnect') aangeroepen om gemiste events op te halen.
- T-863: nieuwe lib/realtime/use-workspace-resync.ts — luistert op
document.visibilitychange (hidden→visible) en window.online; dispatcht
resyncActiveScopes('visible') resp. 'reconnect'. Mounted in
BacklogHydrationWrapper na useBacklogRealtime.
- T-864: 4 nieuwe vitest-cases voor useWorkspaceResync (jsdom): visible→
visible event, online event, hidden negeren, cleanup-bij-unmount.
Daarnaast lint-cleanup: ongebruikte 'order'-variabelen in pbi-list en
story-panel weggehaald.
Verify: lint+typecheck clean, 646/646 tests groen.
Refs: PBI-74, ST-1322, T-861..T-864
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-74): unknown-event fallback tests (Story 6)
T-865 (isUnknownEntityEvent filter) en T-866 (resync-trigger in
applyRealtimeEvent) zijn al in Story 1 geïmplementeerd in store.ts;
deze story breidt de test-coverage uit met expliciete negatieve cases
voor het type-veld noise pattern.
T-867 — 5 nieuwe vitest-cases:
- unknown entity met ANDER product_id → geen resync
- claude_job_status (type) → geen resync
- worker_heartbeat (type) → geen resync
- claude_job_enqueued (type) → geen resync
- payload zonder entity en zonder type → genegeerd
- question-entity (entity-veld, geen type, niet pbi/story/task) → resync trigger
Verify: lint+typecheck clean, 651/651 tests groen.
Refs: PBI-74, ST-1323, T-865..T-867
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-74): cache-headers + LIST endpoints (Story 7)
- T-868: cache: 'no-store' was al ingebouwd in fetchJson helper (Story 1).
Bevestigd door bestaande ensureProductLoaded test die de fetch-init
controleert.
- T-869: force-dynamic toegevoegd op alle vier nieuwe LIST-endpoints.
- T-870: vier nieuwe routes voor ensure*Loaded:
- GET /api/products/:id/backlog → ProductBacklogSnapshot
- GET /api/pbis/:id/stories → BacklogStory[]
- GET /api/stories/:id/tasks → BacklogTask[]
- GET /api/tasks/:id (nieuwe handler naast bestaande PATCH) → TaskDetail
met _detail: true marker
Auth via authenticateApiRequest (Bearer of iron-session); access-control
via productAccessFilter (gebruiker is owner of member van het product).
Statussen worden via taskStatusToApi/storyStatusToApi/pbiStatusToApi
vertaald naar lowercase API-vorm.
- T-871: SSE-route /api/realtime/backlog stuurt al ready-event direct na
LISTEN (regel 106) — geen wijziging nodig.
Verify: lint+typecheck clean, 651/651 tests groen.
Refs: PBI-74, ST-1324, T-868..T-871
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-74): oude stores opruimen (Story 8)
Workspace-store is nu de enige bron voor product-backlog client-state. De
vier voorgangers en de dual-dispatch-infrastructuur zijn verwijderd.
- T-872: grep over codebase op useBacklogStore/usePlannerStore/
useSelectionStore/useProductStore is leeg.
- T-873..T-876: stores/{backlog,planner,selection,product}-store.ts deleted.
- T-877: __tests__/realtime/payload-contract.test.ts en
__tests__/api/backlog-realtime.test.ts deleted — pbi/story/task I|U|D
payload-handling wordt al gedekt door
__tests__/stores/product-workspace/store.test.ts (incl. parent-move,
idempotent inserts, delete-cleanup).
- T-878: lib/realtime/dev-workspace-fingerprint.ts deleted, dual-dispatch
uit BacklogHydrationWrapper en lib/realtime/use-backlog-realtime.ts
weggehaald. stores/products-store.ts (lijst van producten ≠ active
product) blijft ongewijzigd.
Bijwerkingen:
- BacklogPbi en BacklogStory types in components/backlog/story-panel.tsx en
components/sprint/sprint-backlog.tsx krijgen sort_order zodat ze met de
workspace-types overeenkomen.
- Server-pages /products/[id]/page.tsx (desktop+mobile) en
/products/[id]/sprint/[sprintId]/page.tsx selecteren sort_order op story
en mappen het door in de hydration-payload.
Verify: lint+typecheck clean, 626/626 tests groen (verlies van 25 redundante
oude-store tests; workspace-store tests dekken hetzelfde gedrag).
Refs: PBI-74, ST-1325, T-872..T-878
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(PBI-74): richtlijn workspace-store + realtime patroon
Documenteert het patroon dat in Stories 1-8 is opgeleverd, zodat een
volgende workspace-store (sprint, of een nieuwe bounded context) hetzelfde
recept volgt.
- docs/patterns/workspace-store.md (nieuw): wanneer een workspace-store, de
vijf state-slices, selectors-regels (G1/G2), race-safe ensure*Loaded met
activeRequestId-guard (G4), SSE-hook + applyRealtimeEvent met
unknown-event filter, hidden-tab + reconnect resync via
useWorkspaceResync, restore-hint flow met await-chain en URL-prioriteit,
optimistic mutations (applyOptimisticMutation/rollback/settle), API
endpoint-vereisten (force-dynamic, cache: no-store), test-setup met
MemoryStorage + originalActions snapshot + mockImplementation, gotchas
G1-G8 als comment-template, en het 8-staps migratiepad.
- docs/patterns/zustand-optimistic.md: bijgewerkt voor de nieuwe
workspace-store API; verwijst voor het bredere patroon naar
workspace-store.md. Voorbeelden voor pbi-order + entity-patch.
- CLAUDE.md: patterns quickref aangevuld met workspace-store-rij.
Verify: typecheck clean.
Refs: PBI-74
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(PBI-74): solo + notifications hooks volgen ook hidden-tab/resync patroon
Het uitgangspunt van PBI-74 (robuust tegen gemiste SSE-events, hidden tabs
en onbekende notify-vormen) gold universeel — niet alleen voor
product-workspace. use-solo-realtime en use-notifications-realtime hadden
nog dezelfde bug die use-backlog-realtime in Story 5 al opgelost kreeg:
sluit stream op hidden, geen resync.
Reproductie (zoals gemeld): solo-screen open in tab A, product-backlog
open in tab B; bewerk task-title in tab B → tab A's solo-SSE was gesloten
(hidden) en kreeg het NOTIFY-event nooit. Tab terug naar solo →
EventSource reconnect maar geen resync → oude title persisteert. Postgres
NOTIFY heeft geen replay, dus zonder resync zijn die events permanent
verloren.
Fix in beide hooks (zelfde patroon als Story 5 voor backlog):
- Stream blijft open op visibilitychange hidden — geen close() meer.
- Bij hidden→visible én bij window 'online': router.refresh() zodat de
server-component opnieuw fetcht en de initial-state-prop ververst (wat
voor solo de tasks-record reset via initTasks; voor notifications de
questions-bel-state).
- Bij latere 'ready'-events na reconnect (use-solo-realtime): zelfde
router.refresh() trigger zodat we niet vertrouwen op alleen het
visibility-pad.
Verify: lint + typecheck clean, 626/626 tests groen.
Refs: PBI-74
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: fix broken links in research-repo plan
docs/plans/lees-de-readme-md-validated-book.md beschrijft een research-
repo migratiepad. De links waren geschreven vanuit het research-repo-
perspectief (paden als stores/data-store.ts, ../Scrum4Me/CLAUDE.md,
docs/plans/zustand-store-rearchitecture.md zonder relative-prefix), wat
de doc-link-checker hier laat falen.
- Header-note toegevoegd dat het document voor de research-repo is.
- Interne refs (zustand-store-rearchitecture.md, CLAUDE.md) → relatieve
paden die in deze repo wél resolven (./zustand-..., ../../CLAUDE.md).
- Research-repo-only refs (stores/data-store.ts,
hooks/use-event-stream.ts, components/*-select.tsx, etc.) → inline
code-tags met "(research-repo)" suffix; de link-checker slaat ze over
en de leesbaarheid blijft.
Verify: npm run docs:check-links → ✓ All doc links valid (118 files).
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(KIND_DEFAULTS): permission_mode acceptEdits voor idea-kinds + PLAN_CHAT
Spiegel van scrum4me-mcp PR #40. Symptoom: IDEA_GRILL job IDEA-047 werd
3x geclaimd, Claude liep telkens succesvol (exit 0 na 600-900s) maar
deed nooit update_job_status('done'). Lease verliep, retry_count >= 2 →
status FAILED met "agent did not complete job within 2 attempts".
Root cause: KIND_DEFAULTS.permission_mode='plan' voor idea-kinds en
PLAN_CHAT. In autonome batch-mode wacht plan-mode op een human "go" na
elke planning-fase — geen mens in de loop in deze runner-context.
Fix:
- IDEA_GRILL.permission_mode: plan → acceptEdits
- IDEA_MAKE_PLAN.permission_mode: plan → acceptEdits
- PLAN_CHAT.permission_mode: plan → acceptEdits
- PLAN_CHAT.allowed_tools krijgt mcp__scrum4me__update_job_status (ontbrak)
De allowed_tools-lijsten doen de echte sandboxing (geen Bash, geen Edit
voor IDEA_GRILL/PLAN_CHAT). Plan-mode's "veiligheid" wordt al door
tool-allowlists geleverd; acceptEdits is hier puur om Claude door zijn
eigen update_job_status loop te laten lopen zonder approval-wachttijd.
Plus: docs/runbooks/{job-model-selection,worker-idempotency}.md tabellen
bijgewerkt. last_updated note in job-model-selection.md.
Verify: 587 tests in 78 files passed (incl. nieuwe lib/job-config tests).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: remove .claude/scheduled_tasks.lock per ongeluk meegecommit
Lokale tooling-lock-file van de cowork-skills, hoort niet in de repo.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Spiegelt de scrum4me-mcp wijzigingen naar de Scrum4Me web-app zodat
enqueue-laag (lib/job-config-snapshot.ts) en claim-laag dezelfde
defaults gebruiken. Plus runbook-correctie van een eerder gedocumenteerde
maar niet-bestaande Claude CLI-flag.
- T-25: lib/job-config.ts — mapBudgetToEffort export + KIND_DEFAULTS
.allowed_tools voor TASK/SPRINT/IDEA_GRILL/IDEA_MAKE_PLAN omgezet
naar expliciete lijsten zonder wait_for_job/check_queue_empty/
get_idea_context. Comment-block over CLI-flag-mapping en sync met
scrum4me-mcp.
- T-26: docs/runbooks/worker-idempotency.md sectie "Config doorgeven aan
Claude Code (PBI-67)" herschreven. --thinking-budget vervangen door
--effort (mapping-tabel toegevoegd); --max-turns geschrapt (CLI heeft
die flag niet — audit-only). Sectie "Wie doet wat in de runner-
architectuur" toegevoegd.
- T-27: docs/runbooks/job-model-selection.md — notes over max_turns,
thinking_budget en allowed_tools onder de matrix. Nieuwe sectie
"Runner-architectuur" met verwijzing naar plan + worker-idempotency.
- T-28: __tests__/lib/job-config.test.ts (nieuw) — 22 tests:
mapBudgetToEffort grenswaarden + KIND_DEFAULTS.allowed_tools structurele
checks + cascade regression.
Plus: docs/plans/queue-loop-extraction.md (geschreven in plan-mode,
nu gepubliceerd in repo).
Verify: lint OK, typecheck OK, 587 tests in 78 files passed.
Build niet lokaal uitgevoerd (vereist DATABASE_URL voor "Collecting page
data" — diff raakt geen API-route).
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-67/ST-1297): datamodel-velden voor job-model-selectie
Voegt 8 nieuwe optionele velden toe verspreid over Product, Task en
ClaudeJob ten dienste van de override-cascade:
task.requires_opus → job.requested_* → product.preferred_* → kind-default
Bestaande rijen krijgen NULL (Product/ClaudeJob) of false (Task) en
vallen daarmee terug op de kind-defaults uit de resolver (ST-1298).
Migration is additief: alleen ALTER TABLE ADD COLUMN, geen RENAME of
DROP. Bestaande factories en seed-script blijven werken zonder
aanpassing omdat alle nieuwe velden default-waardes hebben.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-67/ST-1299): job-config snapshot bij enqueue + worker-flag-runbook
T-789: Snapshot van resolved JobConfig in ClaudeJob.requested_*
bij elke job-creatie. Helper in lib/job-config-snapshot.ts laadt
product (preferred_*) en task (requires_opus) en draait de resolver
uit lib/job-config.ts (mirror van scrum4me-mcp/src/lib/job-config.ts —
zelfde matrix, sync-comment in bestand). Toegepast op alle 5
enqueue-locaties:
- actions/user-questions.ts (PLAN_CHAT)
- actions/sprint-runs.ts × 3 (SPRINT_IMPLEMENTATION x2,
TASK_IMPLEMENTATION loop)
- actions/ideas.ts (IDEA_GRILL / IDEA_MAKE_PLAN)
Test-mocks uitgebreid met product.findUnique en task.findUnique zodat
de helper bij unit tests veilig terugvalt op kind-defaults (alle 563
tests groen).
T-790: Sectie 'Config doorgeven aan Claude Code' toegevoegd aan
docs/runbooks/worker-idempotency.md met CLI-flag-mapping en de
verwachte aanroep per kind. Forward-link naar
docs/runbooks/job-model-selection.md (volgt in T-794).
Plus: docs/plans/job-model-selection.md (de approved plan-doc).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-67/ST-1300): cost-attribution voor thinking-tokens + admin UI
T-792: token-stats + token-history rekenen actual_thinking_tokens nu
mee in de totale kosten (tegen input-rate, conform Anthropic billing).
COALESCE-veilig zodat oude rijen 0 bijdragen i.p.v. NaN. Nieuwe export
`getTokenStatsByKind` aggregeert tokens en kosten per ClaudeJob.kind
zodat we relatieve uitgaven van IDEA_GRILL/IDEA_MAKE_PLAN/PLAN_CHAT/
TASK_IMPLEMENTATION/SPRINT_IMPLEMENTATION kunnen zien.
T-793: admin/jobs Kosten-tabel toont:
- Nieuwe kolom 'Thinking' (aantal verbruikte thinking-tokens)
- Mismatch-marker (rood) als requested_model afwijkt van actuele
model_id — duidt op een worker die de CLI-flag niet doorgaf.
Tooltip toont aangevraagd model. Geen Sentry/log-noise.
Page-level cost-berekening volgt dezelfde formule (input_price ×
thinking_tokens). 563 tests groen.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(PBI-67/ST-1301): runbook + CLAUDE.md updates voor model/mode-selectie
T-794: Nieuwe runbook docs/runbooks/job-model-selection.md met
override-cascade, kind-default-matrix, override-voorbeelden,
auditspoor en cost-attribution-formule. 107 regels.
T-795: CLAUDE.md hardstop-bullet voor 'Model/mode per ClaudeJob'
(verwijst naar nieuwe runbook) + patterns-quickref-rij voor
job-config resolver. CLAUDE.md blijft 139 regels (≤ 150).
T-796: docs:check-links groen — 108 files, geen broken links. Twee
externe-repo verwijzingen (scrum4me-mcp/...) ge-de-linked tot plain
text omdat de check-links script de zustertree niet traverseert; de
referenties blijven leesbaar.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Nieuw script `npm run db:sync-model-prices` haalt de actuele Claude 4.x
modellijst op bij de Anthropic API en upsert prijzen in `model_prices`.
Anthropic biedt geen prijs-API, dus prijzen blijven onderhouden in een
PRICE_TABLE constante in het script. Cache-tier-prijzen worden afgeleid
via vaste multipliers (read 0.1x, write 1.25x). Nieuwe Claude 4.x modellen
worden gedetecteerd en gelogd als warning zodat duidelijk is wanneer de
tabel handmatig moet worden bijgewerkt.
- scripts/sync-model-prices.ts: idempotent upsert, --dry-run, retry op 5xx
- ANTHROPIC_API_KEY als optional env-var (.env.example, lib/env.ts)
- scripts/README.md: gebruiksinstructies + edge cases
- docs/plans/sync-model-prices.md: ontwerpdocument
Verificatie: `npm run lint`, `vitest` (563/563), TypeScript clean.
Echt gedraaid tegen DB: 3 created (eerste run) -> 3 unchanged (tweede run).
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ST-cmovs79lt: Schema + migratie PushSubscription model
Voeg PushSubscription model toe aan prisma/schema.prisma met
snake_case-conventie, relation field op User, en bijbehorende
migratie (push_subscriptions tabel, FK + index op user_id).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ST-cmovs7e3o: web-push dependency + VAPID env vars feature-gated
Voeg web-push + @types/web-push toe aan package.json.
Registreer NEXT_PUBLIC_VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY,
VAPID_SUBJECT en INTERNAL_PUSH_SECRET als .optional() in lib/env.ts.
Documenteer alle vier in .env.example en README.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ST-cmovs7jgr: lib/push-server.ts met sendPushToUser + stale-cleanup
Server-only push-lib met VAPID feature-gate, send naar alle
subscriptions van een user, en automatische cleanup bij 404/410.
Unit tests: success-pad, 410 verwijdert sub, 404 verwijdert sub,
andere errors loggen zonder delete.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ST-cmovs7ouz: lib/push-client.ts client-side push helpers + stub actions/push.ts
Client-side helpers: isPushSupported, isIOSSafari, isStandalonePWA,
urlBase64ToUint8Array, subscribeToPush, unsubscribeFromPush.
Stub actions/push.ts zodat imports resolven (implementatie volgt
in volgende taak). Unit tests voor urlBase64ToUint8Array.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ST-cmovs7ut4: actions/push.ts subscribeToPushAction + unsubscribeFromPushAction
Vervangt stub met volledige implementatie: requireUser via getSession,
demo-block, Zod-validatie, upsert met user_id-scoping en user-scoped
deleteMany. Tests (8): idempotentie, demo-block, unauthenticated, invalid input.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ST-cmovs80c1: POST /api/internal/push/send met constant-time Bearer check
Route: 503 als INTERNAL_PUSH_SECRET uitstaat, 401 bij verkeerd secret
(timingSafeEqual), 400 bij invalid JSON, 422 bij Zod-fout, 204 bij succes.
push-server.ts: env-import vervangen door process.env om SESSION_SECRET
validatie tijdens build te omzeilen. Tests aangepast.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ST-cmovs862j: Admin test-send route + public/sw.js service worker
POST /api/internal/push/test-send: requireAdmin check (redirect bij
niet-admin), optioneel body met defaults, roept sendPushToUser aan, 204.
public/sw.js: push-handler met showNotification, notificationclick met
same-origin guard, focus bestaand venster of openWindow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ST-cmovs8jvq: PushToggle component met 3 states + iOS-banner
Client component met states loading/unsupported/ios-needs-install/
denied/subscribed/unsubscribed. useEffect detecteert initial status,
permission-prompt alleen via user-click. iOS-banner NL, denied-uitleg,
subscribe/unsubscribe knoppen met sonner-toasts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ST-cmovs8psg: notifications-sheet + iOS meta-tags in layout
notifications-sheet.tsx: PushToggle onderin met sectie
'Notificatie-instellingen' en visuele scheidslijn.
app/layout.tsx: appleWebApp.capable, statusBarStyle en
mobile-web-app-capable meta-tags toegevoegd via Next.js Metadata API.
manifest.json had al display: standalone.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ST-cmovs8vxj: docs/patterns/web-push.md pattern-documentatie
Architectuur-diagram, payload-shape, foutcodes, VAPID-config,
iOS-quirks, demo-users blokkade, trigger-voorbeelden (server +
HTTP) en admin-testroute curl-voorbeeld.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Voorkomt automatische Vercel-deploys op PR-preview en push-naar-main
zolang \`vars.AUTO_DEPLOY_ENABLED == 'true'\` ontbreekt. Default-staat:
auto-deploy UIT, scheelt Actions-minuten op het free-plan.
Handmatig deployen blijft werken via workflow_dispatch (Actions tab →
"Run workflow" → kies preview of production). Die job (\`deploy-manual\`)
is niet aan de flag gebonden.
Aanzetten van auto-deploy: Settings → Secrets and variables → Actions
→ Variables → New repository variable: \`AUTO_DEPLOY_ENABLED\` = \`true\`.
\`changes\` job (path-filter) staat ook achter de flag — die wordt alleen
gebruikt door de twee auto-deploy jobs.
Runbook bijgewerkt met de nieuwe default + uitleg.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(PBI-58): add developer manual chapters under docs/manual/
Adds a 7-file English-language manual targeted at new human contributors:
index, overview, statuses & transitions (with mermaid state diagrams),
git workflow, MCP integration, docker, and troubleshooting. The manual
is the *map* — it cross-references existing runbooks/ADRs/architecture
docs rather than duplicating their content.
Regenerates docs/INDEX.md and validates with check-doc-links.mjs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(PBI-58): add markdown rendering deps + manual:build script
Adds mermaid, rehype-slug, rehype-autolink-headings for the in-app
/manual page. Wires manual:build into prebuild so production builds
always regenerate the chapter TOC.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-58): codegen script for in-app manual TOC
scripts/build-manual.mjs walks docs/manual/, parses YAML front-matter,
strips it from the body, and emits lib/manual.generated.ts with a typed
ManualEntry[] containing slug, title, description, filePath, and the
embedded markdown body. Pure Node 20, mirrors generate-docs-index.mjs.
Inlining the markdown at build time keeps runtime serverless functions
free of filesystem reads, which avoids whole-project NFT tracing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-58): /manual route renders developer manual chapters in-app
Catch-all route at app/(app)/manual/[[...slug]]/page.tsx with
generateStaticParams covering every TOC entry. Server-side
MarkdownView uses react-markdown with remark-gfm, rehype-slug, and
rehype-autolink-headings; mermaid code blocks are routed to a
client-only MermaidBlock that dynamic-imports mermaid on mount.
ManualSidebar (client) reads the typed TOC and highlights the active
chapter via usePathname.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(PBI-58): add Manual link to main nav bar
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Het advies-document dat als input diende voor PBI-50 is nu in docs/plans/
opgeborgen voor traceability. INDEX.md regenerated om hem op te nemen.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* PBI-50 F1: SPRINT_BATCH execution-strategy + cross-repo blocker + branch-resume
Schema-migratie + Scrum4Me-side wiring voor de nieuwe SPRINT_IMPLEMENTATION-flow:
- prisma: PrStrategy ADD VALUE 'SPRINT_BATCH'; ClaudeJobKind ADD VALUE
'SPRINT_IMPLEMENTATION'; nieuwe enum SprintTaskExecutionStatus; ClaudeJob.lease_until
+ status_lease_until index; SprintRun.previous_run_id (self-relation
SprintRunChain) voor branch-hergebruik bij resume; nieuwe sprint_task_executions
tabel met frozen plan_snapshot + verify_required_snapshot per task in scope.
- actions/sprint-runs.ts startSprintRunCore: nieuwe blocker-type 'task_cross_repo'
voor SPRINT_BATCH (pre-flight rejecteert sprints met cross-repo task_url).
Bij SPRINT_BATCH: één SPRINT_IMPLEMENTATION ClaudeJob (geen per-task loop).
- actions/sprint-runs.ts resumePausedSprintRunAction: SPRINT_BATCH-pad met
remaining-execution-check; bij onafgemaakt werk → nieuwe SprintRun met
previous_run_id + run.branch hergebruikt + nieuwe SPRINT_IMPLEMENTATION-job.
Oude SprintRun → CANCELLED. Bestaande PBI-49 P0 scope-DONE pad ongewijzigd.
- actions/products.ts updatePrStrategyAction: accepteert SPRINT_BATCH.
- components/products/pr-strategy-select.tsx: drie opties met helptekst,
gebruikt @prisma/client PrStrategy ipv lokaal type.
- components/sprint/sprint-run-controls.tsx: BLOCKER_LABELS + blockerHref
voor task_cross_repo.
Migratie applied op Neon. Type-check + 532 tests groen.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* PBI-50 F5: cross-repo blocker test voor SPRINT_BATCH
- task_cross_repo blocker fires bij task.repo_url ≠ product.repo_url
- happy path: tasks zonder repo_url-override of met match → één
SPRINT_IMPLEMENTATION-job (niet per-task).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* PBI-50 F5: docs/architecture/sprint-execution-modes.md
Vergelijking PER_TASK vs SPRINT_BATCH met trade-offs, datamodel-
toevoegingen (SprintTaskExecution, lease_until, SprintRunChain) en
MCP-tools-matrix per modus. Toegevoegd aan breadcrumb in
docs/architecture.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(landing): tour uitbreiden naar 6 screenshots incl. Ideas/Insights
Vervangt de oude 3 .jpg-screenshots door 6 nieuwe .png's met de huidige
visuele staat van de app. Volgorde toont de hele flow: ideeën binnen →
producten → backlog → sprint → solo → insights.
- Tour-array van 3 naar 6 figures, grid blijft lg:grid-cols-3 (2x2-rijen)
- Intro-tekst aangepast: "Zes weergaven van Scrum4Me — van inkomende
ideeën tot persoonlijk Kanban-bord en voortgangs-inzichten"
- Bestandsnamen gehernoemd naar lowercase-dash-conventie:
Sprint.png → sprint.png, Solo.png → solo.png, "Product Backlog.png" →
product-backlog.png, Producten.png → producten.png, Insights.png →
insights.png, Ideas-table.png → ideas-table.png,
Ideas-detail.png → ideas-detail.png (alleen voorbereiding, nog niet in
tour gebruikt)
- Oude .jpg-bestanden verwijderd
Niet onderdeel: hero/architectuur/handleiding-rewrite voor v3 — die staan
gepland onder ST-1224 en blijven open.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(landing): v3 — van idee tot pull request, met procesflow + Idea-laag
Verbreedt de landing-propositie van "executie lokaal" (v2) naar de
volledige cyclus idee → grill → plan → execute → PR. Eert M12 Ideas dat
sinds 2026-05-04 het kernconcept van het product is, plus auto-PR en
Sync-tab.
Hero:
- H1 "Van idee tot pull request — op je eigen hardware."
- Subhead benoemt grill→plan→materialise→agent→PR-cyclus en houdt het
lokaal-anker uit v2 vast.
Nieuw §3 "Van idee tot pull request":
- 4 procesflow-kaarten (Idee/Grill/Plan/Execute) met status-chips
(DRAFT/GRILLING/PLAN_READY/DONE→PR) en pijlen tussen kaarten op md+.
- Samenvattende paragraaf over state-machine, materializeIdeaPlanAction
en auto-PR.
Architectuur:
- docs/diagrams/architecture.mmd Worker-label uitgebreid met
"jobs: GRILL · PLAN · IMPL"; beide SVG's geregenereerd.
- Callout "Lokale worker" benoemt nu de drie jobsoorten expliciet.
Feature-grid (set D, 6 kaarten):
- Vervang "Hiërarchisch plannen" door "Ideas — Grill & Plan" op positie 1.
- Lokale Claude-agents: + auto-PR/SQUASH-merge zin.
- Realtime updates: + Sync-tab zin.
- Async vraagkanaal: + Grill-vragen zin.
Quickstart:
- Extra regel over UI-route (/ideas → Nieuw idee → Grill me) onder de
bestaande MCP-installatie code-block.
Scrum-samenvatting:
- Hiërarchie wordt twee-rij-systeem: Idea (DRAFT → GRILLED → PLAN_READY)
als bovenste rij, daaronder Product → PBI → Story → Taak met
"materialiseert ↓"-pijl.
- Terminologie krijgt 2 nieuwe tegels (Idea, Grill/Plan).
Handleiding (10 → 12 stappen):
- Nieuwe stappen 3-5 voor Idea-route (vastleggen, grillen, plan + materialiseren),
visueel gemarkeerd met tertiary-border en chip "Idea-route".
- Oude 7+8 (token + MCP-koppeling) samengevoegd tot stap 10.
- Stap 11 uitgebreid met Sync-tab-volgen.
- Stap 6 hernoemd "opbouwen" → "finetunen".
Plan-doc + grilling-context vastgelegd in docs/plans/landing-v3-idea-flow.md.
Tracked: ST-1224 onder PBI Marketing & Landingspagina.
Verified: lint 0 errors / 7 warnings (alle pre-existing), 564/564 tests,
productie-build slaagt.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Beschrijft hoe agent-jobs met Product.auto_pr=true automatisch
commit → push → PR → auto-merge → deploy doorlopen. Documenteert
welke laag wat doet (worker, scrum4me-mcp, GitHub Actions, Vercel),
setup-vereisten per product, foutpaden en wanneer auto_pr UIT
laten.
Onderdeel van PBI-36 ST-1220. De auto-PR-implementatie zelf zit
in scrum4me-mcp; deze runbook documenteert de bestaande flow plus
de nieuwe auto-merge-stap (scrum4me-mcp PR #23).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Beschrijft beslissingsboom verify_result × diff-staat × branch-staat
→ JobStatus, met SKIPPED gereserveerd voor al-gemergd werk en FAILED
voor échte fouten. Plus StoryLog-verplichting (log_implementation,
log_commit, log_test_result) en idempotency-protocol vóór schrijven.
PBI-33 batch (5-5 22:22) gedocumenteerd als case-study: drie
protocol-overtredingen die deze runbook + de nieuwe SKIPPED-status
aanpakken.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- lib/job-status.ts: SKIPPED ↔ 'skipped' mapping in beide richtingen
- components/shared/job-status.ts: label "Overgeslagen" + neutrale italic styling
- actions/admin/jobs.ts: cancel-guard erkent SKIPPED als eindstatus
- app/api/cron/cleanup-agent-artifacts: SKIPPED ook opruimen na 7d
- lib/insights/agent-throughput: SKIPPED telt mee als terminal
ACTIVE_JOB_STATUSES bewust ongewijzigd — SKIPPED is afgerond.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- new enums IdeaStatus, ClaudeJobKind, IdeaLogType
- new models Idea (with @@unique([user_id, code]) + pbi_id @unique) and IdeaLog
- User.idea_code_counter Int @default(0) for IDEA-{nnn} code generation
- ClaudeJob.task_id nullable; new idea_id + kind fields + index
- ClaudeQuestion.story_id nullable; new idea_id field + index
- existing call sites narrowed to story-questions / task-jobs (idea-paths come in T-502+)
- includes the M12 plan doc copied from /Users/janpetervisser/.claude/plans
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
docs/runbooks/v1-smoke-test.md (NIEUW): 11-secties handmatige checklist
voor de v1.0-pre-launch verificatie — auth, mobile UA-redirect, happy-path
flow, mobile shell, edit-flows, demo-policy, rate-limiting steekproef,
realtime, debug-routes 404 in productie, Lighthouse a11y per pagina,
rollback-trigger.
v1-readiness.md: 4 Before-launch items afgevinkt (demo-policy, privacy,
README, CHANGELOG); smoke-test verwijst nu naar de checklist; PWA-test
en v1.0.0-bump zijn de twee resterende handmatige items.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Acceptatiecriteria vroeg om 'flow per scherm' beschrijving in de
Mobile shell sectie. Toegevoegd: stap-voor-stap flow voor Settings,
Backlog en Solo schermen.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Living document onder docs/plans/v1-readiness.md. Vier secties (Now/Next/
Before launch/Later) met concrete actions voor de stap van v0.9.0 → v1.0.0.
Now-kandidaten:
- Edit-icoon op Product (todo cmoq3ox51 — UI-gat)
- Sentry/error-monitoring
- Rate-limiting op alle mutation-endpoints
- Accessibility-audit (Lighthouse a11y >=95)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Vorige planlocatie (~/.claude/plans/twinkly-plotting-wombat.md) was overschreven
met ST-1209-plan; deze doc neemt het over.
Drie aanbevelingen verwerkt na evaluatie tegen huidige codebase:
- A. Gedeelde entityDialogContentClasses muteren (dekt ST-1133 + ST-1138 in één edit)
- B. Eigen route group app/(mobile)/ — nested layout kan parent-NavBar niet onderdrukken
- C. Gescheiden SplitPane cookie-key voor mobile (backlog-3-mobile)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Story 5 van PBI "Alle dialogen conform docs/patterns/dialog.md".
- lib/schemas/sprint.ts — gedeelde zod-schemas (create/dates/goal)
- actions/sprints.ts — code+fieldErrors voor 422; code: 403 voor
auth/demo errors
- StartSprintButton dialog: useDirtyCloseGuard, useDialogSubmitShortcut,
entityDialog* layout-classes; DemoTooltip op trigger; veld-niveau
errors via fieldErrors
- SprintHeader's date- en complete-dialogen: zelfde behandeling; date-
dialog krijgt dirty-guard, complete-dialog krijgt DemoTooltip op
bevestigen
- docs/specs/dialogs/sprint.md — entity-profile dat alle drie de modes
documenteert; consolidatie naar één SprintDialog component bewust
uitgesteld
- Sprint-dates tests aangepast aan nieuwe action-shape
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reframe the landing page around what makes Scrum4Me unique: code execution
stays on the developer's own hardware (laptop, NAS or VM). The Vercel UI and
Neon DB are a metadata coordination layer; source code never leaves the local
worker. Adds a mermaid-rendered architecture diagram (two-zone: Scrum4Me-stack
vs Jouw kant) with light/dark variants generated via mmdc.
Page changes (app/page.tsx):
- Hero: H1 "Plannen in de cloud. Uitvoeren op je eigen machine." + new
subhead; CTA "Hoe het werkt" replaces "Demo bekijken" (anchors to
#architectuur).
- New section §3 "Architectuur" with light/dark SVG and 4 callout-cards
(Vercel · Neon · Lokale worker · GitHub) honestly describing what each
component stores or runs.
- Feature grid: 6 cards (set C) — combines Sprint Board + Solo Paneel,
adds Lokale Claude-agents, Realtime updates, Async vraagkanaal, Todo's.
LIVE callout removed (folded into Realtime card).
- "Twee manieren"-section replaced by a Quickstart with concrete git-clone
snippet for the MCP-server.
- Handleiding: 9 → 10 steps; MCP recommended in step 8; new step 9
"Story laten uitvoeren" describing the Voer-uit / job-queue flow;
step 1 mentions QR-pairing as alternative login.
- Footer: adds link to madhura68/scrum4me-mcp alongside the app repo.
Tooling:
- New docs/diagrams/architecture.mmd (mermaid source).
- New npm script "diagrams" generates light + dark SVG via mmdc; output
committed to public/diagrams/. No prebuild hook (manual regenerate, like
prisma generate / docs:index).
- Plan + grilling outcomes captured in docs/plans/landing-local-first.md.
Tracked under Scrum4Me story cmoq2qoik0001qa175iynfnaa
(PBI Marketing & Landingspagina, cmoq2q50s0000qa174rmrjove).
Verified: npm run lint (0 new errors), npm test (379/379), npm run build OK.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bundelt vier valkuilen in de huidige agent-flow: PBI-ordering,
schema-conflicten bij parallelle migraties, branch-naam-collisies via
8-char suffix, cross-product orchestratie. Eerste is al gedekt door de
merge-policy PBI; de andere drie zijn entries onder anchor-PBI
"Agent-flow: openstaande beslissingen" (prio 4).
Lokaal commit; PR pas wanneer er meer aanverwante docs-changes zijn.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bevestigt het huidige datamodel (Product.repo_url is single) en kiest "duplicate-PBI per product" voor cross-repo werk; markeert een Initiative-laag (boven PBI) als toekomstige uitbreiding zodra de duplicatie-pijn te groot wordt.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* 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>