COA KPIs System¶
Last Updated: 2026-01-19
Overview¶
The COA KPIs system is a flat, denormalized Chart of Accounts with Key Performance Indicators for construction cost estimation. It replaces the older hierarchical tree-based COA with a tabular approach that embeds all 8 hierarchy levels (L1-L8) directly in each record.
Key Files¶
| Layer | File |
|---|---|
| Frontend Types | frontend/src/types/coaKpi.ts |
| Frontend Hook | frontend/src/hooks/resources/useCOAKpis.ts |
| Frontend API | frontend/src/services/api/coaKpis.ts |
| Backend Router | backend/app/api/v1/routers/coa_kpis.py |
| Backend Schema | backend/app/schemas/coa_kpi.py |
| Backend Repository | backend/app/repositories/coa_kpi.py |
Data Model¶
interface COAKPI {
id: string; // Same as kpiCode
kpiCode: string; // Dot-separated code (e.g., "11.1.1.2.0.0.0")
kpiName: string; // Display name
group: 'bulk' | 'equipment' | 'indirect'; // Partition key
discipline?: string;
// 8-Level Hierarchy (denormalized)
l1Code: string;
l1Description: string;
l2Code?: string;
l2Description?: string;
// ... l3 through l8
// Computed
depth: number; // 1-8 based on filled levels
searchText: string; // For search optimization
// KPI Inheritance
enforceKpi: boolean; // When true, descendants use this KPI
effectiveKpiCode?: string; // The KPI to use (may be from ancestor)
effectiveKpiName?: string;
isInherited: boolean; // True if from enforced ancestor
}
Group Classification¶
| Group | Description | Examples |
|---|---|---|
bulk |
Bulk materials | Cables, pipes, fittings |
equipment |
Tagged equipment | Pumps, motors, valves |
indirect |
Indirect costs | Labor overhead, site costs |
API Endpoints¶
| Endpoint | Method | Description |
|---|---|---|
/coa-kpis |
GET | Paginated list with filters |
/coa-kpis/{kpi_code} |
GET | Single item |
/coa-kpis |
POST | Create |
/coa-kpis/{kpi_code} |
PUT | Update |
/coa-kpis/{kpi_code} |
DELETE | Soft/hard delete |
/coa-kpis/bulk |
POST | Bulk upsert |
/coa-kpis/disciplines |
GET | Distinct disciplines |
Query Filters¶
interface COAKPIFilters {
group?: 'bulk' | 'equipment' | 'indirect';
discipline?: string;
depth?: number;
search?: string;
isActive?: boolean;
limit?: number;
skip?: number;
}
Frontend Usage¶
const {
coaKpis, // Raw items
options, // For combobox (value + label)
optionsWithKpi, // With inheritance info
loading,
hasMore,
loadMore,
} = useCOAKpis({
filters: { group: 'bulk' },
});
MTO Integration¶
When assigning COA to an MTO item:
- User selects COA from combobox
- Frontend auto-populates KPI using
effectiveKpiCode - MTO item updated with
coaCode,coaName,kpiCode,kpiName - Q-Flag can mark item for cost-per-unit calculations
MTO Fields¶
interface MTOItem {
coaCode?: string; // Selected COA code
coaName?: string;
kpiCode?: string; // Effective KPI (may differ from COA)
kpiName?: string;
qFlag?: boolean; // Primary quantity for KPI aggregation
}
KPI Inheritance¶
The effectiveKpiCode is pre-computed:
If enforceKpi = true:
effectiveKpiCode = own kpiCode
Else if ancestor has enforceKpi = true:
effectiveKpiCode = ancestor's kpiCode (isInherited = true)
Else:
effectiveKpiCode = own kpiCode
COA vs COA KPIs¶
| Aspect | Legacy COA (Tree) | COA KPIs (Flat) |
|---|---|---|
| Structure | Hierarchical with parentId | Flat with L1-L8 embedded |
| KPI Inheritance | Computed at query time | Pre-computed |
| Query Performance | Tree traversal | Direct lookup |
| Partition Key | /scope |
/group |
Cosmos DB Configuration¶
- Container:
coa-kpis - Partition Key:
/group - ID: Uses
kpiCodeas document ID