task-d.4
This commit is contained in:
58
docs/adr/0016-won-lost-lifecycle-governance.md
Normal file
58
docs/adr/0016-won-lost-lifecycle-governance.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# ADR 0016: Won / Lost Lifecycle Governance
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
CRM dashboard and reporting previously treated quotation acceptance and rejection as proxies for opportunity outcomes. That made business outcome data unstable because:
|
||||
|
||||
- quotation approval/acceptance does not equal PO received
|
||||
- lost opportunities could be inferred without a required lost reason
|
||||
- reopen rules were undefined
|
||||
- revenue and win/loss KPI logic depended on quotation status instead of the enquiry lifecycle
|
||||
|
||||
Business Discovery 3.0 froze the production rule set:
|
||||
|
||||
- `closed_won` means PO received
|
||||
- `closed_lost` requires a lost reason
|
||||
- won cannot reopen
|
||||
- lost can reopen with audit
|
||||
- won revenue prefers PO amount and falls back to quotation total
|
||||
- lost revenue uses quotation total
|
||||
|
||||
## Decision
|
||||
|
||||
We use `crm_enquiries` as the official business outcome record.
|
||||
|
||||
We add outcome fields on `crm_enquiries`:
|
||||
|
||||
- `closed_won_at`
|
||||
- `closed_lost_at`
|
||||
- `closed_by_user_id`
|
||||
- `po_number`
|
||||
- `po_date`
|
||||
- `po_amount`
|
||||
- `po_currency`
|
||||
- `lost_reason`
|
||||
- `lost_competitor`
|
||||
- `lost_remark`
|
||||
|
||||
We add `crm_enquiry_attachments` for purchase order files with category `purchase_order`.
|
||||
|
||||
All lifecycle transitions must go through the enquiry outcome service layer:
|
||||
|
||||
- `markEnquiryAsWon()`
|
||||
- `markEnquiryAsLost()`
|
||||
- `reopenLostEnquiry()`
|
||||
|
||||
Quotation status is no longer allowed to mutate enquiry outcome automatically.
|
||||
|
||||
## Consequences
|
||||
|
||||
- dashboard won/lost KPI must read enquiry `pipeline_stage`
|
||||
- marketing can see outcome state but PO amount remains server-side restricted
|
||||
- PO attachment access follows commercial-data visibility rules
|
||||
- audit coverage expands to `mark_won`, `mark_lost`, `reopen`, and `upload_po`
|
||||
- downstream reporting can reuse a stable outcome model for Task K
|
||||
41
docs/implementation/task-d4-won-lost-lifecycle-governance.md
Normal file
41
docs/implementation/task-d4-won-lost-lifecycle-governance.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Task D.4 Implementation Summary
|
||||
|
||||
## Completed
|
||||
|
||||
- extended `crm_enquiries` with official won/lost lifecycle fields
|
||||
- added `crm_enquiry_attachments` for purchase order files
|
||||
- seeded `crm_lost_reason` master data
|
||||
- added permissions:
|
||||
- `crm.enquiry.mark_won`
|
||||
- `crm.enquiry.mark_lost`
|
||||
- `crm.enquiry.reopen`
|
||||
- added outcome service operations for:
|
||||
- mark won
|
||||
- mark lost
|
||||
- reopen lost opportunity
|
||||
- added API routes for outcome transitions and PO attachment upload/view/download
|
||||
- added enquiry detail outcome card with:
|
||||
- open / won / lost state
|
||||
- PO data
|
||||
- lost data
|
||||
- closed by / closed date
|
||||
- mark won / mark lost / reopen actions
|
||||
- PO attachment upload and retrieval
|
||||
- removed quotation-status-driven mutation of enquiry pipeline outcome
|
||||
- migrated dashboard summary/funnel/sales won revenue to enquiry outcome helpers
|
||||
- added reporting helpers:
|
||||
- `getWonRevenue()`
|
||||
- `getLostRevenue()`
|
||||
- `getLostByReason()`
|
||||
- `getLostByCompetitor()`
|
||||
- `getWinRate()`
|
||||
|
||||
## Verification
|
||||
|
||||
- `npm exec tsc --noEmit`
|
||||
|
||||
## Notes
|
||||
|
||||
- marketing users still receive outcome state, but PO amount is redacted server-side unless commercial pricing visibility exists
|
||||
- PO attachment endpoints are also restricted to commercial-data viewers
|
||||
- revenue analytics cards still use existing quotation-attribution views for top-party ranking, but won/lost headline KPI and sales won revenue now follow the D.4 lifecycle rule
|
||||
Reference in New Issue
Block a user