An internal main app orchestrates the full recovery lifecycle (leads → cases → mandates → litigation → recoveries → invoices), while a multi-tenant client portal gives each tenant secure read-only visibility — the two kept in sync through a stateless webhook push architecture so clients see updates in near real-time.
Recovery operations spanned case managers, finance, and HR internally, plus creditors and law firms externally — with no real-time, secure way to keep clients in sync without polling.
Clients see their cases in a separate portal, so every change in the main app has to reach it, and webhooks can arrive late, twice or out of order. A mirrored case must never move backwards. Creditors and law firms may only ever see their own cases, staff sign in with their company Microsoft accounts, and the team kept using the system every day while it was rebuilt.
- Two apps, one source of truthAn internal app runs the lifecycle, from lead to case, mandate, litigation, recovery and invoice. The client portal is a read-only mirror.
- Webhook push instead of pollingChanges are pushed to client environments as events. Per-case sequence numbers stop late or duplicated deliveries from moving a case backwards.
- Access enforced in the data layerRole-based access lives in the data layer, not the UI, and tenant-resolve middleware isolates every tenant.
- Company sign-in and finance toolsMicrosoft 365 / Entra ID single sign-on (OAuth 2.0 / OIDC), Zoho Books and Teams integration.
- Commissions and HR in the same systemAn affiliate commission engine with per-agreement schedules, plus contracts and goals.
- Clients follow their cases in their own portal instead of emailing for updates.
- Rebuilt while the team kept using it every day.
- One system from first lead to final invoice, with commissions and HR alongside.
Engineering write-up: Out-of-Order Webhooks: Keeping a Client Portal in Sync →




