Revenue Based estimates V1: 8–12% of annual revenue
Status: accepted Date: 2026-07-28 Fills the ADR-0008 follow-up (“MCA/BLOC funding range formulas”) with the V1 product rule: the Revenue Based pre-approval estimate is 8–12% of exact annual business revenue, applied identically to MCA and BLOC. SBA still never gets a pre-approval estimate (ADR-0003 / ADR-0008).Decision
- Input: a new optional
annualRevenue(exact dollars/year, operator-entered) flows through the canonical input factory (assembleUnderwritingInput) intoUnderwritingInput, and is persisted onunderwritingResults.annualRevenue. It is separate from the questionnaire’s bandedavgRevenue, which remains the eligibility input (ADR-0009). No GHL custom field in V1 — the value lives in Convex and re-underwrite carries it forward server-side (getLatestAnnualRevenueByReportIdInternal), so re-runs triggered by other field edits don’t clear estimates. - Formula:
computeRevenueBasedEstimate(convex/lib/revenueBasedEstimate.ts) returns{ low: 8%, high: 12% }of annual revenue, rounded to whole dollars; null when revenue is absent/non-positive. - Attachment:
deriveProductDecisionsattaches the identical estimate to themcaandblocProduct Decisions regardless of status — mirroring howcardEstimaterides oncard_stacking— and never tosba. - Count-once rule: Total Estimated Funding = Cards + Term Loan + Revenue Based, where the RB contribution is counted once (never MCA + BLOC summed).
lib/funding/estimatedFundingTotals.tsowns the derivation: the RB contribution comes from the first of MCA/BLOC that isqualified/qualified_conditionaland carries an estimate. - Term loan seam: until the term-loan-estimates project ships, the TL contribution comes only from the operator override (
operatorOverrides.termLoanFundingRange). The totals helper takes TL as an input, so engine-computed TL ranges will flow through with no shape change.
Context
The client overview redesign shows a Total Estimated Funding strip and per-product ranges on the Product Decisions card. Product supplied the V1 RB rule (8–12% of annual revenue). Questionnaire revenue is banded (“49,999”), too coarse for a dollar estimate, so operators enter an exact annual figure instead.Considered options
- A — Derive from banded
avgRevenuemidpoints — rejected; bands are too coarse and the top band is open-ended. - B — Exact annual revenue input + engine-computed estimate (accepted).
- C — GHL custom field as the source of truth — rejected for V1; requires per-location field creation (ops burden). Can be added later as a discovery pattern without changing the engine seam.
Consequences
- Golden persona snapshots: unchanged — personas provide no
annualRevenue, so MCA/BLOC estimates stay null. - UI must not sum MCA + BLOC into totals; use
resolveRevenueBasedContribution. - A fresh credit pull (new report) starts without annual revenue until the operator enters it again or a contact-level carry-forward ships; re-underwrites of the same report carry it forward automatically.

