🧠
Ohio Clean Cans — Business Intelligence
Customer Intelligence + Automation Actions
👥 Customer Intelligence
Each card shows a key business metric with a status color (healthy / watch / needs help / informational) and a button to fire the matching automation. Connect data sources to populate the numbers.
Loading metrics…
🔁 New Customers This Month
No data — new-customer feed not connected.
📊 Supporting Charts — Historical Detail (placeholder)

Charts that populate once tenant data is connected:

  • Monthly new customer trend
  • How customers found the business (lead source attribution)
  • Top ZIPs and neighborhoods for new customers
  • Customer loyalty tiers (jobs completed bands)
  • Year-over-year growth (signup year, recurring vs one-time)
  • Subscription plan mix detail
  • Cohort retention by signup year
  • Seasonal signup pattern

Historical charts render once data sources are connected.

📊 Average Stop Revenue
Basic intelligence about your routes — revenue per stop by day, by route, by ZIP. Identifies which routes generate the highest per-stop revenue. Connect data sources to populate.
📊 Revenue per Stop — By Day
No data — connect data sources to populate
📍 Revenue per Stop — By ZIP (Top 10)
No data — connect data sources to populate
📋 Revenue per Stop — By Service Type
No data — connect data sources to populate
📉 Route Profitability
Cost-per-stop comes from your operating expenses divided by total stops. Revenue comes from your payment data. Built for ownership decisions: keep the route, restructure it, cancel it, or adjust frequency. Connect data sources to populate.
📈 Route Profitability by Day and Route
📅 Daily Route Composition — What's Inside Each Route
⚠ Losing Routes — Cycle-Week Detail
📍 ZIP-Level Profitability
🔎 Decision Support — Where Action Is Needed
⚙ Route Inputs — Data Sources for Profitability Calculation
Route Profitability needs accurate inputs. This is where the data comes from. For multi-tenant deployment, this is where each business owner uploads their own numbers.
📊 Required Inputs — What Profitability Math Needs
  1. Total Operating Expenses (year-to-date): Payroll, fuel, vehicle, insurance, software, rent. Pulled from accounting (QuickBooks, Xero, etc.) or uploaded manually.
  2. Total Stops Completed (year-to-date): Number of customer service stops actually performed. Pulled from field-service software (GorillaDesk, Jobber, etc.) or uploaded.
  3. Revenue per Stop (by day & route): Total revenue collected at each stop. Pulled from payment processor (Square, Stripe, etc.) or uploaded.
  4. Route Schedule (day-by-day): Which routes run which days, how many trucks, how many runs per cycle. Pulled from field-service schedule.
  5. Cycle-Week Rotation: If you use a 4-week rotating route schedule, the system needs to know which customers fall in which week.
📂 Connected Data Sources (For Your Tenant)

For the active tenant, these data sources are connected:

  • Payment processor: Status pending — will show: Connected / Disconnected once wired
  • Accounting: Status pending
  • Field-service software: Status pending
💾 Manual Upload (For New Tenants Without API Connections)

If a tenant doesn't have API-connected sources, upload the four required inputs as CSVs. Each tile accepts one file and shows status. Click Download Template to grab a starter file with the right column headers.

