flowchart TD
subgraph INGESTION["🔵 Lead Ingestion"]
WH["POST /api/leads/incoming\n(Webhook)"]
VAL["Validate Payload\n(Zod Schema)"]
IDEM["Idempotency Check\n(ghl_contact_id)"]
INS["Insert Lead\nstatus = pending"]
WH --> VAL --> IDEM --> INS
end
subgraph ASSIGNMENT["🟢 Assignment Engine (SQL RPC)"]
LOCK["pg_advisory_xact_lock\n(Global Serialize)"]
MATCH{"Find Best\nMatching Order"}
CRIT["Match Criteria:\n• Active order + broker\n• Vertical match\n• Credit score ≥ min\n• Capacity remaining\n OR bonus_mode"]
RANK["Ranking:\n1. remaining/total DESC\n2. last_assigned_at ASC"]
LOCK --> MATCH
CRIT -.-> MATCH
RANK -.-> MATCH
end
subgraph ASSIGNED["✅ Match Found"]
UPD_LEAD["Update Lead\nstatus = assigned\nset broker + order"]
UPD_ORDER["Update Order\nleads_delivered++\nleads_remaining--"]
AUTO_COMP{"leads_remaining\n≤ 0?"}
COMP["Auto-Complete\nOrder"]
LOG_A["Log: lead_assigned"]
CREATE_DEL["Create Delivery Rows\n(per broker channels)"]
UPD_LEAD --> UPD_ORDER --> AUTO_COMP
AUTO_COMP -- "Yes & !bonus_mode" --> COMP --> LOG_A
AUTO_COMP -- "No" --> LOG_A
LOG_A --> CREATE_DEL
end
subgraph UNASSIGNED["❌ No Match"]
UPD_UN["Update Lead\nstatus = unassigned"]
QUEUE_UN["Insert into\nunassigned_queue\nwith reason"]
LOG_UN["Log: lead_unassigned"]
REASON["Reasons:\n• No vertical match\n• Credit score too low\n• Capacity exhausted\n• No active orders"]
UPD_UN --> QUEUE_UN --> LOG_UN
REASON -.-> QUEUE_UN
end
subgraph HOURS_CHECK["🕐 Contact Hours Gate"]
CHK_HRS{"Within Broker\nContact Hours?"}
HRS_CFG["Config:\n• anytime\n• business_hours (9-5)\n• custom range\n• weekend_pause\n• timezone"]
HRS_CFG -.-> CHK_HRS
end
subgraph DELIVERY["📤 Delivery Execution"]
PEND["status = pending"]
QUEUED["status = queued"]
subgraph CHANNELS["Delivery Channels"]
CRM["CRM Webhook\nPOST to broker URL\n(pg_net trigger)"]
EMAIL["Email via GHL\nHTML lead details\n(Edge Function)"]
SMS["SMS via GHL\nCompact text\n(Edge Function)"]
end
PEND --> CHANNELS
end
subgraph QUEUE_PROC["⏰ Queue Processor (Cron: */5 min)"]
CRON["process_queued_deliveries()"]
RE_CHK{"Within Hours\nNow?"}
RELEASE["Release Delivery\nLog: delivery_released"]
WAIT["Keep Queued"]
CRON --> RE_CHK
RE_CHK -- "Yes" --> RELEASE
RE_CHK -- "No" --> WAIT
end
subgraph RETRY["🔄 Retry Pipeline"]
FAIL["status = failed"]
RETRY_CHK{"retry_count\n< 3?"}
BACKOFF["Exponential Backoff\n2^n minutes"]
RE_EXEC["Re-execute\nDelivery"]
PERM_FAIL["status = failed_permanent"]
ALERT["Send Admin Alert\n(SMS via GHL)"]
LOG_FAIL["Log: delivery_failed_permanent"]
FAIL --> RETRY_CHK
RETRY_CHK -- "Yes" --> BACKOFF --> RE_EXEC
RETRY_CHK -- "No (≥3)" --> PERM_FAIL --> LOG_FAIL --> ALERT
end
subgraph DASHBOARD["📊 Admin Dashboard"]
KPI["KPI Cards\nLeads · Orders · Brokers\nQueued Deliveries"]
DEL_STATS["Delivery Stats\nSent · Failed · Per Channel"]
CHART["Lead Volume Chart\n(7-day)"]
ACTIVITY["Activity Feed\n(Audit Log)"]
MGMT["Manage:\n• Pause/Resume Brokers\n• Pause/Resume Orders\n• Toggle Bonus Mode\n• Manual Retry"]
end
subgraph DIGEST["📬 Scheduled Reports"]
DAILY["Daily Digest\n(Edge Function)\n6 AM via cron"]
end
%% Main Flow Connections
INS --> LOCK
MATCH -- "Match Found" --> UPD_LEAD
MATCH -- "No Match" --> UPD_UN
CREATE_DEL --> CHK_HRS
CHK_HRS -- "Yes" --> PEND
CHK_HRS -- "No" --> QUEUED
QUEUED --> CRON
RELEASE --> PEND
CRM --> FAIL
EMAIL --> FAIL
SMS --> FAIL
RE_EXEC --> CHANNELS
%% Success path
CRM -- "2xx" --> SENT["status = sent ✅"]
EMAIL -- "2xx" --> SENT
SMS -- "2xx" --> SENT
%% Dashboard reads
SENT -.-> DEL_STATS
FAIL -.-> DEL_STATS
LOG_A -.-> ACTIVITY
LOG_UN -.-> ACTIVITY
%% Styling
classDef success fill:#10b981,stroke:#059669,color:#fff
classDef fail fill:#ef4444,stroke:#dc2626,color:#fff
classDef pending fill:#f59e0b,stroke:#d97706,color:#fff
classDef info fill:#3b82f6,stroke:#2563eb,color:#fff
classDef queued fill:#8b5cf6,stroke:#7c3aed,color:#fff
class SENT success
class PERM_FAIL,FAIL fail
class PEND,QUEUED pending
class WH,CRM,EMAIL,SMS info
class CRON queued
Created
March 13, 2026 14:25
-
-
Save hmseeb/9362f1caeac9dc236200fd6a87b5aa8b to your computer and use it in GitHub Desktop.
PPL Leadr Management — Full System Flow (Mermaid)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment