# Task D.5.2: Lead Domain Service & API Foundation ## Objective Create the first production Lead service and API slice on top of the D.5.1 lead foundation without changing legacy enquiry behavior. ## Review Completed - `AGENTS.md` - `docs/standards/project-foundations.md` - `docs/standards/task-catalog.md` - `docs/adr/0018-lead-enquiry-domain-separation.md` - `docs/implementation/task-d5-lead-enquiry-domain-separation.md` - `docs/implementation/task-d51-lead-foundation-stabilization.md` - `src/db/schema.ts` - `src/features/crm/enquiries/server/service.ts` - `src/features/crm/customers/server/service.ts` - `src/features/crm/security/server/service.ts` - `src/features/foundation/audit-log/service.ts` - `src/features/foundation/document-sequence/service.ts` - `src/features/foundation/master-options/service.ts` ## What Was Added - Lead type contracts in [types.ts](C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/leads/types.ts) - Production lead service in [service.ts](C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/leads/server/service.ts) - Lead request schemas in [lead.schema.ts](C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/leads/schemas/lead.schema.ts) - Route handlers: - [route.ts](C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/crm/leads/route.ts) - [route.ts](C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/crm/leads/[id]/route.ts) - [route.ts](C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/crm/leads/[id]/followups/route.ts) ## Service Behavior - `crm_leads` is now the source of truth for lead CRUD - lead code generation reuses `generateNextDocumentCode()` with `documentType = crm_lead` - lead detail returns `suggestedSalesOwnerId` from `crm_customers.owner_user_id` when a linked customer exists - route handlers do not query Drizzle directly - access is enforced in the service layer through resolved CRM access converted into `CrmSecurityContext` ## Follow-up Persistence Decision Current schema has: - `crm_leads` - `crm_enquiry_followups` - no `crm_lead_followups` Task D.5.2 also prohibits: - new tables - new migrations Because of that, this slice implements lead follow-ups by reusing the audit foundation as the persistence stream for lead follow-up events: - POST `/api/crm/leads/[id]/followups` writes `create_lead_followup` - GET `/api/crm/leads/[id]/followups` reads those audit events back as lead follow-up history - the latest follow-up status is synchronized into `crm_leads.followup_status` This keeps D.5.2 inside its no-migration boundary while still making the API operational. ## Audit Actions This task records: - `create_lead` - `update_lead` - `delete_lead` - `view_lead` - `create_lead_followup` ## Intentional Non-Scope Preservation This task did not change: - enquiry CRUD - enquiry assignment flow - dashboard datasets - reporting datasets - won/lost synchronization - `crm_enquiries.pipeline_stage` - lead UI pages that still point at the legacy enquiry-based workspace ## Verification Planned verification target for this slice: - `npm exec tsc --noEmit` ## Notes For D.5.3+ - lead UI still needs to migrate away from enquiry-backed components - lead assignment and lead-to-enquiry conversion remain for later D.5 phases - if future phases need richer editable follow-up history than audit-backed event replay, a dedicated ADR-backed persistence decision is still needed