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>
This commit is contained in:
parent
0d126695db
commit
48d1e11a2a
12 changed files with 2247 additions and 1 deletions
|
|
@ -527,6 +527,38 @@ curl -X POST -H "Authorization: Bearer $CRON_SECRET" \
|
|||
|
||||
---
|
||||
|
||||
## Workspace store endpoint audit (PBI-74)
|
||||
|
||||
`product-workspace-store` heeft vier `ensure*Loaded`-loaders. Deze tabel
|
||||
documenteert welke routes al bestaan en welke in Story 7 (T-870) toegevoegd
|
||||
worden. Tot dan retourneert de stub-default in vitest een lege response.
|
||||
|
||||
| Loader | URL | Status | Op te leveren in |
|
||||
|---|---|---|---|
|
||||
| `ensureProductLoaded(productId)` | `GET /api/products/:id/backlog` | **ontbreekt** | T-870 (Story 7) |
|
||||
| `ensurePbiLoaded(pbiId)` | `GET /api/pbis/:id/stories` | **ontbreekt** (en `/api/pbis` route-folder bestaat nog niet) | T-870 (Story 7) |
|
||||
| `ensureStoryLoaded(storyId)` | `GET /api/stories/:id/tasks` | **ontbreekt** (alleen `tasks/reorder` bestaat) | T-870 (Story 7) |
|
||||
| `ensureTaskLoaded(taskId)` | `GET /api/tasks/:id` | **ontbreekt** (alleen `PATCH` bestaat) | T-870 (Story 7) |
|
||||
|
||||
Vereisten voor de toe te voegen routes:
|
||||
|
||||
- Auth via `authenticateApiRequest` (Bearer-token), conform bestaande patroon.
|
||||
- Access-control via `getAccessibleProduct(productId, userId)` uit
|
||||
`lib/product-access.ts` waar de route product-context heeft.
|
||||
- `export const dynamic = 'force-dynamic'` zodat Next geen response-cache
|
||||
introduceert (T-869 in Story 7).
|
||||
- Response-shape:
|
||||
- `GET /api/products/:id/backlog` → `ProductBacklogSnapshot` (`{ product?, pbis[], storiesByPbi, tasksByStory }`).
|
||||
- `GET /api/pbis/:id/stories` → `BacklogStory[]`.
|
||||
- `GET /api/stories/:id/tasks` → `BacklogTask[]`.
|
||||
- `GET /api/tasks/:id` → `TaskDetail` (extends `BacklogTask` met `_detail: true` plus extra velden zoals `implementation_plan`, `acceptance_criteria`, `requires_opus`, `estimated_minutes`).
|
||||
- Type-bron: `stores/product-workspace/types.ts`.
|
||||
|
||||
Auth/access-control wijzigt niet — de rearchitecture raakt alleen
|
||||
client-state, niet serverlaag-security.
|
||||
|
||||
---
|
||||
|
||||
## Voorbeeldworkflow voor Claude Code
|
||||
|
||||
1. **Probe:** `GET /api/health?db=1` — bevestig dat de service en DB bereikbaar zijn.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue