Persist circuit reorders

This commit is contained in:
2026-07-25 21:22:10 +02:00
parent 08a2775a88
commit abcb468807
26 changed files with 914 additions and 372 deletions
+15 -21
View File
@@ -27,7 +27,8 @@ The public dispatcher currently supports `circuit.update`, `circuit.insert`,
`circuit.delete`, `circuit-device-row.update`,
`circuit-device-row.insert`, `circuit-device-row.delete`,
`circuit-device-row.move`, `circuit-device-row.move-with-new-circuit`,
`circuit.reorder-section`, `circuit.renumber-section` and
`circuit.reorder-section`, `circuit.reorder-sections`,
`circuit.renumber-section` and
`project-device.update`, `project-device.insert`, `project-device.delete` and
`project-device.sync-rows`, all with schema version `1`. Other command types
are rejected. Insert commands contain the complete entity or circuit block
@@ -37,8 +38,8 @@ 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. Existing Circuit and
CircuitDeviceRow cell edits, standalone insert/delete actions and device-row
moves in the editor consume these endpoints. Reorder and renumber UI paths are
still being migrated.
moves and reorders in the editor consume these endpoints. The renumber UI path
is 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
@@ -52,6 +53,11 @@ in the section. Each assignment records the expected and target `sortOrder`.
The command and its inverse change no circuit field other than `sortOrder`;
equipment identifiers and complete device-row blocks remain unchanged.
`circuit.reorder-sections` contains one complete assignment block per affected
section. All blocks are validated before any write and commit or roll back
together as one revision and one undo step. The editor uses it when applying a
sorted view that changes multiple sections.
`circuit.renumber-section` is an explicit operation requiring one assignment
for every circuit in the section. Assignments contain expected and target
equipment identifiers. The store rejects stale values, duplicate targets and
@@ -169,24 +175,12 @@ Response sketch:
- `GET /circuit-sections/:sectionId/next-identifier`
- preview next identifier for section (`prefix + maxSuffix + 1`)
Circuit and device-row field updates, standalone insertions/deletions and
single or bulk device-row moves are available only as the corresponding
versioned commands through `POST /projects/:projectId/commands`. There are no
direct field-update PATCH, structure POST, move, Circuit DELETE or
CircuitDeviceRow DELETE routes.
### Reorder Circuits
- `PATCH /circuit-sections/:sectionId/circuits/reorder`
- Purpose: persist explicit circuit order within one section.
Request sketch:
```json
{
"orderedCircuitIds": ["cir_2", "cir_1", "cir_3"]
}
```
Circuit and device-row field updates, standalone insertions/deletions, single
or bulk device-row moves and circuit reorders are available only as the
corresponding versioned commands through
`POST /projects/:projectId/commands`. There are no direct field-update PATCH,
structure POST, move, reorder, Circuit DELETE or CircuitDeviceRow DELETE
routes.
### Renumber Section
+7 -5
View File
@@ -126,9 +126,11 @@ Undo/redo wraps editor operations as command objects and reloads the tree after
each command. Existing Circuit and device-row cell edits plus standalone
insert/delete actions execute persistent project commands; their toolbar
undo/redo calls the project-wide server history. New entities receive stable
UUIDs before insertion, and deletion undo restores those same ids. Move,
reorder and renumber operations still use their existing direct API writes and
session-local inverse callbacks during the cutover.
UUIDs before insertion, and deletion undo restores those same ids. Device-row
moves and circuit reorders also use persistent project commands. Applying a
sorted view across multiple sections is atomic and occupies one history step.
Renumbering still uses its direct API write and session-local inverse callback
during the cutover.
Covered operations include:
@@ -142,5 +144,5 @@ Covered operations include:
Current limitations:
- the visible editor stack is still session-local and is empty after reload
- move, reorder and renumber editor actions are not connected to the persistent
command boundary yet
- renumber editor actions are not connected to the persistent command boundary
yet
@@ -3,8 +3,9 @@
- Existing Circuit and CircuitDeviceRow cell edits plus standalone
insert/delete actions and CircuitDeviceRow moves 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
reorder/renumber operations during the cutover.
still session-local, is empty after reload and still contains the direct
renumber operation during the cutover. Circuit reorder is already persistent,
including atomic multi-section sorted-order application.
- Server-side project revisions and persistent undo/redo eligibility exist for
the command types documented in `circuit-list-editor-api.md`; complete editor
command coverage and history reconstruction are not complete.
+8 -4
View File
@@ -92,10 +92,10 @@ sowie eigenständiges Einfügen und Löschen verwendet das Grid bereits über di
UUID vor dem Command; Löschen und Undo bewahren diese Identität. Der Tree liefert
dazu `currentRevision`; Undo/Redo für diese Aktionen läuft über die projektweite
Serverhistorie. Direkte Feld-PATCH-, Struktur-POST-, Move-, Circuit- und
Gerätezeilen-DELETE-Endpunkte sind entfernt. Gerätezeilen-Moves im Grid
verwenden die persistenten Kommandos bereits. Nur Reorder- und
Renumber-UI-Pfade verbleiben vorerst im sichtbaren sitzungslokalen Stack; nach
einem Reload wird dieser noch nicht aus der Serverhistorie rekonstruiert.
Gerätezeilen-DELETE-Endpunkte sind entfernt. Gerätezeilen-Moves und
Stromkreis-Reorders im Grid verwenden die persistenten Kommandos bereits. Nur
der Renumber-UI-Pfad verbleibt 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;
@@ -115,6 +115,10 @@ bleiben unverändert. `circuit.renumber-section` bildet die getrennte,
ausdrücklich ausgelöste Neunummerierung ab. Es speichert alle erwarteten und
neuen BMKs des Abschnitts, löst Tauschkollisionen über temporäre Werte und
ändert weder Sortierung noch Gerätezeilen.
Drag-and-drop verwendet `circuit.reorder-section`. Die explizite Übernahme
einer sortierten Ansicht verwendet `circuit.reorder-sections`, damit alle
betroffenen Bereiche in einer Transaktion und als ein Undo-Schritt gespeichert
werden. Direkte Reorder-Endpunkte existieren nicht mehr.
`project-device.sync-rows` persistiert Synchronisierung, Trennen und erneutes
Verknüpfen als atomaren Mehrzeilen-Command. Jede betroffene Zeile enthält den
vollständigen erwarteten und neuen Stand aller synchronisierbaren Felder,
@@ -200,6 +200,10 @@ Completed foundation:
- `circuit.reorder-section` requires the complete section circuit set and
stores exact expected/target sort positions; its inverse changes no
equipment identifier and never splits a circuit block
- `circuit.reorder-sections` applies the same invariants to every affected
section from a sorted view in one transaction and one history entry
- circuit drag-and-drop and sorted-order application use these commands; the
obsolete direct reorder route and transaction method are removed
- `circuit.renumber-section` is the separate explicit renumber operation; it
stores every expected/target equipment identifier, uses collision-safe
temporary values and restores the exact prior identifiers on undo
@@ -214,8 +218,8 @@ Completed foundation:
Remaining constraints before completing persistent history:
- route the remaining reorder and renumber editor writes through their existing
typed persistent commands and remove the final direct mutation routes
- route the remaining renumber editor writes through its existing typed
persistent command and remove the final direct mutation routes
- reconstruct the visible frontend history state after reload; Circuit and
CircuitDeviceRow field/insert/delete actions plus ProjectDevice operations
already use persistent commands and project-wide undo
+5 -4
View File
@@ -431,10 +431,11 @@ Implemented foundation:
and rollback after a forced late persistence failure
ProjectDevice CRUD, synchronization and disconnect on the project page and
Circuit/CircuitDeviceRow field/insert/delete actions in the circuit-list editor
are connected to this history boundary. Move, reorder and renumber UI paths are
not yet connected; the editor's visible undo/redo stack therefore remains
session-local and is not reconstructed after reload.
Circuit/CircuitDeviceRow field/insert/delete actions, device-row moves and
circuit reorders in the circuit-list editor are connected to this history
boundary. Applying sorted order across multiple sections is one atomic command.
The renumber UI path is not yet connected; the editor's visible undo/redo stack
therefore remains session-local and is not reconstructed after reload.
Acceptance criteria: