Add device row move history

This commit is contained in:
2026-07-23 22:29:44 +02:00
parent ca13efbfcb
commit 0a51703315
14 changed files with 940 additions and 13 deletions
+11 -5
View File
@@ -25,14 +25,20 @@ concurrency checks.
The public dispatcher currently supports `circuit.update`, `circuit.insert`,
`circuit.delete`, `circuit-device-row.update`,
`circuit-device-row.insert` and `circuit-device-row.delete`, all with schema
version `1`. Other command types are rejected. Insert commands contain the
complete entity or circuit block with stable ids; delete commands include the
expected parent identity. Circuit snapshots contain zero, one or multiple
complete device rows. This makes deletion undoable without generating
`circuit-device-row.insert`, `circuit-device-row.delete` and
`circuit-device-row.move`, all with schema version `1`. Other command types are
rejected. Insert commands contain the complete entity or circuit block 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.
`circuit-device-row.move` currently targets existing circuits in the same
circuit list. Creating a new target circuit while moving rows is not yet part
of the persistent command API.
Example:
```json
+8 -3
View File
@@ -86,9 +86,14 @@ 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. Verschiebe-, Sortier-,
Neunummerierungs- und Synchronisierungsoperationen müssen vor der
Frontend-Umstellung ebenfalls als persistente Commands modelliert werden.
sichtbare Historie bleibt daher sitzungslokal.
`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;
Reservewerte aller beteiligten Stromkreise werden atomar neu abgeleitet. Das
Verschieben auf einen freien Platz mit gleichzeitiger Stromkreiserzeugung sowie
Circuit-Sortierung, Neunummerierung und Synchronisierung müssen vor der
Frontend-Umstellung noch als persistente Commands modelliert werden.
## Projektgeräte
@@ -179,12 +179,16 @@ Completed foundation:
- `circuit.insert` and `circuit.delete` persist a complete circuit block with
zero, one or multiple device rows; undo restores all ids and fields without
renumbering
- `circuit-device-row.move` stores exact expected and target circuit/sort
positions for one or multiple rows, recalculates all affected reserve states
and reconstructs a deterministic inverse across multiple source circuits
Remaining constraints before completing persistent history:
- extend the concrete project-scoped command union and executors beyond the
Circuit field/insert/delete and CircuitDeviceRow field/insert/delete slices;
the generic versioned command envelope is complete
Circuit field/insert/delete and CircuitDeviceRow
field/insert/delete/existing-target-move slices; the generic versioned
command envelope is complete
- route the remaining structural, synchronization and destructive domain
writes through the shared command, revision and stack transaction boundary
- replace the session-local frontend command stack only after server-side
@@ -395,6 +395,9 @@ Implemented foundation:
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
- revision metadata, change-set payloads and the project counter are committed
in one SQLite transaction
- a stale expected revision produces no history writes