02 / Product — FinTechFeaturedCase Study

Mitigately

A greenfield debt restructuring platform connecting users with creditors through a 16–20 step intake flow, dynamic contract generation, and a legacy CRM integration that dated to 2008.

ReactTypeScriptTanstack QueryFormikMaterial UIPlaidExpressNode.jsAnvil PDFForth CRMGoogle Maps

8 months · Greenfield build · Small team

At a Glance

Users onboarded

2,400+

through full 16–20 step flow

Completion rate

~74%

up from ~41% before resume feature

API latency

−65%

after async queue for CRM sync

Timeline

8 mo

design to production

* User and completion figures are approximate. Latency improvement reflects p95 API response time after queue introduction.

The Problem

Mitigately needed to guide financially distressed users through a 16–20 step intake process — sometimes across days or weeks — and then automatically generate a legal contract, route it for e-signature, and sync everything into a legacy CRM system last meaningfully updated in 2008.

The CRM was non-negotiable: it was the authoritative source of creditor data and identity. But its APIs were partially undocumented, returned HTTP 200 for both success and failure states, and had unpredictable response structures depending on input context. Designing around it — without hiding it — became the central engineering challenge.

Constraints

CRM could not be replaced — it was the system of record for all creditor data
Sessions had to survive days or weeks — users resume exactly where they left off
CRM APIs were partially undocumented with unreliable HTTP status codes
OTP verification required before any contract could be generated or signed
Data integrity across both MongoDB and CRM had to be guaranteed at all times
UX had to remain consistent across all 16–20 dynamic onboarding steps

Architecture Overview

Frontend

Step-based state machine

Backend

Orchestration + validation layer

Persistence

Dual-write: MongoDB + CRM sync

Auth

Twilio OTP

Contract

Dynamic generation + Anvil e-sign

Post-onboarding

User dashboard + loan tracking

Key Engineering Decisions

Treating onboarding as a state machine, not a form flow

A traditional multi-step form would have collapsed under 16–20 steps with shared state, resumability, and per-step validation. I implemented a centralized step engine using React Context + Formik, where each step is an isolated validation unit within a global workflow state — index-driven, schema-validated, and type-safe throughout.

Enabled resume, skip-ahead, and validation without coupling between steps

Dual-write architecture for CRM reliability

The CRM's most fundamental API — "get user by phone number" — always returned HTTP 200 regardless of whether a user existed. Standard error handling was useless. Rather than working around individual broken endpoints, I redesigned the data layer: MongoDB became the primary operational store, and the CRM was treated as a downstream sync target. An inverted lookup (query Mongo → extract CRM ID → fetch CRM record by ID) made responses deterministic.

Eliminated unreliable CRM query responses as a failure point

Moving CRM sync off the request path

Initially, CRM writes were synchronous and blocking. Every onboarding step that touched the CRM added latency and a potential failure point to what should have been a fast user-facing response. I introduced an internal async queue: MongoDB writes remained immediate, while CRM sync executed in the background. This also meant CRM failures were isolated — they didn't take down user-facing operations.

~65% reduction in p95 API response time; CRM failures no longer surface to users

Persisting step state to the backend for resumability

Users in a debt restructuring flow may need days between sessions. Storing state only in the browser would lose it. Step progress and partial form data were persisted to the backend on each transition, so on re-entry the system could reconstruct the last completed step, partial data, and navigation state exactly.

Completion rate improved from ~41% to ~74% after this was introduced

Outcomes

  • Built a complete 16–20 step onboarding engine with persistent, resumable state from scratch in 8 months
  • Designed a stable integration layer around an unpredictable legacy CRM through dual-write + inverted lookup
  • Reduced API latency by ~65% by moving CRM sync off the synchronous request path
  • Improved onboarding completion from ~41% to ~74% with backend-persisted resumability
  • Delivered full contract generation + e-signature flow via Anvil with OTP-secured access
  • Shipped a post-onboarding dashboard with live loan status and installment tracking

Takeaway

“In real-world systems, reliability isn't achieved by waiting for perfect APIs. It's built by designing around imperfect external systems — through abstraction, persistence, and controlled synchronization. The CRM never got better. The system got resilient enough that it didn't matter.”