admin: mark-filed action to advance manual/admin-assisted orders to completed

Admin-assisted services (UCR, MC authority, etc.) have no automated submission,
so approving them only flips to authorization_signed and then sits there -- there
was no way to advance to completed. Add POST /mark-filed (filed_waiting_state |
completed, optional confirmation #, transactional + audit-logged) and drawer
buttons 'Mark as filed (waiting on agency)' / 'Mark completed' shown for orders in
authorization_signed / ready_to_file / filed_waiting_state. Confirmation number
is recorded into intake_data.filing_status.manual_confirmation.
This commit is contained in:
justin 2026-06-16 03:12:57 -05:00
parent 6c10c6a6cd
commit bf69960e8c
2 changed files with 94 additions and 0 deletions

View file

@ -611,6 +611,74 @@ router.post("/api/v1/admin/compliance-orders/:order_number/rearm-intake", requir
}
});
/**
* POST /api/v1/admin/compliance-orders/:order_number/mark-filed
* Advance an order's fulfillment_status after a human has handled it. Used for
* admin-assisted services (UCR, MC authority, etc.) that have no automated
* filing path: once you've filed it on the government portal, mark it
* filed_waiting_state (submitted, awaiting the agency) or completed (done).
* body: { status: 'filed_waiting_state' | 'completed', note?, confirmation? }
*/
router.post("/api/v1/admin/compliance-orders/:order_number/mark-filed", requireAdmin, async (req, res) => {
const id = req.params.order_number;
const ALLOWED = new Set(["filed_waiting_state", "completed"]);
try {
const status = String(req.body?.status || "");
if (!ALLOWED.has(status)) {
res.status(400).json({ error: "status must be filed_waiting_state or completed." });
return;
}
const { rows } = await pool.query(
`SELECT order_number, fulfillment_status FROM compliance_orders WHERE order_number = $1`,
[id],
);
const order = rows[0];
if (!order) { res.status(404).json({ error: "Order not found." }); return; }
const confirmation = (req.body?.confirmation as string) || "";
const note = (req.body?.note as string)
|| `Marked ${status} by admin${confirmation ? ` (confirmation: ${confirmation})` : ""}`;
const client = await pool.connect();
try {
await client.query("BEGIN");
await client.query(
`UPDATE compliance_orders
SET fulfillment_status = $2, fulfillment_status_at = now(), updated_at = now()
WHERE order_number = $1`,
[id, status],
);
// Record the confirmation number into intake_data.filing_status when given.
if (confirmation) {
await client.query(
`UPDATE compliance_orders
SET intake_data = jsonb_set(
jsonb_set(COALESCE(intake_data, '{}'::jsonb), '{filing_status}',
COALESCE(intake_data->'filing_status', '{}'::jsonb)),
'{filing_status,manual_confirmation}', to_jsonb($2::text))
WHERE order_number = $1`,
[id, confirmation],
);
}
await client.query(
`INSERT INTO order_audit_log (order_type, order_id, order_number, action, from_status, to_status, actor_type, actor_id, actor_name, note)
VALUES ('compliance', 0, $1, 'marked_filed', $2, $3, 'admin', $4, $5, $6)`,
[id, order.fulfillment_status, status, req.admin!.id, req.admin!.username, note],
);
await client.query("COMMIT");
} catch (txErr) {
await client.query("ROLLBACK").catch(() => {});
throw txErr;
} finally {
client.release();
}
res.json({ success: true, order_number: id, status });
} catch (err) {
console.error(`[admin/compliance-orders] mark-filed error for ${id}:`, err);
res.status(500).json({ error: "Mark-filed failed." });
}
});
// ── Document discovery + viewing ─────────────────────────────────────────────
//
// Every prepared/signed filing PDF lives in MinIO. We surface them so you can