💵
Operating Expenses
Annual P&L breakdown by category
Pending
No file selected
🚚
Stops Completed
Year-to-date stops with date + route
Pending
No file selected
💰
Revenue per Stop
Total collected per service date
Pending
No file selected
📅
Route Schedule
Cycle-week rotation, days, trucks
Pending
No file selected
0 of 4 files uploaded
CSV files are parsed client-side first for column-header validation. On Apply, they upload to the tenant\'s data layer and trigger a recalculation of the Route Profitability tab.
🔗 Integrations — Live Data Sources
Drop GorillaDesk exports here and the dashboard refreshes live. No hardcoded numbers, no D1 cache — what you upload is what you see. Future API connections (WooCommerce, Square, QuickBooks) plug in here too.
📤 Drop GorillaDesk Export
📤
Drop a GorillaDesk CSV here
or click to choose a file
Supported: new_customers (*).csv from GorillaDesk export
✅ Currently Loaded
No data loaded. Drop a file above.
📊 QuickBooks — Live API
Click "Pull QB P&L" to fetch live operating-expense data from QuickBooks. This unlocks Route Profitability Margin (KPI 3).
🔒 Other Live API Connections
🛒 WooCommerce Off
Source of truth for: new orders, signup source, promos, recurring vs one-time
◯ Square Off
Source of truth for: live payments, declines, AR aging, refunds
📊 QuickBooks Live
Connected via occ-bi-api worker
🚚 GorillaDesk Live (CSV)
Source of truth for: route schedule, job status, completed cleanings
💎 Customer Lifetime Value
Estimated total revenue you'll earn from a customer over their full relationship with you. Calculation method: Average revenue per customer per year ÷ annual churn rate. Industry-standard formula. Connect data sources to populate.
💎 Lifetime Value Summary
Connecting to lifetime value endpoint…
Median Lifetime Value
across active customers
Top Decile Lifetime Value
90th percentile
Average Tenure
months active
Total Active Lifetime Value
portfolio value
🏆 Top 50 Customers by Lifetime Value
Click "Sync" to load top customers from live data
📊 Lifetime Value by Plan Type
Plan-type breakdown loads after sync
High-lifetime-value customers = highest satisfaction = best referral source
📊 Per-Customer P&L
Profit and loss broken down by individual customer. Revenue from payments minus allocated cost-to-serve (route share + extra-can handling + missed visits). Identifies the profitable customers, the marginal customers, and the unprofitable customers you may need to re-route, re-price, or release. Connect data sources to populate.
💸 Profitability Distribution
No data — connect data sources to populate
Profitable
contribution margin > $0
Marginal
margin between −$50 and $50
Unprofitable
contribution margin < -$50
Avg Margin / Customer
trailing 12 mo
⚠ Bottom 25 by Contribution Margin
🏆 Top 25 by Contribution Margin
Unprofitable customers in re-routable ZIPs → Route Profitability decisions
🔄 One-Time Customer Conversion
One-time customers tracked through their conversion window. The funnel: Day 0 (just had service) → Day 80 (final touch). After Day 80 with no conversion to recurring, they move to the Lost bucket.
🔄 Conversion Funnel
Connecting to one-time conversion endpoint…
In Funnel (Day 0–80)
awaiting conversion
Converted
one-time → recurring
Conversion Rate
trailing 90 days
Lost (past Day 80)
no conversion
Funnel Stages
Funnel stage breakdown loads after sync
One-time customers in funnel → activate drip sequence
💰 Pricing Intelligence
Compares your prices to comparable markets — same population size, similar income level, similar competition density. Tells you if you're under-priced (room to raise on new signups), at market (good), or over-priced (hurting conversion). The comparable-market dataset is research-driven; the framework is built and waiting for the research to be loaded.
📋 Pricing Catalog — Per-Cleaning Rates by Plan and Can Count
Your published rate matrix. New signups quote from this. Existing grandfathered customers stay at their original rate (locked rule).
No data — connect pricing source to populate
📊 Internal — Catalog Price vs Realized Average (Per Plan)
Catalog price = your published rate per cleaning. Realized average = what you're actually collecting per stop. Gap reveals grandfathered customers, prepaid bonuses, or pricing erosion.
No data — connect data sources to populate
🔎 Comparable Market Analysis — Research Pending

What this will show when the research dataset is loaded:

  • Comparable-market pricing range per plan/can-count combination
  • Your position: under market / at market / over market — by percentage
  • Estimated annual revenue opportunity if catalog rates align with market for new signups

Research methodology:

  • Match comparable markets by: city/town size, residential density, median household income, population
  • Pull actual competitor pricing per plan/can-count from those markets (not approximated, not guessed)
  • Filter to markets with similar income profile (avoid comparing high-income suburb to low-income market)

Status: Research project on the build queue. UI shell ready to receive the dataset.

💡 Decision Support — Pricing Actions

Locked rules (cannot be overridden by recommendations):

  • Catalog price applies to NEW signups only. Existing grandfathered customers stay at their original rate.
  • Bulk price increases on existing customers require explicit timing approval — never automated.

Specific price-action recommendations populate here once both the internal data is connected and the comparable-market research is loaded.

🎯 Win-Back Campaign Worker Ready — Awaiting Tenant Connection

Multi-channel reactivation sequence for dormant customers (60+ days no activity). Email + SMS drip with progressively stronger offers — soft check-in → discount offer → final win-back. Auto-suppresses customers on the marketing-exclusions list.
⚙ Campaign Status
No data — connect data sources to populate
Dormant Customers
60+ days inactive
Eligible for Outreach
passes suppression rules
In Sequence Now
worker pending
Recovered MTD
customers returned
📋 Touch Sequence (configurable)
🛠 Trigger & Suppression Rules

Trigger: Customer status = dormant (no completed job in last 60 days) AND not on marketing-exclusions list AND has paid at least one invoice.

Frequency cap: Each customer can enter the win-back sequence once every 180 days. After completing the sequence (success or fail), they are locked out for 6 months.

Suppression: Customers in active dispute, with open support tickets, or flagged on the marketing-exclusions table are skipped automatically.

Conversion tracking: When a dormant customer schedules a new cleaning during the 21-day window or up to 14 days after the final touch, the sequence is marked converted and the credited touch logged for attribution.

⚙ Activation Controls
Last fire: never · Last sequence completion: never
Toggle and Fire Now button are wired. Real sequence runs against tenant data once they connect their customer database, email provider, and text-message provider.

