feat(PBI-63): meerdere sprints per product + EXCLUDED + sprint-switcher (#161)

- Sprint lifecycle: ACTIVE→OPEN, COMPLETED→CLOSED, +ARCHIVED (FAILED behouden)
- TaskStatus: +EXCLUDED (overgeslagen door agent-loop via bestaande TO_DO filter)
- Cookie-gebaseerde actieve sprint per product (lib/active-sprint.ts)
- Route splitsen: /products/[id]/sprint/[sprintId] + /sprint redirect-page
- NavBar: gestapelde product/sprint dropdowns + BUILDING-badge derivatie
- Backlog selectie-modus + nieuwe-sprint-dialog (createSprintWithPbisAction)
- Migratie 20260507210000_sprint_lifecycle: ALTER TYPE RENAME (geen data-rewrite)
- Version bump 1.0.0 → 1.2.0

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Janpeter Visser 2026-05-08 00:15:04 +02:00 committed by GitHub
parent d68aa1e5e6
commit 4a9db57e94
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 966 additions and 290 deletions

View file

@ -131,15 +131,15 @@ export async function propagateStatusUpwards(
let nextStatus: SprintStatus
if (anyPbiFailed) nextStatus = 'FAILED'
else if (allPbisDone) nextStatus = 'COMPLETED'
else nextStatus = 'ACTIVE'
else if (allPbisDone) nextStatus = 'CLOSED'
else nextStatus = 'OPEN'
if (nextStatus !== sprint.status) {
await tx.sprint.update({
where: { id: sprint.id },
data: {
status: nextStatus,
...(nextStatus === 'COMPLETED' ? { completed_at: new Date() } : {}),
...(nextStatus === 'CLOSED' ? { completed_at: new Date() } : {}),
},
})
sprintChanged = true
@ -149,7 +149,7 @@ export async function propagateStatusUpwards(
// SprintRun herevalueren — via ClaudeJob.sprint_run_id van deze task
let sprintRunChanged = false
if (nextSprintStatus === 'FAILED' || nextSprintStatus === 'COMPLETED') {
if (nextSprintStatus === 'FAILED' || nextSprintStatus === 'CLOSED') {
const job = await tx.claudeJob.findFirst({
where: { task_id: taskId, sprint_run_id: { not: null } },
orderBy: { created_at: 'desc' },