Skip to content

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

  1. Factory Pattern: createInitialState() returns deep clones to prevent mutation bugs
  2. Tree Search: Recursive helper for CRUD on hierarchical data
  3. ID-Based Ops: All operations use IDs (not indices) for stability
  4. Zod Validation: Import validates all fields including recursive children