feat(ST-1109.5): auto-mark PBI as DONE when all its stories are DONE on sprint close
Extends completeSprintAction's $transaction with PBI status cascade: - Pre-transaction: identify PBIs touched by this close (via stories.pbi_id), fetch each with all its stories - Skip PBIs already DONE; skip PBIs with 0 stories - Mark PBI DONE only when every story (post-decision) is DONE — stories outside the sprint are evaluated against their current DB status - Promote-only: never demotes a PBI that becomes "incomplete" again Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
878fa161ef
commit
a10ccc936e
1 changed files with 22 additions and 1 deletions
|
|
@ -171,10 +171,28 @@ export async function completeSprintAction(
|
|||
|
||||
const stories = await prisma.story.findMany({
|
||||
where: { id: { in: storyIds }, sprint_id: sprintId, product_id: sprint.product_id },
|
||||
select: { id: true },
|
||||
select: { id: true, pbi_id: true },
|
||||
})
|
||||
if (stories.length !== storyIds.length) return { error: 'Ongeldige Sprint-afronding' }
|
||||
|
||||
const affectedPbiIds = [...new Set(stories.map((s) => s.pbi_id))]
|
||||
const candidatePbis = await prisma.pbi.findMany({
|
||||
where: { id: { in: affectedPbiIds }, status: { not: 'DONE' } },
|
||||
select: { id: true, stories: { select: { id: true, status: true } } },
|
||||
})
|
||||
|
||||
const decisionByStoryId = new Map(entries)
|
||||
const pbiIdsToMarkDone = candidatePbis
|
||||
.filter(
|
||||
(pbi) =>
|
||||
pbi.stories.length > 0 &&
|
||||
pbi.stories.every((s) => {
|
||||
const next = decisionByStoryId.get(s.id) ?? s.status
|
||||
return next === 'DONE'
|
||||
})
|
||||
)
|
||||
.map((p) => p.id)
|
||||
|
||||
await prisma.$transaction([
|
||||
...entries.map(([storyId, status]) =>
|
||||
prisma.story.update({
|
||||
|
|
@ -185,6 +203,9 @@ export async function completeSprintAction(
|
|||
},
|
||||
})
|
||||
),
|
||||
...pbiIdsToMarkDone.map((id) =>
|
||||
prisma.pbi.update({ where: { id }, data: { status: 'DONE' } })
|
||||
),
|
||||
prisma.sprint.update({
|
||||
where: { id: sprintId },
|
||||
data: { status: 'COMPLETED', completed_at: new Date() },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue