Add project device structure history

This commit is contained in:
2026-07-24 09:09:59 +02:00
parent 0bc6c7372f
commit ac16cca77a
15 changed files with 1262 additions and 26 deletions
+16 -8
View File
@@ -28,14 +28,15 @@ The public dispatcher currently supports `circuit.update`, `circuit.insert`,
`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
`project-device.update` and `project-device.sync-rows`, 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.
`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
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` targets existing circuits in the same circuit list.
`circuit-device-row.move-with-new-circuit` atomically creates exactly one
@@ -68,6 +69,13 @@ and derives its inverse from the persisted device. It validates project
ownership and never writes linked `CircuitDeviceRow` values; synchronization
remains a separate explicit command.
`project-device.insert` stores the complete canonical device with a stable id.
User inserts cannot attach existing rows. `project-device.delete` captures the
complete device and every currently linked row before deletion. Its inverse
recreates the same device and reconnects only rows whose complete disconnected
snapshot still matches; device, links, revision and history transition are
atomic.
Example:
```json
+8
View File
@@ -117,6 +117,14 @@ gespeicherten Gerät und schreibt Geräteänderung, Revision und Historienstapel
atomar. Verknüpfte Stromkreiszeilen werden dabei bewusst nicht automatisch
synchronisiert. Der bestehende ProjectDevice-`PUT`-Endpunkt verwendet diesen
Command bis zum UI-Cutover noch nicht.
`project-device.insert` und `project-device.delete` versionieren außerdem den
Lebenszyklus eines Projektgeräts mit stabiler UUID. Beim Löschen speichert das
inverse Insert den vollständigen Gerätestand sowie vollständige, nach dem
Löschen erwartete Snapshots aller zuvor verknüpften Gerätezeilen. Undo setzt
die Links nur zurück, wenn diese Zeilen weiterhin zum Projekt gehören,
unverknüpft und vollständig unverändert sind. Gerät, Linkänderungen, Revision
und Historienstapel teilen dieselbe Transaktion. Die bestehenden Create-,
Import- und Delete-Endpunkte sind noch nicht umgestellt.
## Projektgeräte
@@ -197,13 +197,17 @@ Completed foundation:
protect local values, links and override metadata against silent stale writes
- `project-device.update` persists canonical source-device field changes
independently and never synchronizes linked rows implicitly
- `project-device.insert` and `project-device.delete` preserve stable device
ids; delete undo restores links only from complete unchanged disconnected-row
snapshots in the same transaction
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/move, section-reorder/renumber, ProjectDevice field-update
and row-sync slices; the generic versioned command envelope is complete
field/insert/delete/move, section-reorder/renumber and ProjectDevice
field/insert/delete/row-sync slices; the generic versioned command envelope
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
@@ -411,6 +411,8 @@ Implemented foundation:
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
- ProjectDevice insert/delete commands preserve stable device ids and restore
previously linked rows only from complete unchanged disconnected snapshots
- revision metadata, change-set payloads and the project counter are committed
in one SQLite transaction
- a stale expected revision produces no history writes