Demo Data Management System¶
Last Updated: 2026-01-19
Overview¶
The Demo Data Management system is a client-side data layer for construction cost estimation demo/report pages. It provides centralized state management via Zustand with localStorage persistence, full CRUD operations for KPIs, hierarchical tables, and chart data.
Purpose: Placeholder data layer for demo pages while backend API is developed (LCO-96).
Key Files¶
| File | Purpose |
|---|---|
frontend/src/stores/demoDataStore.ts |
Zustand store with CRUD actions |
frontend/src/data/demo/types.ts |
TypeScript interfaces |
frontend/src/data/demo/schemas.ts |
Zod validation schemas |
frontend/src/data/demo/defaults/ |
Default data for each report |
frontend/src/pages/DemoDataConfigPage.tsx |
Admin UI (/demo-config) |
Demo Pages¶
| Page | Route | Data Used |
|---|---|---|
| Cost Estimate Analysis | /projects/:id/analysis/cost-analysis |
KPIs, cost table |
| Labor Distribution | /projects/:id/analysis/labor-distribution |
KPIs, labor table, charts |
| Dynamic Historical | /projects/:id/analysis/dynamic-historical |
KPIs, historical charts |
| Manpower Plan | /projects/:id/analysis/manpower-plan |
KPIs, manpower tables/charts |
| Demo Config (Admin) | /demo-config |
Full store access |
Store API¶
State Shape¶
interface DemoDataState {
kpis: {
costAnalysis: KpiCardData[];
laborDistribution: KpiCardData[];
dynamicHistorical: KpiCardData[];
manpowerPlan: KpiCardData[];
};
costAnalysisData: CostAnalysisRow[]; // Hierarchical
laborDistributionData: LaborDistributionRow[]; // Hierarchical
manpowerPlanData: { ep: ManpowerRole[]; cm: ManpowerRole[] };
laborChartData: LaborChartDataPoint[];
hoursData: HoursDataPoint[];
historicalData: HistoricalDataPoint[];
manpowerChartData: { ep: ManpowerChartDataPoint[]; cm: ManpowerChartDataPoint[] };
lastModified: string;
version: number;
}
Actions¶
| Action | Description |
|---|---|
updateKpi(page, id, updates) |
Update specific KPI |
updateTableRow(tableKey, rowId, updates) |
Update hierarchical table row |
addTableRow(tableKey, row, parentId?) |
Add row (root or child) |
deleteTableRow(tableKey, rowId) |
Delete row recursively |
updateChartDataPoint(chartKey, id, updates) |
Update chart point |
addChartDataPoint(chartKey, point) |
Add chart point |
deleteChartDataPoint(chartKey, id) |
Delete chart point |
resetSection(section) |
Reset specific section to defaults |
resetAll() |
Reset entire store |
exportData() |
Export as JSON string |
importData(json) |
Import with Zod validation |
Usage Example¶
import { useDemoDataStore } from '@/stores/demoDataStore';
import { useShallow } from 'zustand/react/shallow';
// Read KPIs (with shallow comparison for performance)
const kpis = useDemoDataStore(useShallow((state) => state.kpis.costAnalysis));
// Update a KPI
const { updateKpi } = useDemoDataStore();
updateKpi('costAnalysis', 'kpi-ca-1', { value: '1.15' });
// Export/Import
const { exportData, importData } = useDemoDataStore();
const json = exportData();
const result = importData(jsonString); // { success: boolean, error?: string }
Data Structures¶
KPI Card¶
interface KpiCardData {
id: string;
label: string;
value: string;
subtitle?: string;
trend?: 'up' | 'down' | 'neutral';
}
Hierarchical Table Row¶
interface CostAnalysisRow {
id: string;
name: string;
isParent?: boolean;
originalBudget: number;
// ... other financial fields
children?: CostAnalysisRow[]; // Nested children
}
Persistence¶
- Storage Key:
lco-demo-data - Middleware: Zustand persist + Immer + DevTools
- Migration: Version field supports future schema changes
Architecture Notes¶
- Factory Pattern:
createInitialState()returns deep clones to prevent mutation bugs - Tree Search: Recursive helper for CRUD on hierarchical data
- ID-Based Ops: All operations use IDs (not indices) for stability
- Zod Validation: Import validates all fields including recursive children