Files
alla-allaos-fullstack/docs/implementation/task-d52-lead-domain-service-api-foundation.md
2026-06-24 13:39:25 +07:00

95 lines
3.4 KiB
Markdown

# 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