taks-d.2.1
This commit is contained in:
139
docs/implementation/task-j0-kpi-definition-freeze.md
Normal file
139
docs/implementation/task-j0-kpi-definition-freeze.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user