Skip to main content

Idea Financial term-loan submit: config readiness and E2E acceptance

Status: acceptance runbook (FM-2496)
Target: 2026-09-16, contingency 2026-09-17
Last updated: 2026-09-14

Scope

PR #1675 shipped the Idea Financial destination in the term-loan Submit dialog behind the location-scoped Labs card idea-financial-term-loan (visible to every location, off by default). One destination per Submit: the offer marketplace (Engine, unchanged) or Idea Financial. The Idea branch runs synchronously on Submit: sign in (client credentials) → create application → upload the newest bank statements on file (up to 4, one at a time) and a separate signed application → push. This runbook covers only that slice. Not in scope: Credibly, line of credit, offer accept, checkout requirements, Agents UI, webhooks, retries, billing. Status polling and the offer-page handoff landed later under FM-2711 (convex/ideaFinancialStatus.ts): one read right after submit, then a 15-minute sweep for up to 30 days per application.

What is in the repo

Configuration

Six Convex deployment variables. Set them on the deployment under test with bunx convex env set NAME value (add --prod only with explicit approval for the production write). While any is unset, Submit to Idea reports “Idea Financial is not set up for this account yet” and sends nothing. Deployment state observed 2026-09-14 (read-only):
  • Worktree dev deployment: ENGINE_BEARER_TOKEN set, no IDEA_FINANCIAL_* set.
  • Production: not inspectable from the agent machine (no production key). Treat as unset until someone with access runs the readiness check there.

Readiness check

The report carries hostnames and booleans only, never the client id, secret, or token. Read it as:

Turning the Labs card on

Operator: Settings → Labs → “Idea Financial business funding”. Admin: Admin → Settings → Labs, hand the card to the acceptance location. The card is visible everywhere and off by default, so no operator sees the Send To pick until it is turned on for their location.

E2E acceptance path (synthetic data only)

Run against Idea’s test tenant. Brock holds a broker-portal invite for “[API-TEST] 7 FIGURES CONSULTANT LLC” (email from Idea, 2026-08-03, subject tagged STAGING). Never submit a real person. Use a synthetic owner (name, email, phone, DOB, SSN) that Idea’s test tenant accepts and a synthetic business (name, EIN).
  1. Readiness. Run the readiness check with probeSignIn: true against the deployment and location under test. Expect configured: true, labs.enabled: true, signIn.ok: true. Save the JSON.
  2. Fixture. On a dev or preview location, create a contact with the CRM custom fields Business Name, EIN (9 digits), Business Structure, Business Address, Business City, Business State, Business ZIP, Time in Business, and Average Monthly Revenue (monetary). Upload two synthetic PDFs as bank statements and a distinct synthetic Signed Application in Documents. For the application, choose Verify Signed Application, confirm that the PDF is signed, and enter its signed date before submitting. Optionally attach a credit report so FICO is sent.
  3. Positive path. Open the client → Generate Offers → fill the form → Send To: Idea Financial. Confirm the marketplace disclosures are hidden and the Idea consent statement is shown. Submit. Expect:
    • dialog closes with success; the client page shows “Application sent to Idea Financial” with the Idea application number;
    • termLoanSubmissions row: destination: "idea_financial", status: "success", ideaFinancialApplicationId set, no SSN stored;
    • in Idea’s portal: the application exists under the configured agent with both statements and the signed application attached, then pushed to underwriting.
  4. Zero statements. Repeat on a contact with no bank statements. Expect Submit to stop before a row or partner application is created and ask for a bank statement.
  5. Missing signed application. Repeat with statements but no signed application. Expect Submit to stop before a row or partner application is created and ask for the signed application.
  6. Rejected signed application. Reject the verified application. Expect its signing evidence to be cleared and ordinary document approval to be refused; only a fresh Verify Signed Application confirmation can make it eligible again.
  7. Missing EIN. Clear the EIN custom field and Submit. Expect the dialog to stop with “Idea Financial needs the following … EIN (9 digits) …”, no row written, nothing sent.
  8. Idea rejection. Submit with a value Idea rejects (for example an EIN their validation refuses). Expect the row marked error, the operator message quoting Idea’s field message, and errorDetails holding Idea’s response body and step (never our request body).
  9. Labs off. Turn the card off for the location. Expect the Send To pick to disappear and marketplace Submit to behave exactly as before.
  10. Resubmit. From an Idea-sent file, open Resubmit. Expect no Send To pick (resubmission stays on the marketplace path).
Evidence to attach to FM-2496: the readiness JSON, the submission row(s) with errorDetails, portal screenshots for steps 3 and 7, and the test run below.

Automated evidence (already in the repo)

bun test tests/ideaFinancialAdapter.test.ts tests/ideaFinancialSubmitRouting.test.ts tests/ideaFinancialReadiness.test.ts The routing file includes an end-to-end run of the real submit action with Labs on: a fake CRM answers the contact read and a fake Idea validates the bearer token, the JSON create body (golden), the six multipart upload fields, the distinct signed-application upload, the push, and the row lifecycle, plus the missing-document, missing-business-fact, create-rejected, and retry-after-failed-push cases. The application lookup regression crosses six full 100-row pages before finding the signed application, so a 500-document window cannot silently turn a valid older file into “missing.”

Dependencies (answers needed, not code)

Known edge, documented on the operator page: a retry after a failure that happened after create leaves an earlier application in Idea’s portal. The row keeps its own id, so support can find it.

2026-09-17 contingency

If dependency 5 (credentials) is still open — 1, 3 and 4 closed on 2026-10-02 against Idea’s API docs:
  • Acceptance is limited to the automated suite and the readiness check’s “not configured” path. No live sign-in probe is run.
  • The Labs card stays off (its default), so no operator sees the Send To pick and marketplace Submit is unaffected.
  • No env is set on production. Record the open items on FM-2496 and re-run this runbook once Idea answers.