A real-time, AI-assisted client intake platform for personal injury law firms
A browser softphone, unified inbox and live compliance workspace, where a missed call or a missed consent rule costs a firm a client.
- Domain
- Legal tech, B2B SaaS
- My role
- Frontend owner, web and mobile
- Stack
- React 19, TypeScript, Vite, WebSockets, WebRTC, Web Push, Puppeteer, React Native, Expo
Product and client details anonymized; UI recreated with fictional data.
Context
When someone is hurt in an accident and calls a personal injury firm, the first few minutes decide whether they become that firm’s client. This platform handles a firm’s client intake end to end. An AI voice and chat agent answers calls and website chats, qualifies the caller, and hands off to human intake specialists. The staff app manages everything after that: the live call, every message thread, the lead, the documents and the firm’s settings.
My role
I’ve owned the web frontend for over a year, and I recently started the companion mobile app. Two other engineers build the backend and the AI agent. I work from their API guides, then implement, verify and ship. The backend and the AI agent are theirs. My part is everything the specialists, admins and callers touch.
The problem
Intake work is real-time and unforgiving. A specialist might be on one call while two more ring, a text thread waits for a reply and the AI is mid-conversation with someone else. Every one of those moments carries a rule: was the recording disclosed, did this person consent to texts, is there a conflict of interest, is a filing deadline close? A missed call costs the firm a client. A missed consent rule creates legal risk.
So the frontend has two jobs that pull against each other. It has to be fast and calm under load, and it has to make the right action obvious and the wrong one impossible.
Key decisions
One event stream, one call room
The UI listens to a single WebSocket event stream for everything that changes (calls, messages, the AI’s classification, compliance checks) and joins a WebRTC room for the call audio itself. The tradeoff is that the client has to keep many screens consistent with a stream of changes, which takes more care than pages that simply request and render. In return, every screen updates the moment anything changes.
Rules in the interface, not in people’s heads
Consent, messaging windows and deadlines are enforced where the action happens. The composer locks SMS until texting consent exists, and WhatsApp falls back to approved templates outside its 24-hour window. That adds UI states to design and test for every channel, but specialists don’t have to remember the rules under pressure.
Verify against the real API, with every write mocked
Every feature is verified in a headless Chrome suite against the real development API, with all writes mocked, so a test can never text, call or email a real person. Mocking writes for each new endpoint costs time up front. It also means each release is checked against the API it will actually talk to.
What I built
What does a specialist see when the phone rings?
A recreated call with fictional data. Answer it and watch the workspace fill in. Sound is off unless you turn it on.
Chapter 1: a browser-based intake desk
Incoming calls ring the right specialists through sound, a flashing tab title, a favicon badge and browser notifications. Specialists can answer, hold and transfer (warm or cold, with a brief for the receiver), pass a call to a teammate or back to the AI, run three-way calls, and listen in on the AI’s calls.
Beside the call, a live workspace shows the compliance checks (recording disclosure, texting consent, conflict check, filing deadline), the AI’s live classification and suggested next lines. When the call ends, a wrap-up autosaves with version history.
Chapter 2: one inbox for every channel
Each person gets one thread across calls, SMS, WhatsApp, email, web chat and internal notes, with @mentions for teammates. The composer handles each channel’s rules: texting-consent locks, WhatsApp’s 24-hour window and templates, a choice of sending line, attachments with size limits, saved replies and document requests.
When the AI is handling a conversation, the thread says so and offers a clear way to take over. Context cards keep deadlines, the conflict check, intake progress and key dates in view.
SMS
LockedLocked until texting consent is recorded for this person.
Outside the 24-hour window, only approved templates can be sent.
Free text, attachments within the size limit, saved replies.
Chapter 3: leads and cases
Lead pages carry a timeline and documents. Retainers and medical authorisations go out for e-signature by text or email with one-time codes. There are evidence upload links, smart follow-up chase sequences, call review and scoring, and case briefs.
Chapter 4: firm administration
Admins manage phone numbers and call routing, staff notification preferences (with Web Push through a service worker, and defaults per role), and compliance settings: recording consent per state, and per-channel TCPA consent text in several languages. Super admins get AI agent configuration, QA and sandbox testing controls, and a platform admin can switch between firms.
Chapter 5: the website chat widget
An embeddable, bilingual (English and Spanish) free-consultation flow that captures consent before anything else happens.
Chapter 6: the mobile app
The React Native and Expo app gives specialists the same desk on their phones: push-driven incoming-call ringing in the style of a messaging app, foreground toasts for call activity, a notification bell, session and secure-storage handling, an offline bar, and a Chrome-driven test harness for the web build.
How I work on it
Strict TypeScript across both codebases. I handle shared test environments carefully and write runbooks and status docs for the team. My commit messages explain the product reasoning, not just the diff.
I also triage production issues that come in through support chat. I trace each one through the API contract, then either fix it or write the backend team a precise request.
Outcome
We’ve started onboarding law firms onto the platform, and the mobile app is in active development ahead of its launch.
The platform runs a firm’s intake from the first ring to a signed retainer, in the browser and on the phone. My part of it covers six product areas: a softphone, an omnichannel inbox, lead and case management, firm administration, an embeddable widget and a mobile app, all built against an API I don’t own and verified without contacting a real person.
Stack
React 19, TypeScript, Vite, WebSockets, WebRTC, service workers and Web Push, Puppeteer; React Native with Expo.