Persist circuit cell edits
This commit is contained in:
@@ -5,9 +5,9 @@
|
||||
The circuit-first editor uses tree, circuit, row and project-device endpoints.
|
||||
All paths below are mounted below `/api`. There is no Consumer application API.
|
||||
|
||||
Project responses from `GET /projects` and `GET /projects/:projectId` include
|
||||
`currentRevision`. Versioned project commands use this value for optimistic
|
||||
concurrency checks.
|
||||
Project responses from `GET /projects`, `GET /projects/:projectId` and the
|
||||
circuit-tree endpoint include `currentRevision`. Versioned project commands use
|
||||
this value for optimistic concurrency checks.
|
||||
|
||||
### Project Commands and History
|
||||
|
||||
@@ -35,8 +35,9 @@ with stable ids; delete commands include the expected parent identity. Circuit
|
||||
snapshots contain zero, one or multiple complete device rows. Move commands
|
||||
contain each row's expected and target circuit plus its exact expected and
|
||||
target sort order. This makes deletion and moves undoable without generating
|
||||
replacement identities or renumbering circuits. The editor does not consume
|
||||
these endpoints yet.
|
||||
replacement identities or renumbering circuits. Existing Circuit and
|
||||
CircuitDeviceRow cell edits in the editor consume these endpoints; the
|
||||
remaining structural editor writes are still being migrated.
|
||||
|
||||
`circuit-device-row.move` targets existing circuits in the same circuit list.
|
||||
`circuit-device-row.move-with-new-circuit` atomically creates exactly one
|
||||
@@ -137,6 +138,7 @@ Response sketch:
|
||||
```json
|
||||
{
|
||||
"circuitListId": "cl_1",
|
||||
"currentRevision": 12,
|
||||
"sections": [
|
||||
{
|
||||
"id": "sec_1",
|
||||
@@ -167,8 +169,6 @@ Response sketch:
|
||||
- create circuit in list/section
|
||||
- `POST /projects/:projectId/circuit-lists/:circuitListId/circuits-with-device-rows`
|
||||
- atomically create one circuit and one or more initial device rows
|
||||
- `PATCH /circuits/:circuitId`
|
||||
- update circuit-level fields (BMK, protection, cable, reserve flag, etc.)
|
||||
- `DELETE /circuits/:circuitId`
|
||||
- delete circuit (and related rows via DB relations)
|
||||
- `GET /circuit-sections/:sectionId/next-identifier`
|
||||
@@ -189,11 +189,14 @@ Request sketch (`POST .../circuits`):
|
||||
|
||||
- `POST /circuits/:circuitId/device-rows`
|
||||
- create row inside a circuit
|
||||
- `PATCH /circuit-device-rows/:rowId`
|
||||
- update row values
|
||||
- `DELETE /circuit-device-rows/:rowId`
|
||||
- delete row
|
||||
|
||||
Circuit and device-row field updates are available only as versioned
|
||||
`circuit.update` and `circuit-device-row.update` commands through
|
||||
`POST /projects/:projectId/commands`. There are no direct field-update PATCH
|
||||
routes.
|
||||
|
||||
### Move Device Row
|
||||
|
||||
- `PATCH /circuit-device-rows/:rowId/move`
|
||||
|
||||
@@ -11,7 +11,10 @@ Inline cells are static text by default. A cell enters edit mode by:
|
||||
|
||||
`Enter` confirms changes. `Escape` cancels current edit draft. `Tab` and `Shift+Tab` confirm and move to next/previous editable cell.
|
||||
|
||||
Committed cell edits are persisted as partial database updates. Fields that were not part of the edit are not written back from an older read and therefore cannot overwrite a concurrent change to another field.
|
||||
Committed cells on existing circuits and device rows are persisted as typed
|
||||
project commands with an optimistic project revision. Only the edited fields
|
||||
are included, so an older tree response cannot write unrelated fields back.
|
||||
The server records the inverse in the same transaction.
|
||||
|
||||
## `selectedCell` vs `editingCell`
|
||||
|
||||
@@ -119,7 +122,11 @@ Cross-section device moves show confirmation-required feedback before drop. The
|
||||
|
||||
## Undo/Redo
|
||||
|
||||
Undo/redo wraps editor operations as command objects with async `redo`/`undo` and reloads tree after each command.
|
||||
Undo/redo wraps editor operations as command objects and reloads the tree after
|
||||
each command. Existing Circuit and device-row cell edits execute persistent
|
||||
project commands; their toolbar undo/redo calls the project-wide server
|
||||
history. Other covered operations still use their existing direct API writes
|
||||
and session-local inverse callbacks during the cutover.
|
||||
|
||||
Covered operations include:
|
||||
|
||||
@@ -132,5 +139,6 @@ Covered operations include:
|
||||
|
||||
Current limitations:
|
||||
|
||||
- session-local only
|
||||
- no persisted history across browser reload
|
||||
- the visible editor stack is still session-local and is empty after reload
|
||||
- structural and destructive editor actions are not all connected to the
|
||||
persistent command boundary yet
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
# Circuit List Editor Known Limitations
|
||||
|
||||
- The circuit-list editor still exposes only its session-local undo/redo UI.
|
||||
- Existing Circuit and CircuitDeviceRow cell edits use persistent project
|
||||
commands and project-wide toolbar undo/redo. The editor's visible stack is
|
||||
still session-local, is empty after reload and still contains direct
|
||||
structural/destructive operations during the cutover.
|
||||
- Server-side project revisions and persistent undo/redo eligibility exist for
|
||||
the command types documented in `circuit-list-editor-api.md`; command coverage
|
||||
and the editor UI cutover are not complete.
|
||||
the command types documented in `circuit-list-editor-api.md`; complete editor
|
||||
command coverage and history reconstruction are not complete.
|
||||
- Named logical project snapshots and restore are not implemented yet.
|
||||
- No Revit/CSV/IFCGUID import and export workflow is implemented yet.
|
||||
- Persistence currently targets local SQLite; PostgreSQL is an architectural option, not an implemented runtime.
|
||||
|
||||
@@ -41,7 +41,7 @@ liegt über einen Host-Mount außerhalb des Containers.
|
||||
- `src/app/projects/[projectId]/circuit-lists/[circuitListId]/tree-edit/page.tsx`
|
||||
– unterstützte Editorroute
|
||||
- `src/frontend/components/circuit-tree-editor.tsx` – Editorzustand,
|
||||
Befehlsausführung, Drag-and-drop und sitzungslokales Undo/Redo
|
||||
Befehlsausführung, Drag-and-drop und der schrittweise Historien-Cutover
|
||||
- `src/frontend/components/circuit-grid-*.ts` – reine Grid-Projektion,
|
||||
Zellbesitz, Einfügen und Sicherheitsregeln
|
||||
- `src/frontend/utils/api.ts` – typisierte Frontend-API-Aufrufe
|
||||
@@ -62,7 +62,8 @@ liegt über einen Host-Mount außerhalb des Containers.
|
||||
6. Das Frontend lädt den Circuit-Tree neu und stellt Auswahl beziehungsweise
|
||||
Viewport soweit möglich wieder her.
|
||||
|
||||
Die React-Historie ist derzeit sitzungslokal. Das Datenmodell besitzt bereits
|
||||
Der sichtbare React-Historiestapel ist während des schrittweisen Cutovers noch
|
||||
sitzungslokal. Das Datenmodell besitzt
|
||||
einen projektbezogenen Revisionszähler sowie getrennte Revision-/Change-Set-
|
||||
Tabellen. Ein getestetes Repository kann diese Historienmetadaten optimistisch
|
||||
und atomar fortschreiben. Vorwärts- und Rückwärtskommandos besitzen einen
|
||||
@@ -85,8 +86,13 @@ inversen Kommando gesichert, sodass Undo dieselbe UUID und alle Fachwerte
|
||||
wiederherstellt. `circuit.insert` und `circuit.delete` behandeln einen
|
||||
Stromkreis mit null, einer oder mehreren Gerätezeilen als vollständigen Block.
|
||||
Undo bewahrt dabei sämtliche Circuit-/Row-UUIDs und ändert keine
|
||||
Betriebsmittelkennzeichen. Das Grid verwendet diese Endpunkte noch nicht; seine
|
||||
sichtbare Historie bleibt daher sitzungslokal.
|
||||
Betriebsmittelkennzeichen. Bestehende Circuit- und Gerätezeilen-Zelländerungen
|
||||
verwendet das Grid bereits über die öffentliche Command-Grenze. Der Tree liefert
|
||||
dazu `currentRevision`; Undo/Redo für diese Zellaktionen läuft über die
|
||||
projektweite Serverhistorie. Die direkten PATCH-Endpunkte für diese Felder sind
|
||||
entfernt. Andere Editoraktionen verbleiben vorerst im sichtbaren
|
||||
sitzungslokalen Stack; nach einem Reload wird dieser noch nicht aus der
|
||||
Serverhistorie rekonstruiert.
|
||||
`circuit-device-row.move` verschiebt oder sortiert eine oder mehrere Zeilen
|
||||
zwischen vorhandenen Stromkreisen derselben Liste. Erwartete und neue
|
||||
Stromkreis-/Sortierpositionen machen Forward und Inverse deterministisch;
|
||||
@@ -159,7 +165,8 @@ bei einem späteren Wechsel trotzdem einen eigenen PostgreSQL-Adapter.
|
||||
|
||||
## Noch nicht unterstützt
|
||||
|
||||
- persistentes Undo/Redo und Projektversionen
|
||||
- vollständiges persistentes Undo/Redo, sichtbare Historie nach Reload und
|
||||
benannte Projektstände
|
||||
- Mehrbenutzerbetrieb und Konfliktauflösung
|
||||
- Revit-/CSV-/IFCGUID-Round-trip
|
||||
- vollständige elektrische Dimensionierung
|
||||
|
||||
@@ -173,6 +173,11 @@ Completed foundation:
|
||||
to SQLite
|
||||
- public command, undo and redo endpoints require an expected revision; undo
|
||||
and redo reconstruct the eligible persisted inverse or forward command
|
||||
- the circuit tree returns the project's current revision; existing Circuit
|
||||
and CircuitDeviceRow cell edits use the public command endpoint, while their
|
||||
toolbar undo/redo actions use project-wide persistent history
|
||||
- obsolete direct Circuit and CircuitDeviceRow field-update PATCH routes are
|
||||
removed so these editor writes cannot bypass revision history
|
||||
- `circuit-device-row.insert` and `circuit-device-row.delete` preserve stable
|
||||
row ids, complete deleted-row snapshots and circuit reserve state through
|
||||
atomic insert/delete, revision and stack transitions
|
||||
@@ -210,10 +215,10 @@ Remaining constraints before completing persistent history:
|
||||
is complete
|
||||
- route the remaining structural and destructive domain
|
||||
writes through the shared command, revision and stack transaction boundary
|
||||
- replace the session-local frontend command stack only after server-side
|
||||
command coverage is complete for structural and destructive circuit-editor
|
||||
operations; the ProjectDevice synchronization UI already uses its persistent
|
||||
command and project-wide undo endpoint
|
||||
- finish routing structural and destructive circuit-editor operations through
|
||||
persistent commands, then reconstruct the visible frontend history state
|
||||
after reload; Circuit/CircuitDeviceRow cell edits and ProjectDevice
|
||||
synchronization already use persistent commands and project-wide undo
|
||||
- do not model IFCGUID as an overloaded circuit equipment identifier
|
||||
- keep database backup/restore checks separate from project history tests
|
||||
|
||||
|
||||
@@ -390,6 +390,9 @@ Implemented foundation:
|
||||
- a central application dispatcher reconstructs persisted commands and exposes
|
||||
optimistic command, undo and redo endpoints for Circuit and CircuitDeviceRow
|
||||
field updates
|
||||
- the circuit tree exposes `currentRevision`; existing Circuit and
|
||||
CircuitDeviceRow cell edits use those optimistic commands and project-wide
|
||||
undo/redo instead of direct field-update PATCH routes
|
||||
- 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
|
||||
@@ -424,10 +427,11 @@ Implemented foundation:
|
||||
- integration coverage verifies sequential revisions, stale-command rejection
|
||||
and rollback after a forced late persistence failure
|
||||
|
||||
ProjectDevice CRUD, synchronization and disconnect on the project page are
|
||||
connected to this history boundary. The circuit-list editor and the remaining
|
||||
domain writes are not fully connected; its visible undo/redo therefore remains
|
||||
session-local until the remaining tasks are implemented.
|
||||
ProjectDevice CRUD, synchronization and disconnect on the project page and
|
||||
existing Circuit/CircuitDeviceRow cell edits in the circuit-list editor are
|
||||
connected to this history boundary. Remaining structural editor writes are not
|
||||
fully connected; the editor's visible undo/redo stack therefore remains
|
||||
session-local and is not reconstructed after reload.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user