JEISA-WEBAPP/scripts/po-photo-ingest.mjs
Dave 0b8f003f87 feat(po): add MCP server, agent-friendly PO API, and PDF rendering
- server/pb-mcp.mjs: 15-tool MCP server for purchase-order workflow
  (CRUD, suppliers, stock, customers, customer POs, validate_draft,
  generate_order_number)
- src/lib/api/purchaseOrders.ts: typed helpers shared by UI + MCP + n8n
- src/components/purchase-orders/pdf.ts: jsPDF PO generator
- src/components/purchase-orders/ViewOrderDialog.tsx: read-only dialog
- src/components/purchase-orders/AttachmentsDialog.tsx: attachment mgmt
- src/components/purchase-orders/NumberInput.tsx: numeric input
- scripts/mcp-create-po.mjs: end-to-end driver (MCP stdio smoke test)
- pocketbase/pb_migrations/1786200007_*: schema migration
- docs/MCP_AND_N8N.md: MCP + n8n integration guide

Verified end-to-end via MCP: generate_order_number → create_purchase_order
with snapshot_items for an actual quote (DRILL-19042 / 161053).
2026-09-07 11:12:13 +02:00

59 lines
No EOL
2 KiB
JavaScript

#!/usr/bin/env node
/**
* PO from photo (OCR) — CLI wrapper.
*
* node scripts/po-photo-ingest.mjs <base64-image-or-file>
*
* Delegates to the shared ingestPhotoAndCreate() helper in
* `src/lib/api/photoIngest.ts`. Real OCR providers (OpenAI Vision /
* Google Document AI / AWS Textract) live in that module; the CLI just
* wires input + auth + output.
*
* Required env:
* POCKETBASE_URL defaults to https://pb.jeistk.apphub.co.za
* POCKETBASE_ADMIN_EMAIL defaults to david@wfsales.co.za
* POCKETBASE_ADMIN_PASSWORD defaults to 1234567890
* OCR_PROVIDER openai | google | textract | stub (default stub)
* OPENAI_API_KEY required for openai
*/
import fs from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import PocketBase from 'pocketbase';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const ROOT = path.resolve(__dirname, '..');
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';
async function main() {
const input = process.argv[2];
if (!input) {
console.error('Usage: node scripts/po-photo-ingest.mjs <file-or-base64-string>');
process.exit(2);
}
let image: Buffer;
try {
image = await fs.readFile(input);
} catch {
image = Buffer.from(input.replace(/^data:[^;]+;base64,/, ''), 'base64');
}
const pb = new PocketBase(PB_URL);
await pb.admins.authWithPassword(PB_EMAIL, PB_PASSWORD);
const photoUrl = pathToFileURL(path.join(ROOT, 'src/lib/api/photoIngest.ts')).href;
const photo = await import(photoUrl);
const result = await photo.ingestPhotoAndCreate({ pb, image, mimeType: 'image/png' });
console.log(JSON.stringify({ ok: true, ...result }, null, 2));
}
main().catch((err) => {
console.error(err?.message || err);
process.exit(1);
});