Leads & CRM — Code Map
API
Module — leads (public lead intake)
| File | Purpose |
|---|---|
apps/api/src/leads/leads.module.ts | Wires LeadsController + LeadsService + cross-import to OrganizationLeadsService. |
apps/api/src/leads/leads.controller.ts | Two public endpoints: platform waitlist + minisite contact form. |
apps/api/src/leads/leads.service.ts | Tiny — only handles platform leads (inserts leads + platform_leads). |
Module — organization-leads (staff CRM)
| File | Purpose |
|---|---|
apps/api/src/organization-leads/organization-leads.module.ts | Wires controller + service. |
apps/api/src/organization-leads/organization-leads.controller.ts | All staff CRM routes under organizations/:orgId/leads. Decorated with @RequiresFeature('lead_management'). |
apps/api/src/organization-leads/organization-leads.service.ts | List/get/create/update/convert/analytics. Owns dedup + auto-task + status event history. |
Routes
| Method | Path | Handler | Auth |
|---|---|---|---|
| POST | /leads | LeadsController.createPlatformLead | @Public |
| POST | /leads/organization/:orgId | LeadsController.createMinisiteLead | @Public |
| GET | /organizations/:orgId/leads/analytics | OrganizationLeadsController.getAnalytics | Bearer + staff + lead_management |
| GET | /organizations/:orgId/leads | listLeads | same |
| GET | /organizations/:orgId/leads/:leadId | getLead | same |
| POST | /organizations/:orgId/leads | createLead | same |
| PATCH | /organizations/:orgId/leads/:leadId | updateLead | same |
| POST | /organizations/:orgId/leads/:leadId/convert | convertLead | Bearer + owner/admin + lead_management |
Web
| Component / Route | Description |
|---|---|
apps/web/src/app/[lang]/(protected)/dashboard/leads/page.tsx + leads-content.tsx + leads-page.driver.tsx | List, filters, search. |
apps/web/src/components/leads/add-lead-dialog.tsx | Manual create. |
apps/web/src/components/leads/convert-lead-dialog.tsx | Convert UI; calls POST /leads/:id/convert. |
apps/web/src/components/leads/lead-detail-sheet.tsx | Side sheet showing detail + status events + edit form. |
i18n: leads.* in apps/web/src/i18n/dictionaries/. |
DB tables
| Table | Used as |
|---|---|
leads | Canonical lead row. |
platform_leads | Waitlist tag for platform-marketing leads. |
organization_leads | Per-org link + assignment + trial date + converted membership. |
lead_status_events | Append-only history. |
memberships | Created by convertLead; source_lead_id set. |
users | Find-or-create shell on convert. |
tasks | Auto-task on new lead. |
Shared schemas
libs/shared/src/lib/schemas/lead.schema.ts exports the Zod schemas used by controllers:
createPlatformLeadSchema— name/email/phone/locale/source/note.createOrganizationLeadSchema— same; source defaults to'manual'(public minisite path overrides to'minisite').updateOrganizationLeadSchema— name/email/phone/note/status/assignedToUserId/trialDate.listOrganizationLeadsSchema— search/status/source/page/limit query params.convertLeadSchema— firstName/lastName/email/role.
Enums: leadSource, leadStatus (see libs/db/src/lib/schema/enums.ts).
Events
| Event | Producer | Consumers |
|---|---|---|
MEMBERSHIP_ACTIVATED { source:'lead_converted' } | convertLead | Forms fan-out (compliance forms), analytics, future welcome emails (per code comments). |
Tests
| File | What it covers |
|---|---|
apps/web/src/app/[lang]/(protected)/dashboard/leads/leads-page.driver.tsx | Web driver for leads page (driver pattern — see CLAUDE.md). |
| API unit specs | No dedicated unit spec found for LeadsService or OrganizationLeadsService as of this audit. TODO: add. |