ST-1243: F1 schema + propagateStatusUpwards-helper voor sprint-flow
Schema-uitbreidingen voor de sprint-niveau jobflow (PBI-46): - TaskStatus, StoryStatus, PbiStatus, SprintStatus krijgen FAILED - Nieuwe enums: SprintRunStatus, PrStrategy - Nieuw SprintRun-model dat per-task ClaudeJobs groepeert - ClaudeJob.sprint_run_id koppeling + index - Product.pr_strategy (default SPRINT) - Bijhorende Prisma-migratie propagateStatusUpwards vervangt updateTaskStatusWithStoryPromotion en herevalueert de keten Task → Story → PBI → Sprint → SprintRun bij elke task-statuswijziging. Bij FAILED cancelt het sibling-jobs in dezelfde SprintRun. PBI-status BLOCKED blijft handmatig en wordt niet overschreven. Status-mappers + theme krijgen failed-token + label-uitbreidingen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ab8c3dca3f
commit
3eaaacaeb8
15 changed files with 795 additions and 146 deletions
|
|
@ -9,6 +9,24 @@ vi.mock('@/lib/prisma', () => ({
|
|||
},
|
||||
story: {
|
||||
findUniqueOrThrow: vi.fn(),
|
||||
findMany: vi.fn(),
|
||||
update: vi.fn(),
|
||||
},
|
||||
pbi: {
|
||||
findUniqueOrThrow: vi.fn(),
|
||||
findMany: vi.fn(),
|
||||
update: vi.fn(),
|
||||
},
|
||||
sprint: {
|
||||
findUniqueOrThrow: vi.fn(),
|
||||
update: vi.fn(),
|
||||
},
|
||||
claudeJob: {
|
||||
findFirst: vi.fn(),
|
||||
updateMany: vi.fn(),
|
||||
},
|
||||
sprintRun: {
|
||||
findUnique: vi.fn(),
|
||||
update: vi.fn(),
|
||||
},
|
||||
$transaction: vi.fn(),
|
||||
|
|
@ -31,6 +49,24 @@ const mockPrisma = prisma as unknown as {
|
|||
}
|
||||
story: {
|
||||
findUniqueOrThrow: ReturnType<typeof vi.fn>
|
||||
findMany: ReturnType<typeof vi.fn>
|
||||
update: ReturnType<typeof vi.fn>
|
||||
}
|
||||
pbi: {
|
||||
findUniqueOrThrow: ReturnType<typeof vi.fn>
|
||||
findMany: ReturnType<typeof vi.fn>
|
||||
update: ReturnType<typeof vi.fn>
|
||||
}
|
||||
sprint: {
|
||||
findUniqueOrThrow: ReturnType<typeof vi.fn>
|
||||
update: ReturnType<typeof vi.fn>
|
||||
}
|
||||
claudeJob: {
|
||||
findFirst: ReturnType<typeof vi.fn>
|
||||
updateMany: ReturnType<typeof vi.fn>
|
||||
}
|
||||
sprintRun: {
|
||||
findUnique: ReturnType<typeof vi.fn>
|
||||
update: ReturnType<typeof vi.fn>
|
||||
}
|
||||
$transaction: ReturnType<typeof vi.fn>
|
||||
|
|
@ -75,7 +111,14 @@ describe('PATCH /api/tasks/:id', () => {
|
|||
})
|
||||
// Default sibling state: only this task, already DONE → no story-promotion
|
||||
mockPrisma.task.findMany.mockResolvedValue([{ status: 'DONE' }])
|
||||
mockPrisma.story.findUniqueOrThrow.mockResolvedValue({ status: 'DONE' })
|
||||
mockPrisma.story.findUniqueOrThrow.mockResolvedValue({
|
||||
id: 'story-1',
|
||||
status: 'DONE',
|
||||
pbi_id: 'pbi-1',
|
||||
sprint_id: null,
|
||||
})
|
||||
mockPrisma.story.findMany.mockResolvedValue([{ status: 'DONE' }])
|
||||
mockPrisma.pbi.findUniqueOrThrow.mockResolvedValue({ id: 'pbi-1', status: 'DONE' })
|
||||
// Pass-through for $transaction so tests behave as if Prisma ran the run-fn directly.
|
||||
mockPrisma.$transaction.mockImplementation(async (run: (tx: typeof prisma) => Promise<unknown>) => {
|
||||
return run(prisma)
|
||||
|
|
@ -190,7 +233,14 @@ describe('PATCH /api/tasks/:id', () => {
|
|||
story_id: 'story-1',
|
||||
})
|
||||
mockPrisma.task.findMany.mockResolvedValue([{ status: 'DONE' }, { status: 'DONE' }])
|
||||
mockPrisma.story.findUniqueOrThrow.mockResolvedValue({ status: 'IN_SPRINT' })
|
||||
mockPrisma.story.findUniqueOrThrow.mockResolvedValue({
|
||||
id: 'story-1',
|
||||
status: 'IN_SPRINT',
|
||||
pbi_id: 'pbi-1',
|
||||
sprint_id: null,
|
||||
})
|
||||
mockPrisma.story.findMany.mockResolvedValue([{ status: 'DONE' }])
|
||||
mockPrisma.pbi.findUniqueOrThrow.mockResolvedValue({ id: 'pbi-1', status: 'READY' })
|
||||
|
||||
const res = await patchTask(...makeRequest({ status: 'done' }))
|
||||
expect(res.status).toBe(200)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue