docs: sync data-model, glossary en specs met huidig schema (#164)
Brengt de docs gelijk met de werkelijkheid na PBI-46/47/50/58/59/61/63 en M12. Belangrijkste fixes: - data-model.md herschreven naar prisma/schema.prisma: nieuwe entiteiten (Idea, IdeaLog, IdeaProduct, UserQuestion, ClaudeQuestion, ClaudeJob, SprintRun, SprintTaskExecution, ClaudeWorker, LoginPairing, PushSubscription, ModelPrice, ProductMember), nieuwe enums (FAILED/EXCLUDED, OPEN/CLOSED/ARCHIVED, ADMIN, etc.) en codes (PBI/ST/T/SP-N) toegevoegd; verwijderde todos-tabel verwijderd. - glossary.md: Sprint zonder "max 1 actief" (PBI-63), Story/Task incl. FAILED/EXCLUDED, Todo verwijderd, Idea/SprintRun/ClaudeJob/ verify_result toegevoegd. - project-structure.md: app/(app)/todos vervangen door ideas/insights/jobs/manual/admin/solo; api-tree volledig. - overview.md: "geen realtime in v1" en Docker-rationale herschreven — Postgres LISTEN/NOTIFY + SSE, claude_jobs als queue, opt-in Docker-deploy-flow. - functional.md: F-08 Todo-lijst -> Ideeen-laag, F-09 multi-sprint, F-10 Task-status incl. FAILED/EXCLUDED, F-11 endpoint-lijst, navigatiestructuur, datamodel-schets en Flow 3 bijgewerkt. - README.md API-tabel: /api/todos weg, ideas/jobs/users/profile/health toegevoegd, kort over realtime/auth-pair/internal/cron. - patterns + mcp-integration runbook: Todo-/ACTIVE-references vervangen door Idea/OPEN; create_todo MCP-tool note over verwijdering. Linkcheck groen (105 files), INDEX hergegenereerd (98 docs). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3842c05ae9
commit
f7464db837
12 changed files with 544 additions and 424 deletions
|
|
@ -3,7 +3,7 @@ title: "Scrum4Me — Functionele Specificatie"
|
|||
status: active
|
||||
audience: [maintainer, contributor]
|
||||
language: nl
|
||||
last_updated: 2026-05-04
|
||||
last_updated: 2026-05-08
|
||||
---
|
||||
|
||||
# Scrum4Me — Functionele Specificatie
|
||||
|
|
@ -322,31 +322,30 @@ Elke story heeft een activiteitenlog die alle door Claude Code vastgelegde stapp
|
|||
|
||||
---
|
||||
|
||||
### F-08: Todo-lijst
|
||||
### F-08: Ideeën-laag (Idea capture, grill, plan)
|
||||
|
||||
**Prioriteit:** v1 — Hoog
|
||||
**Prioriteit:** v1 — Hoog (M12 — vervangt Todo-lijst)
|
||||
**Persona:** Lars (snelle vastlegging), Dina (losse klantnotities)
|
||||
|
||||
**Omschrijving:**
|
||||
Een snelle todo-lijst voor taken die aan een specifiek product zijn gekoppeld. Todo-items kunnen worden afgevinkt en gepromoveerd naar een PBI of story in dat product. Zowel de UI als de REST API vereisen een `product_id` bij aanmaken — zodat Claude Code altijd werkt binnen de context van de actieve product backlog.
|
||||
Een idea is een gestructureerde voorganger van een PBI. De gebruiker maakt een idea snel aan (titel + optioneel product). Een agent _grilt_ het idea via een interactieve Q&A-loop (`IDEA_GRILL`-job → `grill_md`); daarna materialiseert een tweede agent het idea in een deterministisch plan (`IDEA_MAKE_PLAN`-job → `plan_md`) dat parsed wordt naar PBI + stories + tasks. De `todos`-tabel uit eerdere versies is per migratie ST-1239 gedropt en volledig vervangen door `ideas`.
|
||||
|
||||
**Acceptatiecriteria:**
|
||||
- [ ] Todo aanmaken via snel-invoerveld (Enter om op te slaan); product (dropdown) en titel verplicht
|
||||
- [ ] Todo aanmaken ook mogelijk via REST API: `POST /api/todos` (body: `{ "title": string, "product_id": string }`) — zodat Claude Code bevindingen kan vastleggen binnen de actieve product backlog
|
||||
- [ ] Todo-lijst is zichtbaar als apart scherm of persistent zijpaneel
|
||||
- [ ] Todo afvinken markeert het als afgerond (visueel doorgestreept)
|
||||
- [ ] Afgevinkte todo's blijven zichtbaar; kunnen worden gearchiveerd via "Archiveer afgeronde items"
|
||||
- [ ] Todo promoveren naar PBI: dialoog pre-selecteert het gekoppelde product (bewerkbaar), vraagt prioriteit; todo verdwijnt na promotie
|
||||
- [ ] Todo promoveren naar story: dialoog pre-selecteert het gekoppelde product (bewerkbaar), vraagt PBI en prioriteit; todo verdwijnt na promotie
|
||||
- [ ] Titel van het todo-item is vooringevuld in de promotiedialoog (bewerkbaar)
|
||||
- [ ] Promotie is niet ongedaan te maken; dialoog waarschuwt hiervoor
|
||||
- [ ] Idea aanmaken via snel-invoerveld (Enter om op te slaan); titel verplicht, product optioneel
|
||||
- [ ] Idea-lijst toont items per status (`DRAFT`, `GRILLING`, `GRILLED`, `PLAN_READY`, `PLANNED`, …)
|
||||
- [ ] Per idea kan de gebruiker een grill-job starten — agent stelt vragen via het claude-question-kanaal
|
||||
- [ ] Per idea kan de gebruiker (na succesvol grillen) een make-plan-job starten — agent produceert strict yaml-frontmatter; parse-fail = `PLAN_FAILED`
|
||||
- [ ] `PLAN_READY` toont de gegenereerde PBI/story/task-structuur als preview; bevestigen materialiseert ze in de productbacklog en zet de idea op `PLANNED`
|
||||
- [ ] Idea's zijn user-private (geen `productAccessFilter`); secundaire producten via `idea_products`
|
||||
- [ ] Demo-gebruiker kan idea's lezen maar niet schrijven of grillen
|
||||
|
||||
**Randgevallen:**
|
||||
- Geen producten aangemaakt → promotie-dialoog toont melding "Maak eerst een product aan"
|
||||
- Promoveren naar story zonder PBI's in het product → dialoog toont melding "Maak eerst een PBI aan"
|
||||
- Idea heeft geen primair product → make-plan vraagt eerst om producttoekenning voordat materialisatie kan
|
||||
- Grill-job time-out / agent crash → status valt terug naar `GRILL_FAILED`; gebruiker kan opnieuw grillen
|
||||
- Plan-output past niet in het strict yaml-format → `PLAN_FAILED` + `IdeaLog{JOB_EVENT}` met de parse-error
|
||||
|
||||
**Data:**
|
||||
- Opgeslagen: `todos` (id, user_id, product_id, title, done, archived, created_at, updated_at)
|
||||
- Opgeslagen: `ideas`, `idea_products`, `idea_logs`, `user_questions` — zie [data-model](../architecture/data-model.md) en het [M12 plan](../plans/M12-ideas.md). Het profiel voor de IdeaDialog staat in [docs/specs/dialogs/idea.md](./dialogs/idea.md).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -356,12 +355,13 @@ Een snelle todo-lijst voor taken die aan een specifiek product zijn gekoppeld. T
|
|||
**Persona:** Lars, Dina, Remi
|
||||
|
||||
**Omschrijving:**
|
||||
Het Scrum Team kan een Sprint aanmaken met een Sprint Goal. Per product kan er één actieve Sprint zijn. Stories worden via een gesplitst scherm vanuit de Product Backlog naar de Sprint Backlog gesleept.
|
||||
Het Scrum Team kan meerdere Sprints per product aanmaken (PBI-63), elk met een eigen Sprint Goal en stabiele `code` (`SP-N`). Een sprint-switcher in de product-header schakelt tussen sprints. Stories worden via een gesplitst scherm vanuit de Product Backlog naar de Sprint Backlog gesleept.
|
||||
|
||||
**Acceptatiecriteria:**
|
||||
- [ ] Sprint aanmaken vereist een Sprint Goal (verplicht, max. 500 tekens)
|
||||
- [ ] Sprint is gekoppeld aan een product
|
||||
- [ ] Er kan maar één actieve Sprint per product tegelijk zijn
|
||||
- [ ] Sprint is gekoppeld aan een product en krijgt automatisch een `code` (`SP-1`, `SP-2`, …) sequentieel per product
|
||||
- [ ] Een product mag tegelijk meerdere `OPEN`-sprints hebben; de sprint-switcher in de product-header bepaalt welke actief is in de UI
|
||||
- [ ] Optionele `start_date` en `end_date` op een sprint (puur planningsmetadata)
|
||||
- [ ] Sprint Backlog scherm is gesplitst: Sprint Backlog links, stories per PBI rechts
|
||||
- [ ] Rechterpaneel toont alle PBI's inklapbaar, met hun stories eronder
|
||||
- [ ] Stories die al in de Sprint zitten zijn visueel gemarkeerd en niet opnieuw sleepbaar
|
||||
|
|
@ -369,14 +369,14 @@ Het Scrum Team kan een Sprint aanmaken met een Sprint Goal. Per product kan er
|
|||
- [ ] Story in de Sprint Backlog is herrangschikbaar via drag-and-drop
|
||||
- [ ] Story uit Sprint verwijderen via contextmenu of verwijderknop → story keert terug in Product Backlog
|
||||
- [ ] Sprint Goal is bewerkbaar na aanmaken
|
||||
- [ ] Sprint afronden zet alle stories op DONE of terug op OPEN (keuze per story in afronden-dialoog)
|
||||
- [ ] Sprint afronden zet status op `CLOSED` en past stories aan volgens de afsluit-keuze (DONE of terug naar OPEN, per story in afronden-dialoog)
|
||||
|
||||
**Randgevallen:**
|
||||
- Gebruiker probeert tweede Sprint aan te maken terwijl er al een actieve Sprint is → foutmelding met link naar actieve Sprint
|
||||
- Story wordt uit Sprint verwijderd terwijl er taken aan hangen → taken blijven bestaan maar worden losgekoppeld van de Sprint
|
||||
- Sprint wordt afgerond met openstaande stories → afsluit-dialoog dwingt een keuze per story; geen impliciete defaults
|
||||
|
||||
**Data:**
|
||||
- Opgeslagen: `sprints` (id, product_id, sprint_goal, status (ACTIVE | COMPLETED), created_at, completed_at?)
|
||||
- Opgeslagen: `sprints` (id, product_id, code, sprint_goal, status (`OPEN | CLOSED | ARCHIVED | FAILED`), start_date?, end_date?, created_at, completed_at?). Voor uitvoering door agents zie ook `sprint_runs` + `sprint_task_executions` in [data-model](../architecture/data-model.md).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -395,16 +395,16 @@ In het Sprint Planning scherm worden stories uit de Sprint Backlog opgedeeld in
|
|||
- [ ] Omschrijving is optioneel (max. 1000 tekens)
|
||||
- [ ] Prioriteit is verplicht (1–4)
|
||||
- [ ] Taken zijn gerangschikt op prioriteit en volgorde; volgorde instelbaar via drag-and-drop (dnd-kit)
|
||||
- [ ] Taakstatus is instelbaar via de UI: TO_DO | IN_PROGRESS | DONE
|
||||
- [ ] Story toont een voortgangsindicator (bijv. "2/5 taken Done")
|
||||
- [ ] Taakstatus is instelbaar via de UI: `TO_DO | IN_PROGRESS | REVIEW | DONE` (plus `FAILED` en `EXCLUDED` gezet door agent-flows; zie `lib/task-status.ts`)
|
||||
- [ ] Story toont een voortgangsindicator (bijv. "2/5 taken Done"); auto-promotie van story naar DONE wanneer alle tasks DONE zijn
|
||||
- [ ] Taak verwijderen vereist bevestiging
|
||||
|
||||
**Randgevallen:**
|
||||
- Story heeft geen taken → lege staat rechts met prompt om eerste taak aan te maken
|
||||
- Alle taken van een story zijn Done → story-voortgang toont 100% maar story-status wijzigt niet automatisch
|
||||
- Alle taken van een story zijn Done → story promoot automatisch naar DONE in dezelfde transactie
|
||||
|
||||
**Data:**
|
||||
- Opgeslagen: `tasks` (id, story_id, sprint_id, title, description, priority (1–4), sort_order, status (TO_DO | IN_PROGRESS | DONE), created_at, updated_at)
|
||||
- Opgeslagen: `tasks` (id, story_id, product_id, sprint_id?, code, title, description?, implementation_plan?, priority (1–4), sort_order, status (`TO_DO | IN_PROGRESS | REVIEW | DONE | FAILED | EXCLUDED`), verify_only, verify_required, repo_url?, created_at, updated_at)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -419,13 +419,16 @@ Een REST API waarmee Claude Code stories en taken kan ophalen, de taakvolgorde k
|
|||
**Acceptatiecriteria:**
|
||||
|
||||
**Endpoints:**
|
||||
- [ ] `GET /api/health` — liveness, optioneel `?db=1` voor DB-ping (geen auth)
|
||||
- [ ] `GET /api/products` — lijst van actieve producten waarvoor de tokengebruiker eigenaar of teamlid is
|
||||
- [ ] `GET /api/products/:id/next-story` — hoogst geprioriteerde open story van de actieve Sprint
|
||||
- [ ] `GET /api/products/:id/next-story` — hoogst geprioriteerde open story van de actieve sprint
|
||||
- [ ] `GET /api/products/:id/claude-context` — bundled context (product / sprint / story / tasks) voor MCP
|
||||
- [ ] `GET /api/sprints/:id/tasks?limit=10` — eerste N taken in huidige volgorde
|
||||
- [ ] `PATCH /api/stories/:id/tasks/reorder` — accepteert geordende lijst van taak-id's
|
||||
- [ ] `POST /api/stories/:id/log` — vastleggen van implementatieplan, testresultaat of commit
|
||||
- [ ] `PATCH /api/tasks/:id` — status bijwerken (TO_DO → IN_PROGRESS → DONE) en/of `implementation_plan` opslaan
|
||||
- [ ] `POST /api/todos` — todo aanmaken vanuit Claude Code (body: `{ "title": string, "product_id": string }`)
|
||||
- [ ] `PATCH /api/tasks/:id` — status bijwerken (`todo → in_progress → review → done`) en/of `implementation_plan` opslaan
|
||||
- [ ] `GET / POST /api/ideas` en `GET / PATCH /api/ideas/:id` — idea CRUD (vervangt voormalig `POST /api/todos`)
|
||||
- [ ] `GET /api/jobs/:id/sub-tasks` — sprint-task-executions van een SPRINT_IMPLEMENTATION-job
|
||||
|
||||
**Authenticatie:**
|
||||
- [ ] Alle endpoints vereisen `Authorization: Bearer <token>` header
|
||||
|
|
@ -529,9 +532,14 @@ De app is deployable op Vercel + Neon PostgreSQL en lokaal draaibaar met een Neo
|
|||
/dashboard (productenlijst)
|
||||
/products/new (product aanmaken)
|
||||
/products/:id (Product Backlog — gesplitst scherm)
|
||||
/products/:id/sprint (Sprint Backlog — gesplitst scherm)
|
||||
/products/:id/sprint (Sprint Backlog — gesplitst scherm; sprint-switcher in product-header)
|
||||
/products/:id/sprint/planning (Sprint Planning — gesplitst scherm)
|
||||
/todos (todo-lijst)
|
||||
/solo (Solo board — Kanban per ingelogde gebruiker, top-level)
|
||||
/ideas (Idea-laag, vervangt voormalige /todos)
|
||||
/ideas/:id (Idea-detail met grill / make-plan)
|
||||
/jobs (Job-queue inzicht)
|
||||
/insights (Tokenkosten + run-statistieken)
|
||||
/manual (In-app developer manual)
|
||||
/settings (profiel, account, product backlogs, rollen, API-tokens)
|
||||
/settings/tokens (API-tokenbeheer)
|
||||
|
||||
|
|
@ -599,19 +607,29 @@ Telefoon-gebruikers (UA met `Mobi`-substring) krijgen een minimale mobile-shell
|
|||
|
||||
## Datamodel (schets)
|
||||
|
||||
> Volledige tabeldefinities staan in [data-model](../architecture/data-model.md). Onderstaande tabel is een korte schets per entiteit.
|
||||
|
||||
| Entiteit | Sleutelvelden | Relaties / opmerkingen |
|
||||
|---|---|---|
|
||||
| `users` | id, username, password_hash, is_demo, bio?, bio_detail?, avatar_data?, created_at | Profielvelden optioneel; avatar opgeslagen als WebP bytea |
|
||||
| `user_roles` | id, user_id, role (enum) | Meervoudige rollen per gebruiker |
|
||||
| `api_tokens` | id, user_id, token_hash, label, revoked_at | Max. 10 actief per gebruiker |
|
||||
| `products` | id, user_id, name, description, repo_url, definition_of_done, archived | Hoogste niveau in de hiërarchie |
|
||||
| `pbis` | id, product_id, title, description, priority (1–4), sort_order | Geordend binnen prioriteitsgroep |
|
||||
| `stories` | id, pbi_id, product_id, title, description, acceptance_criteria, priority, sort_order, status, sprint_id? | Status: OPEN / IN_SPRINT / DONE |
|
||||
| `story_logs` | id, story_id, type, content, status?, commit_hash?, commit_message?, created_at | Aangemaakt via API; read-only in UI |
|
||||
| `sprints` | id, product_id, sprint_goal, status (ACTIVE / COMPLETED), created_at, completed_at? | Max. 1 actieve Sprint per product |
|
||||
| `tasks` | id, story_id, sprint_id, title, description, implementation_plan?, priority, sort_order, status | Status: TO_DO / IN_PROGRESS / DONE; implementation_plan door MCP |
|
||||
| `todos` | id, user_id, product_id, title, done, archived, created_at | Gekoppeld aan product backlog; verplicht in UI en API |
|
||||
| `product_members` | id, product_id, user_id, created_at | Many-to-many; alleen Developers; eigenaar via products.user_id |
|
||||
| `users` | id, username, email?, password_hash, is_demo, must_reset_password, active_product_id?, idea_code_counter, min_quota_pct, bio?, bio_detail?, avatar_data?, created_at | Profielvelden optioneel; avatar als WebP bytea |
|
||||
| `user_roles` | id, user_id, role (`PRODUCT_OWNER \| SCRUM_MASTER \| DEVELOPER \| ADMIN`) | Meervoudige rollen per gebruiker |
|
||||
| `api_tokens` | id, user_id, token_hash, label, revoked_at | Max. 10 actief per gebruiker; gekoppeld aan max. 1 ClaudeWorker |
|
||||
| `products` | id, user_id, name, code?, description, repo_url, definition_of_done, auto_pr, pr_strategy, archived | Hoogste niveau; eigenaar + members |
|
||||
| `pbis` | id, product_id, code, title, description, priority (1–4), sort_order, status (`READY \| BLOCKED \| FAILED \| DONE`), pr_url?, pr_merged_at? | Geordend binnen prioriteitsgroep; auto-DONE bij sprint-close |
|
||||
| `stories` | id, pbi_id, product_id, sprint_id?, assignee_id?, code, title, description, acceptance_criteria, priority, sort_order, status (`OPEN \| IN_SPRINT \| DONE \| FAILED`) | Auto-promotie als alle tasks DONE |
|
||||
| `story_logs` | id, story_id, type (`IMPLEMENTATION_PLAN \| TEST_RESULT \| COMMIT`), content, status?, commit_hash?, commit_message?, metadata?, created_at | Aangemaakt via API; read-only in UI |
|
||||
| `sprints` | id, product_id, code, sprint_goal, status (`OPEN \| CLOSED \| ARCHIVED \| FAILED`), start_date?, end_date?, created_at, completed_at? | Meerdere sprints per product (PBI-63) |
|
||||
| `sprint_runs` | id, sprint_id, started_by_id, status (`QUEUED \| RUNNING \| PAUSED \| DONE \| FAILED \| CANCELLED`), pr_strategy, branch?, pr_url?, pause_context?, previous_run_id? | Eén run per uitvoering; chained retries |
|
||||
| `tasks` | id, story_id, product_id, sprint_id?, code, title, description?, implementation_plan?, priority, sort_order, status (`TO_DO \| IN_PROGRESS \| REVIEW \| DONE \| FAILED \| EXCLUDED`), verify_only, verify_required, repo_url? | `code` blijft stabiel bij re-parenting |
|
||||
| `claude_jobs` | id, user_id, product_id, task_id?, idea_id?, sprint_run_id?, kind, status, claimed_by_token_id?, model_id?, tokens, plan_snapshot?, base/head_sha?, branch?, pr_url?, summary?, error?, retry_count, lease_until? | Job-queue voor agents |
|
||||
| `sprint_task_executions` | id, sprint_job_id, task_id, order, plan_snapshot, verify_required_snapshot, verify_only_snapshot, status (`PENDING \| RUNNING \| DONE \| FAILED \| SKIPPED`), verify_result?, verify_summary?, skip_reason? | Bevroren scope per SPRINT_IMPLEMENTATION-claim |
|
||||
| `claude_workers` | id, user_id, token_id (unique), product_id?, started_at, last_seen_at, last_quota_pct?, last_quota_check_at? | Live-presence per actieve agent |
|
||||
| `model_prices` | id, model_id (unique), input/output/cache_read/cache_write_price_per_1m, currency | Prijslookup voor jobs-pagina |
|
||||
| `ideas` / `idea_products` / `idea_logs` / `user_questions` | zie data-model | Idea-laag (M12); vervangt voormalige `todos` |
|
||||
| `claude_questions` | id, story_id?, task_id?, idea_id?, product_id, asked_by, question, options?, status, answer?, answered_by?, answered_at?, created_at, expires_at | Agent ↔ user vraag-kanaal (M11) |
|
||||
| `login_pairings` | id, secret_hash, desktop_token_hash, status, user_id?, desktop_ua?, desktop_ip?, expires_at, approved_at?, consumed_at? | QR-pairing-flow (M10) |
|
||||
| `push_subscriptions` | id, user_id, endpoint (unique), p256dh, auth, user_agent?, last_used_at | Web-push subscriptions |
|
||||
| `product_members` | id, product_id, user_id, created_at | Many-to-many; alleen Developers; eigenaar via `products.user_id` |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -672,17 +690,18 @@ Telefoon-gebruikers (UA met `Mobi`-substring) krijgen een minimale mobile-shell
|
|||
|
||||
---
|
||||
|
||||
### Flow 3: Todo promoveren naar story
|
||||
### Flow 3: Idea grillen en materialiseren
|
||||
|
||||
**Startpunt:** Todo-lijst
|
||||
1. Lars heeft een todo: "Voeg rate limiting toe aan de API"
|
||||
2. Hij klikt op "Promoveren → Story"
|
||||
3. Dialoog opent: product (vooringevuld met laatste product), PBI (dropdown), prioriteit
|
||||
4. Hij kiest product "Factuur-tool", PBI "Beveiliging", prioriteit 2
|
||||
5. Bevestigen → todo verdwijnt, story is aangemaakt
|
||||
6. Lars navigeert naar de Product Backlog → story staat in de juiste prioriteitsgroep
|
||||
**Startpunt:** Idea-lijst (`/ideas`)
|
||||
1. Lars maakt een idea aan: "Voeg rate limiting toe aan de API"
|
||||
2. Hij koppelt het aan product "Factuur-tool" en start een grill-job
|
||||
3. Een agent claimt de `IDEA_GRILL`-job en stelt vragen via het claude-question-kanaal — Lars antwoordt in de UI
|
||||
4. Agent eindigt met `update_idea_grill_md`; status → `GRILLED`
|
||||
5. Lars start een make-plan-job; agent produceert strict yaml-frontmatter
|
||||
6. Status → `PLAN_READY`; Lars bekijkt de preview (PBI + stories + tasks)
|
||||
7. Bevestigen materialiseert de structuur in de Product Backlog; idea-status → `PLANNED`
|
||||
|
||||
**Resultaat:** Losse gedachte is in drie stappen onderdeel van de formele Product Backlog.
|
||||
**Resultaat:** Een ruwe gedachte wordt via één gestructureerde dialoog een complete PBI-tak met stories en tasks — zonder handmatig opnieuw te tikken.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -696,9 +715,9 @@ Een gebruiker kan één product als "actief" markeren. Dit actieve product wordt
|
|||
|
||||
- **Producten** — altijd bereikbaar, toont alle producten van de gebruiker
|
||||
- **Product Backlog** — alleen klikbaar als er een actief product is
|
||||
- **Sprint** — alleen klikbaar als er een actief product is én een actieve sprint bestaat; anders tooltip "Geen actieve sprint"
|
||||
- **Sprint** — alleen klikbaar als er een actief product is én minimaal één sprint bestaat; sprint-switcher in de product-header bepaalt welke
|
||||
- **Solo** — alleen klikbaar als er een actief product is
|
||||
- **Todo's** — altijd bereikbaar
|
||||
- **Ideeën** — altijd bereikbaar (vervangt voormalig "Todo's")
|
||||
|
||||
In het midden van de NavBar staat een dropdown met de naam van het actieve product. Via deze dropdown kan de gebruiker wisselen tussen producten of naar "Producten beheren" navigeren.
|
||||
|
||||
|
|
@ -921,7 +940,7 @@ export async function claimAllUnassignedInActiveSprintAction(
|
|||
const session = await requireProductWriter(productId)
|
||||
|
||||
const activeSprint = await prisma.sprint.findFirst({
|
||||
where: { product_id: productId, status: 'ACTIVE' },
|
||||
where: { product_id: productId, status: 'OPEN' },
|
||||
select: { id: true },
|
||||
})
|
||||
if (!activeSprint) throw new Error('Geen actieve sprint gevonden')
|
||||
|
|
@ -1075,7 +1094,7 @@ export default async function SoloPage({
|
|||
if (!product) notFound()
|
||||
|
||||
const activeSprint = await prisma.sprint.findFirst({
|
||||
where: { product_id: id, status: 'ACTIVE' },
|
||||
where: { product_id: id, status: 'OPEN' },
|
||||
select: { id: true, sprint_goal: true },
|
||||
})
|
||||
if (!activeSprint) return <NoActiveSprint product={product} />
|
||||
|
|
@ -1353,7 +1372,7 @@ Inhoud:
|
|||
|
||||
### 7h. `<NoActiveSprint>` — empty state
|
||||
|
||||
Geen ACTIVE sprint: nette empty-state met titel, korte uitleg en link naar productpagina om er een te starten (ST-302 stappen).
|
||||
Geen OPEN sprint: nette empty-state met titel, korte uitleg en link naar productpagina om er een te starten (ST-302 stappen).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -1413,7 +1432,7 @@ Eenvoudig nu we weten dat `isDemo` in de sessiecookie zit:
|
|||
3. **DndContext** — wrap kaarten zonder `useDraggable` als `isDemo`, of zet `disabled` op de hele context.
|
||||
|
||||
**Seed-vereiste:** in `prisma/seed.ts` (ST-004) zorgen dat de demo-user (`is_demo = true`) een product heeft met:
|
||||
- Een ACTIVE sprint
|
||||
- Een OPEN sprint
|
||||
- Stories met `assignee_id = demoUser.id` en bijbehorende taken in alle drie statussen (om bord werkend te tonen)
|
||||
- Minstens 1 ongeclaimde story (om "Toon openstaande" te demonstreren — demo-user kan niet claimen, ziet wel hoe het werkt)
|
||||
|
||||
|
|
@ -1428,7 +1447,7 @@ Eenvoudig nu we weten dat `isDemo` in de sessiecookie zit:
|
|||
</NavLink>
|
||||
```
|
||||
|
||||
Plek: tussen "Producten" en "Todos" (of zoals layout het bepaalt). Altijd zichtbaar voor ingelogde users — geen product-context nodig, die kiest de redirect-handler zelf.
|
||||
Plek: tussen "Producten" en "Ideeën" (of zoals layout het bepaalt). Altijd zichtbaar voor ingelogde users — geen product-context nodig, die kiest de redirect-handler zelf.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue