lead menu

nquiry menu
This commit is contained in:
phaichayon
2026-06-19 10:39:11 +07:00
parent 0650cf6297
commit c0cc880be2
46 changed files with 5985 additions and 420 deletions

439
plans/task-d.3.1.md Normal file
View File

@@ -0,0 +1,439 @@
# Task D.3.1: Leads / Enquiries Navigation Separation
## Goal
แยกเมนู Leads และ Enquiries ออกจากกันเพื่อลดความสับสนของผู้ใช้งาน
Business Process ยังคงเป็น:
```txt
Lead
↓ Assign To Sales
Enquiry
Quotation
Won / Lost
```
แต่ UX จะถูกแยกเป็น 2 Workspace
```txt
CRM
├── Dashboard
├── Leads
├── Enquiries
├── Quotations
├── Approvals
└── Settings
```
Important:
Task นี้เป็น UX Separation เท่านั้น
Do NOT create:
```txt
crm_leads
```
Do NOT duplicate:
```txt
API
Schema
Database
Server Service
```
ยังคงใช้
```txt
crm_enquiries
```
เป็น Single Source of Truth
---
# Scope D3.1.1 Navigation
Update:
```txt
src/config/nav-config.ts
```
Add:
```txt
CRM
├ Leads
└ Enquiries
```
Remove old combined menu if exists.
Permissions:
Leads menu:
```txt
crm.lead.read
```
Enquiries menu:
```txt
crm.enquiry.read
```
---
# Scope D3.1.2 Routes
Add:
```txt
/dashboard/crm/leads
/dashboard/crm/leads/[id]
```
Keep:
```txt
/dashboard/crm/enquiries
/dashboard/crm/enquiries/[id]
```
Rules:
Leads page:
```txt
pipelineStage = lead
```
Enquiries page:
```txt
pipelineStage = enquiry
```
---
# Scope D3.1.3 Reuse Existing Module
Do NOT create:
```txt
src/features/crm/leads
```
Reuse:
```txt
src/features/crm/enquiries/**
```
Implementation pattern:
```ts
getEnquiries({
pipelineStage: "lead"
})
getEnquiries({
pipelineStage: "enquiry"
})
```
Shared:
```txt
API
Types
Mutations
Queries
Schema
Server Service
```
---
# Scope D3.1.4 Leads UI
Leads page should focus on Marketing workflow.
Columns:
```txt
Code
Lead Source
Company
Contact
Assigned Sales
Created By
Created At
Age
Status
```
Actions:
```txt
View
Edit
Assign To Sales
Mark Lost
```
Hide:
```txt
Quotation Count
Revenue
Chance %
Quotation Value
```
---
# Scope D3.1.5 Enquiries UI
Enquiries page should focus on Sales workflow.
Columns:
```txt
Code
Project
Billing Customer
Enquiry Owner
Chance %
Estimated Value
Quotation Count
Next Follow-up
Status
```
Actions:
```txt
View
Edit
Create Quotation
Follow-up
Won
Lost
```
---
# Scope D3.1.6 Detail Page Labels
Lead Detail:
```txt
Lead Information
Lead Source
Lead Owner
Assigned Sales
```
Enquiry Detail:
```txt
Enquiry Information
Project Information
Enquiry Owner
Follow-ups
Quotations
```
Both pages may internally reuse the same component.
Only labels and visibility differ.
---
# Scope D3.1.7 Permissions
Add:
```txt
crm.lead.read
crm.lead.create
crm.lead.update
crm.lead.assign
crm.lead.delete
```
Map existing behavior:
```txt
marketing
admin
super_admin
```
Default:
Marketing:
```txt
Lead permissions
```
Sales:
```txt
Enquiry permissions
```
Managers:
```txt
Both
```
---
# Scope D3.1.8 Dashboard Alignment
Dashboard cards should use:
Lead:
```txt
pipelineStage = lead
```
Enquiry:
```txt
pipelineStage = enquiry
```
Links:
```txt
Lead KPI
→ /dashboard/crm/leads
Enquiry KPI
→ /dashboard/crm/enquiries
```
---
# Scope D3.1.9 Query Freshness
After:
```txt
Assign Lead
Convert Lead → Enquiry
Won
Lost
```
Invalidate:
```txt
lead list
enquiry list
lead detail
enquiry detail
dashboard KPI
```
Rules:
Assigned lead should disappear from Leads immediately and appear in Enquiries immediately.
No manual refresh allowed.
---
# Scope D3.1.10 ADR Update
Update:
```txt
docs/adr/0011-lead-enquiry-ownership-model.md
```
Add section:
```txt
Navigation Separation
```
Document:
```txt
Lead and Enquiry are separate UX workspaces.
Lead and Enquiry are NOT separate domain entities.
Both are stored in crm_enquiries.
pipelineStage determines business state.
```
---
# Explicit Non-Scope
Do NOT implement:
```txt
crm_leads table
Lead API
Lead schema
Lead server service
Campaign module
Lead scoring
Marketing automation
Import/Export redesign
```
---
# Output
1. Files Added
2. Files Modified
3. Navigation Changes
4. Route Changes
5. Permission Changes
6. Query Invalidation Added
7. Dashboard Changes
8. ADR Updates
9. Remaining Risks
---
# Definition of Done
✔ Leads menu exists
✔ Enquiries menu exists
✔ Leads page shows only lead-stage records
✔ Enquiries page shows only enquiry-stage records
✔ Lead assignment moves record between pages immediately
✔ Dashboard links point correctly
✔ No duplicate lead module created
✔ No new database table created
✔ Existing enquiry APIs reused
✔ ADR updated

464
plans/task-d.3.md Normal file
View File

