Fundrail: one screen instead of opening every loan file
An app built around how one mortgage broker works. Calls, texts, emails and voice memos file themselves on the right client.
"I used to open every loan file each morning to see where things stood. Now one screen tells me who needs a call and what documents are missing."
Independent mortgage broker

What changed
The situation
The broker works three licensed roles at once. His mornings started in the loan system, opening each file one by one. Follow-ups slipped, and documents arrived in pieces across email and text.
Off-the-shelf CRMs wanted him to type everything in. His work happens on the phone.
What I built
One list from first call to closing
Every client sits on a single list with the next step, open tasks and quiet days in view.
Touches file themselves
A recorded call, a text, an email or a voice memo lands on the right client automatically, with a plain-English summary.
Promises become tasks
"I'll send the pay stubs Friday" turns into a dated task, owned by the right person, without duplicates.
An off-track list ranked by what's at stake
Clients who've gone quiet too long for their stage rise to the top, sorted by how much is at risk. An optional Monday digest can land before the week starts.
Compliance reminders, not roadblocks
The app warns on files that need attention under the rules he works under. It never blocks him.
The rule that makes it trustworthy
AI suggests; the broker decides. The system never moves a client between stages on its own. It flags a suggestion and waits for a yes. Every number traces back to the call or message it came from.
Why custom, and why now
When the tool fits the day, he uses it, and the morning file-by-file review goes away. Because the whole stack is one template, the same system can be stood up for a second broker in its own account in an afternoon.
How it fits together
The app, a small intake function, a queue and a worker that handles transcription, AI and filing, all in one AWS account built for this client.
Colors follow AWS service categories; grey is outside the account; dashed lines are background paths. Swipe the diagram sideways.
Step by step
- The broker opens the app on any device. CloudFront serves it over HTTPS from a private bucket; Cognito handles his sign-in.
- The app syncs records, uploads voice memos and asks the system to send texts or emails, all through one hook function.
- His business line (Twilio) posts call recordings and inbound texts to the same hook.
- The hook reads and writes the client record store in S3, with a lock so two changes can’t overwrite each other.
- Slow work goes onto an SQS queue, so the phone and the app always get an instant answer.
- The worker takes one item at a time, so filing is always in order.
- Audio goes to Transcribe. When the transcript is ready, EventBridge puts it back on the queue.
- Bedrock (Claude) reads the transcript and pulls out the summary, promises, meetings and any stage suggestion.
- Deterministic rules match the client, file the touch, turn promises into tasks and save the record.
- Emails go out as the broker through Gmail, meetings go to his calendar, and the optional Monday digest goes out through SES.
Technical details
For your IT person: components, trade-offs and security. Open any section.
Components
| Layer | Service | What it does here |
|---|---|---|
| Edge | CloudFront, S3, ACM | Serves the single-page app from a private bucket over TLS 1.2+ on a custom domain. DNS stays in Cloudflare, set to DNS only. |
| Identity | Cognito | Personal sign-ins for the broker and for me as admin. There are no shared passwords. |
| Intake | Lambda (function URL) | One hook handles app sync, memo and transcript uploads, and Twilio call and text webhooks. It authenticates each caller, stores media, queues work and returns at once. |
| Queue | SQS + dead-letter queue | Separates intake from processing. Anything that fails repeatedly moves to the dead-letter queue and raises an alarm instead of vanishing. |
| Processing | Lambda worker | Sends each item to the right step by type: audio, text, email poll, calendar, digest. Concurrency is capped at one, so filing happens in order. |
| Speech | Amazon Transcribe | Asynchronous transcription of recorded calls and voice memos. Its completion event comes back through EventBridge. |
| AI | Amazon Bedrock (Claude) | Structured extraction: summary, promises with owner and due date, meetings, risk flags and a suggested stage. The prompt is version-controlled with the code. |
| Records | S3 (versioned) | Clients, touches, tasks and meetings in one document with an optimistic lock. Every prior version can be recovered. |
| Schedules | EventBridge | A Gmail poll every five minutes, the optional Monday digest, and Transcribe job events. |
| Outbound | Twilio, Gmail API, Calendar API, SES | Texts from the business number, email sent as the broker, calendar events, and the weekly digest. |
| Secrets | Systems Manager Parameter Store | Encrypted API keys and tokens, read when a function starts. Nothing secret lives in the code. |
| Operations | CloudWatch, SNS, Budgets, CloudTrail | Alarms on errors and on the dead-letter queue, a dashboard, a monthly spending cap and a full audit trail. |
| Delivery | CloudFormation (SAM) | One template builds the whole stack. Sandbox and production run as separate stacks, and an offline test harness drives every route with stubbed services. |
Design decisions and trade-offs
Security and privacy
- The client's data lives in an AWS account that is his alone, not in a shared multi-customer database.
- Buckets are private. Only CloudFront can read the app files, and only the functions can touch records.
- Each function has a role scoped to exactly what it needs.
- Recorded calls play an announcement first, and each record notes that it did.
- Alerts go to business channels only, never to a personal inbox.
- CloudTrail keeps an audit log of every change to the account.
The public demo
The live demo runs the real app code in your browser. The storage, queue and AI steps are replaced with in-browser stand-ins, and the data is a fictional brokerage. Nothing you type leaves your browser. The build fails if any real client detail slips in.
What's next
- Native lead capture, so the third-party lead tool can be retired.
- Tighter sync with the loan system.
- A records database for multi-broker use.
Want something like this?
Tell me how the work moves today. I'll tell you what I'd build and what it would cost.
