Fix inconsistent line endings across all project files for cross-environment consistency. Add complete unit test suite covering core utilities, API routes, and server services. Add Playwright E2E test setup with smoke, auth, and agent API tests. Update all project configuration files to match standardized formatting. Fix MCP API error handling to properly propagate HTTP status codes and use correct JSON-RPC error codes. Add VSCode workspace configuration, extensions, and example MCP config files. Update .gitignore to exclude new test and build artifacts.
94 lines
3.1 KiB
TypeScript
94 lines
3.1 KiB
TypeScript
import PocketBase from "pocketbase";
|
|
import { readFileSync } from "fs";
|
|
import { resolve } from "path";
|
|
|
|
const PB_URL = "http://127.0.0.1:8090";
|
|
const ADMIN_EMAIL = "david.els1@outlook.com";
|
|
const ADMIN_PASSWORD = "1234567890";
|
|
|
|
const CUSTOMERS_FILE = "/Volumes/KIOXIA/Downloads/WFDASH - wfdash_customers (wfdash_customers) 2026-05-24_12-58.json";
|
|
const COMPANIES_FILE = "/Volumes/KIOXIA/Downloads/WFDASH - wfdash_company (wfdash_company) 2026-05-24_12-58.json";
|
|
|
|
function normalizeDate(val: string | null): string | null {
|
|
if (!val) return null;
|
|
return val.replace(" ", "T");
|
|
}
|
|
|
|
function parseJson(path: string): Record<string, unknown>[] {
|
|
const raw = readFileSync(resolve(path), "utf-8");
|
|
return JSON.parse(raw);
|
|
}
|
|
|
|
function chunks<T>(arr: T[], size: number): T[][] {
|
|
const result: T[][] = [];
|
|
for (let i = 0; i < arr.length; i += size) {
|
|
result.push(arr.slice(i, i + size));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
async function importCollection<T extends Record<string, unknown>>(
|
|
pb: PocketBase,
|
|
collectionName: string,
|
|
records: T[],
|
|
mapper: (r: T) => Record<string, unknown>,
|
|
) {
|
|
console.log(`\nImporting ${records.length} records into "${collectionName}"...`);
|
|
let success = 0;
|
|
let errors = 0;
|
|
|
|
for (let i = 0; i < records.length; i++) {
|
|
try {
|
|
await pb.collection(collectionName).create(mapper(records[i]), { $autoCancel: false });
|
|
success++;
|
|
} catch (err: unknown) {
|
|
errors++;
|
|
if (errors <= 3) {
|
|
const msg = err instanceof Error ? err.message : String(err);
|
|
console.error(` Error on record ${i}: ${msg}`);
|
|
}
|
|
}
|
|
if ((i + 1) % 20 === 0 || i === records.length - 1) {
|
|
const pct = Math.round(((i + 1) / records.length) * 100);
|
|
process.stdout.write(`\r Progress: ${success + errors}/${records.length} (${pct}%) | OK: ${success} | Err: ${errors}`);
|
|
}
|
|
}
|
|
console.log(`\n Done: ${success} created, ${errors} failed`);
|
|
}
|
|
|
|
async function main() {
|
|
const pb = new PocketBase(PB_URL);
|
|
console.log("Authenticating as admin...");
|
|
await pb.collection("_superusers").authWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD);
|
|
|
|
// --- Import companies ---
|
|
const companyRecords = parseJson(COMPANIES_FILE);
|
|
await importCollection(pb, "companies", companyRecords, (r) => ({
|
|
company: r.company ?? "",
|
|
address: r.address ?? "",
|
|
vendor: r.vendor ?? "",
|
|
}));
|
|
|
|
// --- Import customers ---
|
|
const customerRecords = parseJson(CUSTOMERS_FILE);
|
|
await importCollection(pb, "customers", customerRecords, (r) => ({
|
|
customer: r.customer ?? "",
|
|
email: r.email ?? "",
|
|
alternative_email: r.alternative_email ?? null,
|
|
buyer_email: r.buyer_email ?? null,
|
|
number: r.number ?? "",
|
|
company: r.company ?? "",
|
|
dateadded: normalizeDate(r.dateadded as string | null),
|
|
lastvisiteddate: normalizeDate(r.lastvisiteddate as string | null),
|
|
rep: r.rep ?? null,
|
|
coordinates: r.coordinates ?? null,
|
|
description: r.description ?? null,
|
|
}));
|
|
|
|
console.log("\n\n✅ Import complete!");
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error("Import failed:", err);
|
|
process.exit(1);
|
|
});
|