CRM: Suspension Treatment
Status: Unresolved as of 2026-05-04. We need to agree which dashboard views include suspended accounts and which don’t, and apply the rule consistently.
The issue
Section titled “The issue”Suspended accounts have ri.suspendTill set on the recurring invoice. A common pattern is suspendTill = 2100-12-31 (sentinel “indefinite suspension”) — billing is paused, no invoices issued, no cash collected, but the line is still in the CRM as Fulfilled / Completed.
None of the bridge endpoints currently filter on suspendTill. They check firstInvoiceOn, expireOn, and dateOfCancellation, but a line that’s been frozen indefinitely still passes the active-in-month test and contributes MRR.
Surfaced via Kinsella Storage (38029959) on 2026-05-04: signed Dec 2025, BizSite Network-M recurring set to suspendTill=2100-12-31 with no invoices ever issued, but nextInvoiceOn 2026-03-31 → counted as €24/mo “new client” sold by John Fownes in 2026. Not actually billing. Not a real €24.
Affected endpoints
Section titled “Affected endpoints”All three bridges share the same active-in-month logic:
| Endpoint | Suspended currently treated as… | Should they be? |
|---|---|---|
/dashboard-revenue-bridge | Active (counts toward opening/closing MRR, not lost) | ? |
/dashboard-am-bridge | Active | ? |
/dashboard-sales-rep-bridge | Active (credited as new/returned/increased sales) | ? |
/dashboard-am-portfolio | Active | ? |
/dashboard-solution-portfolio | Active | ? |
/dashboard-suspensions | Explicitly listed (this is the suspension report) | n/a |
/dashboard-check-account | Active line shown with suspendTill flag | Probably correct as-is |
The competing interpretations
Section titled “The competing interpretations”- Cash / billing view: Exclude suspended. We’re not invoicing, not collecting, not earning. Including them inflates MRR figures and hides churn risk.
- Customer view: Include suspended. They’re still our customer on paper; the AM still owns them; the sales rep still closed the deal. Excluding them shifts the number from “what we have” to “what we’re billing”.
- Mixed view: Include in account counts (it’s still an account), exclude from MRR (we’re not billing it).
Open questions to agree
Section titled “Open questions to agree”- What’s the canonical definition of “MRR” in revenue-bridge?
- “Recurring billings issued this month” → exclude suspended.
- “Recurring contracts on the books” → include.
- When does a suspension become a churn event? Currently a suspended-then-cancelled account fires “lost” only on cancellation. Should the suspension itself fire a loss with a “suspended” status?
- Should sales reps be credited for sales that immediately suspended? The Kinsella case is interesting — John genuinely closed the deal, but no money flowed.
- AM-portfolio account counts — when an AM looks at “their book”, do they expect suspended accounts in the count?
Practical impact (rough — needs measurement)
Section titled “Practical impact (rough — needs measurement)”We don’t currently have a clean count of suspended accounts in each bridge view. Quick check via /dashboard-suspensions:
curl -H "x-api-key: $KEY" \ https://fcr-dashboard-api.fcrmedia.workers.dev/dashboard-suspensions \ | jq '.accountCount, .totalSuspendedMRR'This is probably a few percent of the book — material enough to notice in a corkscrew, not enough to break trend lines.
Recommendation
Section titled “Recommendation”Hold a 15-min decision call covering:
- One canonical rule per endpoint family (bridges, portfolios)
- Whether to add a
suspendTillfilter to active-in-month or expose a?includeSuspended=trueflag - Whether suspension transitions need to be a first-class movement type in the bridges (alongside new/lost/increased/etc.)
Once decided: a single shared util applies the rule across all three bridges + portfolios. Revisit before the next financial reporting cycle.
Related
Section titled “Related”worker/src/handlers/revenue-bridge.js— active-in-month check (line ~157-174)worker/src/handlers/am-bridge.js— same checkworker/src/handlers/sales-rep-bridge.js— same checkworker/src/handlers/suspensions.js— the only endpoint that’s currently aware of suspension state- Kinsella Storage 38029959 — canonical example for the signed-but-suspended-immediately pattern