6.6 KiB
Task D.5.2: Lead Domain Service & API Foundation
Status
Planned
Objective
Build the production Lead service layer and API foundation on top of the existing D.5.1 Lead Foundation.
This task introduces Lead as a first-class CRM domain without changing assignment workflows, dashboard datasets, reports, or legacy enquiry behavior.
The objective is to:
- establish Lead service architecture
- establish Lead API contracts
- establish Lead security boundaries
- establish Lead follow-up lifecycle handling
- prepare D.5.3 Lead Assignment → Create Enquiry
Mandatory Review
Review before implementation:
AGENTS.mddocs/standards/project-foundations.mddocs/standards/task-catalog.mddocs/adr/0018-lead-enquiry-domain-separation.mddocs/implementation/task-d5-lead-enquiry-domain-separation.mddocs/implementation/task-d51-lead-foundation-stabilization-output-completion.md- Customer Ownership Foundation
- Authorization Foundation
- Audit Foundation
- Master Option Foundation
- Document Sequence Foundation
Foundation Rules
The following already exist and must be reused:
crm_leads
crm_enquiries.lead_id
crm_lead_awareness
crm_lead_status
crm_lead_followup_status
crm_lead_lost_reason
crm_lead document sequence
crm_enquiry document sequence
Do not recreate:
tables
migrations
seed categories
document sequence configuration
Scope D5.2.1 Lead Service Layer
Create:
src/features/crm/leads/server/service.ts
Required operations:
listLeads()
getLeadById()
createLead()
updateLead()
deleteLead()
Rules:
- Use
crm_leadsas the Lead source of truth - No direct DB access from route handlers
- Keep legacy enquiry behavior unchanged
- Do not create enquiry from lead in this task
Reuse:
Customer Foundation
Audit Foundation
Authorization Foundation
Document Sequence Foundation
Master Option Foundation
Scope D5.2.2 Lead DTO Contracts
Create:
src/features/crm/leads/types.ts
Request contracts:
CreateLeadInput
UpdateLeadInput
LeadListFilters
CreateLeadFollowupInput
Response contracts:
LeadSummary
LeadDetail
LeadListResponse
LeadFollowupSummary
Lead Detail must include:
suggestedSalesOwnerId
when customer owner exists.
Important:
Do not auto assign.
Do not create enquiry.
This is suggestion only.
Scope D5.2.3 Lead Code Generation
Use existing document sequence foundation.
Document type:
crm_lead
Expected format:
LD2606-001
No custom numbering logic allowed.
Scope D5.2.4 Lead API Routes
Create:
GET /api/crm/leads
POST /api/crm/leads
GET /api/crm/leads/[id]
PATCH /api/crm/leads/[id]
DELETE /api/crm/leads/[id]
Routes must call:
Lead Service Layer
Route handlers must not query Drizzle directly.
Scope D5.2.5 Lead Follow-up Foundation
Create:
GET /api/crm/leads/[id]/followups
POST /api/crm/leads/[id]/followups
Rules:
- Reuse existing CRM follow-up pattern
- Do not create a second follow-up architecture
- Use lead follow-up status from master options
- Keep follow-up scoped to organization and CRM access
Scope D5.2.6 Lead Security
Reuse:
resolveCrmMembershipAccess()
Visibility:
Marketing:
own leads
Managers:
team scope
Admins:
organization scope
Rules:
- Do not check role strings directly
- Use resolved CRM access
- Enforce security in service layer
- UI visibility alone is not enough
Scope D5.2.7 Customer Ownership Integration
When customer owner exists:
customer.ownerUserId
Return:
suggestedSalesOwnerId
in Lead Detail.
Important:
- Do not auto assign
- Do not create enquiry
- Do not update
crm_enquiries - This is suggestion only
Scope D5.2.8 Master Option Integration
Lead APIs must expose options through existing master-option infrastructure:
awareness
status
followupStatus
lostReason
Use categories:
crm_lead_awareness
crm_lead_status
crm_lead_followup_status
crm_lead_lost_reason
Rules:
- No hardcoded labels
- Option values must come from foundation master options
- Keep inactive options hidden from normal API responses unless explicitly requested
Scope D5.2.9 Audit Logging
Reuse:
auditCreate()
auditUpdate()
auditDelete()
auditAction()
Required audit actions:
create_lead
update_lead
delete_lead
view_lead
create_lead_followup
Rules:
- Audit every mutation
- Audit lead detail view if existing audit convention supports view logging
- Do not introduce a separate audit pattern
Scope D5.2.10 Legacy Compatibility
Keep current system operational.
Current legacy behavior:
crm_enquiries.pipeline_stage
must remain untouched.
Do not:
change enquiry services
change assignment flow
change dashboard
change reports
change won/lost synchronization
Those belong to later D.5 phases.
Deliverables
New:
src/features/crm/leads/**
New APIs:
/api/crm/leads
/api/crm/leads/[id]
/api/crm/leads/[id]/followups
Documentation:
docs/implementation/task-d52-lead-domain-service-api-foundation.md
Expected Outputs
Lead Service:
CRUD operational
Lead API:
CRUD operational
Lead Follow-up:
API operational
Security:
resolved CRM access enforced
Audit:
lead actions recorded
Legacy CRM:
unchanged
Explicit Non-Scope
Do not:
- create Lead UI
- create Lead assignment flow
- create Lead → Enquiry conversion
- create Enquiry from Lead
- update dashboard
- update reports
- migrate legacy data
- remove
pipeline_stage - change existing enquiry APIs
- change quotation conversion behavior
These belong to:
D.5.3+
Verification
Run:
npm exec tsc --noEmit
Verify:
Create Lead
Update Lead
Delete Lead
View Lead
List Lead
Lead code generation
Lead follow-up creation
Lead follow-up listing
Audit logging
Current Enquiry APIs still function
Current Dashboard still functions
Current Reports still function
Definition of Done
Task is complete when:
- Lead service layer exists
- Lead CRUD APIs exist
- Lead follow-up APIs exist
- Lead security uses resolved CRM access
- Lead code generation uses sequence foundation
- Lead master options use foundation categories
- Audit logging exists
- Existing CRM functionality remains unchanged
Result:
Lead Domain Service = Established
Lead API Foundation = Established
Ready for D.5.3 Lead Assignment → Create Enquiry