task-d.4
This commit is contained in:
710
plans/task-d.4.md
Normal file
710
plans/task-d.4.md
Normal file
@@ -0,0 +1,710 @@
|
||||
# Task D.4: Won / Lost Lifecycle Governance
|
||||
|
||||
## Objective
|
||||
|
||||
Formalize CRM opportunity outcomes by introducing production-grade:
|
||||
|
||||
* Closed Won lifecycle
|
||||
* Closed Lost lifecycle
|
||||
* PO tracking
|
||||
* Lost reason governance
|
||||
* Outcome analytics foundation
|
||||
|
||||
This task replaces temporary dashboard assumptions and becomes the official business outcome model for CRM.
|
||||
|
||||
---
|
||||
|
||||
# Background
|
||||
|
||||
Business Discovery 3.0 has frozen:
|
||||
|
||||
## Closed Won
|
||||
|
||||
Definition:
|
||||
|
||||
```txt
|
||||
PO Received
|
||||
```
|
||||
|
||||
Only a received Purchase Order can move an enquiry to:
|
||||
|
||||
```txt
|
||||
closed_won
|
||||
```
|
||||
|
||||
Quotation approval or quotation acceptance alone does not create a Won outcome.
|
||||
|
||||
---
|
||||
|
||||
## Closed Lost
|
||||
|
||||
Definition:
|
||||
|
||||
```txt
|
||||
Sales opportunity permanently lost
|
||||
```
|
||||
|
||||
Lost requires:
|
||||
|
||||
```txt
|
||||
Lost Reason
|
||||
```
|
||||
|
||||
Optional:
|
||||
|
||||
```txt
|
||||
Lost Competitor
|
||||
Lost Remark
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.1 Outcome Schema
|
||||
|
||||
Extend:
|
||||
|
||||
```txt
|
||||
crm_enquiries
|
||||
```
|
||||
|
||||
Add:
|
||||
|
||||
```txt
|
||||
closedWonAt
|
||||
closedLostAt
|
||||
|
||||
closedByUserId
|
||||
|
||||
poNumber
|
||||
poDate
|
||||
poAmount
|
||||
poCurrency
|
||||
|
||||
lostReason
|
||||
lostCompetitor
|
||||
lostRemark
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
```txt
|
||||
Won
|
||||
OR
|
||||
Lost
|
||||
```
|
||||
|
||||
never both.
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.2 Lost Reason Master Data
|
||||
|
||||
Add master option category:
|
||||
|
||||
```txt
|
||||
crm_lost_reason
|
||||
```
|
||||
|
||||
Seed:
|
||||
|
||||
```txt
|
||||
competitor_won
|
||||
budget_not_approved
|
||||
project_cancelled
|
||||
customer_no_response
|
||||
technical_requirement_mismatch
|
||||
price_too_high
|
||||
timeline_not_fit
|
||||
other
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
```txt
|
||||
Lost Reason
|
||||
```
|
||||
|
||||
required when closing lost.
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.3 Outcome Service Layer
|
||||
|
||||
Create centralized lifecycle service.
|
||||
|
||||
Supported actions:
|
||||
|
||||
```txt
|
||||
markWon()
|
||||
markLost()
|
||||
reopenOpportunity()
|
||||
```
|
||||
|
||||
All outcome transitions must go through service layer.
|
||||
|
||||
No direct status updates.
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.4 Mark Won Workflow
|
||||
|
||||
Action:
|
||||
|
||||
```txt
|
||||
Mark Won
|
||||
```
|
||||
|
||||
Available only when:
|
||||
|
||||
```txt
|
||||
pipelineStage = enquiry
|
||||
```
|
||||
|
||||
Required fields:
|
||||
|
||||
```txt
|
||||
PO Number
|
||||
PO Date
|
||||
```
|
||||
|
||||
Optional:
|
||||
|
||||
```txt
|
||||
PO Amount
|
||||
PO Currency
|
||||
PO Attachment
|
||||
Remark
|
||||
```
|
||||
|
||||
System behavior:
|
||||
|
||||
```txt
|
||||
pipelineStage = closed_won
|
||||
|
||||
closedWonAt = now
|
||||
closedByUserId = current user
|
||||
```
|
||||
|
||||
Audit:
|
||||
|
||||
```txt
|
||||
crm_enquiry
|
||||
|
||||
action = mark_won
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.5 PO Attachment
|
||||
|
||||
Add attachment support.
|
||||
|
||||
Allowed:
|
||||
|
||||
```txt
|
||||
PDF
|
||||
Image
|
||||
Excel
|
||||
```
|
||||
|
||||
Relationship:
|
||||
|
||||
```txt
|
||||
crm_enquiry
|
||||
```
|
||||
|
||||
Attachment category:
|
||||
|
||||
```txt
|
||||
purchase_order
|
||||
```
|
||||
|
||||
UI:
|
||||
|
||||
```txt
|
||||
Upload PO
|
||||
View PO
|
||||
Download PO
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.6 Mark Lost Workflow
|
||||
|
||||
Action:
|
||||
|
||||
```txt
|
||||
Mark Lost
|
||||
```
|
||||
|
||||
Available only when:
|
||||
|
||||
```txt
|
||||
pipelineStage = enquiry
|
||||
```
|
||||
|
||||
Required:
|
||||
|
||||
```txt
|
||||
Lost Reason
|
||||
```
|
||||
|
||||
Optional:
|
||||
|
||||
```txt
|
||||
Lost Competitor
|
||||
Lost Remark
|
||||
```
|
||||
|
||||
System behavior:
|
||||
|
||||
```txt
|
||||
pipelineStage = closed_lost
|
||||
|
||||
closedLostAt = now
|
||||
closedByUserId = current user
|
||||
```
|
||||
|
||||
Audit:
|
||||
|
||||
```txt
|
||||
crm_enquiry
|
||||
|
||||
action = mark_lost
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.7 Reopen Opportunity
|
||||
|
||||
Allow controlled reopen.
|
||||
|
||||
Available for:
|
||||
|
||||
```txt
|
||||
closed_lost
|
||||
```
|
||||
|
||||
Only.
|
||||
|
||||
Not allowed for:
|
||||
|
||||
```txt
|
||||
closed_won
|
||||
```
|
||||
|
||||
Reason:
|
||||
|
||||
```txt
|
||||
Won must remain final once PO exists.
|
||||
```
|
||||
|
||||
Required:
|
||||
|
||||
```txt
|
||||
Reopen Reason
|
||||
```
|
||||
|
||||
Audit:
|
||||
|
||||
```txt
|
||||
action = reopen
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.8 UI Changes
|
||||
|
||||
Enquiry Detail
|
||||
|
||||
Add:
|
||||
|
||||
```txt
|
||||
Outcome
|
||||
```
|
||||
|
||||
Section.
|
||||
|
||||
Display:
|
||||
|
||||
```txt
|
||||
Won
|
||||
Lost
|
||||
Open
|
||||
```
|
||||
|
||||
Fields:
|
||||
|
||||
```txt
|
||||
PO Information
|
||||
Lost Information
|
||||
Closed By
|
||||
Closed Date
|
||||
```
|
||||
|
||||
Actions:
|
||||
|
||||
```txt
|
||||
Mark Won
|
||||
Mark Lost
|
||||
Reopen
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.9 Dashboard KPI Migration
|
||||
|
||||
Replace temporary logic.
|
||||
|
||||
Current:
|
||||
|
||||
```txt
|
||||
quotation accepted
|
||||
```
|
||||
|
||||
Proxy.
|
||||
|
||||
New:
|
||||
|
||||
```txt
|
||||
pipelineStage = closed_won
|
||||
```
|
||||
|
||||
Official.
|
||||
|
||||
---
|
||||
|
||||
Update:
|
||||
|
||||
## Won Count
|
||||
|
||||
```txt
|
||||
closed_won
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Lost Count
|
||||
|
||||
```txt
|
||||
closed_lost
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Win Rate
|
||||
|
||||
```txt
|
||||
Won / (Won + Lost)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Lost Analysis
|
||||
|
||||
```txt
|
||||
Lost By Reason
|
||||
Lost By Competitor
|
||||
Lost By Sales
|
||||
Lost By Product Type
|
||||
Lost By Branch
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.10 Revenue Rules
|
||||
|
||||
Freeze:
|
||||
|
||||
## Won Revenue
|
||||
|
||||
Priority:
|
||||
|
||||
```txt
|
||||
PO Amount
|
||||
```
|
||||
|
||||
If available.
|
||||
|
||||
Fallback:
|
||||
|
||||
```txt
|
||||
Quotation Total
|
||||
```
|
||||
|
||||
if PO Amount is empty.
|
||||
|
||||
---
|
||||
|
||||
Lost Revenue:
|
||||
|
||||
```txt
|
||||
Quotation Total
|
||||
```
|
||||
|
||||
for reporting opportunity loss.
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.11 Report Foundation
|
||||
|
||||
Prepare data for Task K.
|
||||
|
||||
Add reusable reporting helpers:
|
||||
|
||||
```txt
|
||||
getWonRevenue()
|
||||
getLostRevenue()
|
||||
|
||||
getLostByReason()
|
||||
|
||||
getLostByCompetitor()
|
||||
|
||||
getWinRate()
|
||||
```
|
||||
|
||||
Organization scoped.
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.12 Permissions
|
||||
|
||||
Add:
|
||||
|
||||
```txt
|
||||
crm.enquiry.mark_won
|
||||
crm.enquiry.mark_lost
|
||||
crm.enquiry.reopen
|
||||
```
|
||||
|
||||
Default:
|
||||
|
||||
```txt
|
||||
sales
|
||||
sales_manager
|
||||
department_manager
|
||||
crm_admin
|
||||
```
|
||||
|
||||
Not granted:
|
||||
|
||||
```txt
|
||||
marketing
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.13 Security
|
||||
|
||||
Marketing may see:
|
||||
|
||||
```txt
|
||||
Won
|
||||
Lost
|
||||
Outcome Summary
|
||||
```
|
||||
|
||||
Marketing may not see:
|
||||
|
||||
```txt
|
||||
PO Amount
|
||||
Revenue
|
||||
Quotation Pricing
|
||||
```
|
||||
|
||||
Enforce server-side.
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.14 Audit
|
||||
|
||||
Entity:
|
||||
|
||||
```txt
|
||||
crm_enquiry
|
||||
```
|
||||
|
||||
Actions:
|
||||
|
||||
```txt
|
||||
mark_won
|
||||
mark_lost
|
||||
reopen
|
||||
upload_po
|
||||
```
|
||||
|
||||
Payload:
|
||||
|
||||
```txt
|
||||
poNumber
|
||||
poAmount
|
||||
|
||||
lostReason
|
||||
lostCompetitor
|
||||
|
||||
closedBy
|
||||
closedAt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Scope D4.15 Verification
|
||||
|
||||
Scenario 1
|
||||
|
||||
```txt
|
||||
Enquiry
|
||||
→ Mark Won
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
```txt
|
||||
closed_won
|
||||
PO stored
|
||||
audit created
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Scenario 2
|
||||
|
||||
```txt
|
||||
Enquiry
|
||||
→ Mark Lost
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
```txt
|
||||
closed_lost
|
||||
lost reason stored
|
||||
audit created
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Scenario 3
|
||||
|
||||
```txt
|
||||
Lost
|
||||
→ Reopen
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
```txt
|
||||
enquiry
|
||||
reopen audit created
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Scenario 4
|
||||
|
||||
```txt
|
||||
Won
|
||||
→ Reopen
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
```txt
|
||||
blocked
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Scenario 5
|
||||
|
||||
Marketing User
|
||||
|
||||
Expected:
|
||||
|
||||
```txt
|
||||
see outcome
|
||||
cannot see PO amount
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Documentation
|
||||
|
||||
Create:
|
||||
|
||||
```txt
|
||||
docs/adr/0016-won-lost-lifecycle-governance.md
|
||||
docs/implementation/task-d4-won-lost-lifecycle-governance.md
|
||||
```
|
||||
|
||||
Freeze:
|
||||
|
||||
```txt
|
||||
PO = Won
|
||||
Lost Reason required
|
||||
Won cannot reopen
|
||||
Lost can reopen
|
||||
Revenue attribution rule
|
||||
Win/Loss KPI rule
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Explicit Non-Scope
|
||||
|
||||
Do NOT implement:
|
||||
|
||||
```txt
|
||||
Sales Order
|
||||
Project Handover
|
||||
Invoice
|
||||
Delivery Note
|
||||
ERP Integration
|
||||
Forecasting
|
||||
Probability Scoring
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Deliverables
|
||||
|
||||
1. Won Lifecycle
|
||||
2. Lost Lifecycle
|
||||
3. PO Tracking
|
||||
4. Lost Reason Governance
|
||||
5. Outcome Analytics Foundation
|
||||
6. Dashboard KPI Migration
|
||||
7. Security Rules
|
||||
8. Audit Coverage
|
||||
9. ADR 0016
|
||||
|
||||
---
|
||||
|
||||
# Definition of Done
|
||||
|
||||
Task D.4 is complete when:
|
||||
|
||||
* PO creates Closed Won
|
||||
* Lost requires Lost Reason
|
||||
* Won/Lost KPIs use pipelineStage
|
||||
* Lost analytics exist
|
||||
* Revenue rules are frozen
|
||||
* Marketing visibility restrictions are enforced
|
||||
* Audit logs exist
|
||||
* ADR 0016 exists
|
||||
|
||||
Result:
|
||||
|
||||
```txt
|
||||
Lead
|
||||
→ Enquiry
|
||||
→ Quotation
|
||||
→ Closed Won (PO)
|
||||
|
||||
Lead
|
||||
→ Enquiry
|
||||
→ Quotation
|
||||
→ Closed Lost
|
||||
```
|
||||
|
||||
becomes the official CRM business outcome lifecycle.
|
||||
Reference in New Issue
Block a user