createDeliverable: fall back to org default pipeline when project has none

If a deliverable is created on a project that has no `pipelineTemplateId`,
look up the org's default `PipelineTemplate` and use its stages — mirrors
the existing fallback in `createProject`. Also persists the chosen
template back onto the project so future deliverables don't re-resolve
and the deliverable detail UI can show "Pipeline: …".

Closes the gap where a deliverable created before a pipeline was attached
to its project landed with zero stages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
DJP 2026-05-12 20:12:03 -04:00
parent bdb133d49a
commit 4aa711c7ae

View file

@ -46,9 +46,39 @@ export async function createDeliverable(
});
if (!project) throw new Error("Project not found");
// Use dynamic pipeline stages if project has a template, else fall back to global
const useDynamic = !!project.pipelineTemplate;
const dynamicStages = project.pipelineTemplate?.stages ?? [];
// Default-pipeline fallback: if the project has no template attached,
// try the org's default PipelineTemplate before giving up to global
// PipelineStageTemplate seeds. Mirrors the behaviour of createProject.
let resolvedTemplate = project.pipelineTemplate;
if (!resolvedTemplate) {
const def = await prisma.pipelineTemplate.findFirst({
where: {
organizationId: project.organizationId,
isDefault: true,
isArchived: false,
},
include: {
stages: {
include: { dependsOn: true },
orderBy: { order: "asc" },
},
},
});
if (def) {
resolvedTemplate = def;
// Persist the choice on the project so subsequent deliverables don't
// re-resolve and so the deliverable detail UI can show "Pipeline: …".
await prisma.project.update({
where: { id: projectId },
data: { pipelineTemplateId: def.id },
});
}
}
// Use dynamic pipeline stages if project (or default fallback) has a
// template, else fall back to global PipelineStageTemplate seeds.
const useDynamic = !!resolvedTemplate;
const dynamicStages = resolvedTemplate?.stages ?? [];
// Always fetch global templates (needed for templateId FK even with dynamic pipelines)
const globalTemplates = await prisma.pipelineStageTemplate.findMany({