Files
alla-allaos-fullstack/plans/task-d.5.3.md
phaichayon 0c28735c90 task-d.5.3
2026-06-24 14:23:15 +07:00

5.3 KiB

Task D.5.3: Lead Assignment → Create Enquiry Foundation

Status

Planned

Objective

Implement the first production transition from Lead into Enquiry.

This task establishes the business boundary between:

Marketing Domain
    ↓
Lead

Sales Domain
    ↓
Enquiry

A Lead remains the marketing-owned source record.

An Enquiry becomes the sales execution workspace.

This task introduces:

  • Lead assignment workflow
  • Enquiry creation from Lead
  • Lead ↔ Enquiry relationship
  • Initial ownership transfer
  • Enquiry bootstrap generation

without changing quotation, dashboard, reporting, or approval behavior.


Mandatory Review

Review:

  • AGENTS.md
  • Project Foundations Registry
  • Task Catalog
  • ADR-0018 Lead / Enquiry Domain Separation
  • Task D.5
  • Task D.5.1
  • Task D.5.2
  • Customer Ownership Foundation
  • CRM Security Foundation
  • Audit Foundation
  • Document Sequence Foundation

Existing Foundation

Verified available:

crm_leads
crm_enquiries
crm_enquiries.lead_id

crm_lead sequence
crm_enquiry sequence

Lead Service
Lead API

Do not recreate:

tables
migrations
seed data
master-option categories

Business Model

Before Assignment

Owner:

Marketing

Workspace:

Lead

After Assignment

Owner:

Sales

Workspace:

Enquiry

Relationship

1 Lead
    ↓
0..N Enquiries

Lead remains immutable historical source.

Enquiries become sales execution records.


Scope D5.3.1 Lead Assignment Service

Create:

src/features/crm/leads/server/assignment.service.ts

Required operation:

assignLead()

Input:

AssignLeadInput

Fields:

leadId
salesOwnerId
assignmentRemark

Validation:

lead exists
lead active
salesOwnerId valid
same organization

Scope D5.3.2 Create Enquiry From Lead

Create:

createEnquiryFromLead()

inside assignment service.


Rules

Assignment automatically creates:

crm_enquiry

linked to:

crm_leads.id

through:

crm_enquiries.lead_id

Reuse:

generateNextDocumentCode()

with:

crm_enquiry

Expected:

EN2606-001

or existing enquiry format.

No custom numbering logic.


Scope D5.3.3 Enquiry Bootstrap Mapping

When enquiry is created:

Copy:

customerId
contactId
projectName
projectLocation
productType
description
estimatedValue
priority

from Lead.


Do NOT copy:

marketing-only notes
internal marketing activity history
audit events

Lead remains unchanged.


Scope D5.3.4 Lead Assignment API

Create:

POST /api/crm/leads/[id]/assign

Handler must call:

Lead Assignment Service

No direct DB access.


Response:

{
  leadId: string;
  enquiryId: string;
  enquiryCode: string;
}

Scope D5.3.5 Ownership Transfer

After assignment:

Lead:

status = assigned

Lead:

assigned_sales_owner_id
assigned_at
assigned_by

updated.


Enquiry:

owner_user_id

set to assigned salesperson.


Marketing remains able to:

view lead
view assignment result

but not manage enquiry.


Scope D5.3.6 CRM Security

Reuse:

resolveCrmMembershipAccess()

Assignment permission:

lead.assign

Only:

Marketing Manager
CRM Manager
Admin

or equivalent resolved permission.


Do not check role strings directly.


Scope D5.3.7 Duplicate Protection

Prevent:

multiple enquiry creation

for the same assignment action.


Rules:

If assignment already produced an active enquiry:

return existing enquiry

instead of creating a second one.


Scope D5.3.8 Audit Logging

Reuse audit foundation.

Required actions:

assign_lead
create_enquiry_from_lead

Audit must capture:

leadId
enquiryId
salesOwnerId

Scope D5.3.9 Legacy Compatibility

Do not modify:

quotation flow
approval flow
dashboard
reports
won/lost process

Current enquiry APIs must continue functioning.


Deliverables

New:

src/features/crm/leads/server/assignment.service.ts

New API:

POST /api/crm/leads/[id]/assign

Documentation:

docs/implementation/task-d53-lead-assignment-create-enquiry-foundation.md

Verification

Run:

npm exec tsc --noEmit

Verify:

Assign Lead
Create Enquiry
Reuse Existing Enquiry
Lead Status Update
Audit Logging
Security Enforcement

Verify:

Quotation APIs still work
Dashboard still works
Reports still work

Explicit Non-Scope

Do not:

  • create Lead UI
  • create Opportunity UI
  • create quotation conversion
  • change approval workflow
  • change reports
  • change dashboard
  • migrate historical data
  • implement won/lost synchronization

These belong to later D.5 phases.


Definition of Done

Task is complete when:

  • Lead assignment API exists
  • Assignment creates or reuses enquiry
  • crm_enquiries.lead_id is populated
  • Enquiry owner is assigned salesperson
  • Lead assignment is audited
  • Existing CRM functionality remains unchanged

Result:

Lead Assignment = Established

Lead → Enquiry Transition = Established

Ready for Opportunity Workspace Separation