Attribution that ties ad spend to invoiced revenue, AI workflows that run inside the CRM, and the reporting a business steers by — designed, built, and shipped by one person, inside a working field-service company. Before that: twelve years leading an agency marketing team through an acquisition that doubled the client base, and a SaaS company founded and sold.
FIG. 01 — THE STACK AS BUILT (SIMPLIFIED)EVERY BOX HAS A CASE STUDY — CLICK TO JUMP
8
Direct reports led (agency)
317+
Clients at peak
2×
Client base via acquisition
~11×
LSA return on invoiced revenue
54K+
SMS opt-ins built from zero
1 exit
SaaS founded & acquired
The work, circuit by circuit
One leadership case from twelve years running an agency marketing team, then five systems from the last twelve months as Operations Director at a regional electrical contractor, where I own the marketing, reporting, and automation stack. Customer data and company financials are redacted or synthetic; the architecture is shown in full.
LEAD-01
Doubling the book without dropping it
Inland Cellular · Agency Marketing Director · 2013 – 2025
Fault found
An acquisition of a key competitor took the agency's client base from 135 to 280. Twice the accounts had to run through the same team, the same process, and the same reporting — without the existing clients feeling it.
Rewired
Served on the M&A team; led the product and marketing integration workstreams
Led 8 direct reports — engineers, designers, and account managers — and supported 7 outside sales reps
Ran hundreds of campaigns across paid search, social, email/SMS, web, TV, radio, print, and outdoor, with $50–60K/month in managed ad spend
Led cross-functional go-to-market launches with engineering, sales, customer service, training, legal, and finance
317+clients at peak
20–25%YoY growth, 8 straight years
54K+SMS opt-ins for one client, from zero
ResultThe client base kept growing after the integration, on a recurring-revenue base that grew 20–25% a year for eight consecutive years. Selected to present on business-segment retention at the Competitive Carriers Association national conference.
CKT-01
Attribution you can take to the CFO: click → call → invoice → cash
INTERACTIVE
Fault found
Reported conversions didn't match the phone ringing. The audit found the primary Google Ads conversion — phone calls — firing on bot traffic, four analytics tag loaders running at once after years of vendor changes, and an auto-created form goal inflating the count. Nothing connected ad spend to revenue.
Rewired
Consolidated every loader into one Google Tag Manager container
Rebuilt conversions to count only verified outcomes: form submits via a thank-you page, and calls of 30+ seconds as the primary signal
128-term negative keyword list; killed a display campaign the clean numbers showed wasn't paying back
Replaced paid reporting connectors with Google Ads Scripts + Apps Script pipelines, cross-checked against Search Console
Tagged lead source on every CRM customer, so spend ties to invoices and collections — not just form fills
Try the discovery yourself
Illustrative data. The real audit found the primary phone-call conversion counting bots; filtering restored numbers leadership could trust.
~11×Local Services Ads return on invoiced revenue
~7×on cash actually collected
ResultConversion counts reconcile with reality, and the best channel is proven all the way to the bank — so budget moves on revenue, not on form fills.
CKT-02
The CRM as an operating system
INTERACTIVE
Fault found
A small office buried in repetitive work — retyping supplier invoices, texting customers from a separate phone app, filing job photos by hand, compiling daily numbers — with the glue held together by a stack of paid Zaps that broke whenever an upstream field changed.
The worst of them: a 27-step Zapier chain with four path splits, just to set up a new service job.
Rewired
Two-way SMS ↔ CRM bridge: inbound texts thread onto the right job; outbound texts go from the job record
Slash commands inside CRM comments — the team runs automations without leaving the job (below)
AI invoice intake: supplier invoices collected from email every 10 minutes, plus a Chrome extension for portal-only receipts; Claude extracts line items and drafts the bill
Proposal & invoice follow-up engine: SMS + email cadence with click tracking and one-word pause/stop
New-job setup, job folders, file sync, tech dispatch, and Street View job-site photos — all native workflows + Apps Script
Daily Field Digest: yesterday's jobs, hours, and exceptions, summarised by Claude from the CRM API
Commands the crew types into a job comment
/SMSText the job's customer from the CRM; replies thread back
/OMW"On my way" text with the tech's first name
/REPORTBudgeted vs. actual labor hours
/MONEYContract, invoiced, paid, and cost snapshot
/LOOSE @nameLog a loose-end task so nothing hangs
/DRIVELink to the job's document folder
Run the invoice workflow
// press Run — this simulates the production pipeline, step for step
Simulation of the live workflow. The PO check stays human on purpose: suppliers occasionally print the wrong PO, and a wrong-job bill costs more than the ten seconds it takes to confirm.
Webhook: job createdEnrich: cost groups + Street ViewUpdate job record
27 chained steps · 4 path splits · breaks when any upstream field changes
Daily Field Digest — the 7pm email to leadershipformat real · data synthetic
FIELD OPSDaily Field DigestTuesday · 3 jobs · 21.5 crew hours
J-1042 Kitchen remodel — Hillcrest9.0h
Alex5.0h
Sam4.0h
Roughed in island circuits and under-cabinet lighting; rough inspection requested for Thursday.
J-1051 Panel upgrade — 200A8.5h
Jordan8.5h
Swapped panel and meter base; utility reconnect confirmed. Flag: no daily log photo uploaded.
J-1055 Service call — breaker trip4.0h
Sam4.0h
Traced to a failed GFCI on a shared circuit; replaced and tested. Invoice ready.
10 → 0Zaps retired
27 → 3steps to set up a service job
ResultThe CRM became the place work actually happens — texting, follow-ups, invoices, and reporting run from the job record, and the paid Zapier layer is gone.
CKT-03
Governing the AI stack: an audit of my own automations, fixed in a day
Fault found
A year of fast building had produced 11 automation projects with no version control. A read-only audit with Claude Code found 15 separate copies of the same CRM API wrapper, three copies of the Claude call, API keys pasted into four projects, and an unauthenticated public webhook.
Worse for the business: four reports computed unbilled work four different ways, so their numbers never reconciled — and the customer follow-up engine was quietly failing about 91% of its runs.
Rewired
Every project pulled into one git repo, with a CLAUDE.md of hard rules: no push without a reviewed diff and a named go-ahead, never print or commit secrets, commit before and after every change
Keys moved to a secrets store, rotated, and the old ones revoked; the public webhook retired for a native workflow with a restricted key
One shared billing module, so every report uses the same definition of contract, billed, and unbilled
Two duplicate fuel reports merged; the math moved from the LLM into code, and Claude only writes the note
Webhook runs a pinned, versioned deployment with one-command rollback; slow jobs queued so the CRM's 10-second webhook limit can't drop them
Panel schedule — audit findings and their status
Circuit
Fault
Fix
Status
Secrets
API keys hardcoded in 4 projects
Moved to Script Properties; rotated; old keys revoked
Closed
Webhooks
A public endpoint with no auth
Retired; native workflow with a restricted key
Closed
Follow-ups
~91% of runs failing (request too large)
Fetch portal keys per document, only when a link is built
Closed
Money logic
4 reports, 4 definitions of "unbilled"
One shared billing module used by every report
Closed
LLM math
Fuel totals computed by the model
Computed in code; model writes the summary only
Closed
Data loss
Reports silently truncated at 100 records; UTC day windows
Cursor paging; Pacific-time windows
Closed
Change control
Live edits, no history, no rollback
Git + pinned deployments + rollback runbook
Closed
~60reviewed commits in about a day
~91%follow-up runs failing — found and fixed
4 → 1definitions of unbilled work
ResultAI speed with operational discipline: every automation is versioned, reviewable, and reversible, secrets are out of the code, and the numbers leadership sees agree with each other.
CKT-04
The scoreboard the business runs by
INTERACTIVE
Fault found
Monthly targets weren't yet tied to the cost base, so there was no breakeven or capacity model to plan against — and marketing spend had nothing in finance to answer to.
Rewired
Capacity-based financial model: fixed-cost base, breakeven, and monthly revenue targets from billable capacity
A live scoreboard leadership reviews monthly, tying job volume and revenue mix to targets
Weekly unbilled-work and invoice digests that surface billing gaps before month-end close
Year-over-year revenue by job type, so spend follows the work worth winning
The scoreboard, rebuilt with illustrative datastructure real · values synthetic
$1,240
Revenue YTD ($K)
87
Jobs won
118%
vs. breakeven
49%
Proposal win rate
Service 40% Residential 30% Commercial 20% Other 10%
ResultMonthly business reviews run on a shared, current picture — the rhythm-of-business function, built from scratch.
CKT-05
A self-service quoting funnel
Fault found
Quoting small electrical jobs was a bottleneck: every inquiry waited on a callback before hearing a number, and slow quotes lose jobs.
Rewired
React application with a 10-step guided intake, from job type to a usable estimate
Every question structured to emit clean, routable lead data — not a free-text form
Shipped as a standalone funnel alongside paid and organic acquisition
ResultA bottleneck became a conversion asset that qualifies leads while it quotes them. It sits behind a customer login, so I walk it through end to end in a live demo.
Also built and running
Unbilled-work digest — weekly, grouped by who bills
Week Ahead email — next week's crew schedule and gaps, Sunday night
Log nudge — texts a tech who clocks out without a daily log
Callback & rework tracker — feeds the monthly field report
Fleet dashboards — fuel, maintenance, and service-due tasks
Marketing ROI export — CRM + ad spend into Looker Studio
Receipt Grabber — Chrome extension for portal-only receipts
Local SEO rebuild — location pages with structured data
Proposal follow-up campaign — for quotes sitting 30+ days
How I got here
One continuous line: build a marketing system, run it on a P&L, then build the next one bigger.
2009 – 2013
QpINs.com — Founder / Owner
Founded an SMS loyalty-marketing SaaS. Permission-based lifecycle marketing before the term existed: 200+ clients, 10,000+ loyalty kiosks shipped across the US, Canada, and Mexico, two vertical software lines licensed. Acquired by Inland Cellular.
2013 – 2025
Inland Cellular — Agency Marketing Director
Joined via the acquisition; grew into leading the agency marketing practice and enterprise portfolio. Led 8 direct reports and supported 7 outside sales reps; $50–60K/month in managed ad spend; 20–25% year-over-year growth on a recurring-revenue base for eight consecutive years; served on the M&A team for an acquisition that doubled the client base. National conference speaker (Competitive Carriers Association).
2025 – present
Operations Director — regional electrical contractor
Recruited to modernize a licensed electrical contractor. Own the go-to-market engine, the financial reporting, and every system on this page — the connective tissue between field operations, marketing, and finance.
B.S. Business (Marketing), University of Idaho · HubSpot Inbound Marketing Certified