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