@@ -0,0 +1,464 @@
# Task D.3: Lead / Enquiry Ownership Refinement
## Goal
ปรับ CRM Pipeline ให้สอดคล้องกับ Business Process ล่าสุด
Current:
```txt
Lead (unassigned enquiry)
Opportunity (assigned enquiry)
Quotation
Won / Lost
```
New Business Flow:
```txt
Lead
↓ Assign To Sales
Enquiry
Quotation
Won / Lost
```
Important:
Task D.3 focuses on ownership, visibility, permissions, and lifecycle only.
Lead and Enquiry continue using the same underlying business fields and form structure.
Do NOT split the Lead form and Enquiry form yet.
Future form differences will be handled in a separate task if business requirements diverge.
---
# Business Rules
## Lead
Owner:
```txt
Marketing (MK)
```
Purpose:
```txt
Lead collection
Lead qualification
Lead nurturing
```
Status examples:
```txt
new
contacted
qualified
disqualified
assigned
```
Lead may exist without sales assignment.
---
## Enquiry
Owner:
```txt
Sales
```
Purpose:
```txt
Project follow-up
Opportunity development
Competitor tracking
Quotation preparation
```
Enquiry begins when:
```txt
Lead assigned to Sales
```
or
```txt
Sales creates enquiry directly
```
---
# Scope D3.1 Pipeline Terminology Refinement
Replace current KPI and workflow terminology.
Old:
```txt
Lead = enquiry without assignment
Opportunity = enquiry with assignment
```
New:
```txt
Lead = marketing-owned pipeline stage
Enquiry = sales-owned pipeline stage
```
Rules:
* Stop using Opportunity terminology in UI where practical
* Use Lead and Enquiry terminology consistently
* Preserve existing data compatibility
---
# Scope D3.2 Enquiry Pipeline Stage
Add field:
```txt
pipelineStage
```
Allowed values:
```txt
lead
enquiry
closed_won
closed_lost
```
Default:
```txt
lead
```
Rules:
### Marketing-created lead
```txt
pipelineStage = lead
assignedToUserId = null
```
### Assign to sales
Automatically:
```txt
pipelineStage = enquiry
assignedToUserId = salesUserId
assignedAt = now()
```
### Reassign
Keep:
```txt
pipelineStage = enquiry
```
### Won
```txt
pipelineStage = closed_won
```
### Lost
```txt
pipelineStage = closed_lost
```
---
# Scope D3.3 Assign Flow Refinement
Current assign flow already exists.
Update behavior:
Assign:
```txt
Lead
Enquiry
```
When assign executes:
```txt
assignedToUserId
assignedAt
assignedBy
pipelineStage = enquiry
```
Audit:
```txt
assign
lead_to_enquiry
```
---
# Scope D3.4 MK Visibility Policy
Marketing users must be able to monitor progress.
MK can view:
```txt
Lead
Enquiry
Follow-ups
Status
Pipeline Stage
Assigned Sales
Won/Lost Result
```
MK cannot view:
```txt
Quotation Amount
Quotation Item
Quotation Cost
Discount
Margin
Approval Data
```
MK cannot:
```txt
Edit enquiry owned by sales
Create quotation
Modify quotation
Approve quotation
```
---
# Scope D3.5 Sales Visibility Policy
Sales can:
```txt
View assigned enquiries
Edit assigned enquiries
Create quotations
Manage follow-ups
View quotation pricing
```
Rules remain compatible with existing assignment ownership.
---
# Scope D3.6 Dashboard KPI Alignment
Update KPI service layer.
New definitions:
### Lead Count
```txt
pipelineStage = lead
```
### Enquiry Count
```txt
pipelineStage = enquiry
```
### Won Count
```txt
pipelineStage = closed_won
```
### Lost Count
```txt
pipelineStage = closed_lost
```
Remove dependency on:
```txt
assignedToUserId == null
```
for lead calculation.
---
# Scope D3.7 Revenue Rules
No revenue logic change.
Still use:
```txt
Quotation Amount
Revenue Attribution
Project Party Governance
```
from Task D.2.1.
---
# Scope D3.8 UI Labels
Update CRM wording.
Examples:
```txt
Assign Sales
→ Convert To Enquiry
Assigned Sales
→ Enquiry Owner
Open Opportunities
→ Active Enquiries
```
Do not rename database tables.
Only update business-facing labels.
---
# Scope D3.9 Backward Compatibility
Do NOT:
```txt
Create crm_leads table
Split enquiry form
Split enquiry schema
Split enquiry API
```
Continue using:
```txt
crm_enquiries
```
as the single source of truth.
Lead vs Enquiry is determined by:
```txt
pipelineStage
```
and ownership.
---
# Scope D3.10 ADR
Create:
```txt
docs/adr/0011-lead-enquiry-ownership-model.md
```
Document:
```txt
Lead ownership
Enquiry ownership
Assignment flow
MK visibility restrictions
Won/Lost lifecycle
```
This ADR supersedes the Opportunity terminology frozen in Task J.0.
---
# Explicit Non-Scope
Do NOT implement:
```txt
crm_leads table
Lead form
Lead API
Lead import
Campaign module
Marketing automation
Lead scoring
New dashboard widgets
```
---
# Output
1. Files Added
2. Files Modified
3. Pipeline Changes
4. Ownership Changes
5. Visibility Rules Added
6. KPI Changes
7. ADR Added
8. Migration Notes
9. Remaining Risks
---
# Definition of Done
✔ Lead and Enquiry terminology updated
✔ Assign converts Lead → Enquiry
✔ MK can monitor enquiries
✔ MK cannot see quotation pricing
✔ Sales owns enquiries
✔ Dashboard KPI follows pipelineStage
✔ No duplicate Lead module created
✔ Existing enquiry form reused
✔ Existing data remains compatible
✔ ADR created