// Quick live timing of the dashboard's PocketBase calls. import { performance } from "node:perf_hooks"; import PocketBase from "pocketbase"; async function main() { const url = process.env.NEXT_PUBLIC_POCKETBASE_URL || "http://127.0.0.1:8090"; const email = process.env.PB_ADMIN_EMAIL; const password = process.env.PB_ADMIN_PASSWORD; if (!email || !password) { console.error("Missing PB_ADMIN_EMAIL / PB_ADMIN_PASSWORD"); process.exit(1); } const pb = new PocketBase(url); await pb.collection("_superusers").authWithPassword(email, password); console.log("PB:", url); const twelveWeeksAgo = new Date(Date.now() - 84 * 24 * 60 * 60 * 1000).toISOString(); const startOfMonth = new Date(new Date().getFullYear(), new Date().getMonth(), 1).toISOString(); type Timed = { label: string; ms: number; count?: number }; const results: Timed[] = []; const measure = async (label: string, fn: () => Promise<{ items?: unknown[]; totalItems?: number } | unknown[]>) => { const a = performance.now(); try { const r = (await fn()) as { items?: unknown[]; totalItems?: number } | unknown[]; const b = performance.now(); const count = Array.isArray(r) ? r.length : Array.isArray(r?.items) ? (r.items as unknown[]).length : r?.totalItems; results.push({ label, ms: b - a, count }); } catch (e) { const b = performance.now(); console.log(`!! ${label} ERR ${(e as { message?: string })?.message ?? ""}`); results.push({ label, ms: b - a, count: -1 }); } }; console.log("\n--- Sequential timing of each dashboard call ---"); await measure("customers total count", () => pb.collection("customers").getList(1, 1)); await measure("quotes active count", () => pb.collection("quotes").getList(1, 1, { filter: '(status = "new" || status = "claimed" || status = "processed" || status = "emailed" || status = "approval_pending") && is_template != true', }) ); await measure("orders this month count", () => pb.collection("orders").getList(1, 1, { filter: `created >= "${startOfMonth}"` }) ); await measure("follow-ups getFullList", () => pb.collection("quotes").getFullList({ filter: `follow_up_due != "" && follow_up_due <= "${new Date().toISOString()}" && status != "complete" && status != "cancelled" && status != "rejected" && is_template != true`, sort: "follow_up_due", expand: "customer", }) ); await measure("quotes 500 + customer expand", () => pb.collection("quotes").getList(1, 500, { filter: "is_template != true", expand: "customer" }) ); await measure("orders 12w 500", () => pb.collection("orders").getList(1, 500, { sort: "-created", filter: `created >= "${twelveWeeksAgo}"` }) ); await measure("customers 12w 500", () => pb.collection("customers").getList(1, 500, { sort: "-created", filter: `created >= "${twelveWeeksAgo}"` }) ); await measure("order_items month 500", () => pb.collection("order_items").getList(1, 500, { filter: `created >= "${startOfMonth}"` }) ); await measure("order_items 12w 500", () => pb.collection("order_items").getList(1, 500, { filter: `created >= "${twelveWeeksAgo}"` }) ); await measure("quotes 12w 500", () => pb.collection("quotes").getList(1, 500, { filter: `created >= "${twelveWeeksAgo}" && is_template != true` }) ); await measure("stock_items FULL LIST", () => pb.collection("stock_items").getFullList()); console.log("\nlabel ms rows/total"); console.log("------------------------------------------------------ -------"); let totalMs = 0; for (const r of results) { totalMs += r.ms; console.log(`${r.label.padEnd(45)} ${r.ms.toFixed(0).padStart(6)} ${String(r.count ?? "-").padStart(8)}`); } console.log("------------------------------------------------------ -------"); console.log(`TOTAL sequential: ${totalMs.toFixed(0).padStart(6)} ms`); console.log("(In the page, Promise.all parallelises these; real wall-clock ≈ slowest single call.)"); } main().catch((e) => { console.error(e); process.exit(1); });