Vernon Tech & MediaCase Study
All case studies · Product: VTM CRM
In-house build // 2026

The operating system we built to run the entire agency.

VTM CRM carries a business from the first text to a signed contract to recurring revenue in one place. No DocuSign, no separate texting app, no email tool, no invoicing vendor. One React frontend, one Postgres database, and Claude wired through the middle.

131 API endpoints50+ database tables~12 integrationsweb + mobile one codebase$0 per-signature fees
VTM CRM dashboard, cinematic render
The problem

A growing agency was renting its own workflow.

Every part of the business lived in a different tool with a different login and a different bill. A lead’s history was smeared across a pipeline app, a texting app, an inbox and a spreadsheet. Nothing talked to anything, and the data was never really ours.

HubSpot
Starter Customer Platform / Sales Hub Starter, 2 seats
$360 / yr · $30/mo
DocuSign
Standard, 1 seat (100 envelopes/user/year)
$360 / yr · $30/mo
OpenPhone (now Quo)
Business, 1 seat
$276 / yr · $23/mo
Mailchimp
Standard, 2,500 contacts
$720 / yr · $60/mo
Calendly
Standard, 1 seat
$120 / yr · $10/mo
QuickBooks Online
Plus (5 users)
$1,680 / yr · $140/mo
Buffer
Team, 4 channels
$480 / yr · $40/mo
Notion
Plus, 2 seats
$240 / yr · $20/mo
Annual cost of the stack, mid-tier plans$4,236 / yr
→
consolidated
into one
V

VTM CRM

One record per business. One database. Every channel, contract and dollar attached to the same customer, owned by us.

PipelineE-signiMessageGmailInvoicingSchedulingMarketing
The approach

How we thought about the problem.

Four decisions shaped the whole build. They are the same decisions we bring to a client system, which is exactly why this case study exists.

01 / Data

Own the record, don’t rent it.

One row follows a business the whole way: lead, client, project, recurring plan. Its texts, emails, contracts and payments all foreign-key back to it, so history is never scattered across four vendors again.

02 / Intelligence

Put the model in the loop.

Claude does not sit off to the side in a chat box. It drafts the agreement, writes the follow-up, cleans the email and proposes the next action right inside the screen where the work happens.

03 / Leverage

Build what you’d otherwise subscribe to.

E-signature, two-way texting, scheduling and invoicing became features, not monthly bills. The signing engine alone replaced a per-signature vendor with pdf-lib and a private storage bucket.

04 / Reuse

Design it like a product.

A stable core plus installable feature modules. The same foundation that runs our agency installs for a client in days, which is how it became a repeatable line of business.

The stack

What it’s built on, and how the pieces talk.

If you want to understand modern app architecture, this is a clean example: a visual frontend, a thin serverless API, and a relational database with row-level security. Every screen in this case study is that same three-layer request.

Layer 1

Frontend

The visual interface. A React single-page app plus a native mobile app, both hitting the same API.

React 18Vite49 pagesExpo / React Native
request · Supabase JWT
Layer 2

API

Thin serverless functions, one file per endpoint, no server to babysit, scales on demand.

131 serverless functionsNodeVercel8 cron jobs
query · row-level security
Layer 3

Database

The source of truth. Postgres tables, authentication and file storage in one managed platform.

SupabasePostgres50+ tablesAuthStorage
Wired in
Stripe + Connect
Gmail + Calendar
Anthropic Claude
iMessage bridge
MailerLite
Upload-Post
HeyGen + ElevenLabs
Apify
The iMessage bridge is the clever one: Vercel can’t drive Messages.app, so a small worker on a Mac polls the queue, sends through AppleScript, and reads new texts back out of chat.db. Real blue bubbles, no Twilio.
Inside the product

Ten surfaces, one database.

These are the real screens, rebuilt faithfully from the app with invented customers. Every one reads and writes to the same Postgres tables described above.

The command center

The whole business, the moment you log in.

A role-aware home: today’s meetings, overdue tasks, money owed and active leads across the top, then live Stripe revenue, MRR and recent payments, with the week’s calendar, the team to-do and active projects underneath.

