task-d.5.3
This commit is contained in:
537
plans/task-d.5.3.md
Normal file
537
plans/task-d.5.3.md
Normal file
@@ -0,0 +1,537 @@
|
||||
# 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:
|
||||
|
||||
```txt
|
||||
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:
|
||||
|
||||
```txt
|
||||
crm_leads
|
||||
crm_enquiries
|
||||
crm_enquiries.lead_id
|
||||
|
||||
crm_lead sequence
|
||||
crm_enquiry sequence
|
||||
|
||||
Lead Service
|
||||
Lead API
|
||||
```
|
||||
|
||||
Do not recreate:
|
||||
|
||||
```txt
|
||||
tables
|
||||
migrations
|
||||
seed data
|
||||
master-option categories
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Business Model
|
||||
|
||||
## Before Assignment
|
||||
|
||||
Owner:
|
||||
|
||||
```txt
|
||||
Marketing
|
||||
```
|
||||
|
||||
Workspace:
|
||||
|
||||
```txt
|
||||
Lead
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## After Assignment
|
||||
|
||||
Owner:
|
||||
|
||||
```txt
|
||||
Sales
|
||||
```
|
||||
|
||||
Workspace:
|
||||
|
||||
```txt
|
||||
Enquiry
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Relationship
|
||||
|
||||
```txt
|
||||
1 Lead
|
||||
↓
|
||||
0..N Enquiries
|
||||
```
|
||||
|
||||
Lead remains immutable historical source.
|
||||
|
||||
Enquiries become sales execution records.
|
||||
|
||||
---
|
||||
|
||||
# Scope D5.3.1 Lead Assignment Service
|
||||
|
||||
Create:
|
||||
|
||||
```txt
|
||||
src/features/crm/leads/server/assignment.service.ts
|
||||
```
|
||||
|
||||
Required operation:
|
||||
|
||||
```txt
|
||||
assignLead()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Input:
|
||||
|
||||
```ts
|
||||
AssignLeadInput
|
||||
```
|
||||
|
||||
Fields:
|
||||
|
||||
```ts
|
||||
leadId
|
||||
salesOwnerId
|
||||
assignmentRemark
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Validation:
|
||||
|
||||
```txt
|
||||
lead exists
|
||||
lead active
|
||||
salesOwnerId valid
|
||||
same organization
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope D5.3.2 Create Enquiry From Lead
|
||||
|
||||
Create:
|
||||
|
||||
```txt
|
||||
createEnquiryFromLead()
|
||||
```
|
||||
|
||||
inside assignment service.
|
||||
|
||||
---
|
||||
|
||||
Rules
|
||||
|
||||
Assignment automatically creates:
|
||||
|
||||
```txt
|
||||
crm_enquiry
|
||||
```
|
||||
|
||||
linked to:
|
||||
|
||||
```txt
|
||||
crm_leads.id
|
||||
```
|
||||
|
||||
through:
|
||||
|
||||
```txt
|
||||
crm_enquiries.lead_id
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Reuse:
|
||||
|
||||
```txt
|
||||
generateNextDocumentCode()
|
||||
```
|
||||
|
||||
with:
|
||||
|
||||
```txt
|
||||
crm_enquiry
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Expected:
|
||||
|
||||
```txt
|
||||
EN2606-001
|
||||
```
|
||||
|
||||
or existing enquiry format.
|
||||
|
||||
No custom numbering logic.
|
||||
|
||||
---
|
||||
|
||||
# Scope D5.3.3 Enquiry Bootstrap Mapping
|
||||
|
||||
When enquiry is created:
|
||||
|
||||
Copy:
|
||||
|
||||
```txt
|
||||
customerId
|
||||
contactId
|
||||
projectName
|
||||
projectLocation
|
||||
productType
|
||||
description
|
||||
estimatedValue
|
||||
priority
|
||||
```
|
||||
|
||||
from Lead.
|
||||
|
||||
---
|
||||
|
||||
Do NOT copy:
|
||||
|
||||
```txt
|
||||
marketing-only notes
|
||||
internal marketing activity history
|
||||
audit events
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Lead remains unchanged.
|
||||
|
||||
---
|
||||
|
||||
# Scope D5.3.4 Lead Assignment API
|
||||
|
||||
Create:
|
||||
|
||||
```txt
|
||||
POST /api/crm/leads/[id]/assign
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Handler must call:
|
||||
|
||||
```txt
|
||||
Lead Assignment Service
|
||||
```
|
||||
|
||||
No direct DB access.
|
||||
|
||||
---
|
||||
|
||||
Response:
|
||||
|
||||
```ts
|
||||
{
|
||||
leadId: string;
|
||||
enquiryId: string;
|
||||
enquiryCode: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope D5.3.5 Ownership Transfer
|
||||
|
||||
After assignment:
|
||||
|
||||
Lead:
|
||||
|
||||
```txt
|
||||
status = assigned
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Lead:
|
||||
|
||||
```txt
|
||||
assigned_sales_owner_id
|
||||
assigned_at
|
||||
assigned_by
|
||||
```
|
||||
|
||||
updated.
|
||||
|
||||
---
|
||||
|
||||
Enquiry:
|
||||
|
||||
```txt
|
||||
owner_user_id
|
||||
```
|
||||
|
||||
set to assigned salesperson.
|
||||
|
||||
---
|
||||
|
||||
Marketing remains able to:
|
||||
|
||||
```txt
|
||||
view lead
|
||||
view assignment result
|
||||
```
|
||||
|
||||
but not manage enquiry.
|
||||
|
||||
---
|
||||
|
||||
# Scope D5.3.6 CRM Security
|
||||
|
||||
Reuse:
|
||||
|
||||
```txt
|
||||
resolveCrmMembershipAccess()
|
||||
```
|
||||
|
||||
Assignment permission:
|
||||
|
||||
```txt
|
||||
lead.assign
|
||||
```
|
||||
|
||||
Only:
|
||||
|
||||
```txt
|
||||
Marketing Manager
|
||||
CRM Manager
|
||||
Admin
|
||||
```
|
||||
|
||||
or equivalent resolved permission.
|
||||
|
||||
---
|
||||
|
||||
Do not check role strings directly.
|
||||
|
||||
---
|
||||
|
||||
# Scope D5.3.7 Duplicate Protection
|
||||
|
||||
Prevent:
|
||||
|
||||
```txt
|
||||
multiple enquiry creation
|
||||
```
|
||||
|
||||
for the same assignment action.
|
||||
|
||||
---
|
||||
|
||||
Rules:
|
||||
|
||||
If assignment already produced an active enquiry:
|
||||
|
||||
```txt
|
||||
return existing enquiry
|
||||
```
|
||||
|
||||
instead of creating a second one.
|
||||
|
||||
---
|
||||
|
||||
# Scope D5.3.8 Audit Logging
|
||||
|
||||
Reuse audit foundation.
|
||||
|
||||
Required actions:
|
||||
|
||||
```txt
|
||||
assign_lead
|
||||
create_enquiry_from_lead
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Audit must capture:
|
||||
|
||||
```txt
|
||||
leadId
|
||||
enquiryId
|
||||
salesOwnerId
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope D5.3.9 Legacy Compatibility
|
||||
|
||||
Do not modify:
|
||||
|
||||
```txt
|
||||
quotation flow
|
||||
approval flow
|
||||
dashboard
|
||||
reports
|
||||
won/lost process
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Current enquiry APIs must continue functioning.
|
||||
|
||||
---
|
||||
|
||||
# Deliverables
|
||||
|
||||
New:
|
||||
|
||||
```txt
|
||||
src/features/crm/leads/server/assignment.service.ts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
New API:
|
||||
|
||||
```txt
|
||||
POST /api/crm/leads/[id]/assign
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Documentation:
|
||||
|
||||
```txt
|
||||
docs/implementation/task-d53-lead-assignment-create-enquiry-foundation.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Verification
|
||||
|
||||
Run:
|
||||
|
||||
```txt
|
||||
npm exec tsc --noEmit
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Verify:
|
||||
|
||||
```txt
|
||||
Assign Lead
|
||||
Create Enquiry
|
||||
Reuse Existing Enquiry
|
||||
Lead Status Update
|
||||
Audit Logging
|
||||
Security Enforcement
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Verify:
|
||||
|
||||
```txt
|
||||
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:
|
||||
|
||||
```txt
|
||||
Lead Assignment = Established
|
||||
|
||||
Lead → Enquiry Transition = Established
|
||||
|
||||
Ready for Opportunity Workspace Separation
|
||||
```
|
||||
Reference in New Issue
Block a user