forked from jappel/leistungsbilanz-ts
Integrate project building structure
This commit is contained in:
commit
868f48e7ac
44 changed files with 5898 additions and 377 deletions
|
|
@ -14,6 +14,8 @@ ausdrücklich getrennt und dürfen nicht als bereits implementiert verstanden we
|
|||
Drag-and-drop, Sortierung, Filterung und Undo/Redo
|
||||
- [Seitenansicht und PDF-Export](print-view.md) – Deckblatt,
|
||||
Verteilerübersicht, Verteilerpläne, Büro-Logo
|
||||
- [Gebäudestruktur](building-structure.md) – Gebäude → Etagen → Räume,
|
||||
Befehle, Snapshot-Schema 7, eigene Seite
|
||||
- [Editor-API](circuit-list-editor-api.md) – unterstützte Circuit-First-Endpunkte
|
||||
- [Bekannte Einschränkungen](circuit-list-editor-known-limitations.md) –
|
||||
bewusst noch nicht implementierte oder begrenzte Funktionen
|
||||
|
|
|
|||
81
docs/building-structure.md
Normal file
81
docs/building-structure.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# Gebäudestruktur (Gebäude → Etagen → Räume)
|
||||
|
||||
Projekte mit mehreren Gebäuden werden über eine eigene Ebene **Gebäude**
|
||||
gegliedert. Etagen können einem Gebäude zugeordnet sein, Räume und Verteilungen
|
||||
hängen wie bisher an der Etage. Das Gebäude eines Raums oder einer Verteilung
|
||||
ergibt sich also aus der Etage; eine zweite, konkurrierende Zuordnung gibt es
|
||||
nicht. Abstimmung mit Julian: Issue #6.
|
||||
|
||||
## Datenmodell
|
||||
|
||||
| Tabelle | Feld | Bedeutung |
|
||||
|---|---|---|
|
||||
| `buildings` | `id`, `project_id` (FK, cascade), `name`, `sort_order` | Gebäude eines Projekts |
|
||||
| `floors` | `building_id` (nullable FK → `buildings`, `ON DELETE set null`) | optionales übergeordnetes Gebäude |
|
||||
|
||||
Migration `0009_buildings`. Bestehende Etagen behalten `building_id = null` und
|
||||
erscheinen in der Oberfläche als „Ohne Gebäude“. Es gibt keine Zwangsmigration
|
||||
und kein automatisch angelegtes Standardgebäude. Vor dem Anwenden der Migration
|
||||
auf eine bestehende Datenbank ist wie bei jeder Schemamigration eine separate
|
||||
Datenbanksicherung anzulegen.
|
||||
|
||||
## Befehle, Undo/Redo
|
||||
|
||||
Alle Änderungen laufen über die bestehende Orts-Struktur
|
||||
(`ProjectLocationStructureProjectCommandRepository`) mit Revision, Inverse und
|
||||
persistentem Undo/Redo:
|
||||
|
||||
- `project-building.insert` / `project-building.delete` mit vollständigem
|
||||
Gebäude-Snapshot (Schema-Version 1)
|
||||
- `project-building.update`: ändert nur den Namen
|
||||
- Löschen eines Gebäudes wird abgelehnt, solange Etagen zugeordnet sind
|
||||
(„Das Gebäude kann nicht gelöscht werden, solange Etagen zugeordnet sind.“)
|
||||
- Etagenbefehle `project-floor.insert/.update/.delete` haben seit
|
||||
Schema-Version **2** das Feld `buildingId`. `project-floor.update` darf Name
|
||||
und/oder Gebäude ändern, nicht aber `sortOrder`. Ein referenziertes Gebäude
|
||||
muss zum Projekt gehören.
|
||||
- Version-1-Etagenbefehle aus bestehender Historie bleiben ausführbar. Sie
|
||||
stammen aus der Zeit vor den Gebäuden und werden vor der Ausführung mit
|
||||
`buildingId = null` auf Version 2 gehoben; auch die daraus neu gespeicherten
|
||||
Vorwärts- und Inversbefehle sind Version 2. Das ist bei linearer Historie
|
||||
exakt: Wird ein Gebäude später zugeordnet, liegt dieser neuere Befehl im
|
||||
Undo-Stapel vor dem alten Befehl und wird zuerst zurückgenommen.
|
||||
- Raumbefehle bleiben unverändert (Version 1).
|
||||
|
||||
## Snapshots und Transfer
|
||||
|
||||
Projekt-Snapshot-Schema **7** enthält `buildings` und `floors[].buildingId`.
|
||||
Alle älteren unterstützten Versionen (1–6) werden beim Einlesen mit leerer
|
||||
Gebäudeliste und `buildingId = null` hochgestuft; gespeicherte Sicherungspunkte
|
||||
bleiben wiederherstellbar. Die Relationen werden geprüft (Gebäude gehört zum
|
||||
Projekt, `buildingId` verweist auf ein Gebäude des Snapshots). Restore löscht
|
||||
und schreibt Gebäude zusammen mit den Etagen; der Projekt-Transfer vergibt neue
|
||||
Gebäude-IDs und stellt die Etagenverweise um.
|
||||
|
||||
## API
|
||||
|
||||
- `GET /api/projects/:projectId/buildings` – Gebäude sortiert nach
|
||||
`sortOrder`, Name
|
||||
- `POST /api/projects/:projectId/buildings` – `{ "name": "Haus A", "expectedRevision": 3 }`
|
||||
- `PUT /api/projects/:projectId/buildings/:buildingId` – `{ "name": "Haus B", "expectedRevision": 4 }`
|
||||
- `DELETE /api/projects/:projectId/buildings/:buildingId` – `{ "expectedRevision": 5 }`
|
||||
- `POST/PUT /api/projects/:projectId/floors[/:floorId]` akzeptieren zusätzlich
|
||||
optional `buildingId` (`string | null`). Fehlt das Feld, bleibt beim Bearbeiten
|
||||
das bisherige Gebäude erhalten; ältere Clients funktionieren unverändert.
|
||||
|
||||
## Oberfläche
|
||||
|
||||
Gebäude, Etagen und Räume werden auf der eigenen Seite
|
||||
`/projects/:projectId/struktur` („Gebäudestruktur“) gepflegt, erreichbar über
|
||||
die Seitenleiste und die Kennzahlen der Projektübersicht. Drei Spalten
|
||||
Gebäude → Etagen → Räume filtern sich gegenseitig: Klick auf ein Gebäude zeigt
|
||||
nur dessen Etagen, Klick auf eine Etage nur deren Räume, „Alle“ hebt den Filter
|
||||
auf. Hinzufügen, Bearbeiten und Löschen laufen über Icon-Buttons wie in der
|
||||
Stromkreisliste.
|
||||
|
||||
## Offen
|
||||
|
||||
- Revit: Das Gebäude kann später aus einem Revit-Parameter kommen und über die
|
||||
bestehende CSV-Zuordnung gemappt werden (Frage an Julian in Issue #6).
|
||||
- Sortierung von Gebäuden per Drag-and-drop ist noch nicht umgesetzt; neue
|
||||
Gebäude werden hinten angehängt.
|
||||
|
|
@ -257,15 +257,27 @@ returns HTTP `409` with `PROJECT_HISTORY_OPERATION_UNAVAILABLE`.
|
|||
`distribution-board.delete-subtree`. Persistent Undo/Redo restores or
|
||||
removes the same complete subtree, including protection devices.
|
||||
|
||||
### Project Floors and Rooms
|
||||
### Project Buildings, Floors and Rooms
|
||||
|
||||
- `GET /projects/:projectId/buildings`
|
||||
- `POST /projects/:projectId/buildings`
|
||||
- body: `{ "name": "Haus A", "expectedRevision": 12 }`
|
||||
- executes `project-building.insert` with a stable building id
|
||||
- response: `{ "building": { ... }, "revision": { ... }, "history": { ... } }`
|
||||
- `PUT /projects/:projectId/buildings/:buildingId`
|
||||
- body: `{ "name": "Haus B", "expectedRevision": 13 }` (name only)
|
||||
- `DELETE /projects/:projectId/buildings/:buildingId`
|
||||
- body: `{ "expectedRevision": 14 }`
|
||||
- rejects buildings with assigned floors
|
||||
- `POST /projects/:projectId/floors`
|
||||
- body: `{ "name": "EG", "expectedRevision": 13 }`
|
||||
- executes `project-floor.insert` with a stable floor id
|
||||
- body: `{ "name": "EG", "buildingId": "building_1", "expectedRevision": 13 }`
|
||||
(`buildingId` optional, `null` = no building)
|
||||
- executes `project-floor.insert` (command version 2) with a stable floor id
|
||||
- response: `{ "floor": { ... }, "revision": { ... }, "history": { ... } }`
|
||||
- `PUT /projects/:projectId/floors/:floorId`
|
||||
- body: `{ "name": "1. OG", "expectedRevision": 14 }`
|
||||
- executes an exact persistent floor update
|
||||
- body: `{ "name": "1. OG", "buildingId": null, "expectedRevision": 14 }`
|
||||
- executes an exact persistent floor update of name and/or building; a
|
||||
missing `buildingId` keeps the current building
|
||||
- `DELETE /projects/:projectId/floors/:floorId`
|
||||
- body: `{ "expectedRevision": 15 }`
|
||||
- rejects floors with assigned rooms or distribution boards
|
||||
|
|
|
|||
|
|
@ -255,9 +255,11 @@ Werte, Revision und Historienstapel gemeinsam. `PUT /api/projects/:projectId`
|
|||
verlangt deshalb `expectedRevision`, liefert Projekt plus aktualisierten
|
||||
Historienstand und besitzt keinen separaten direkten Settings-Schreibweg mehr.
|
||||
Kommando- und Snapshot-Payloads müssen dem aktuellen Baseline-Schema entsprechen.
|
||||
Die Projektseite zeigt Verteilungen, Etagen und Räume als kompakte
|
||||
Bestandsübersichten; ihre versionierten Erstellwege öffnen beschriftete Modals
|
||||
statt dauerhafter Eingabezeilen. Projektgeräte werden als durchsuchbare,
|
||||
Die Projektseite zeigt Verteilungen als kompakte Bestandsübersicht; ihre
|
||||
versionierten Erstellwege öffnen beschriftete Modals statt dauerhafter
|
||||
Eingabezeilen. Gebäude, Etagen und Räume werden auf der eigenen Seite
|
||||
„Gebäudestruktur“ (`/projects/:projectId/struktur`) gepflegt; Etagen können
|
||||
einem Gebäude zugeordnet sein (`docs/building-structure.md`). Projektgeräte werden als durchsuchbare,
|
||||
fünfspaltige Übersicht dargestellt. Manuelle Anlage, Übernahme aus der globalen
|
||||
Bibliothek und vollständige Bearbeitung erfolgen in einem gemeinsamen Modal.
|
||||
Die anschließende Vorschau verknüpfter Stromkreiszeilen bleibt davon getrennt,
|
||||
|
|
@ -457,6 +459,8 @@ Derselbe Befehl versioniert die Felder der Verteiler-Infokarte
|
|||
Infokarte liegt im Bearbeiten-Dialog der Verteilung; die Werte sind lokale
|
||||
Planungswerte und sollen später über den Revit-Abgleich nur nach Vorschau und
|
||||
ausdrücklicher Bestätigung vorbelegt werden. `fedFrom` ist vorerst Freitext.
|
||||
Snapshot-Schema 7 enthält zusätzlich die Gebäude und die Gebäudezuordnung
|
||||
der Etagen; ältere Versionen werden ohne Gebäude hochgestuft.
|
||||
Snapshot-Schema 6 enthält diese Felder und die Deckblattangaben des
|
||||
Projekts; ältere Versionen werden mit `null`
|
||||
hochgestuft. Snapshot-Schema 5 enthält zusätzlich den manuellen Mengenanteil jeder
|
||||
|
|
|
|||
|
|
@ -275,6 +275,10 @@ Completed foundation:
|
|||
- `project-floor.insert` and `project-room.insert` persist complete location
|
||||
records with stable ids; their inverses reject changed or referenced records
|
||||
so Undo never clears room assignments or device-row links implicitly
|
||||
- `project-building.insert/.update/.delete` persist complete building records;
|
||||
deleting a building with assigned floors is rejected. Floor commands carry
|
||||
`buildingId` since command version 2; version 1 floor commands from older
|
||||
history are upgraded with `buildingId = null` before execution
|
||||
- the floor and room POST routes require the current expected revision and the
|
||||
project page tracks the returned history state
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue