Files
alla-allaos-fullstack/docs/implementation/task-j0-kpi-definition-freeze.md
phaichayon 5be6c54272 taks-d.2.1
2026-06-17 14:46:52 +07:00

140 lines
4.6 KiB
Markdown

# Task J.0: KPI Definition Freeze
## Scope delivered
- Froze the CRM sales pipeline definitions that Dashboard KPI must use.
- Froze customer party terminology so enquiry, quotation, and dashboard reporting use the same business language.
- Froze KPI and revenue formulas before Task J dashboard work begins.
- Declared that KPI definition changes after this point require a new ADR or equivalent decision record.
## Governance rule
- After Task J.0, KPI definitions, pipeline meanings, and dashboard counting rules must not change silently.
- Any future change to these definitions requires a new ADR so reporting behavior stays auditable.
## Frozen sales pipeline
### Lead
- Definition: enquiry is not assigned to sales yet.
- Rule: `assignedToUserId = null`
- Rule: `pipelineStage = lead`
- KPI impact: `Lead Count`, `Lead Aging`, `Lead Source`, `New Leads`, `Unassigned Leads`
### Opportunity
- Definition: enquiry has already been assigned to sales.
- Rule: `assignedToUserId != null`
- Rule: `pipelineStage = opportunity`
- Auto transition: assigning sales moves the record from `Lead` to `Opportunity`
- KPI impact: `Opportunity Count`, `Opportunity Value`, `Hot Opportunities`, `Opportunity Aging`, `Open Opportunities`
### Closed Won
- Definition: customer confirms the award, or the project is officially awarded.
- Rule: `pipelineStage = closed_won`
### Closed Lost
- Definition: competitor wins, budget is not approved, customer cancels, or project does not proceed.
- Rule: `pipelineStage = closed_lost`
## Frozen opportunity lifecycle
```txt
Lead
-> Assign Sales
Opportunity
-> Create Quotation
Opportunity
-> Approved Quotation
Opportunity
-> Award
Closed Won
```
## Frozen customer party definitions
- `Billing Customer`: the company used for quotation issue and billing.
- `End Customer`: the real project owner.
- `Contractor`: the construction contractor or main contractor.
- `Consultant`: the project consultant.
- `Customer`: a general commercial counterparty or related party when a more specific role is not applicable.
These terms are frozen as the shared language for CRM forms, detail views, and future dashboard/reporting logic.
## Frozen KPI definitions
### Lead metrics
- `Lead Count` = enquiries where `pipelineStage = lead`
- `New Leads` = lead-stage enquiries created within the selected reporting period
- `Unassigned Leads` = lead-stage enquiries where `assignedToUserId = null`
- `Lead Aging` = age of lead-stage enquiries based on creation date until current/report date
### Opportunity metrics
- `Opportunity Count` = enquiries where `pipelineStage = opportunity`
- `Open Opportunities` = opportunities still active and not moved to `closed_won` or `closed_lost`
- `Hot Opportunities` = opportunity-stage enquiries flagged by the future dashboard/business rule layer
- `Opportunity Aging` = age of opportunity-stage enquiries based on entry into active opportunity lifecycle until current/report date
### Conversion metrics
- `Lead -> Opportunity` = `Opportunity Created / Total Leads`
- `Opportunity -> Quotation` = `Opportunity With Quotation / Total Opportunities`
- `Quotation -> Won` = `Closed Won / Total Opportunities With Quotation`
## Frozen revenue rules
### Opportunity value
- Source: `crm_enquiries.estimatedValue`
- Condition: only count rows where `pipelineStage = opportunity`
### Quotation value
- Source: `crm_quotations.totalAmount`
- Condition: count quotations where `status != cancelled`
### Won value
- Source: `crm_quotations.totalAmount`
- Condition: count quotation-linked business only when parent enquiry `pipelineStage = closed_won`
### Lost value
- Source: `crm_quotations.totalAmount`
- Condition: count quotation-linked business only when parent enquiry `pipelineStage = closed_lost`
## Frozen ownership rules for reporting
- Dashboard ownership for `Lead` and `Opportunity` must use `assignedToUserId`.
- Dashboard ownership for `Quotation` must use `salesmanId`.
This prevents mixing enquiry ownership with quotation ownership in the same KPI bucket.
## Explicit non-scope items
Task J.0 intentionally does not add lifecycle timestamp fields or new master-data defaults.
Deferred fields:
- `convertedToOpportunityAt`
- `closedWonAt`
- `closedLostAt`
- `lostReason`
- `defaultPartyRole`
These remain technical debt and should be added only when downstream reporting or workflow requirements justify schema changes.
## Dashboard readiness
Task J can now build CRM dashboard KPIs on top of these frozen definitions:
- KPI definitions frozen
- sales pipeline frozen
- customer party definitions frozen
- revenue rules frozen
- dashboard semantics ready for implementation