3.0 KiB
Circuit List Editor Migration
Status
Upgrade-only. New installations already use the Circuit-First schema and do not run this workflow.
Goal
Migrate legacy row-first consumers into the circuit-first model without deleting legacy data.
Legacy Mapping
Legacy Consumer rows map into:
Circuitfor shared circuit identity and circuit-level technical fieldsCircuitDeviceRowfor per-device load rows
Multiple legacy consumers can map into one circuit when they share normalized circuit identity.
For one circuit list, all new circuits, device rows, trace mappings and the migration report are committed in one SQLite transaction. A failed run therefore leaves none of those prepared migration writes behind.
Grouping Strategy (circuitNumber)
Migration groups legacy rows by normalized circuitNumber:
- valid/normalizable values become one target circuit per normalized value
- duplicates are grouped under that circuit (multiple
CircuitDeviceRows) - missing/invalid values trigger generated identifiers and may fall back to
unassignedsection
Default Section Backfill
Before migration, default sections are created/backfilled per circuit list.
This guarantees a valid target section space, including unassigned when no section can be inferred.
Migration Commands
Run in this order for local database workflows:
- Backup:
npm run db:backup
- Migrate schema:
npm run db:migrate
- Verify circuit schema:
npm run db:verify:circuit-schema
- Backfill missing sections:
npm run db:backfill:sections
- Migrate legacy consumers:
npm run db:migrate:legacy-consumers
The migration command finishes with a cutover verification across the complete
database. It exits with an error while any legacy consumer lacks a migration
mapping, including consumers that cannot be migrated because they have no circuit
list assignment. The legacy multi-list UI was removed only after this check passed;
old /projects/:projectId/circuit-lists bookmarks redirect to the project page.
Validation Checks
After migration, verify:
- tree endpoint returns sections/circuits/rows
- grouped duplicate circuit numbers are reported
- generated identifiers are reported where expected
- migrated rows include
legacyConsumerIdtraceability - no duplicate BMKs exist inside one circuit list
If Tree Endpoint Returns Empty Sections
Likely causes:
- circuit-first tables missing (migration not run)
- sections not backfilled yet
- migrated dataset genuinely empty for selected list
Actions:
- Run schema migration and verification commands.
- Run section backfill command.
- Run legacy-consumer migration command.
- Retry tree endpoint.
Legacy Data Retention
Do not delete legacy consumers yet.
- legacy read/write endpoints have been removed from the application server
- migration trace tables reference old/new mapping
- retained rows allow upgrade verification and audit of the completed mapping
- a future automatic cleanup migration must migrate and verify old databases before dropping these source and trace tables