feat(PBI-59): Sprint.code (SP-N sequentieel per product) (#153)
Voegt een verplicht code-veld toe aan Sprint, sequentieel per product (consistent met PBI-N, ST-NNN, T-N). - **Schema** — `Sprint.code String @db.VarChar(30)` + `@@unique([product_id, code])` - **Migratie** — voegt kolom toe als nullable, backfillt bestaande sprints via `ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY created_at)` als `SP-N`, en zet daarna NOT NULL + UNIQUE. - **Generator** — `generateNextSprintCode(productId)` in lib/code-server.ts volgt het patroon van story/pbi/task; createSprintAction gebruikt `createWithCodeRetry` voor race-bescherming. - **Seed** — sprint-counter per product (`SP-1`, `SP-2`, ...). Zichtbaar in: - Sprint-header (`Product › Sprint actief · SP-3`) - JobCard + JobDetailPane voor SPRINT_IMPLEMENTATION jobs - Insights: VelocityChart x-axis (compacter dan goal-truncated), AlignmentTrend tooltip, SprintInfoStrip - actions/jobs-page.ts: `sprintCode` is weer een echte code i.p.v. null Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
16f01283ef
commit
a268df3680
20 changed files with 97 additions and 29 deletions
|
|
@ -39,7 +39,8 @@ export default function JobCard({
|
|||
if (kind === 'TASK_IMPLEMENTATION') {
|
||||
titleText = taskCode && taskTitle ? `${taskCode} ${taskTitle}` : taskTitle || 'Taak'
|
||||
} else if (kind === 'SPRINT_IMPLEMENTATION') {
|
||||
titleText = sprintGoal || (sprintCode ? `Sprint ${sprintCode}` : 'Sprint')
|
||||
if (sprintCode && sprintGoal) titleText = `${sprintCode} ${sprintGoal}`
|
||||
else titleText = sprintGoal || sprintCode || 'Sprint'
|
||||
} else if (kind === 'IDEA_GRILL' || kind === 'IDEA_MAKE_PLAN') {
|
||||
titleText = ideaCode && ideaTitle ? `${ideaCode} ${ideaTitle}` : ideaTitle || 'Idee'
|
||||
} else if (kind === 'PLAN_CHAT') {
|
||||
|
|
|
|||
|
|
@ -25,8 +25,11 @@ function subjectLabel(job: JobWithRelations): { label: string; value: string } |
|
|||
if (!job.taskTitle) return null
|
||||
return { label: 'Taak', value: job.taskCode ? `${job.taskCode} ${job.taskTitle}` : job.taskTitle }
|
||||
case 'SPRINT_IMPLEMENTATION':
|
||||
if (!job.sprintGoal) return null
|
||||
return { label: 'Sprint', value: job.sprintGoal }
|
||||
if (!job.sprintGoal && !job.sprintCode) return null
|
||||
return {
|
||||
label: 'Sprint',
|
||||
value: job.sprintCode && job.sprintGoal ? `${job.sprintCode} ${job.sprintGoal}` : (job.sprintGoal ?? job.sprintCode ?? ''),
|
||||
}
|
||||
case 'IDEA_GRILL':
|
||||
case 'IDEA_MAKE_PLAN':
|
||||
case 'PLAN_CHAT':
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue