// scripts/migrations/2026-07-15-add-stock-line-drv-id.ts // // One-shot schema migration: add a `drv_id` relation field to // `stock_purchase_items`, pointing at the `users` auth collection. // Mirrors `order_items.drv_id` so the collection-pool page can // assign a driver to a stock line the same way it does for a // customer line. The field is optional because stock lines in // `collection_pool` (unassigned) don't have a driver yet. // // Idempotent: re-running is a no-op when the field is already // present. // // NOTE: We construct the PB client INLINE (instead of importing // `getAdminPocketBase` from `@/lib/server/pocketbase-admin`) so // the env-file loader below can run BEFORE the PB client reads // `process.env.NEXT_PUBLIC_POCKETBASE_URL` at module-load time. // Otherwise the client connects to the localhost fallback. /* eslint-disable */ import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import PocketBase from "pocketbase"; function loadEnvFile(name: string) { try { const raw = readFileSync(resolve(process.cwd(), name), "utf8"); for (const line of raw.split("\n")) { const trimmed = line.trim(); if (!trimmed || trimmed.startsWith("#")) continue; const m = trimmed.match(/^([A-Z0-9_]+)\s*=\s*(.+)$/i); if (m && !process.env[m[1]]) { process.env[m[1]] = m[2].replace(/^["']|["']$/g, "").trim(); } } } catch { // .env.local doesn't exist — fall through; PB env vars may be // set in the shell. } } loadEnvFile(".env.local"); const COLLECTION_NAME = "stock_purchase_items"; const FIELD_NAME = "drv_id"; const USERS_COLLECTION_NAME = "users"; async function main() { const url = process.env.NEXT_PUBLIC_POCKETBASE_URL; const email = process.env.PB_ADMIN_EMAIL; const password = process.env.PB_ADMIN_PASSWORD; if (!url || !email || !password) { throw new Error( "NEXT_PUBLIC_POCKETBASE_URL, PB_ADMIN_EMAIL, PB_ADMIN_PASSWORD must be set (via .env.local or shell).", ); } const pb = new PocketBase(url); await pb.collection("_superusers").authWithPassword(email, password); // Resolve the auth collection id dynamically — matches the // pattern in 2026-07-14-create-stock.ts. const usersCol = await pb.collections.getOne(USERS_COLLECTION_NAME); 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(`[stock-line-drv-id] field already present on ${COLLECTION_NAME}`); return; } const newField = { name: FIELD_NAME, type: "relation", required: false, presentable: false, collectionId: usersCol.id, cascadeDelete: false, minSelect: 0, maxSelect: 1, }; await pb.collections.update(collection.id, { fields: [...existing, newField], }); console.log( `[stock-line-drv-id] created drv_id (relation → users) on ${COLLECTION_NAME}`, ); } main().catch((err) => { console.error("[stock-line-drv-id] failed:", err); process.exit(1); });