GET /home · role-scoped · Stripe live revenue
CRM Dashboard
CRM Dashboard
Pipeline

From first touch to signed client, on one board.

Leads sit on a drag-and-drop board by temperature, each card showing the deal size, the source, and who owns it. The moment a lead signs, the same record becomes a client. No re-entry.

crm_clients · stage lead→ongoing · lead_temperature · potential_value
Leads · Board
Leads · Board
Clients

Every paying client, sorted by what they’re worth.

Once a deposit lands, the lead quietly becomes a client here: plan value, outstanding balance, project count, and history on one row, with revenue rolled up on top.

crm_clients · record_type=client · crm_invoices · crm_subscriptions
Clients
Clients
Messaging · built-in iMessage

Real blue-bubble texts, inside the CRM.

Text clients from the business number through a Mac bridge: threads, tapbacks, attachments and transcribed voice notes, all attached to the client record. If iMessage ever fails it falls back to SMS. Not Twilio.

crm_sms_messages · channel imessage|sms · crm_imessage_threads
Inbox · Clients
Inbox · Clients
Email · Gmail

Your whole inbox, built in.

Connect Gmail once and the CRM becomes a full mail client: real threads, two-way label sync, scheduled send, and a first-draft reply Claude writes per lead. Incoming mail is cached so it opens instantly.

crm_gmail_cache · Gmail History API · crm_email_queue
Email · Inbox
Email · Inbox
Money · Stripe

Revenue, MRR, and late payers on one screen.

Invoices, subscriptions, deposits and Stripe Connect fees roll up here. Overdue balances surface at the top with a one-tap nudge that texts and emails the client, then flips to “nudged” so nothing gets chased twice.

crm_invoices · phase_number / total_phases · crm_subscriptions
Money · Overview
Money · Overview
AI · Claude woven in

An assistant that does the work, not just chats.

It has real tools over your live data: find the leads that went cold, draft each follow-up, and propose the action for you to approve. Ask it to chase cold leads and it comes back with the drafts and a button, not advice.

assistant · claude-sonnet-5 · tools: availability · people · propose_action
Assistant
Assistant
Outreach

A cold-email pipeline that runs itself.

Prospects move across a seven-stage board while an agent sends from your own mailbox, reads the replies, classifies them, and pauses automation the instant a human needs to step in.

crm_outreach_prospects · stage · crm_outreach_senders
Outreach · Pipeline
Outreach · Pipeline
Marketing · content engine

Plan a week of content, publish everywhere.

Draft posts, let AI write the captions and build carousels, then schedule across every platform from one calendar. Email marketing runs on the same contact records, so the audience you sell to is the one you nurture.

crm_content_scripts · crm_content_clients · Upload-Post
Content · This week
Content · This week
E-signature · replaces DocuSign

Send a contract, take the deposit, provision the account.

Claude drafts the agreement from the deal. The client opens a no-login page, signs by drawing or typing, and pays the deposit. The server generates the signed PDF, stamps an IP-and-timestamp certificate, files it in a private bucket, and creates the client’s portal login, all in one request.

crm_agreements · sign_token · signed_ip · signed_at · status draft→sent→signed
Secure e-signature
Secure e-signature
And in your pocket

The same system, as a native app.

A React Native app on TestFlight puts the inbox, the money, the agreements and the assistant on the phone, hitting the same API. Four real screens:

Home
Home
iMessage
iMessage
Money
Money
Assistant
Assistant
Why clients switch

The math a client sees before they say “I want this.”

Replacing an eight-tool stack with one owned system frees $4,236 a year in subscriptions and 112.5 hours of hands-on work (worth $5,625 at $50/hr) per 100 clients, which is $9,561 a year every year after the one-time build, and $23,283 over three years.

Software you stop paying for
$4,236
per year, at mid-tier plans, across 8 tools. $12,708 over three years.
Hours given back
113 hrs
per year at 100 clients, across 7 everyday actions. Worth about $5,625 at $50/hr.
Net position
$4,161
year one, after One-time build, owned asset ($5,400). $23,283 over three years, before counting the hours.

