From 80a16e68e84f327a8fd3f8bcf1e34c8e81e2e094 Mon Sep 17 00:00:00 2001 From: DJP Date: Tue, 12 May 2026 22:54:03 -0400 Subject: [PATCH] Deliverable: persist omgJobNumber through create / update / edit pre-fill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The OMG # field was registered on the form + validator but never made it onto the prisma write — `createDeliverable` destructured a fixed list of columns and the new field wasn't on it. Same gap on the update path. Also the edit dialog never pre-filled the current value when reopening. - createDeliverable: include omgJobNumber (empty string → null). - updateDeliverable: normalise omgJobNumber the same way before passing to prisma.deliverable.update. - Deliverable detail page edit dialog: defaultValues now seeds omgJobNumber from the loaded row. Empty-string normalisation matters because of the unique-per-org constraint — two manual deliverables both clearing the field would otherwise collide on `""`. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../deliverables/[deliverableId]/page.tsx | 1 + src/lib/services/deliverable-service.ts | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/page.tsx b/src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/page.tsx index 2c1d16f..612c21c 100644 --- a/src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/page.tsx +++ b/src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/page.tsx @@ -533,6 +533,7 @@ export default function DeliverableDetailPage() { isPending={updateDeliverable.isPending} defaultValues={{ name: deliverable.name, + omgJobNumber: deliverable.omgJobNumber ?? undefined, priority: deliverable.priority, dueDate: deliverable.dueDate ? new Date(deliverable.dueDate).toISOString().slice(0, 10) diff --git a/src/lib/services/deliverable-service.ts b/src/lib/services/deliverable-service.ts index e4e9001..a10ee4e 100644 --- a/src/lib/services/deliverable-service.ts +++ b/src/lib/services/deliverable-service.ts @@ -130,6 +130,12 @@ export async function createDeliverable( const deliverable = await tx.deliverable.create({ data: { name: data.name, + // Empty string → null so the unique constraint doesn't trip + // when two manual deliverables both leave the field blank. + omgJobNumber: + data.omgJobNumber && data.omgJobNumber.trim() !== "" + ? data.omgJobNumber.trim() + : null, priority: data.priority, notes: data.notes, projectId, @@ -351,9 +357,18 @@ export async function updateDeliverable( }; } + // Normalise omgJobNumber: empty string → null so the unique-per-org + // constraint doesn't trip when two deliverables both clear the field. + const normalised: typeof data = { ...data }; + if (Object.prototype.hasOwnProperty.call(normalised, "omgJobNumber")) { + const v = (normalised as any).omgJobNumber; + (normalised as any).omgJobNumber = + typeof v === "string" && v.trim() !== "" ? v.trim() : null; + } + const deliverable = await prisma.deliverable.update({ where: { id }, - data, + data: normalised, }); // Regenerate embedding asynchronously (non-blocking)