chore: export ensureComplianceSalesOrder for rescue/backfill use
This commit is contained in:
parent
68e6b60951
commit
e2467752dc
2 changed files with 74 additions and 1 deletions
|
|
@ -285,7 +285,7 @@ const CDR_STUDY_GRANTING_SLUGS = new Set([
|
|||
* /checkout/create-session path did, so webhook-confirmed card orders had no SO
|
||||
* and the workers logged "Sales Order not found 404".
|
||||
*/
|
||||
async function ensureComplianceSalesOrder(
|
||||
export async function ensureComplianceSalesOrder(
|
||||
orderId: string,
|
||||
orderType: string,
|
||||
rows: Record<string, unknown>[],
|
||||
|
|
|
|||
73
scripts/rescue-mitchell.mjs
Normal file
73
scripts/rescue-mitchell.mjs
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* Rescue Mitchell Allen's batch CB-95BA6C90: the 5 DOT services were paid + the
|
||||
* workers ran, but (a) no customers row (login bug, card order predates fix),
|
||||
* (b) no ERPNext Sales Order (webhook SO bug), and (c) the authorization/signing
|
||||
* emails failed (localhost:25 SMTP bug) so he never got his e-sign links.
|
||||
*
|
||||
* Now that the SMTP + SO fixes are deployed, this:
|
||||
* 1. creates his customers row (so he can log in),
|
||||
* 2. creates the ERPNext SO via the deployed ensureComplianceSalesOrder path,
|
||||
* 3. re-dispatches each service worker so the (now-working) emails go out.
|
||||
*
|
||||
* Run: docker exec performancewest-api-1 node /app/scripts/rescue-mitchell.mjs
|
||||
*/
|
||||
import pg from "pg";
|
||||
|
||||
const BATCH = "CB-95BA6C90";
|
||||
const WORKER_URL = process.env.WORKER_URL || "http://workers:8090";
|
||||
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
|
||||
|
||||
const { rows } = await pool.query(
|
||||
`SELECT order_number, service_slug, customer_email, customer_name, erpnext_sales_order, intake_data
|
||||
FROM compliance_orders WHERE batch_id=$1 ORDER BY created_at`, [BATCH]);
|
||||
if (!rows.length) { console.log("no orders for batch"); process.exit(1); }
|
||||
|
||||
const email = rows[0].customer_email.toLowerCase().trim();
|
||||
const name = rows[0].customer_name || "Customer";
|
||||
let company = null;
|
||||
try { const i = typeof rows[0].intake_data === "string" ? JSON.parse(rows[0].intake_data) : rows[0].intake_data; company = i?.company || i?.legal_name || i?.entity_name || null; } catch {}
|
||||
|
||||
// 1) customers row (portal login)
|
||||
const c = await pool.query(
|
||||
`INSERT INTO customers (email, name, company) VALUES ($1,$2,$3)
|
||||
ON CONFLICT (email) DO UPDATE SET name=COALESCE(customers.name,EXCLUDED.name), company=COALESCE(customers.company,EXCLUDED.company)
|
||||
RETURNING id, (password_hash IS NOT NULL) AS has_pw`, [email, name, company]);
|
||||
console.log(`[rescue] customers row id=${c.rows[0].id} email=${email} has_password=${c.rows[0].has_pw}`);
|
||||
|
||||
// 2) ERPNext Sales Order (reuse the deployed handlePaymentComplete SO path is internal;
|
||||
// here call the worker-friendly path: build the SO via the same helper by importing checkout)
|
||||
// Simpler + safe: re-run handlePaymentComplete is guarded (already paid -> returns early),
|
||||
// so directly create the SO using the exported ensureComplianceSalesOrder if available.
|
||||
const checkout = await import("/app/dist/routes/checkout.js");
|
||||
if (typeof checkout.ensureComplianceSalesOrder === "function") {
|
||||
await checkout.ensureComplianceSalesOrder(BATCH, "compliance_batch", rows, "card");
|
||||
console.log("[rescue] ensureComplianceSalesOrder ran");
|
||||
} else {
|
||||
console.log("[rescue] NOTE: ensureComplianceSalesOrder not exported; SO will be built-from-PG by worker (404 warning is harmless)");
|
||||
}
|
||||
|
||||
// refresh SO id
|
||||
const after = await pool.query(`SELECT order_number, service_slug, erpnext_sales_order FROM compliance_orders WHERE batch_id=$1`, [BATCH]);
|
||||
const soName = after.rows.find(r => r.erpnext_sales_order)?.erpnext_sales_order || BATCH;
|
||||
console.log(`[rescue] SO = ${soName}`);
|
||||
|
||||
// 3) re-dispatch each worker so authorization/signing emails resend (now that SMTP works)
|
||||
for (const r of after.rows) {
|
||||
try {
|
||||
const res = await fetch(`${WORKER_URL}/jobs`, {
|
||||
method: "POST", headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
action: "process_compliance_service",
|
||||
order_name: r.erpnext_sales_order || soName,
|
||||
order_number: r.order_number,
|
||||
service_slug: r.service_slug,
|
||||
}),
|
||||
});
|
||||
console.log(`[rescue] re-dispatched ${r.order_number} (${r.service_slug}) -> HTTP ${res.status}`);
|
||||
} catch (e) {
|
||||
console.log(`[rescue] dispatch error ${r.order_number}: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
await pool.end();
|
||||
console.log("[rescue] DONE");
|
||||
Loading…
Add table
Add a link
Reference in a new issue