6 Critical Actions Before Evelyn Call | $334K+ Revenue Attribution at Stake
The timer calls --process which doesn't exist in argparse. Needs to be --days 7.
--process to --days 7Line 10: ExecStart=...nexus_offline_conversions.py --days 7
gcloud compute scp then sudo systemctl daemon-reload on VM
python nexus_offline_conversions.py --days 7 --dry-run should complete without error
nexus_gclid_bridge.py (~300 lines)Lightweight webhook receiver on VM port 8502. Receives WordPress form submissions, extracts GCLID, writes to ServiceTitan lead externalData.
nexus-gclid-bridge.service: always-on, listening on port 8502, restart on failure.
WPForms webhook or Zapier: on form submit, POST to https://morpheus.callbrightside.com:8502/gclid with GCLID + contact fields.
Fill out callbrightside.com form with test GCLID. Verify it appears in ServiceTitan lead's externalData.
python nexus_offline_conversions.py --days 7 --dry-run should now find GCLID matches and show upload candidates.
python nexus_offline_conversions.py --days 30 (no --dry-run). Uploads matched GCLID+revenue to Google Ads UPLOAD_CLICKS actions.
Check account 7269555791 > Conversions > "Offline Revenue" action. Should show imported conversions with real dollar values.
Robert + EvelynPHONE_TO_CAMPAIGN in nexus_attribution_engine.py line 109 is entirely commented out. Every phone-based attribution rule short-circuits. 110 abandoned calls in 6 months going untracked.
28,719 historical call records. Extract unique destination numbers and their call volumes.
Proposed mapping needs verification:
| Number | 3CX Calls | Proposed Source | Confirm? |
|---|---|---|---|
| (913) 276-4920 | 44 | PPC tracking number | ❓ VERIFY |
| (913) 297-9941 | 62 | Main line, Google organic | ❓ VERIFY |
| (913) 963-1029 | - | Official BSP, existing customer | ❓ VERIFY |
| (913) 358-0252 | - | Need identification | ❌ UNKNOWN |
| (913) 358-0380 | - | Need identification | ❌ UNKNOWN |
PHONE_TO_CAMPAIGN dictAfter Robert confirms, update the mapping. Each number gets a campaign source string.
python nexus_attribution_engine.py --scan --verbose --days 180. Check phone_stats section shows campaign mapping active.
job.total shows $227K for Jan-Feb. Kalen's verbal numbers are $334K. That's a $97K (30%) gap. Every ROI calculation is wrong because we're using quoted amounts, not invoiced amounts.
nexus_revenue_resolver.py (~250 lines)Shared module. Bulk-pulls invoices: GET /accounting/v2/tenant/{T}/invoices. Builds {job_id: invoice_total} lookup. SQLite cache (re-pull if > 24h). Exposes get_revenue(job_id) -> float.
Replace job.get("total") with get_revenue(job_id) in:
| Script | Line | Current |
|---|---|---|
| nexus_lead_roi_engine.py | 318 | job.get("total") |
| st_ticket_by_service.py | 71 | job.get("total") |
| nexus_attribution_engine.py | 328 | job.get("total") |
| nexus_cpl_monitor.py | 345 | job.get("total") |
Replace _FALLBACK_REVENUE_WEEKLY = 57_700 (line 102) and _ap_roi_map hardcoded values (line 4214) with invoice-based calculations. Every revenue panel shows "Source: ST Invoicing API" + staleness warning.
python nexus_revenue_resolver.py --test. Invoice totals should be > job.total. Output: revenue_truth_latest.json
job.total. Once the resolver is live, EVERY revenue display auto-corrects to invoice truth. Stephanie and Kalen stop arguing about numbers; the system produces the definitive total.
Google Ads > Local Services Ads > Profile. Account 7269555791.
RobertSeasonal (Nov-Feb), $1.5K avg ticket, Emergency Eric persona. Currently missing.
$2.5K avg ticket, 100% booking rate currently. Needs dedicated category.
Gateway service to larger jobs, $800 avg ticket. Research Robert persona.
Seasonal (March-May), $1.2K avg, Emergency Eric persona. Spring storm season NOW.
8 photos needed. LSA photo ranking is a massive signal since April 2025:
| # | Photo | Priority |
|---|---|---|
| 1 | 👨🔧 Team photo in branded shirts | HIGH |
| 2 | 🚽 Before/After sewer repair | HIGH |
| 3 | 📹 Tech with camera inspection | MED |
| 4 | 🚚 Branded truck | MED |
| 5 | 🌡️ Water heater install before/after | MED |
| 6 | 🔍 Leak detection equipment | LOW |
| 7 | 💧 Sump pump installation | LOW |
| 8 | 🔥 Emergency heater repair | LOW |
Cross-reference 234 keywords. Identify: DIY terms, career terms, competitor brand terms, irrelevant geo terms, informational-only terms.
Nexus AI| Category | Examples | Est. Count |
|---|---|---|
| 🛠️ DIY / How-to | how to, DIY, tutorial, guide, yourself | ~25 |
| 💼 Career / Jobs | jobs, salary, hiring, apprentice, career | ~15 |
| 🏢 Competitors | roto-rooter, mr rooter, a1 sewer | ~12 |
| 🌐 Wrong Geo | Kansas City MO (if targeting KS only), other states | ~10 |
| 📚 Informational | what is, definition, wikipedia, reddit | ~15 |
| 🏠 Non-Service | HVAC, electrical, roofing, backflow, appliance | ~20 |
Output: output/negative_keywords_google_ads.csv. Ready for bulk upload to all 5 new campaigns.
Evelyn applies shared negative keyword list across all 5 new campaigns. Saves $100s/month on irrelevant clicks.
Evelyn5 campaigns x (15 headlines + 4 descriptions) = 95 ad copy assets. Use content engine personas.
Nexus AI| Theme | Headline Style | Example |
|---|---|---|
| 🚨 Emergency | Urgency + Availability | "KC Sewer Emergency? We're There in 60 Min" |
| 🏆 Trust | Credentials + Heritage | "5th-Gen Master Plumber, 390+ 5-Star Reviews" |
| ⭐ Social Proof | Reviews + Numbers | "KC's Highest-Rated Sewer Repair Team" |
| 📍 Location | Hyperlocal | "Overland Park Sewer Experts, Not a Franchise" |
| 💰 Value | Transparency + Pricing | "Free Sewer Camera Inspection, Upfront Pricing" |
Output: output/google_ads_copy_drafts.json. Organized by campaign > ad group > headlines + descriptions. Ready for Evelyn to paste into campaign builder.
Sitelinks, callout extensions, structured snippets per service. Pre-built so Evelyn can add immediately.
| Deliverable | What Changes | When |
|---|---|---|
| 📊 Nexus Dashboard nexus_dashboard.py |
• Phone Analytics page: replace "Enterprise Upgrade In Progress" with real 3CX data • Attribution Health page: populate 7-step pipeline from real data • Revenue panels: switch from job.total to invoice-based truth • Replace _FALLBACK_REVENUE_WEEKLY with calculated value
|
After Actions 1-3 |
| 📄 BSP_Google_Ads_Conversion_Fix_Plan.html |
• Mark Phase 0 as COMPLETED (green) • Update Phase 1 timeline (GCLID bridge this week) • Add Phase 5 details from Evelyn call |
NOW + Post-Evelyn |
| 📄 BSP_Monday_Standup_March_2026.html |
• Update revenue numbers to invoice-based truth (after Action 3) • Add Google Ads progress section (Phase 0 done, pipeline in progress) • Add 3CX call metrics when available |
After Action 3 |
| 📄 BSP_LSA_Strategy.html |
• Add 4 new service categories (Action 4) • Update with post-Phase 0 conversion value corrections • Add budget split recommendation from Evelyn call |
After Action 4 + Evelyn |
| 📄 BSP_Lead_Source_ROI_Report.html |
• Recalculate all ROI using invoice totals (not job.total) • Revenue by source will shift significantly • Verdict badges may change (Google could improve from KEEP to GROW) |
After Action 3 |
| ✨ NEW: BSP_Revenue_Pipeline_War_Room.html This document |
Created tonight. Living action plan with saveable notes. | DONE |
| ✨ NEW: evelyn_meeting_agenda_20260311.html | Created tonight. Meeting agenda with timer and saveable notes. | DONE |
| When | Action | Owner | Impact |
|---|---|---|---|
| Tonight (Mar 10) | 🔧 Fix systemd timer bug (5 min) 🔧 Build GCLID bridge script 🔧 Build revenue resolver script |
Nexus AI | Unblocks pipeline |
| Tue Mar 11 AM | 📞 Confirm phone mapping with Robert 📝 Generate negative keyword list ✍️ Generate ad copy drafts |
Robert + Nexus AI | Assets ready for Evelyn |
| Wed Mar 11 10am | 📞 Evelyn Call • Present pipeline status • Hand off keywords + ad copy • Agree on 5 new campaigns |
Robert + Evelyn | Campaign plan locked |
| Wed-Thu (Mar 11-12) | 🚀 Deploy GCLID bridge to VM 🔧 Configure WordPress webhook 🧪 End-to-end pipeline test |
Robert + Nexus AI | Pipeline flowing |
| Fri Mar 14 | 📊 First offline conversion upload 📄 Update all HTML deliverables 📍 Add LSA service categories |
All | Smart Bidding starts learning |
💾 All notes auto-save to localStorage every 2 seconds. They persist between sessions. Click Export to download as text file.
NEW DISCOVERY β 2026-04-14. During the zeus_st_module_sync.py repair tonight, the sync pipeline shift from the /estimates/export endpoint (archival, stopped Jun 2025) to the live /estimates endpoint with modifiedOnOrAfter filter revealed 1,749 Open estimates worth $4,887,216 sitting untouched in ServiceTitan.
Up to now this battle plan focused on customer acquisition β finding more opportunities and filling the top of the pipe. That framing is incomplete. The pipe has a hole at the close, not at the top. 1,749 prospects already invited a Bright Side tech, received a quote, and never closed. The sales job is done. Only the follow-up is missing.
Logged via nexus_html_logger.py at 2026-04-14T05:33:48.414607 UTC
Post-Apr-14 context (reorders this entire plan). Tonight we discovered $4.88M in Open estimates that were invisible because the data pipeline had been returning archival data for 9 months. The Fix-the-Pipes framing expands.
This plan has focused on operational pipes β plumbing ops, communication chains, data flows. Tonight revealed a sales-close pipe nobody was watching: 1,749 quotes sitting at Open, worth $4,887,216, with nothing in ServiceTitan flagging them for follow-up. Of those, $553K is in the hot 0-7 day window right now.
Before tonight, this plan prioritized acquisition: weather landing pages, Google Ads volume increase, Daniel tuning. After tonight, recovery comes first:
Ashton + Kalen, 2 hours: configure ServiceTitan so every new estimate creates an auto-follow-up task at day 3, day 7, day 14. This is the structural fix preventing future quotes from going dark. Goes into the Pipe-Fix plan as an operational discipline, not a one-off.
This plan is an operational document. For the full Stephanie-facing strategic view including all four pain points, the nine decisions, and supporting documents, see: BSP_Strategic_Synthesis_Apr14.html (the Apr 14 session capstone).
Logged via nexus_html_logger.py at 2026-04-14T06:04:38.008772 UTC