# Task D.5.3: Lead Assignment -> Create Enquiry Foundation ## Objective Establish the first production lead-assignment flow that preserves `crm_leads` as the marketing-owned source record while creating or reusing a linked `crm_enquiries` record for the sales execution workspace. ## 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-d52-lead-domain-service-api-foundation.md` - `docs/security/crm-authorization-boundaries.md` - `src/features/crm/leads/server/service.ts` - `src/features/crm/enquiries/server/service.ts` - `src/features/crm/customers/server/service.ts` - `src/features/foundation/audit-log/service.ts` - `src/features/foundation/document-sequence/service.ts` ## What Changed - Added lead bootstrap and assignment fields to `crm_leads`: - `description` - `product_type` - `priority` - `estimated_value` - `assigned_sales_owner_id` - `assigned_at` - `assigned_by` - `assignment_remark` - Added [assignment.service.ts](C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/leads/server/assignment.service.ts) with: - `assignLead()` - internal `createEnquiryFromLead()` - Added [route.ts](C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/crm/leads/[id]/assign/route.ts) for `POST /api/crm/leads/[id]/assign` - Extended lead DTOs and schemas so new lead records can carry the data needed to bootstrap an enquiry - Added `assigned` to seeded `crm_lead_status` - Tightened enquiry-owner validation so assignees must be sales-assignable members, not merely any organization member ## Assignment Behavior - route permission is `crm.lead.assign` - service validates: - lead exists and is active - actor can access the lead through resolved CRM scope - assignee belongs to the same organization and is a sales-assignable member - if an active enquiry already exists for the lead: - no second enquiry is created - the existing enquiry is returned - lead assignment metadata is synchronized - if no active enquiry exists: - enquiry code generation reuses `generateNextDocumentCode()` with `documentType = crm_enquiry` - enquiry is created with `lead_id = crm_leads.id` - enquiry owner compatibility fields use the existing enquiry model: - `assigned_to_user_id` - `assigned_at` - `assigned_by` - `assignment_remark` ## Lead -> Enquiry Bootstrap Mapping When creating the enquiry from a lead, the flow copies: - `customerId` - `contactId` - `description` - `projectName` - `projectLocation` - `productType` - `estimatedValue` - `priority` The enquiry title is derived from `lead.projectName` and falls back to `Lead ` when the project name is empty. ## Audit Actions This task records: - `assign_lead` on `crm_lead` - `create_enquiry_from_lead` on `crm_enquiry` Captured linkage includes: - `leadId` - `enquiryId` - `salesOwnerId` ## Compatibility Notes This task intentionally does not change: - quotation flows - approval flows - dashboard datasets - reporting datasets - won/lost lifecycle flows - legacy enquiry list/detail APIs outside the stricter assignee validation `crm_enquiries.pipeline_stage` remains in place for compatibility, but lead assignment now creates a dedicated enquiry record instead of mutating a lead record in place.