82 lines
3.1 KiB
TypeScript
82 lines
3.1 KiB
TypeScript
|
|
/**
|
||
|
|
* Migration — create / repair the `raw_price_list` PocketBase collection.
|
||
|
|
*
|
||
|
|
* Two responsibilities:
|
||
|
|
*
|
||
|
|
* 1. Create the collection from `docs/pocketbase/raw_price_list.collection.json`
|
||
|
|
* if it doesn't exist. Schema is the single source of truth; this script
|
||
|
|
* strips the leading `_comment` keys before sending to PB.
|
||
|
|
*
|
||
|
|
* 2. On a pre-existing collection (the user's case — the live PB had the
|
||
|
|
* collection already, but with PB's default `null` superuser-only rules),
|
||
|
|
* relax the rules to `@request.auth.id != ''` so any logged-in user can
|
||
|
|
* CRUD. We DON'T touch the schema on a pre-existing collection — the
|
||
|
|
* field names there are the source of truth (the live one uses
|
||
|
|
* `supplier_file` and `supplier_name` as a relation).
|
||
|
|
*
|
||
|
|
* Idempotent — safe to re-run.
|
||
|
|
*
|
||
|
|
* Run with:
|
||
|
|
* npm run pb:migrate:raw-price-list
|
||
|
|
*/
|
||
|
|
import fs from "node:fs";
|
||
|
|
import path from "node:path";
|
||
|
|
import PocketBase from "pocketbase";
|
||
|
|
|
||
|
|
const PB_URL = process.env.NEXT_PUBLIC_POCKETBASE_URL || "http://127.0.0.1:8090";
|
||
|
|
const ADMIN_EMAIL = process.env.PB_ADMIN_EMAIL;
|
||
|
|
const ADMIN_PASSWORD = process.env.PB_ADMIN_PASSWORD;
|
||
|
|
|
||
|
|
if (!ADMIN_EMAIL || !ADMIN_PASSWORD) {
|
||
|
|
throw new Error("PB_ADMIN_EMAIL and PB_ADMIN_PASSWORD are required.");
|
||
|
|
}
|
||
|
|
|
||
|
|
const ROOT = path.resolve(process.cwd(), "docs", "pocketbase");
|
||
|
|
|
||
|
|
const AUTH_RULE = "@request.auth.id != ''";
|
||
|
|
|
||
|
|
async function main() {
|
||
|
|
const pb = new PocketBase(PB_URL);
|
||
|
|
await pb.collection("_superusers").authWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD);
|
||
|
|
|
||
|
|
const existing = await pb.collections.getList(1, 1, { filter: `name = "raw_price_list"` });
|
||
|
|
|
||
|
|
if (existing.items.length === 0) {
|
||
|
|
// ── Create from schema file ─────────────────────────────────
|
||
|
|
const def = JSON.parse(
|
||
|
|
fs.readFileSync(path.join(ROOT, "raw_price_list.collection.json"), "utf8"),
|
||
|
|
);
|
||
|
|
const sanitized = JSON.parse(
|
||
|
|
JSON.stringify(def, (key, value) => (key.startsWith("_") ? undefined : value)),
|
||
|
|
);
|
||
|
|
delete sanitized.id; // let PB assign its own 15-char id
|
||
|
|
|
||
|
|
const created = await pb.collections.create(sanitized);
|
||
|
|
console.log(`Created raw_price_list (${created.id}) with auth rules = @request.auth.id != ''`);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── Pre-existing collection: relax the rules ─────────────────
|
||
|
|
const col = existing.items[0];
|
||
|
|
const updates: Record<string, unknown> = {};
|
||
|
|
if (col.listRule !== AUTH_RULE) updates.listRule = AUTH_RULE;
|
||
|
|
if (col.viewRule !== AUTH_RULE) updates.viewRule = AUTH_RULE;
|
||
|
|
if (col.createRule !== AUTH_RULE) updates.createRule = AUTH_RULE;
|
||
|
|
if (col.updateRule !== AUTH_RULE) updates.updateRule = AUTH_RULE;
|
||
|
|
if (col.deleteRule !== AUTH_RULE) updates.deleteRule = AUTH_RULE;
|
||
|
|
|
||
|
|
if (Object.keys(updates).length === 0) {
|
||
|
|
console.log(`raw_price_list (${col.id}) already has correct auth rules, nothing to do.`);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
await pb.collections.update(col.id, updates);
|
||
|
|
console.log(`Relaxed raw_price_list (${col.id}) auth rules → ${AUTH_RULE}`);
|
||
|
|
console.log("Pricelist migration complete.");
|
||
|
|
}
|
||
|
|
|
||
|
|
main().catch((err) => {
|
||
|
|
console.error(err);
|
||
|
|
process.exit(1);
|
||
|
|
});
|