Files
alla-allaos-fullstack/plans/task-d.5.md
phaichayon c1ecd5ea50 commit
2026-06-23 22:13:08 +07:00

7.7 KiB

Task D.5: Lead / Enquiry Domain Separation

Objective

Refactor CRM pipeline architecture by separating Lead and Enquiry into dedicated business entities.

Replace the current shared crm_enquiries + pipelineStage model with a true business flow:

Lead
→ Enquiry
→ Quotation
→ Won / Lost

The new model must support:

1 Lead
→ N Enquiries

1 Enquiry
→ N Quotations

1 Quotation
→ N Options

and remove the ambiguity caused by stage-based mutation.


Business Discovery 3.1 (Frozen)

Marketing Flow

Marketing
↓
Create Lead
↓
Follow Up
↓
Assign Sales
↓
Create Enquiry

Marketing owns Leads.


Sales Flow

Sales
↓
Create Enquiry Directly

Sales can create Enquiries without a Lead.


Sales Execution Flow

Enquiry
↓
Quotation
↓
PO Received
↓
Won

or

Enquiry
↓
Lost

Mandatory Review

Before implementation review:

  • AGENTS.md
  • Project Foundations Registry
  • Task Catalog
  • ADR 0011 Lead / Enquiry Ownership Model
  • ADR 0016 Won / Lost Lifecycle Governance
  • Customer Ownership Foundation
  • Reporting Foundation
  • Authorization Foundation
  • Dashboard Foundation

Required Skills

Governance

  • AGENTS.md
  • Task Contract Template
  • Architecture Rules
  • Task Review Checklist

CRM

  • Lead / Enquiry Governance
  • Won / Lost Governance
  • Customer Ownership Governance
  • Revenue Attribution Governance

Security

  • CRM Authorization Foundation
  • Scope Enforcement Foundation

Scope D5.1 Lead Table

Create:

crm_leads

Lead becomes a dedicated entity.

Core fields:

id

organizationId
branchId

code

customerId
contactId

projectName
projectLocation

awarenessId

status
followupStatus
lostReason

outcome

ownerMarketingUserId

createdBy
createdAt
updatedAt
deletedAt

Scope D5.2 Lead Awareness

Master option category:

crm_lead_awareness

Seed:

Google Search / Website
Social Media
Email Marketing
Visit
Exhibition / Event
Brochure / Catalog
Word of Mouth
Corporate Car
Product Label
Re-purchasing
Introducing
BCI

Purpose:

ลูกค้ารู้จักเราจากช่องทางใด

Used in:

  • Lead Form
  • Lead Dashboard
  • Lead Reports
  • Marketing Analytics

Scope D5.3 Lead Status

Master option:

crm_lead_status

Values:

new_job
follow_up
closed_lost
cancel

Display:

New Job
Follow Up
Closed Lost
Cancel

Scope D5.4 Lead Follow-up Status

Master option:

crm_lead_followup_status

Values:

budget_pending
project_under_review
spec_clarification
site_survey_waiting
drawing_followup
quotation_preparation
waiting_po

Display:

รองบประมาณ
ระหว่างพิจารณาโครงการ
เคลียร์สเปค
รอสำรวจหน้างาน
ติดตามแบบงาน
ระหว่างการเสนอราคา
รอลูกค้าออก PO

Visible only when:

Lead Status = Follow Up

Scope D5.5 Lead Lost Reason

Master option:

crm_lead_lost_reason

Values:

price
delivery_time
sales_person
service
customer
product_quality
other
transfer

Display:

ราคา
ระยะเวลาจัดส่ง
พนักงานขาย
การบริการ
ลูกค้า
คุณภาพสินค้า
อื่นๆ
Transfer

Visible only when:

Lead Status = Closed Lost
or
Lead Status = Cancel

Scope D5.6 Lead Outcome

Add:

crm_leads.outcome

Values:

open
won
lost

Purpose:

Marketing KPI and reporting.

Marketing must not update manually.


Scope D5.7 Enquiry Refactor

Refactor:

crm_enquiries

to become a pure Sales entity.

Remove Lead lifecycle responsibilities.

Add:

leadId nullable

Relationship:

