diff --git a/package.json b/package.json index 5d5a1ec..a510a8e 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,9 @@ "pb:migrate:price-list-sku-normalised": "npx tsx scripts/migrations/2026-06-30-add-price-list-sku-normalised.ts", "pb:migrate:quote-items-sku": "npx tsx scripts/migrations/2026-06-30-add-quote-items-sku-and-pricing.ts", "pb:migrate:rfq-outbound": "npx tsx scripts/migrations/2026-06-30-create-rfq-outbound.ts", - "pb:migrate:sprint-categories": "npx tsx scripts/migrations/2026-07-02-add-sprint-categories-and-claims.ts", + "pb:migrate:sprint-categories": "npx tsx scripts/migrations/2026-07-02-add-sprint-categories-and-claims.ts", "pb:migrate:po-pdf-tokens": "npx tsx scripts/migrations/2026-07-09-po-pdf-tokens.ts", + "pb:migrate:po-additional-attachments": "npx tsx scripts/migrations/2026-07-09-po-additional-attachments.ts", "smoke:counter": "npx tsx scripts/smoke/counter.ts", "smoke:counter-concurrent": "npx tsx scripts/smoke/counter-concurrent.ts", "smoke:create-from-email": "npx tsx scripts/smoke/create-from-email.ts", diff --git a/scripts/migrations/2026-07-09-po-additional-attachments.ts b/scripts/migrations/2026-07-09-po-additional-attachments.ts new file mode 100644 index 0000000..862576e --- /dev/null +++ b/scripts/migrations/2026-07-09-po-additional-attachments.ts @@ -0,0 +1,55 @@ +// scripts/migrations/2026-07-09-po-additional-attachments.ts +// +// One-shot schema migration: add an `additional_attachments` file +// field to the `purchase_orders` collection. Same shape as +// `documents` (file, multi, no PB cap, any mime type). +// +// Why this exists: the operator wants to attach supporting files +// (supplier quotes, drawings, NDAs) to a PO that travel with the +// outbound email alongside the versioned PDF. We use a separate +// field rather than stuffing extras into `documents` so the +// `documents ↔ documents_history` invariant the PDF download +// path depends on stays clean. +// +// Idempotent: re-running is a no-op when the field is already present. + +import { getAdminPocketBase } from "@/lib/server/pocketbase-admin"; + +const COLLECTION_NAME = "purchase_orders"; +const FIELD_NAME = "additional_attachments"; + +async function main() { + const pb = await getAdminPocketBase(); + + const collection = await pb.collections.getOne(COLLECTION_NAME); + const existing = (collection.fields ?? []) as Array<{ name: string }>; + if (existing.some((f) => f.name === FIELD_NAME)) { + console.log(`[po-additional-attachments] field already present on ${COLLECTION_NAME}`); + return; + } + + const newField = { + name: FIELD_NAME, + type: "file", + required: false, + presentable: false, + protected: false, + maxSelect: 0, + maxSize: 0, + mimeTypes: null, + thumbs: null, + }; + + await pb.collections.update(collection.id, { + fields: [...existing, newField], + }); + + console.log( + `[po-additional-attachments] created field on ${COLLECTION_NAME} (file, multi, any mime)`, + ); +} + +main().catch((err) => { + console.error("[po-additional-attachments] failed:", err); + process.exit(1); +}); \ No newline at end of file