#!/usr/bin/env node /** * Give every quote a valid-until date: 30 days after the quote date. * * Quotes were created with an empty validUntil field, so the quote PDF * printed "Valid Until: N/A" - which reads as an unfinished document. The * quote form now defaults it to 30 days out; this brings the existing * quotes in line. * * Quotes that already have a validUntil are left untouched. * * Usage: * node scripts/backfill-quote-validity.mjs # dry run (default) * node scripts/backfill-quote-validity.mjs --apply # apply to the instance */ import PocketBase from "pocketbase"; const PB_URL = process.env.POCKETBASE_URL || "https://pb.jeistk.apphub.co.za"; const PB_EMAIL = process.env.POCKETBASE_ADMIN_EMAIL || "david@wfsales.co.za"; const PB_PASSWORD = process.env.POCKETBASE_ADMIN_PASSWORD || "1234567890"; const APPLY = process.argv.includes("--apply"); const VALID_DAYS = 30; function validUntilFor(quoteDate) { const d = new Date(quoteDate); if (Number.isNaN(d.getTime())) return null; d.setDate(d.getDate() + VALID_DAYS); return d.toISOString(); } const pb = new PocketBase(PB_URL); pb.autoCancellation(false); await pb.admins.authWithPassword(PB_EMAIL, PB_PASSWORD); const quotes = await pb.collection("quotes").getFullList(200); const updates = []; for (const quote of quotes) { if (quote.validUntil) continue; // already set - leave alone const base = quote.quoteDate || quote.created; const validUntil = validUntilFor(base); if (!validUntil) continue; updates.push({ id: quote.id, number: quote.quote_number, base, validUntil }); } console.log(`quotes: ${quotes.length}, needing a valid-until date: ${updates.length}`); for (const u of updates) { console.log(` ${u.number}: ${u.base} -> ${u.validUntil}`); } if (!APPLY) { console.log("\nDry run. Re-run with --apply to write these dates."); process.exit(0); } for (const u of updates) { await pb.collection("quotes").update(u.id, { validUntil: u.validUntil }); console.log(` updated ${u.number}`); } console.log("\nDone.");