524 lines
20 KiB
Markdown
524 lines
20 KiB
Markdown
# Implementation Phases and Todo List
|
|
|
|
## Important Strategy
|
|
|
|
There is already an existing codebase.
|
|
|
|
Do not blindly continue with the current implementation if it conflicts with this specification.
|
|
|
|
Do not blindly delete the current codebase either.
|
|
|
|
First audit the existing code against this specification, then refactor or replace the parts that conflict with the target model.
|
|
|
|
The most important architectural correction is:
|
|
|
|
A circuit is not the same thing as one device row.
|
|
|
|
A circuit contains zero, one or multiple device rows.
|
|
|
|
## Phase 0: Audit Existing Codebase
|
|
|
|
Goal:
|
|
|
|
Determine which parts of the current codebase can be kept.
|
|
|
|
Tasks:
|
|
|
|
- identify current data model
|
|
- identify whether rows are modeled as circuits, devices or mixed entities
|
|
- identify hardcoded section logic
|
|
- identify current drag-and-drop implementation
|
|
- identify current table/editing implementation
|
|
- identify current project device concept
|
|
- identify persistence layer and migrations
|
|
- list conflicts with the new specification
|
|
- propose refactor plan before changing code
|
|
|
|
Deliverable:
|
|
|
|
- short audit report
|
|
- keep/refactor/delete recommendation per major module
|
|
|
|
## Phase 1: Core Data Model and Basic Table
|
|
|
|
Goal:
|
|
|
|
Implement the stable foundation.
|
|
|
|
Tasks:
|
|
|
|
- define sections
|
|
- define circuits
|
|
- define circuit device rows
|
|
- define project devices
|
|
- allow manual rows
|
|
- allow empty/reserve circuits
|
|
- calculate row total power
|
|
- calculate circuit total power
|
|
- display sections as separator rows
|
|
- display single-device circuits as compact rows
|
|
- display multi-device circuits with summary row and indented device rows
|
|
- implement manual equipment identifier editing
|
|
- implement next identifier generation as highest number + 1
|
|
- prevent automatic renumbering
|
|
|
|
Acceptance criteria:
|
|
|
|
- a section can contain multiple circuits
|
|
- a circuit can contain zero, one or multiple device rows
|
|
- deleting a device does not automatically delete the circuit unless the user chooses so
|
|
- circuit total power is calculated from all device rows
|
|
- equipment identifiers are stable unless manually changed or explicitly renumbered
|
|
|
|
## Phase 2: Spreadsheet-Like Editing
|
|
|
|
Goal:
|
|
|
|
Make the table efficient to edit.
|
|
|
|
Tasks:
|
|
|
|
- static text cells by default
|
|
- inline editing on double click / Enter / typing / F2
|
|
- Enter, Tab, Shift+Tab, Escape behavior
|
|
- keyboard navigation
|
|
- Ctrl + Plus row insertion
|
|
- Ctrl + Shift + Plus support
|
|
- Delete behavior
|
|
- validation warnings for duplicate identifiers
|
|
|
|
Acceptance criteria:
|
|
|
|
- common values can be edited without opening full forms
|
|
- keyboard workflow is usable for repetitive entry
|
|
- accidental edits can be cancelled
|
|
|
|
## Phase 3: Project Device Sidebar
|
|
|
|
Goal:
|
|
|
|
Allow dragging project devices into the circuit list.
|
|
|
|
Tasks:
|
|
|
|
- implement project device list
|
|
- search project devices
|
|
- filter project devices
|
|
- show basic technical values
|
|
- drag project device into valid section
|
|
- drop onto free placeholder to create a circuit
|
|
- drop onto existing circuit to add device
|
|
- create linked device rows
|
|
- prefill display name but keep it local after insertion
|
|
|
|
Acceptance criteria:
|
|
|
|
- project devices can create new circuits
|
|
- project devices can be added to existing circuits
|
|
- invalid sections reject drops or require confirmation
|
|
- linked rows keep the source relationship
|
|
|
|
## Phase 4: Drag-and-Drop Restructuring
|
|
|
|
Goal:
|
|
|
|
Allow restructuring circuits and device assignments.
|
|
|
|
Tasks:
|
|
|
|
- drag from circuit handle moves whole circuit
|
|
- drag from device area moves device row
|
|
- move device between circuits
|
|
- move device to free placeholder to create new circuit
|
|
- move circuit inside section
|
|
- visual drop indicator
|
|
- valid/invalid drop zone feedback
|
|
- multi-row selection with Ctrl + click and Shift + click
|
|
- multi-row drag preserving internal order
|
|
|
|
Acceptance criteria:
|
|
|
|
- circuits can be reordered without renumbering
|
|
- devices can be reassigned to other circuits
|
|
- circuit totals recalculate after moves
|
|
- multi-row movement does not break circuit/device grouping
|
|
|
|
## Phase 5: Filtering, Sorting and Columns
|
|
|
|
Goal:
|
|
|
|
Add Excel-like table management.
|
|
|
|
Tasks:
|
|
|
|
- filter menu per column header
|
|
- sort ascending/descending per column
|
|
- sorting circuits as complete blocks
|
|
- preserve device grouping when sorting
|
|
- column visibility configuration
|
|
- column reorder by drag and drop
|
|
- reset default column layout
|
|
|
|
Acceptance criteria:
|
|
|
|
- user can filter by room, cost group, category, phase type, etc.
|
|
- user can sort within sections
|
|
- sorting does not split circuits
|
|
- sorting does not renumber
|
|
- user can renumber explicitly after sorting
|
|
|
|
## Phase 6: Undo / Redo
|
|
|
|
Goal:
|
|
|
|
Make structural editing safe.
|
|
|
|
Tasks:
|
|
|
|
- implement undo/redo stack
|
|
- support insert circuit
|
|
- support insert device
|
|
- support delete circuit
|
|
- support delete device
|
|
- support move circuit
|
|
- support move device
|
|
- support multi-row move
|
|
- support renumber section
|
|
- support cell edits
|
|
- support sync operations
|
|
- support disconnect linked project device
|
|
|
|
Acceptance criteria:
|
|
|
|
- destructive changes can be reverted
|
|
- renumbering can be undone
|
|
- drag-and-drop restructuring can be undone
|
|
|
|
Note:
|
|
|
|
Undo/redo should be considered from the beginning. Implement technically as early as possible if the architecture allows it.
|
|
|
|
## Phase 7: Linked Device Synchronization
|
|
|
|
Goal:
|
|
|
|
Control updates from project devices to circuit list rows.
|
|
|
|
Tasks:
|
|
|
|
- track linked project devices
|
|
- track overridden fields
|
|
- show affected rows when a project device changes
|
|
- implement sync dialog
|
|
- allow field-level selection
|
|
- apply to one / selected / all linked rows
|
|
- allow disconnecting selected rows
|
|
|
|
Acceptance criteria:
|
|
|
|
- displayName is not synchronized by default
|
|
- user sees affected distribution boards and circuits
|
|
- user controls which fields are overwritten
|
|
- local values are not silently lost
|
|
|
|
## Phase 8: Future Sizing Preparation
|
|
|
|
Goal:
|
|
|
|
Prepare for future electrical sizing logic.
|
|
|
|
Tasks:
|
|
|
|
- keep circuit-level protection and cable fields
|
|
- keep voltage and cosPhi
|
|
- support future control requirement
|
|
- structure sizing rules separately from UI
|
|
- add warning/status concept
|
|
|
|
Acceptance criteria:
|
|
|
|
- the codebase can later add rule-based sizing without redesigning circuits/devices
|
|
- users can manually override calculated suggestions
|
|
|
|
## Phase 9: Development Environment and Docker
|
|
|
|
Goal:
|
|
|
|
Make short development sessions quick to start and stop.
|
|
|
|
Tasks:
|
|
|
|
- add a Docker-based local development setup
|
|
- start frontend, API and SQLite persistence with one command
|
|
- keep the database in an explicit persistent volume
|
|
- run or document pending database migrations during startup
|
|
- add concise start, stop and reset instructions
|
|
- retain a non-Docker development path for direct debugging
|
|
|
|
Acceptance criteria:
|
|
|
|
- a new development session starts with one documented command
|
|
- stopping and restarting does not lose the local database
|
|
- frontend and API health can be checked without manual port setup
|
|
- the development workflow works consistently across short sessions
|
|
|
|
Note:
|
|
|
|
This phase may be moved earlier if repeated local startup overhead begins to slow down feature development.
|
|
|
|
## Phase 10: Deferred Circuit Editor UX Polish
|
|
|
|
Goal:
|
|
|
|
Improve everyday usability after the core circuit workflows are stable.
|
|
|
|
Tasks:
|
|
|
|
- keep column headers visible while scrolling down long circuit lists
|
|
- keep undo/redo controls reachable without scrolling to the top
|
|
- preserve the user's viewport when toolbar undo/redo is applied instead of jumping to the changed row
|
|
- reduce the default table width and contain horizontal scrolling within the editor
|
|
- review sensible default columns and responsive behavior for typical browser widths
|
|
- redesign column filtering with clearer controls, active-filter indicators and an easy reset action
|
|
|
|
Implemented layout foundation:
|
|
|
|
- table scrolling is contained inside the editor so sticky headers remain visible
|
|
- the toolbar remains reachable while the page scrolls
|
|
- programmatic grid focus preserves the viewport during undo/redo reloads
|
|
- wide tables no longer expand the surrounding browser layout
|
|
- active sorts and filters are summarized above the grid and can be removed individually or reset together
|
|
- column filter buttons show their selected-value count
|
|
- filter menus provide value search, select-all/select-none controls and explicit cancel/apply actions
|
|
- filter values and visible columns use full-width selectable rows instead of permanent checkbox controls
|
|
- column settings use the same searchable panel pattern as column filters
|
|
- column headings are visually plain text while remaining keyboard-accessible sort controls
|
|
|
|
Acceptance criteria:
|
|
|
|
- users retain column context anywhere in a long list
|
|
- undo/redo does not disrupt the current reading position
|
|
- the editor remains usable without overflowing the browser layout
|
|
- active filters are easy to understand, change and clear
|
|
|
|
## Phase 11: Persistence and Transaction Foundation
|
|
|
|
Goal:
|
|
|
|
Prepare the current SQLite implementation for persistent history and a later PostgreSQL adapter without changing user-facing behavior.
|
|
|
|
Tasks:
|
|
|
|
- add real SQLite integration tests for transaction commit and rollback
|
|
- introduce an injectable transaction / unit-of-work boundary
|
|
- remove direct database-client access from domain services
|
|
- treat synchronous SQLite transactions as an adapter detail
|
|
- remove dead persistence methods after coverage exists
|
|
- verify database backup and restore independently from project history
|
|
|
|
Acceptance criteria:
|
|
|
|
- critical multi-write commands roll back completely in a real database test
|
|
- domain command behavior is not coupled to `better-sqlite3`
|
|
- adding a PostgreSQL persistence adapter does not require rewriting editor domain rules
|
|
|
|
Implemented foundation:
|
|
|
|
- database contexts can be created independently from the production singleton
|
|
- SQLite foreign-key enforcement is enabled explicitly for every context
|
|
- the distribution-board repository receives its database dependency explicitly
|
|
- distribution-board setup has real in-memory SQLite commit and rollback coverage using production migrations
|
|
- database backups use SQLite's online backup API and include committed WAL data
|
|
- every backup is opened independently and checked for integrity and foreign-key violations
|
|
- an integration test restores the backup into a separate database and verifies its snapshot contents
|
|
- circuit-device-row creation/deletion and reserve-state changes use an explicitly injected transaction store
|
|
- a new circuit and all of its initial device rows use the same transaction store
|
|
- device-row moves, reserve-state updates and optional target creation share one transaction
|
|
- project-device synchronization, disconnect and reconnect use a separate injected transaction store
|
|
- section renumbering and circuit reordering use a separate injected transaction store
|
|
- circuit-device-row transaction tests cover both successful commits and forced SQLite rollbacks
|
|
- project-device row synchronization has real multi-row SQLite commit and rollback coverage
|
|
- BMK swaps and section reorder have real SQLite commit and rollback coverage
|
|
- the legacy consumer migration receives its database dependency at the script entry point
|
|
- legacy circuit, row, mapping and report writes have real late-failure rollback coverage
|
|
- circuit and device-row persistence value mapping is separated from the general repositories
|
|
- the legacy consumer UI and application read/write endpoints are removed after verified data cutover
|
|
- retained legacy rows are accessible only through explicit database upgrade tooling
|
|
- project devices no longer persist duplicate legacy power, phase, cosPhi or remark fields
|
|
|
|
## Phase 12: Project Revisions and Persistent Undo / Redo
|
|
|
|
Goal:
|
|
|
|
Persist project-wide change history and restore points across reloads and application restarts.
|
|
|
|
Tasks:
|
|
|
|
- [x] add project-scoped monotonic revision storage
|
|
- [x] add immutable append-only server-side change-set storage with versioned
|
|
forward/inverse payloads
|
|
- [x] add optimistic checks when appending a revision
|
|
- route domain writes and history records through one shared transaction
|
|
- define concrete serializable domain command descriptions and executors
|
|
outside React
|
|
- [x] persist undo/redo eligibility on the server
|
|
- [x] expose public command, undo and redo endpoints for the first supported
|
|
update command types
|
|
- add named and periodic logical project snapshots
|
|
- restore a historical snapshot as a new revision
|
|
- keep database backups separate from logical history
|
|
|
|
Implemented foundation:
|
|
|
|
- projects start at revision zero and advance monotonically
|
|
- each revision has one separately stored logical change set
|
|
- forward and inverse changes use complete, versioned JSON command envelopes
|
|
- invalid or lossy command payloads are rejected before persistence
|
|
- an internal typed `circuit.update` command generates its inverse from the
|
|
persisted pre-command state
|
|
- circuit update, inverse command, change set and revision share one SQLite
|
|
transaction with stale-command and late-failure rollback coverage
|
|
- an internal typed `circuit-device-row.update` command uses the same boundary,
|
|
records derived ProjectDevice override metadata and rejects cross-project
|
|
rows, device links and rooms
|
|
- relational project-wide undo/redo stacks persist eligible original change
|
|
sets, enforce LIFO order and clear redo on a new user command
|
|
- stack transitions are part of the domain/revision transaction and have
|
|
late-failure rollback coverage
|
|
- a read-only project history endpoint exposes revision, stack depths and top
|
|
change-set ids
|
|
- a central application dispatcher reconstructs persisted commands and exposes
|
|
optimistic command, undo and redo endpoints for Circuit and CircuitDeviceRow
|
|
field updates
|
|
- typed CircuitDeviceRow insert/delete commands preserve complete row snapshots
|
|
and stable ids; row mutation, circuit reserve state, revision and history
|
|
stack transition commit or roll back together
|
|
- typed Circuit insert/delete commands treat the circuit and all device rows as
|
|
one block, preserve every stable id and never renumber neighbouring circuits
|
|
- typed CircuitDeviceRow move commands persist exact old/new circuit and sort
|
|
positions for single or multi-row moves between existing circuits and derive
|
|
affected reserve states in the same transaction
|
|
- placeholder-target moves persist one complete generated circuit identity and
|
|
all row positions atomically; undo restores every source and removes only an
|
|
unchanged generated circuit, without renumbering
|
|
- complete section reorders persist every expected and target circuit
|
|
`sortOrder`; undo/redo changes neither equipment identifiers nor device rows
|
|
- explicit section renumber commands persist every expected and target
|
|
equipment identifier, apply swaps collision-safely and restore exact prior
|
|
identifiers without changing sort positions or device rows
|
|
- ProjectDevice row synchronization, disconnect and reconnect persist complete
|
|
expected/target sync snapshots in one atomic multi-row command; undo restores
|
|
local values, links and override metadata without silent overwrites
|
|
- canonical ProjectDevice field updates persist independently with exact
|
|
inverses and never overwrite linked CircuitDeviceRow values implicitly
|
|
- revision metadata, change-set payloads and the project counter are committed
|
|
in one SQLite transaction
|
|
- a stale expected revision produces no history writes
|
|
- integration coverage verifies sequential revisions, stale-command rejection
|
|
and rollback after a forced late persistence failure
|
|
|
|
The current editor operations are not connected to this history boundary yet.
|
|
Undo/redo therefore remains session-local until the remaining tasks are
|
|
implemented.
|
|
|
|
Acceptance criteria:
|
|
|
|
- undo/redo remains available after a page reload
|
|
- every logical command and inverse is atomic and auditable
|
|
- restoring an older state does not delete intervening history
|
|
- concurrent stale commands cannot silently overwrite newer project state
|
|
|
|
## Phase 13: External Model Round-Trip
|
|
|
|
Goal:
|
|
|
|
Exchange model objects and planning parameters with Revit or comparable tools through CSV or another agreed format.
|
|
|
|
Tasks:
|
|
|
|
- model external sources, import batches and stable IFCGUID objects
|
|
- stage and validate imports before applying them
|
|
- show additions, changes, missing objects and conflicts
|
|
- link external objects explicitly to project-domain entities
|
|
- apply an import as one auditable project revision
|
|
- configure inbound and outbound parameter mappings
|
|
- export against a known project revision while preserving IFCGUID
|
|
|
|
Acceptance criteria:
|
|
|
|
- repeated imports match objects deterministically by source and IFCGUID
|
|
- imports never silently overwrite local planning values
|
|
- users approve the diff before it changes the project
|
|
- exported data can be assigned back to the correct Revit objects
|
|
|
|
PostgreSQL should be introduced when shared multi-user operation, background jobs or operational scale justify it. External-object count alone does not require an immediate migration.
|
|
|
|
## Phase 14: Documentation and Collaboration Handoff
|
|
|
|
Goal:
|
|
|
|
After the legacy consumer path has been removed, provide one accurate entry point for developers, contributors and LLM-assisted work.
|
|
|
|
Timing:
|
|
|
|
- perform the final rewrite after legacy cutover so the documentation describes only the supported architecture
|
|
- update documentation incrementally during earlier phases, but do not present transitional paths as the long-term design
|
|
|
|
README target structure:
|
|
|
|
- short project purpose and current maturity/status
|
|
- supported domain workflow at a high level
|
|
- technology stack
|
|
- prerequisites
|
|
- recommended Docker development quick start
|
|
- direct local development start
|
|
- test, type-check and build commands
|
|
- database persistence, migration, backup and restore basics
|
|
- production deployment/install instructions once a production setup exists
|
|
- concise documentation map
|
|
- contribution entry point
|
|
|
|
README content to remove or relocate:
|
|
|
|
- historical requirement checklists
|
|
- file-by-file implementation status from early prototypes
|
|
- obsolete legacy consumer architecture
|
|
- long domain specifications already maintained in `docs/`
|
|
- broken links and claims that are not verified by the current code
|
|
|
|
Documentation tasks:
|
|
|
|
- add a `docs/README.md` index with current, future and archived documents clearly separated
|
|
- keep current architecture, domain invariants, API behavior and interaction behavior synchronized with code
|
|
- archive superseded initial requirements under `docs/archive/` when they are still useful for traceability
|
|
- remove obsolete documentation that has no remaining historical or operational value
|
|
- update `AGENTS.md` with current entry points, supported/deprecated paths and forward architecture constraints
|
|
- add a concise contributor workflow for branches, migrations, tests and commits
|
|
- document how a colleague creates an empty local database and optionally loads safe sample data
|
|
- avoid duplicating the same architecture facts across README, `AGENTS.md` and detailed docs; link to one source of truth
|
|
|
|
Deployment documentation requirements:
|
|
|
|
- distinguish development Compose from production deployment
|
|
- do not label the hot-reload development stack as a production setup
|
|
- document required environment variables, ports, health checks, persistent storage and migration behavior
|
|
- verify backup and restore procedures
|
|
|
|
Acceptance criteria:
|
|
|
|
- a colleague can clone the repository and start a clean development environment using only the README
|
|
- a contributor can identify the supported architecture and relevant code entry points without reading historical specs
|
|
- an LLM receives domain invariants, current module boundaries and deferred architecture direction without relying on stale legacy files
|
|
- every README command and internal documentation link is verified
|
|
- production instructions describe a real tested deployment path or clearly state that none is supported yet
|
|
|
|
Implemented handoff:
|
|
|
|
- README is a concise setup and project entry point without prototype status lists
|
|
- `docs/README.md` separates current, operational, future, specification and archived material
|
|
- current runtime, module boundaries and upgrade-only legacy data are documented explicitly
|
|
- contributor workflow covers clean databases, safe demo data, migrations, tests and commits
|
|
- development Compose is clearly separated from the currently unsupported production deployment
|
|
- `AGENTS.md` points LLM-assisted work to supported code paths and deferred architecture
|
|
- obsolete frontend placeholder documents were removed and early Codex prompts were archived
|