# 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.
