The recompute engine replaces per-event blind handlers with a single component that reads all account state, computes what dunning status should be, and applies the minimal diff. Every event triggers a full re-evaluation.

Gather Compute Apply Emit

One engine, one truth. Every event — regardless of type — triggers the same full re-evaluation. The engine gathers all signals, computes the correct state, applies the minimal diff, and emits domain events.

TableOwnerWhat It StoresWho ReadsWho Writes
subs_dunningArea 3Dunning state per accountA3 recompute, NinjaPanelA3 recompute only
subs_accountSharedAccount flags, billing profileA1, A2, A3A1 (profiles), A3 (bad_debt flag)
subs_customerSharedStripe ↔ CF customer mappingA1, A2, A3A1 (setup), A2 (checkout)
subs_mandateArea 3Payment mandatesA3 recomputeA3 recompute
subs_stuck_eventsArea 3Unprocessed eventsA3 recompute, opsA3 recompute

Shared tables (subs_account, subs_customer) are written by multiple areas — changes require cross-team coordination.

invoice.payment_succeeded

Payment confirmed. Engine clears dunning state, resets retry counters, and removes any bad_debt flags.

invoice.payment_failed

Payment declined. Engine evaluates retry eligibility, updates dunning state, and may escalate consequences.

invoice.finalized

Invoice ready for collection. Engine checks if the account is already in dunning and adjusts state accordingly.

customer.subscription.updated

Subscription state changed. Engine re-evaluates whether dunning state is still consistent with current subscriptions.

charge.refunded

Refund processed. Engine recalculates account standing based on the updated payment history.

MetricBefore (Blind Handlers)After (Recompute Engine)
Coverage19% — each handler covers one event100% — engine evaluates all signals
ResolutionDays — manual investigationMinutes — next event triggers full recompute
DisagreementCommon — handlers overwrite each otherImpossible — one engine sees everything
19% → 100%
coverage
days → minutes
resolution
common → impossible
disagreement