Leads Module
Reference business module for the EloSync platform. Every future module (Tasks, Invoices, Inventory, etc.) must mirror this structure.
Guides
| Audience | Document |
|---|---|
| Operators / workspace users | leads-user.md |
| Engineers | leads-developer.md |
| Production / ops | leads-production.md |
| Meta App + EloSync connect | meta-app-setup.md |
| Module Development Standard | module-development.md |
| Tenant API | ../api/tenant-v1-leads.md |
Capabilities (Sprint 2 CRM UX)
- Pipeline stages (seeded: New → Contacted → Qualified → Proposal → Negotiation → Won / Lost)
- Disposition tags — multi-select catalog (CRUD + sort order); seeded Not Contacted (default), Contacted, No Response (auto follow-up days), Invalid Number, Not Interested, Not Applied, Follow Up Later (requires creating a follow-up). Tags are independent of stage/status; badges on board, table, and detail.
- Independent status —
active,waiting,on_hold,closed,archived(not derived from stage) - Priority —
low,medium,high,urgent - Lead value —
lead_value(renamed fromestimated_value; API still accepts the old key as an alias on write) - Assignment with assignment history table
- Notes, follow-ups (create / update-reschedule / complete), activity timeline
- Kanban board (default) + table view; drag-and-drop auto-saves the stage change
- Hybrid list sheet — New /
Nand board/table peek open a side sheet for fast create and tabbed peek; dedicated record pages remain for convert, AI, deep links, and notifications - KPIs via
GET /leads/stats; board viaGET /leads/board - Export CSV / XLSX of the current filtered set (
leads.export) - Import CSV / XLSX via multi-step wizard (
leads.import) — column mapping (including optional first Note), duplicate modes, preview, queued processing, history + reports - Inbound integrations (
leads.manage_integrations) — Custom webhooks (Zapier-ready) + Meta Lead Ads OAuth / Page subscribe - Convert (
leads.convert) — setsconverted_at, records a converted activity, sets statusclosed; creates/links a real Contact when that module is installed; creates/links a Company from the lead company name or optionalcompany_id/company_name(company timelineConvertedFromLead); optionally creates an Opportunity unless Settings → Leads requires one (leads.convert_require_opportunity) or enforces a minimum amount (leads.convert_min_opportunity_amount); storesconversion_metawith company/contact/opportunity ids and names; firesLeadConverted(Automation triggerlead.converted). Without Contacts, convert stays status-only for contacts - Assignee scoping — without
leads.assign, users only see their own leads - Inactivity digest — assigned Active leads with no meaningful activity for N working days trigger one assignee in-app digest and one manager table email (clickable name, phone, email). Leads stay assigned. Settings → Leads. Catalog 1.9.0.
- Follow-up KPI filters — click Today's / Overdue follow-up KPIs to filter list/board (
follow_up=today|overdue). Catalog 1.9.1. - Real-time board sync — private Reverb channel
tenant.{id}.leads.board(auth: same tenant +leads.view) broadcastsLeadCreated/LeadUpdated/LeadStageChanged/LeadAssigned/LeadDeleted; the board view invalidatesleads/board+leads/stats(debounced) so teammates see moves, assignments, and deletes without a manual refresh. Mirrors the Live Chat inbox invalidate pattern. Catalog 1.8.0. Go-live: production readiness. - Module licensing (
module:leads) + Spatie permissions — catalog 1.9.1 - Created by / Updated by — denormalized on the lead row (backfilled from activity on upgrade); filterable on list/board; table columns; System when null (imports/webhooks). Updated by follows field edits, notes, tags, and follow-ups. Go-live: production readiness.
- Audit + activity logging; assignment / follow-up notifications (mail + database)
Permissions
leads.view · create · update · delete · assign · export · import · convert · manage_integrations