Files
alla-allaos-fullstack/docs/adr/0016-won-lost-lifecycle-governance.md
phaichayon ffa5de8311 task-d.4
2026-06-22 16:57:02 +07:00

1.7 KiB

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