Direct Lenders — V1 Implementation Plan (Two Lenders)
Status: Plan, pre-implementation. No code ships with this document. Sources:docs/direct-lenders/direct-lenders-spec.md— the full design spec (PR #1273, unmerged at time of writing). This plan is a deliberately small V1 slice of that spec, not a replacement for it.- “Lender Integration V 1.0” (Leo Kanell) — the super-broker MCA/BLOC/SBA solution doc that defines the two V1 lenders, their routing rule, ISO signup links, and required deal package. Summarized in Section 1.
VISION.md spec-gate for this plan doc only). Each implementation phase below that touches a gated surface (Convex schema, lender integrations) needs its own human-delegated task before work begins. Gated phases are marked.
1. What the V1.0 source doc decides
The “Lender Integration V 1.0” doc resolves several open questions from the design spec:
Two notes on the source doc:
- Step 9 (under the Sandbar section) says “Submit Client App & Bank statements to Lexington Capital” — read as a copy/paste typo for Sandbar, since the surrounding steps are all Sandbar. Confirm with Leo/Kevin.
- The exact-75k boundary is still undefined (spec open question #6). Default proposed here: **≥ 75k → Sandbar**, because the existing business-questionnaire revenue band
$75k–$150kalready starts at $75k (see Section 3). Confirm.
2. V1 scope philosophy: smallest complete slice
The full spec proposes a new module (top-level nav, 4 new Convex tables, eligibility engine, per-lender email templates, admin lender CRUD). V1 deliberately defers almost all of it. What makes this V1 viable at minimal cost is that the Revenue Based workflow already exists and already contains both lenders:ESTABLISHED_FUNDING_WORKFLOW_STEPSincomponents/funding/FundingWorkflow.tsxalready runs: approve → agreement → gather docs → business questionnaire → submit to partner → handoff → record commission.components/funding/establishedLenders.tsalready lists Sandbar Fund and Lexington Capital aspriority: true, status: 'broker'entries — withcontactInfo: 'TBD — onboarding in progress'.- The business questionnaire already captures a monthly-revenue band that splits exactly at $75k (
25_75kvs75_150kinEstablishedWorkflowDialog.tsx), so the routing rule needs no new data capture.
In scope (V1)
- Real catalog data for the two lenders (signup links, submission instructions, doc requirements).
- Revenue-based routing recommendation in the partner-selection step.
- Doc collection stays tax-returns-only. FM does not collect the V1.0 package via the upload link (decided 2026-07-29): bank statements are displayed as the lenders’ deal-package requirement at the submit step and sourced from the client directly. No signed application — see Section 1.
- Per-operator ISO-registration tracking (self-attested “I’m signed up” for V1).
- A submission record with manual status updates (
submitted → in_review → approved → declined → funded) and a funded rollup.
Deferred (explicitly out of V1)
lenderscatalog table + admin CRUD UI (spec open question #5) — V1 hardcodes two lenders in code config, same as today’sestablishedLenders.ts.- Top-level “Lender” nav tab (spec open question #3) — V1 lives inside the existing Revenue Based workflow and contact page.
- API/portal submission automation, per-lender email template rendering and sending — V1 submission is the operator following the lender’s own instructions; FM records that it happened.
- Eligibility engine beyond the single revenue-routing rule.
- Funding-plan product block (spec open question #2).
- LoanBud / additional lenders (spec open question #8).
3. Routing rule → existing data
The routing key is the business questionnaire’smonthlyRevenue band (components/funding/EstablishedWorkflowDialog.tsx, MONTHLY_REVENUE_BANDS), which the workflow already requires before the submit step:
The contact-level
averageMonthlyRevenue field cannot be the routing key — its $50,000 – $100,000 band straddles the $75k boundary. The questionnaire band is the source of truth; when it is missing, show both lenders with no recommendation rather than guessing.
Routing is a recommendation, not a hard filter: the recommended lender is pre-selected and badged (“Recommended — revenue under/over $75k/mo”), the other remains selectable. This keeps operator judgment in the loop and sidesteps the boundary question until confirmed.
4. Phased delivery (one PR per phase)
Phase 1 — Catalog + routing + docs package (no schema, not gated)
All code-config and UI changes inside the existing Revenue Based workflow:establishedLenders.ts: extendLenderEntrywith V1 fields (isoSignupUrl,submitInstructions,revenueRouting: 'under_75k' | 'over_75k') and fill in real data for Lexington + Sandbar from the V1.0 doc. Drop theTBD — onboarding in progressplaceholders.- Submit-to-partner dialog (
EstablishedWorkflowDialog.tsx): for the two V1 lenders, replace the Slack-message flow with a direct-submission checklist view: recommended lender from the questionnaire band (Section 3), the lender’s ISO signup link (if not yet registered), per-lender submission instructions, and the required-docs checklist read from the catalog entry. Non-V1 lenders keep the existing Slack flow untouched. - Doc collection (
gather_documentationstep): unchanged — tax returns only. (Earlier drafts added asigned_applicationdocument type and a 4-monthbank_statementcontext here; both removed 2026-07-29 — the Established workflow uses no signed application, and FM does not collect bank statements via the upload link. The lenders’ 4-month statement requirement is shown on the deal package at the submit step.) - Unit tests for the routing-band mapping and lender filtering.
Phase 2 — Schema: registrations + submissions (GATED: Convex schema change, needs Brock approval)
Minimal subset of the spec’s data model — two tables plus events, all scoped bylocationId, new fields optional:
lenderRegistrations— one per operator × lender:locationId,lenderSlug(code-config key, nolenderstable in V1),status(empty | pending | connected),connectedAt,connectedBy. V1 status is self-attested via an “I’ve signed up as an ISO” action; theerror/ineligiblestates from the spec are deferred until there is anything automated that can fail.lenderSubmissions—locationId,contactId,lenderSlug,product(mca | bloc | sba),status(submitted | in_review | approved | declined | funded),submittedAt,updatedAt,fundedAmount?,documentsSnapshot(doc ids attached at submit time).lenderSubmissionEvents— append-only audit:submissionId,type,at,actor,note?.
by_location_lender on registrations; by_location_status, by_location_lender_status, by_contact on submissions; by_submission on events. Feature flag NEXT_PUBLIC_DIRECT_LENDER_ENABLED gates the UI that writes these tables (env-level first, per the spec’s dark-launch plan).
The naming follows the spec (lenderRegistrations ≈ lenderConnections) so the full system can grow into these tables without a migration — V1 just doesn’t populate the spec’s automation-oriented fields (credentials, environment, eligibility, externalRef).
Phase 3 — Tracking UI wired to the schema
- ISO registration: in the submit-to-partner dialog, a “Mark as registered” action flips
lenderRegistrations.statustoconnected; unregistered lenders show the signup link + a “registration required before submitting” gate (mirrors today’spending_setupdisabled-card pattern). - Submission record: “Mark submitted” on the dialog creates the
lenderSubmissionsrow, snapshotting selected documents, and completes thesubmit_to_partnerworkflow step. - Manual status updates: a status control on the contact’s funding view (and the
handoff_to_lender/record_payment_receivedsteps) advances the submission;fundedprompts forfundedAmount. - Funded rollup: per-lender funded totals summed from
fundedsubmissions, displayed at the bottom of the Revenue Based view (per Robert M’s V1 notes). - Convex function tests + a manual end-to-end walkthrough (recorded) before ship.
5. Hard scope boundary (unchanged from spec)
- No changes to the Engine/MoneyLion term-loan path, card underwriting, or the 7 Figures processing-team flow. The Revenue Based workflow is the existing manual lender-paid path — extending it is additive to the correct surface.
- The Slack-message submission flow remains for all non-V1 lenders.
- No changes to
convex/lib/loanOfferCuration.ts(spec Section 5 default: separate module, no shared code).
6. Open questions for this V1
- **Exact-75k → Sandbar (matches the questionnaire band edge). Needs Leo/Kevin confirmation.
- Source-doc step 9 typo — confirm Sandbar deals go to Sandbar, not Lexington.
- Signed client application — RESOLVED 2026-07-29 (Kevin): the Established workflow does not use a signed application at all. The lender works application details directly with the client after handoff. Nothing to collect or store on FM’s side.
- Slack-flow retirement for the two V1 lenders — Phase 1 replaces the Slack ask with direct-submission instructions for Lexington/Sandbar specifically. Confirm the 7 Figures channel should no longer be the intermediary for these two. UPDATE 2026-07-29 (Kevin): all Established lenders other than Lexington and Sandbar are being retired — the Slack flow goes away with them (follow-up PR in progress).
- Schema approval — Phase 2 needs Brock’s sign-off on the three tables before implementation (VISION.md: Convex schema changes are gated).