crm_leads 1
→ N crm_enquiries

Scope D5.8 Lead Assignment

Replace:

pipelineStage change

with:

Create Enquiry

Flow:

Lead
↓
Assign Sales
↓
Create Enquiry

Lead remains.

Enquiry is created.


Scope D5.9 Direct Sales Enquiry

Support:

Sales
↓
Create Enquiry Directly

Business Rule:

leadId = null

Allowed.

Examples:

Existing Customer
Walk-in Customer
Direct Referral
Sales Prospecting

Scope D5.10 Multiple Product Types

Support:

1 Lead
→ N Enquiries

Example:

Lead LD2606-001

├─ EN2606-001 Crane
├─ EN2606-002 Dock Door
└─ EN2606-003 Solar

Each enquiry has:

productTypeId
salesmanId
assignedToUserId

independently.


Scope D5.11 Outcome Synchronization

Marketing should never update outcomes manually.

When:

Enquiry = Won

Update:

Lead Outcome = Won

Automatically.


When:

All Enquiries linked to Lead = Lost

Update:

Lead Outcome = Lost

Automatically.


Lead Outcome is derived from Enquiry outcomes.


Scope D5.12 Document Sequences

Create dedicated sequences.

Lead:

LD2606-001

Enquiry:

EN2606-001

Separate document types.

Separate counters.


Scope D5.13 Dashboard Refactor

Lead KPI Source:

crm_leads

Enquiry KPI Source:

crm_enquiries

No stage filtering.


Scope D5.14 Reporting Refactor

Update:

  • Lead Pipeline
  • Lead Aging
  • Lead Conversion
  • Enquiry Pipeline
  • Enquiry Aging
  • Funnel Reports

Reuse:

Reporting Foundation

No parallel reporting implementation.


Scope D5.15 Security Refactor

Lead visibility:

Marketing
Managers
Admins

Enquiry visibility:

Assigned Sales
Managers
Admins

Use:

resolveCrmMembershipAccess()

No direct role checks.


Scope D5.16 Data Migration

Migrate existing records.

Rules:

pipelineStage = lead
→ crm_leads

pipelineStage = enquiry
→ crm_enquiries

pipelineStage = closed_won
→ crm_enquiries

pipelineStage = closed_lost
→ crm_enquiries

Preserve:

  • follow-ups
  • customers
  • attachments
  • ownership
  • audit history

Deliverables

New Tables

  • crm_leads

Modified Tables

  • crm_enquiries

New Master Options

  • crm_lead_awareness
  • crm_lead_status
  • crm_lead_followup_status
  • crm_lead_lost_reason

New APIs

  • /api/crm/leads
  • /api/crm/leads/[id]
  • /api/crm/leads/[id]/assign
  • /api/crm/leads/[id]/followups

Updated APIs

  • /api/crm/enquiries
  • /api/crm/dashboard
  • /api/crm/reports

Documentation

Create:

docs/adr/0018-lead-enquiry-domain-separation.md
docs/implementation/task-d5-lead-enquiry-domain-separation.md

Explicit Non-Scope

Do NOT:

  • redesign quotation workflow
  • redesign approval workflow
  • redesign PDF workflow
  • redesign role model

Reuse existing foundations.


Verification

Verify:

1 Lead
→ N Enquiries

Verify:

1 Enquiry
→ N Quotations

Verify:

Sales Direct Enquiry
(leadId = null)

Verify:

Lead Outcome Auto Sync

Verify:

Lead Sequence
Enquiry Sequence

Verify:

Dashboard
Reports
Security

continue functioning.

Run:

npm exec tsc --noEmit

Definition of Done

Task is complete when:

  • Lead and Enquiry are separate entities
  • Sales can create Enquiries directly
  • Marketing can create Leads
  • 1 Lead → N Enquiries works
  • 1 Enquiry → N Quotations works
  • Lead outcomes are automatically derived from Enquiry outcomes
  • Lead and Enquiry document sequences are independent
  • Dashboard and Reports use separated datasets
  • Security follows existing CRM authorization foundation

Result:

Lead Domain = Established

Enquiry Domain = Established

Marketing Pipeline = Clear

Sales Pipeline = Clear