Go-to-market use cases -> Lead OS (applied now)
This document ties each revenue play to what already runs in this repo after the Erie / directory / billing / integration work. Keep `src/config/gtm-use-cases.ts` in sync when you change flows.
For a route-level map of what visitors can open without authentication vs what requires an operator session, see `PRODUCT-SURFACES.md` (and the in-app hub at `/docs` on a running deployment).
| # | Play | Applied via (runtime) | This week (concrete) |
|---|---|---|---|
| 1 | Erie.pro exclusive niche (plumbing first) | POST /api/intake + x-tenant-id: erie + category -> directory-lead-flow -> nodes 010 seed -> lead-delivery-hub | Plumbing page -> form -> npm run verify:migrations -> test lead -> 20 plumber calls |
| 2 | Exclusive category ownership (city x niche) | Same stack; one active node per `(tenant_id, metadata.category)` as ops rule; separate lead_os_tenants + billing_subscriptions per sold territory | Package "only plumber for {city}" -> one deal -> seed tenant/node -> enable in control plane |
| 3 | Managed lead ops | sendLead() / triggerWorkflow() / notifyClient() + SuiteDash + Activepieces URLs | One vertical tenant -> webhooks -> LEAD_OS_ENABLE_LIVE_SENDS staged -> 3 demos |
| 4 | National directory territories | Add coverage records in src/lib/directory-coverage.ts; seed tenants and nodes only for sold/active cities; avoid cloned frontend pages | /directory/national-* -> regional/state/city page -> second city seed + smoke intake |
| 5 | White-label agencies | billing_* tables + operator actions + per-customer LEAD_OS_TENANT_ID deploy | Agency plan row + control plane demo |
| 6 | Home services concierge | Multiple nodes rows keyed by metadata.category; same intake | "Request anything" UI sends category -> 1-2 nodes |
| 7 | Legal / immigration intake | category = practice area slug; message = case summary; billing enforce for seat | One attorney node + pilot intake JSON |
| 8 | Internal ops (YourDeputy) | All internal forms -> /api/intake + /dashboard/control-plane + Idempotency-Key | Wire forms; watch DLQ / pricing |
| 9 | Integration hub | lead-delivery-hub.ts + env webhooks; events in lead_os_events | One Activepieces flow; retire duplicate Zaps |
| 10 | Platform resale | Defer - docs + billing exist; no new SKU until case studies | 3-5 wins from rows 1-9 first |
Technical pointers (all plays)
- Intake:
src/app/api/intake/route.ts- tenant match, billing (402), idempotency,persistLead(body, tenantConfig), directory block. - Routing:
src/lib/erie/directory-lead-flow.ts-LEAD_OS_DIRECTORY_TENANTS, node lookup,lead_os_directory_routes, eventsdirectory_*. - Coverage catalog:
src/lib/directory-coverage.ts- national, national-niche, region, state, and major-city directory pages through one/directory/[vertical]template. - Delivery:
src/lib/integrations/lead-delivery-hub.ts-sendLead,triggerWorkflow,notifyClient. - Seed reference:
db/migrations/010_erie_directory_seed.sql. - Env templates:
.env.erie.example,.env.example(, , ...).
Exclusivity (practical rule)
"Exclusive plumber for Erie" = business + data: only one nodes row with status = 'active' and metadata.category = 'plumbing' for that tenant_id. Additional providers stay `paused` until you sell the slot. The router already picks the first active match; enforce exclusivity in ops, not magic auto-pricing.
Directory expansion rule
Do not clone the Erie frontend for each city. Erie is the first seeded city directory, but national, regional, state, and major-city access pages are generated from src/lib/directory-coverage.ts. Add buyer nodes and tenant records only when a market is sold or operationally active.
Code import (optional UI / admin)
import { GTM_USE_CASES, getGtmUseCaseById } from "@/config/gtm-use-cases";Use for internal dashboards or onboarding wizards.
Operator tooling (execution)
- Terminal -
npm run gtm:print(optional--json,--id=<n>, or--slug=<slug>). Use case #1 answers to botherie-exclusive-nicheand the aliaserie-plumbing. - Dashboard - sign in as an operator, open `/dashboard/gtm`. Each card shows anchors, env keys, checklist, and derived links to dashboard routes, APIs, and repo files. Change status (
not_started->live, etc.) or notes; values persist perLEAD_OS_TENANT_IDin `gtm_use_case_statuses` (migration011). - API -
GET /api/operator/gtmfor JSON automation;PATCH/POSTsame path with{ "slug": "...", "status": "in_progress", "notes": "..." }(at least one ofstatusornotes). Unknown slugs -> . Tenant header must match the deployment when is sent.