📈 Active Dormant Upsell Worker Ready — Awaiting Tenant Connection

Truck-proximity-triggered upsell. When your truck is routed through a customer's neighborhood, the system pitches relevant upgrades. Quarterly customers are NOT targets — they chose quarterly for lowest cost. Real targets: bi-monthly → monthly upgrades, can-count expansion (extra cans observed by crew), add-on services.
⚙ Campaign Status
No data — connect data sources to populate
Bi-Monthly Targets
eligible for monthly upgrade
Can-Count Expansion
crew-flagged extra cans
Add-On Candidates
top-decile lifetime value
Converted MTD
worker pending
🎯 Targeting Tiers (configurable)
🛠 Trigger & Suppression Rules

Trigger: A truck route runs through a customer's neighborhood AND that customer matches a targeting tier AND has not received an upsell touch in the last 60 days.

NOT targeted: Quarterly customers. They picked quarterly for the lowest cost — pushing them to monthly is the wrong target.

Channels: Email (primary) and in-crew-app prompt during the cleaning visit.

Frequency cap: One upsell touch per customer per 60 days, regardless of which tier they qualify for.

Pricing rule: The published catalog price applies only to NEW signups. Existing grandfathered customers stay at their original rate even if they accept an upgrade.

⚙ Activation Controls
Last fire: never · Last upgrade: never
Toggle and Fire Now button are wired. Real campaign runs against tenant data once they connect their route schedule, customer database, and email provider.

💳 Payment Follow-Up Worker Ready — Awaiting Tenant Connection

Payment recovery worker handles declined-card retries, dunning emails, and overdue-invoice nudges. This panel shows live counts (and lets you trigger manual retry runs) once tenant payment + accounting data is connected.
⚙ Worker Status
Worker ready — not yet connected to tenant data
Declined YTD
cards declined
Overdue AR
accounting balance
Recovered MTD
retries succeeded
Active Dunning
in sequence
📋 Worker Behavior

Decline retry: Three attempts (T+0, T+3 days, T+7 days) before flagging for manual review.

Dunning sequence: Email at 7 / 14 / 21 / 28 days overdue, text at 14 days, phone-call task at 21 days.

Charge timing: Authorize at crew check-in, capture in the evening batch.

Suppression: Skip if the customer is in dispute or has an open support ticket.

Missed-cleaning / fuel fee charge: Auto-tracking and messaging run automatically, but the actual dollar charge requires owner approval per incident.

⚙ Activation Controls
Last fire: never · Last recovered: never
Toggle pauses the entire payment-follow-up sequence (decline retries + dunning + phone tasks). Manual Fire runs the retry sweep on demand against currently overdue accounts.

🔁 One-Time Customer Drip Worker Ready — Awaiting Tenant Connection

A drip sequence that nurtures one-time customers through the Day 0–80 conversion window with timed email and text touches designed to convert them to a recurring plan.
⚙ Worker Status
Worker ready — not yet connected to tenant data
In Drip
currently active
Converted MTD
one-time → recurring
Email Open Rate
drip avg
Avg Time to Convert
days from one-time job
📋 Drip Schedule
  • Day 1: Thank-you / "Did everything go well?" email
  • Day 7: Recurring-plan benefits email — soft pitch
  • Day 21: Discount offer — "10% off your first 3 cleanings if you go recurring"
  • Day 45: Social-proof email — neighborhood testimonials
  • Day 80: Final offer — last chance for the discount before the customer exits the funnel

Schedule, copy, and discount amounts are draft — tenant configures their own.

⚙ Activation Controls
Last fire: never · Last converted: never
Toggle pauses the entire one-time drip sequence (all 5 touches). Manual Fire runs a sweep on demand against every one-time customer currently inside the Day 0–80 conversion window.

🤝 Referral Engine Worker Ready — Awaiting Tenant Connection

Referral attribution and reward worker. Tracks customers who came in via word-of-mouth, attributes each new customer back to their referring customer, and triggers the configured credit reward automatically.
⚙ Worker Status
Worker ready — not yet connected to tenant data
Referrals YTD
attributed customers
Top Referrers
5+ referrals each
Credits Issued
YTD
Avg Tenure
referred customers
📋 Reward Mechanics

Trigger: A new customer whose lead source is "word of mouth" and who names a referring customer.

Reward: Credit automatically applied to the referrer's next invoice (amount configurable).

Two-sided bonus: The referred customer gets a discount on their first cleaning.

Top referrers: Tracked for VIP recognition (potential annual gift or extra perk).

Reward amounts and bonus structure are tenant-configurable.

⚙ Activation Controls
Last fire: never · Last credit issued: never
Toggle pauses referral attribution and credit issuance. Manual Fire sweeps recently-added customers, attributes any whose lead source is "word of mouth" with a referrer name, and issues the configured credit reward.
Saved — will persist once data sources are connected