LIS Command Center
Multi-agent business intelligence system for Legacy Insurance Solutions. Connects HubSpot CRM, EZLynx agency management, Slack notifications, and automated analytics into a single operational dashboard.
What It Does
- Daily briefings with deal pipeline status
- Real-time alerts for overdue deals and growth insights
- EZLynx-to-HubSpot sync for insurance policies
- Automated analytics and performance tracking
- Slack notifications for team awareness
Tech Stack
- Database: Supabase (PostgreSQL)
- Frontend: Vercel (Next.js dashboard)
- Notifications: Slack Bot
- CRM: HubSpot (deals, contacts, owners)
- Automation: n8n Cloud workflows
- Scraping: Playwright (EZLynx)
HubSpot Owners
Database Tables
Dashboard & Briefings
The daily briefing system aggregates deal status, analytics, and alerts into a single morning report delivered via Slack and the web dashboard.
Daily Briefing Flow
Briefing Data Structure
| daily_briefings Table | |
|---|---|
| briefing_date | Date of the briefing (one per day) |
| deals_summary | JSON: total deals, by stage, by owner, new vs stale |
| pipeline_value | Total weighted pipeline value across all stages |
| ai_insights | GPT-4o generated analysis: trends, risks, opportunities |
| action_items | Array of recommended actions for the day |
| alerts_count | Number of active alerts requiring attention |
Dashboard Metrics
- Pipeline value (total + by product line)
- Deal velocity (avg days per stage)
- Win rate (trailing 30/60/90 days)
- Revenue forecast (weighted pipeline)
- Owner performance comparison
- Stale deal count and aging
Slack Integration
- Channel: #lis-command-center
- Workspace: legacyinsurancecohq.slack.com
- Daily briefing: Formatted summary at 7 AM
- Alerts: Real-time for urgent items
- Deal actions: When deals need attention
process-deal-action is deployed on Supabase Edge Functions. It handles deal action processing when triggered from the dashboard or Slack interactions.Deal Pipeline
HubSpot deal tracking across multiple insurance product lines. Each product has its own pipeline stages with unique IDs.
Pipeline Stages per Product Line
| HubSpot Pipeline Stage IDs | |||
|---|---|---|---|
| Stage | Auto | Homeowners | Renters / Life |
| New Lead | appointmentscheduled |
appointmentscheduled |
appointmentscheduled |
| Quoting | qualifiedtobuy |
qualifiedtobuy |
qualifiedtobuy |
| Proposal Sent | presentationscheduled |
presentationscheduled |
presentationscheduled |
| Closed Won | closedwon |
closedwon |
closedwon |
| Closed Lost | closedlost |
closedlost |
closedlost |
deals_snapshot Table
| Key Fields | |
|---|---|
| hubspot_deal_id | HubSpot deal record ID |
| deal_name | Contact name + product line |
| pipeline_id | Which product line pipeline |
| stage_id | Current pipeline stage |
| owner_id | HubSpot owner (Shane, Sonny, or LISA) |
| amount | Deal value (annual premium) |
| days_in_stage | How long the deal has been in current stage |
| last_activity | Timestamp of last deal activity |
| snapshot_date | When this snapshot was taken |
deal_actions Table
Recommended actions generated by the AI analysis engine. Processed by the process-deal-action edge function.
| Action Types | |
|---|---|
| follow_up | Contact needs a follow-up call or email |
| stage_advance | Deal ready to move to next stage |
| reassign | Deal should be reassigned to different owner |
| close_stale | Deal has been stale too long, recommend closing |
| escalate | High-value deal needs manager attention |
Alerts & Growth Insights
Proactive monitoring for deal risks and growth opportunities. Alerts fire in real-time; growth insights are generated daily.
Alert Types
| alerts Table | |
|---|---|
| stale_deal | Deal inactive for 7+ days |
| overdue_task | Scheduled follow-up is past due |
| high_value_risk | Deal >$5K stalling in pipeline |
| owner_overload | Owner has 15+ active deals |
| pipeline_gap | Product line has no new leads in 7 days |
| sync_failure | EZLynx sync failed or returned errors |
Growth Insights
| growth_insights Table | |
|---|---|
| cross_sell | Client has Auto but no Home policy |
| renewal_opp | Policy renewal coming in 30 days |
| referral_ready | Happy client, high satisfaction score |
| upsell | Coverage gap identified in current policy |
| market_trend | Product line showing growth trajectory |
Analytics Daily
| analytics_daily Table | |
|---|---|
| date | Analytics date |
| new_deals | Deals created today (by product line) |
| deals_won | Deals closed won today |
| deals_lost | Deals closed lost today |
| revenue_won | Total premium from won deals |
| avg_deal_velocity | Average days from lead to close |
| conversion_rate | Won / (Won + Lost) trailing 30 days |
| pipeline_value | Total active pipeline value |
EZLynx Sync Pipeline
Playwright-based scraper extracts policy data from EZLynx, parses it, matches it against HubSpot contacts, and syncs deal status. Handles the critical quirks of EZLynx's data format.
Sync Pipeline Flow
Pipeline Stage IDs by Product Line
| EZLynx Product → HubSpot Pipeline Mapping | ||
|---|---|---|
| Auto | Personal auto, commercial auto | Auto pipeline |
| Homeowners | HO3, HO5, dwelling fire | Home pipeline |
| Renters | HO4 (tenant/renter policies) | Renters pipeline |
| Life | Term, whole, universal life | Life pipeline |
EZLynx labels Renters policies as "Home" or "Homeowners" in its export. The only way to distinguish them is by premium amount: policies under $300/year are Renters, above are true Homeowners. The sync engine applies this $300 threshold automatically.
Couple Name Extraction
EZLynx often stores names as couples:
John & Jane Smith→ Primary: John SmithSmith, John & Jane→ Primary: John SmithJohn Smith & Jane Doe→ Primary: John Smith
The matching engine extracts the primary name for HubSpot lookup. Secondary name is stored as a note.
Renewal vs New Business
The sync engine separates:
- New Business: No prior policy in EZLynx for this client + product line. Creates a new HubSpot deal.
- Renewals: Existing policy found. Updates the existing deal and moves to renewal stage rather than creating a duplicate.
Match key: client name + product line + effective date window.
Reconciliation Engine
After each sync, the reconciliation engine verifies data integrity between EZLynx and HubSpot. Catches mismatches, duplicates, and missing records.
Reconciliation Flow
What Gets Checked
| Reconciliation Rules | ||
|---|---|---|
| Policy count match | EZLynx export count = HubSpot deal count per product line | Auto |
| Premium alignment | EZLynx premium matches HubSpot deal amount (within $5 tolerance) | Auto |
| Duplicate detection | Same client + product line should not have multiple active deals | Auto |
| Orphaned deals | HubSpot deals with no matching EZLynx policy | Auto |
| Missing contacts | EZLynx policies with no matching HubSpot contact | Auto |
| Stage consistency | Bound policies in EZLynx should be "Closed Won" in HubSpot | Auto |
Common Reconciliation Fixes
- Duplicate deal: Merge in HubSpot, keep the one with more activity
- Premium mismatch: Update HubSpot amount from EZLynx (source of truth)
- Missing contact: Create contact in HubSpot, then re-run sync
- Stage mismatch: Update HubSpot stage to match EZLynx policy status
Never Do
- Don't update EZLynx from HubSpot (EZLynx is source of truth for policies)
- Don't delete HubSpot deals without checking EZLynx first
- Don't manually override the $300 Renters threshold
- Don't ignore sync_failure alerts — they cause data drift
Renewal Intelligence Pipeline
Automated weekly pipeline that scrapes policy expiration data from EZLynx, categorizes by urgency, sends Slack alerts, and feeds a visual renewal calendar on the dashboard.
📅 Pipeline Flow
🔴 Urgency Tiers
| Critical (0-30 days) | |
|---|---|
| Full policy detail | Up to 8 shown in Slack |
| Warning (31-60 days) | |
| Summary with premiums | 5 shown + count |
| Watch (61-90 days) | |
| Aggregate count | Total premium at stake |
⚙️ SSRS Date Filters
The scraper now sets SSRS ReportViewer date parameters before export:
- Custom date range — Pass
start_dateandend_dateto any report - Historical pulls —
extract_historical_reports()pulls quarterly data going back 12+ months - Auto-detection — Finds SSRS date inputs by known IDs or falls back to panel scanning
🕒 Scheduling
Tool: tools/renewal_pipeline.py — runs as Windows Task Scheduler job
- Trigger: Weekly, Monday 6:00 AM
- Action:
python renewal_pipeline.py - Automatically sets 90-day date filter on the expiration report
- Sends Slack alert, pushes to Supabase, saves execution log
- Can be tested with
skip_scraper=Trueto reuse existing data
📈 Dashboard: Renewal Calendar
New dashboard component shows all policies expiring in the next 90 days with interactive urgency tier filtering. Click a tier to expand its policies — each shows client name, LOB, carrier, premium, and countdown.
Bundle Tracker & Cross-Sell Detection
Identifies clients with single lines of business and surfaces the highest-value cross-sell opportunities to grow wallet share.
🔮 How It Works
📊 Bundle Rate KPI
The bundle rate shows the percentage of clients with 2+ active LOBs (e.g., Auto + Home). Higher rates mean better retention and more revenue per customer.
- Bundled clients — 2+ active pipelines
- Single LOB clients — Cross-sell targets
- Top missing LOBs — What to pitch next
🎯 Scoring Algorithm
| Score Components | |
|---|---|
| Premium Base | Up to 50 points from existing premium |
| LOB Bonus | 15 points per missing common LOB |
| Max Score | 100 (high-premium, single-LOB client) |
Natural bundles: Auto+Home, Auto+Renters, Home+Umbrella
💻 Dashboard View
The Bundle Tracker component shows:
- Bundle rate percentage as a prominent KPI
- Summary cards: Bundled vs Single LOB vs Total clients
- Top cross-sell demand (most missing LOBs across all clients)
- Scrollable list of opportunities with existing LOBs → missing LOBs visualization
- Color-coded LOB tags (Auto=blue, Home=green, Life=pink, etc.)
🛠 NBS/RWL Classification
The parser now auto-classifies transactions as New Business or Renewal when EZLynx's Transaction_Type2 field is missing:
- Customer Since vs Effective Date — Same year = New Business
- LOB Origination Date — Matches effective = NBS, earlier = RWL
- Policy Creation Date — Within 30d of effective = NBS
- Source Report — Retention/Expiration report = likely RWL
Architecture
How all the pieces connect: Supabase as the data layer, n8n as the automation engine, and integrations flowing through APIs.
System Architecture
Connection Details
| Service Config | |
|---|---|
| Supabase | Project: oipmskrmitcntytkrivi |
| n8n | smrich.app.n8n.cloud |
| Slack | legacyinsurancecohq.slack.com |
| HubSpot | 3 owners (Shane, Sonny, LISA) |
| Edge Function | process-deal-action |
Build Phases
- Phase 1-3: Core ✓DB tables, HubSpot sync, dashboard
- Phase 4: Notifications ✓Slack alerts, daily briefings, renewal scanner
- Phase 5: AI Skills ✓GPT-4o analysis and recommendations
- Phase 6: Renewals ✓SSRS date filters, renewal pipeline, calendar view
- Phase 7: Cross-Sell ✓Bundle tracker, cross-sell scoring, stale drill-down
Data Flow Summary
| Integration Points | ||
|---|---|---|
| EZLynx → Supabase | Policy data scraped and stored for matching | Daily sync |
| HubSpot → Supabase | Deal snapshots pulled and stored | Every 4 hours |
| Supabase → HubSpot | Deal actions executed (stage changes, assignments) | On demand |
| Supabase → Slack | Alerts, briefings, action notifications | Real-time + daily |
| Supabase → Vercel | Dashboard reads from Supabase directly | Real-time |
| EZLynx → Slack | Renewal alerts (30/60/90d expiration tiers) | Weekly |
| HubSpot → Bundle | Cross-sell analysis pushed to bundle_opportunities | Weekly |