openvibers/openvibe.billing Commits

Reconcile reads service_outbox alone (the legacy outbox is empty; a later contract drops it) (#90)

OP OpenVibers committed 21 days ago · 355b3eeb5c · 1 file, +3 −2

Changes

ddiff --git a/server/reconcile.js b/server/reconcile.js
iindex 0e85555..16e7dec 100644
---- a/server/reconcile.js
++++ b/server/reconcile.js
@@@ -99,9 +99,10 @@ async function reconcile(ctx, { store = true, trigger = 'manual' } = {}) {
check('receipts.ledger', !rcptBad.length, rcptBad.length ? { offenders: rcptBad } : { transactions: rcpt.length });
const extBooked = await db.prepare('SELECT x.receipt_ref, t.id AS txn_id FROM external_receipts x JOIN transactions t ON t.receipt_ref = x.receipt_ref').all();
++ // service_outbox alone (2026-10-23): the legacy outbox has been empty since 0006 moved its rows, and a later contract
++ // migration drops it once this release is the N-1.
const extUnsent = await db.prepare(`SELECT x.receipt_ref, x.event_id FROM external_receipts x
-- WHERE x.status = 'announced' AND (x.event_id IS NULL OR NOT EXISTS (SELECT 1 FROM service_outbox o WHERE o.event_id = x.event_id)
-- AND NOT EXISTS (SELECT 1 FROM outbox legacy WHERE legacy.event_id = x.event_id AND legacy.sent_at IS NOT NULL))`).all();
++ WHERE x.status = 'announced' AND (x.event_id IS NULL OR NOT EXISTS (SELECT 1 FROM service_outbox o WHERE o.event_id = x.event_id))`).all();
const extTwice = await db.prepare(`SELECT (envelope #>> '{subject,id}') AS receipt_ref, COUNT(*) AS events FROM service_outbox
WHERE (envelope #>> '{event_type}') = 'billing.receipt.external' GROUP BY 1 HAVING COUNT(*) > 1`).all();
const extOffenders = [...extBooked.map((r) => ({ ...r, problem: 'booked in the journal' })), ...extUnsent.map((r) => ({ ...r, problem: 'announced without an outbox event' })),