The stack this replaces

Current published list prices, mid-tier plans, billed annually.
HubSpotStarter Customer Platform / Sales Hub Starter, 2 seats$360 / yr
DocuSignStandard, 1 seat (100 envelopes/user/year)$360 / yr
OpenPhone (now Quo)Business, 1 seat$276 / yr
MailchimpStandard, 2,500 contacts$720 / yr
CalendlyStandard, 1 seat$120 / yr
QuickBooks OnlinePlus (5 users)$1,680 / yr
BufferTeam, 4 channels$480 / yr
NotionPlus, 2 seats$240 / yr
Annual stack$4,236
VTM CRM$5,400 once
Paid once. $0 per signature, $0 per seat, $0 per contact, forever. Add a seat, send the 500th contract, or grow the list to 10,000 and the price does not move. Hosting (Supabase, Vercel, domain) is budgeted separately at a $25/mo ceiling and is subtracted from the savings below.

Time saved at 100 clients

Minutes to do it by hand in the old tools versus inside the system, scaled to a year.
ActionBy handIn the systemSaved / yr
Send a contract for e-signatureExport the agreement to PDF, log into DocuSign, upload the file, drag in 5 to 8 fields (signature, initials, date, name, amount), add the signer name and email, type a message, preview, send. Then check back later to see if it was signed and send a reminder. Deposit and portal access are handled separately.15 min4 min18 hrs
Text a clientSwitch to the phone app, search for the contact, switch back to the CRM to remember where the project stands, switch again, type, send. Nothing is logged against the client record.2 min1 min10 hrs
Invoice and chase a late paymentOpen QuickBooks, create or find the customer, key in the line items and amounts from the signed agreement, send the invoice. Then run the aging report, notice it is late, write a reminder email, notice again a week later, send a second reminder, text the client.12 min2 min17 hrs
Schedule a meeting and prep for itSend the Calendly link, watch for the booking, confirm the Meet link landed on the calendar, then before the call pull up the client across the CRM, the invoice tool and the notes doc. Take notes during. Afterward type them up and paste them somewhere findable.10 min3 min12 hrs
Write a follow-up email to a warm leadOpen the lead, re-read the history to remember what was discussed, decide on an angle, write the email from a blank box, send, then log it so the next follow-up knows it happened.6 min1.5 min23 hrs
Onboard a new clientCreate the contact and deal in HubSpot, create the customer in QuickBooks, add the signer in DocuSign, spin up the project page in Notion, add them to the Mailchimp audience. Same name, email, phone and address typed five times, with five chances to typo it.15 min1 min23 hrs
Convert a lead into a clientCopy the lead's details out of the lead tool and re-key them as a customer record, then reconcile which of the two is now the source of truth.6 min0 min10 hrs
Total hours given back per year113 hrs
Runs while you sleep
⚡
Follow-ups cron

Fires the scheduled follow-up on a lead or client so nobody goes cold because a human forgot.

Every 5 minutes
⚡
Reminders cron

Sends appointment and task reminders to the client and to the team before the thing happens.

Every 5 minutes
⚡
Email cron

Pulls inbound email into the right client record so the thread lives with the deal instead of in an inbox.

Every 15 minutes
⚡
Email queue cron

Sends queued outbound email on schedule with retries, so a failed send is caught instead of silently lost.

Every 15 minutes
⚡
Audit drain cron

Works through the queue of AI lead audits, generating the prospect's report without anyone sitting there waiting on it.

Every 5 minutes
⚡
Audit follow-up cron

Follows up with prospects who requested an audit, on its own schedule.

Hourly
What it adds up to

One system, measured.

131
Serverless API endpoints, one file each
50+
Postgres tables, one connected schema
~12
Integrations, replacing a stack of subscriptions
$0
Per-signature fees, e-sign built in-house
The takeaway

We didn’t buy a CRM.
We engineered one.

This is the same team, the same stack and the same thinking we bring to a client build. If your business is stitched together across a dozen tools, we can consolidate it into one system you actually own.

Build one for your business →
Vernon Tech & Media