// Add POS pricing and purchase-cost history fields to the stock schema. // Idempotent: safe to run more than once. /* eslint-disable */ import PocketBase from "pocketbase"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; 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 match = trimmed.match(/^([A-Z0-9_]+)\s*=\s*(.+)$/i); if (match && !process.env[match[1]]) { process.env[match[1]] = match[2].replace(/^['"]|['"]$/g, "").trim(); } } } catch { // Fall back to environment variables already supplied by the shell. } } loadEnvFile(".env"); loadEnvFile(".env.local"); 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( "Set NEXT_PUBLIC_POCKETBASE_URL, PB_ADMIN_EMAIL and PB_ADMIN_PASSWORD.", ); } const pb = new PocketBase(url); await pb.collection("_superusers").authWithPassword(email, password); const stockItems = await pb.collections.getOne("stock_items"); const categories = await pb.collections.getOne("categories"); const stockItemFields = (stockItems.fields ?? []) as Array< Record >; const existingStockNames = new Set( stockItemFields.map((field) => field.name), ); const additions: Array> = [ { name: "cost_price", type: "number", required: false, options: { min: 0, noDecimal: false }, }, { name: "selling_price", type: "number", required: false, options: { min: 0, noDecimal: false }, }, { name: "markup", type: "number", required: false, options: { min: 0, noDecimal: false }, }, { name: "category", type: "relation", required: false, collectionId: categories.id, cascadeDelete: false, maxSelect: 1, }, { name: "cost_history", type: "json", required: false, options: { maxSize: 0 }, }, ]; const missingStockFields = additions.filter( (field) => !existingStockNames.has(field.name), ); if (missingStockFields.length > 0) { await pb.collections.update(stockItems.id, { fields: [...stockItemFields, ...missingStockFields], }); console.log( `Added stock_items fields: ${missingStockFields.map((f) => f.name).join(", ")}`, ); } else { console.log("stock_items pricing fields already exist"); } const ledger = await pb.collections.getOne("stock_ledger"); const ledgerFields = (ledger.fields ?? []) as Array>; if (!ledgerFields.some((field) => field.name === "unit_cost")) { await pb.collections.update(ledger.id, { fields: [ ...ledgerFields, { name: "unit_cost", type: "number", required: false, options: { min: 0, noDecimal: false }, }, ], }); console.log("Added stock_ledger.unit_cost"); } else { console.log("stock_ledger.unit_cost already exists"); } } main().catch((error) => { console.error("[add-stock-pricing-fields] failed:", error); process.exit(1); });