Migration: Remove Legacy flowMeter Field
Date: 2026-01-15
Type: Breaking Change
Status: Completed
Summary
Removed all legacy flowMeter string fields from the flow meter and calibration systems. The system now exclusively uses asset_id with JOIN to data_assets table to retrieve display_id for display purposes.
Motivation
- Eliminate data redundancy and inconsistency
- Enforce referential integrity through foreign keys
- Standardize on asset-based identification system
- Simplify data model and reduce maintenance burden
Changes Made
1. Type Definitions (src/features/flow-meter/types.ts)
Before:
typescript
export type FlowMeterRecord = {
site: string;
flowMeter: string; // DEPRECATED
assetId?: string;
assetDisplayId?: string;
// ...
};
export type DustLocRefill = {
site: string;
flowMeter?: string; // DEPRECATED
assetId?: string;
assetDisplayId?: string;
// ...
};
export type FlowMeterCalibration = {
site: string;
flowMeter?: string; // legacy fallback
assetId?: string;
// ...
};After:
typescript
export type FlowMeterRecord = {
site: string;
assetId: string; // Now required
assetDisplayId: string; // Now required
// ...
};
export type DustLocRefill = {
site: string;
assetId: string; // Now required
assetDisplayId: string; // Now required
// ...
};
export type FlowMeterCalibration = {
site: string;
assetId: string; // Now required
assetDisplayId: string; // Now required
// ...
};2. Database Service (src/features/flow-meter/services/databaseService.ts)
Updated Mapping Functions:
mapFlowMeterRow()- Now only usesassetIdandassetDisplayIdmapDustLocRefillRow()- RemovedflowMeterfieldmapFlowMeterCalibrationRow()- RemovedflowMeterfield, addedassetDisplayId
Updated Query Functions (All now JOIN with data_assets):
fetchAllFlowMeterData()- JOINsdata_assetsfordisplay_idfetchFlowMeterDataByDateRange()- Added JOINfetchAllRefills()- Already had JOIN, removed fallbackfetchRefillsByDateRange()- Added JOINfetchRefillsBySite()- Added JOINfetchAllCalibrations()- Added JOIN
Updated Insert/Update Functions:
insertRefill()- Removedflow_meterparameter,asset_idnow requiredupdateRefill()- Removedflow_meterparameterinsertCalibration()- Removedflow_meterparameter,asset_idnow requiredupdateCalibration()- Removedflow_meterparameterinsertFlowMeterData()- Changed fromflow_metertoasset_id
3. UI Components
AddRefillModal (src/features/flow-meter/components/AddRefillModal.tsx)
- Removed
flowMeterstate and legacy flow meter dropdown - Simplified to only show asset selection
- Shows error message if no assets available for site
onSubmitinterface updated to requireassetId
EditRefillModal (src/features/flow-meter/components/EditRefillModal.tsx)
- Removed
flowMeterstate - Flow meter now read-only (cannot be changed after creation)
- Site selection disabled during edit
- Displays
assetDisplayIdin read-only field onSubmitinterface updated to requireassetId
SiteSummaryCard (src/features/flow-meter/components/SiteSummaryCard.tsx)
- Filtering logic updated to only use
assetDisplayId - Removed
flowMeterfallback
CalibrationModal (src/features/flow-meter/components/CalibrationModal.tsx)
- Removed
flowMeterfield handling assetIdnow required (validation added)onSubmitinterface updated
4. Page Components
Refill Management (src/app/(admin)/(pages)/refill-management/index.tsx)
- Table displays only
assetDisplayId handleAddRefillupdated to passassetIdhandleEditRefillupdated to passassetId- Removed
flowMeterRecordsprop from EditRefillModal
Flow Meter Index (src/app/(admin)/(pages)/flow-meter/index.tsx)
- Filter logic updated to use
assetDisplayIdexclusively - Table columns display
assetDisplayId
Calibration Management (src/app/(admin)/(pages)/calibration-management/index.tsx)
- Search updated to use
assetDisplayId - Total assets calculation simplified
handleAddCalibrationrequiresassetIdhandleEditCalibrationrequiresassetId- Table displays
assetDisplayId
5. Dashboard Components
CalibrationReminder (src/app/(admin)/(dashboards)/index/components/CalibrationReminder.tsx)
- Key generation uses only
assetId - Display label uses
assetDisplayId
useDashboardCalibrationCompliance Hook
- Updated to use
assetIdfor keys - Display label uses
assetDisplayId
6. Data Services
dataAggregation.ts
- Deduplication key updated to use
assetIdinstead offlowMeter
csvParser.ts
- Updated CSV format to expect 6 columns:
- site
- assetId
- assetDisplayId
- litres
- dateTime
- scrapedAt
- Removed
flowMetercolumn
dataImporter.ts
- Import logic updated to use
asset_idinstead offlow_meter - Both batch import functions updated
Database Schema Changes
The migration assumes the following database schema changes have been applied:
data_flow_meterstable:flow_metercolumn deprecated (or removed)asset_idcolumn is required with FK todata_assets(asset_id)
ops_dustloc_refillstable:flow_metercolumn deprecated (or removed)asset_idcolumn is required with FK todata_assets(asset_id)
ops_flow_calibrationstable:flow_metercolumn deprecated (or removed)asset_idcolumn is required with FK todata_assets(asset_id)
Data Migration Required
IMPORTANT: Before deploying this change, a data migration must be run to:
- Populate
asset_idfor all existing records that only haveflow_meter - Create corresponding
data_assetsentries if they don't exist - Verify all foreign key constraints are satisfied
Breaking Changes
CSV Import Format Changed:
- Old format:
site, flowMeter, litres, dateTime, scrapedAt - New format:
site, assetId, assetDisplayId, litres, dateTime, scrapedAt
- Old format:
API Interfaces Changed:
- All refill/calibration creation/update functions now require
assetId flowMeterparameter removed from all interfaces
- All refill/calibration creation/update functions now require
Component Props Changed:
- Components no longer accept or display
flowMeterfield assetIdandassetDisplayIdare now required
- Components no longer accept or display
Validation
Build status: ✅ SUCCESS
bash
pnpm build:check
# Exit code: 0Testing Checklist
- [ ] Add new refill with asset selection
- [ ] Edit existing refill (verify flow meter is read-only)
- [ ] Add new calibration with asset selection
- [ ] Edit existing calibration
- [ ] View refill management table
- [ ] View calibration management table
- [ ] View flow meter page with filtering
- [ ] Check dashboard calibration reminders
- [ ] Import CSV with new format
- [ ] Verify data aggregation works correctly
Files Modified
Type Definitions:
src/features/flow-meter/types.ts
Database Services:
src/features/flow-meter/services/databaseService.tssrc/features/flow-meter/services/dataAggregation.tssrc/features/flow-meter/services/csvParser.tssrc/features/flow-meter/services/dataImporter.ts
Components:
src/features/flow-meter/components/AddRefillModal.tsxsrc/features/flow-meter/components/EditRefillModal.tsxsrc/features/flow-meter/components/SiteSummaryCard.tsxsrc/features/flow-meter/components/CalibrationModal.tsx
Pages:
src/app/(admin)/(pages)/refill-management/index.tsxsrc/app/(admin)/(pages)/flow-meter/index.tsxsrc/app/(admin)/(pages)/calibration-management/index.tsx
Dashboard:
src/app/(admin)/(dashboards)/index/components/CalibrationReminder.tsxsrc/features/dashboard/hooks/useDashboardCalibrationCompliance.ts
Rollback Plan
If issues are discovered:
- Revert all code changes (git revert)
- Do NOT rollback database schema changes (keep asset_id columns)
- Re-apply data migration to restore flowMeter values if needed
- Consider gradual migration approach instead
Benefits
- Data Integrity: Foreign key constraints prevent orphaned records
- Single Source of Truth: Asset display names managed centrally
- Simplified Logic: No more fallback chains or duplicate display logic
- Type Safety: Required fields prevent null/undefined issues
- Maintainability: Cleaner codebase without legacy code paths
Notes
- The migration requires database schema changes to be applied first
- All existing records must have valid
asset_idvalues before deployment - CSV import files must be updated to new format
- Any external integrations using the old format will break