From 927b868dcb41082d4252695769df09a73106c6d8 Mon Sep 17 00:00:00 2001 From: Julian Appel Date: Sun, 2 Aug 2026 15:47:12 +0200 Subject: [PATCH] Plan Revit CSV integration --- docs/README.md | 2 + docs/spec/07-implementation-phases-todo.md | 6 + .../spec/revit-csv-phase-14-audit-and-plan.md | 330 ++++++++++++++++++ 3 files changed, 338 insertions(+) create mode 100644 docs/spec/revit-csv-phase-14-audit-and-plan.md diff --git a/docs/README.md b/docs/README.md index fbbd4bd..69a2115 100644 --- a/docs/README.md +++ b/docs/README.md @@ -25,6 +25,8 @@ ausdrücklich getrennt und dürfen nicht als bereits implementiert verstanden we - [Projektversionen und externer Modellaustausch](project-history-and-external-model-architecture.md) - [LLM-Kontext für die Revit-Anforderungsplanung](revit-requirements-llm-context.md) +- [Revit-CSV-Anforderungen](spec/revit-csv-integration-requirements.md) +- [Phase-14-Audit und Implementierungsplan](spec/revit-csv-phase-14-audit-and-plan.md) - [Zukünftige Dimensionierung](spec/06-future-sizing-and-calculations.md) - [Roadmap und Phasen](spec/07-implementation-phases-todo.md) - [Aktueller Produkt-Backlog](spec/08-current-product-backlog.md) diff --git a/docs/spec/07-implementation-phases-todo.md b/docs/spec/07-implementation-phases-todo.md index 4ebae4f..84e0132 100644 --- a/docs/spec/07-implementation-phases-todo.md +++ b/docs/spec/07-implementation-phases-todo.md @@ -532,6 +532,12 @@ Acceptance criteria: ## Phase 14: External Model Round-Trip +Status: Phase 14.0 (Audit und Verträge) ist dokumentiert und wartet vor der +Laufzeitimplementierung auf Freigabe. Siehe +[Phase-14-Audit und Implementierungsplan](revit-csv-phase-14-audit-and-plan.md) +und die verbindlichen +[Revit-CSV-Anforderungen](revit-csv-integration-requirements.md). + Goal: Exchange model objects and planning parameters with Revit or comparable tools through CSV or another agreed format. diff --git a/docs/spec/revit-csv-phase-14-audit-and-plan.md b/docs/spec/revit-csv-phase-14-audit-and-plan.md new file mode 100644 index 0000000..88ef0cb --- /dev/null +++ b/docs/spec/revit-csv-phase-14-audit-and-plan.md @@ -0,0 +1,330 @@ +# Phase 14: Audit- und Implementierungsplan für die Revit-CSV-Anbindung + +## Status + +Phase 14.0 ist abgeschlossen. Dieses Dokument beschreibt den gegen den aktuellen +Code geprüften Zielzuschnitt. Die Laufzeitimplementierung beginnt gemäß der +verbindlichen Revit-Spezifikation erst nach Freigabe dieses Audits. + +Fachliche Quelle bleibt +[Revit-CSV-Integration – Anforderungen und Implementierungsanweisung](revit-csv-integration-requirements.md). +Dieses Dokument konkretisiert dafür Namen, Modulgrenzen, Persistenz und die +Reihenfolge kleiner Arbeitspakete. + +## Ergebnis des Bestandsaudits + +### Beibehalten + +- Das Circuit-First-Modell bleibt unverändert: Ein `Circuit` besitzt null bis + viele `CircuitDeviceRow`-Datensätze. +- `ProjectDevice` bleibt die kanonische projektweite Vorlage. Ein Import darf + diese Datensätze weder erzeugen noch ändern, solange der Nutzer dies nicht + ausdrücklich bestätigt. +- `CircuitDeviceRow.linkedProjectDeviceId` bleibt die optionale Verbindung + zwischen einer Gerätezeile und genau einer Projektgerätevorlage. +- Die bestehenden getrennten Drag-and-drop-Pfade für Projektgeräte, + Gerätezeilen und Stromkreise bleiben bestehen. Externe Objekte erhalten einen + vierten, fachlich eigenen Pfad. +- Alle bestätigten Änderungen verwenden typisierte Commands mit + `expectedRevision`, vollständiger Gegenrichtung und + `project-command-transaction.persistence.ts` als gemeinsamer + Transaktionsgrenze. +- Snapshot-Erfassung, Restore und Projektduplikat bleiben explizite Adapter mit + fester Fremdschlüsselreihenfolge und UUID-Remapping. +- SQLite und die heutige Server-Komposition bleiben der einzige unterstützte + Laufzeitadapter. + +### Erweitern oder gezielt refaktorieren + +- `ProjectStateSnapshot` und der portable Projekttransfer werden additiv um den + bestätigten externen Projektzustand erweitert. Bereits veröffentlichte + Snapshot-Versionen werden nicht verändert. +- Der Command-Dispatcher erhält schmale Stores für externe Konfiguration, + Importübernahme, Objektplanung und Row-Zuordnung. Controller erhalten keine + konkreten SQLite-Abhängigkeiten. +- Der Stromkreislisteneditor erhält später einen separaten Drawer für + unzugeordnete externe Objekte. Die bestehende Projektgeräteauswahl wird nicht + dafür zweckentfremdet. +- Vor der ersten externen Row-Zuordnung wird die Mengenhoheit einer + `CircuitDeviceRow` explizit gemacht; Details stehen unter „Mengenmodell“. + +### Hinzufügen + +- verlustarmer CSV-Transportadapter außerhalb von React und Circuit-Domain; +- projektweite, versionierte Revit-CSV-Konfiguration; +- eine zunächst implizite externe Modellquelle je Projekt; +- Importbatches einschließlich Originaltransport und akzeptiertem + Konfigurationsstand; +- persistente externe Objekte mit `IfcGUID`, getrennten Quell- und + Planungswerten und einzelnem Lebenszyklus; +- Quellraum-Mappings auf interne Räume und Standardverteilungen; +- explizite Verknüpfungen zu `ProjectDevice`, `CircuitDeviceRow` und optionaler + abweichender Verteilung; +- Vorschau-, Konflikt- und Exportprojektionen als reine Anwendungsservices; +- fokussierte Parser-, Command-, Transaktions-, Snapshot-, Transfer- und + End-to-End-Tests. + +### Entfernen + +Es existiert kein unterstützter Revit-Laufzeitpfad. Deshalb wird in Phase 14 +kein bestehender Fachpfad entfernt und keine Legacy-Kompatibilität eingeführt. + +## Vorgeschlagenes Domänenmodell + +Die Namen sind ab Phase 14.1 verbindliche Arbeitsnamen. Tabellen verwenden die +jeweilige englische Pluralform in `snake_case`. + +### `ExternalModelSource` + +- stabile interne UUID; +- `projectId`; +- technischer Name und Quelltyp `revit_csv`; +- Verweis auf den zuletzt bestätigten Importbatch. + +In der ersten Ausbaustufe wird genau eine Quelle je Projekt automatisch +angelegt. Es gibt bewusst keine sichtbare Mehrquellenverwaltung. Die +Eindeutigkeit eines externen Objekts ist trotzdem von Anfang an +`(sourceId, ifcGuid)`. + +### `ExternalCsvConfiguration` + +- stabile UUID und `projectId` mit genau einer aktiven Konfiguration; +- Konfigurationsschema-Version; +- CSV-Dialekt: Encoding, BOM, Trennzeichen, Zeilenende, Quote-Zeichen, + Dezimalformat und Kopfzeilenerkennung; +- exakte Spaltenzuordnung; +- geordnete, exakte Familie-und-Typ-Regeln; +- monotoner Konfigurationsstand. + +Eine Änderung ersetzt den vollständigen erwarteten Konfigurationssnapshot in +einem Command. Jeder bestätigte Importbatch speichert zusätzlich den dabei +verwendeten Konfigurationssnapshot. Damit bleiben ältere Importe erklärbar, +ohne eine zweite veränderbare Historientabelle einzuführen. + +### `ExternalImportBatch` + +- stabile UUID, `projectId`, `sourceId`, Importart und Zeitstempel; +- Dateiname, SHA-256 und zugehörige Projektrevision; +- verwendeter Konfigurationssnapshot; +- Originaldatei als Bytes; +- verlustarme logische Zellmatrix mit Zeilenklassen und Dialektmetadaten. + +Die Kombination aus Originalbytes und Matrix ist bewusst gewählt: Die Bytes +belegen den unveränderten Eingang, die Matrix erlaubt einen gezielten +Rückexport einzelner gemappter Objektzellen, ohne unbekannte Spalten, +Titelzeilen, Leerzeilen oder Summenzeilen neu zu interpretieren. + +### `ExternalRoomMapping` + +- stabile UUID, `sourceId` und normalisierter Quellraumschlüssel; +- Quellgeschoss-, Raumnummer- und Raumname-Snapshot; +- optionales `roomId`; +- optionale `defaultDistributionBoardId`. + +Das Mapping bleibt Teil der optionalen externen Integration. Dadurch erhält +das allgemeine Raummodell keine Revit-spezifische Pflichtbeziehung. + +### `ExternalModelObject` + +- stabile interne UUID, `projectId`, `sourceId` und unveränderte `ifcGuid`; +- letzter gesehener und letzter akzeptierter Importbatch; +- akzeptierte Quellwerte getrennt als strukturierter Snapshot; +- lokale Planungswerte für Anzeigename, Kategorie, Anschlussart, wirksame + Menge, Leistung je Einheit, Gleichzeitigkeitsfaktor, `cosPhi`, Kostengruppe + und Bemerkung; +- explizite Override-Metadaten; +- optionales `externalRoomMappingId`; +- optionale abweichende `distributionBoardId`; +- optionales `linkedProjectDeviceId`; +- optionales `circuitDeviceRowId`; +- Anwesenheitsstatus für bestätigte fehlende Objekte. + +Die n:1-Beziehung entsteht durch `circuitDeviceRowId` am Einzelobjekt: Viele +einzeln nachverfolgbare IFC-Objekte dürfen genau einer Gerätezeile zugeordnet +sein. Eine Mehrfachsteckdose bleibt ein einzelnes Objekt und trägt ihre +wirksame Menge größer eins. + +Konflikte werden soweit möglich aus akzeptiertem Quellstand, neuem +Vorschaustand und lokalen Overrides berechnet. Nur ein vom Nutzer bestätigter +Anwesenheits- oder Planungszustand wird persistiert. + +## Mengenmodell der Gerätezeile + +Die heutige `CircuitDeviceRow.quantity` unterscheidet nicht zwischen manueller +Menge und verknüpften IFC-Objekten. Ohne Erweiterung könnte das Lösen eines +Objekts manuelle Mengen löschen oder doppelt zählen. + +Vor Phase 14.3 wird deshalb `manualQuantity` ergänzt: + +```text +quantity = manualQuantity + + Summe(effectiveQuantity aller verknüpften ExternalModelObjects) +``` + +- Bei der Migration erhält jede bestehende Row + `manualQuantity = quantity`; ihr Ergebnis bleibt unverändert. +- Eine ausschließlich aus externen Objekten erstellte Row startet mit + `manualQuantity = 0`. +- `quantity` bleibt zunächst der materialisierte Gesamtwert für bestehende + Berechnungen, Filter und Exporte und wird im selben Command aktualisiert. +- Ein externes Objekt wird nie geteilt und kann höchstens einer Row zugeordnet + sein. +- Objekte dürfen nur aggregiert werden, wenn die rowbestimmenden lokalen Werte + übereinstimmen. Widersprüchliche Werte werden in der ersten Ausbaustufe nicht + automatisch vereinheitlicht, sondern benötigen getrennte Rows oder eine + ausdrückliche Nutzerentscheidung. +- Eine bestehende Row mit manueller Menge darf externe Objekte aufnehmen; beim + Lösen bleibt der manuelle Anteil erhalten. + +Für die UI vor Phase 14.3 bleibt noch festzulegen, ob eine nach dem Lösen leere +Row stehen bleibt oder nach gesonderter Bestätigung gelöscht wird. Ein stiller +Row-Lebenszyklus ist ausgeschlossen. + +## Command-Schnittstellen + +Alle Payloads tragen `schemaVersion: 1`, vollständige erwartete und gewünschte +Snapshots und werden mit der aktuellen Projektrevision geplant. Große +Importcommands dürfen umfangreich sein; sie müssen für Redo deterministisch +bleiben und dürfen spätere Quellstände nicht erneut auswerten. + +- `external-csv-configuration.update`: vollständige projektweite + Konfiguration ändern. +- `external-import.apply-initial`: Quelle, Batch, Raum-Mappings, externe + Objekte und bestätigte Links atomar einfügen. +- `external-import.apply-follow-up`: neuen Batch und die vollständigen + erwarteten/gewünschten Änderungen bestehender, neuer und fehlender Objekte + atomar übernehmen. +- `external-model-object.update-planning`: lokale Werte und Overrides eines + oder mehrerer Objekte ändern. +- `external-model-object.update-project-device-link`: ProjectDevice-Links + explizit setzen oder lösen, ohne das ProjectDevice zu verändern. +- `external-model-object.assign-to-row`: Objekte einer bestehenden Row + zuweisen und deren materialisierte Menge atomar aktualisieren. +- `external-model-object.assign-to-new-row`: stabile neue Row einfügen, + Objekte verknüpfen und gegebenenfalls den Reserve-Status aktualisieren. +- `external-model-object.assign-to-new-circuit`: stabilen Circuit samt Schutz, + Row und Objektlinks in einem Schritt einfügen. Das geplante BMK wird im + Command gespeichert und bei Redo nicht neu berechnet. +- `external-model-object.unassign-from-row`: einzelne Objektlinks lösen und + die Menge exakt aktualisieren. +- `external-model-object.delete-missing`: nur ausdrücklich bestätigte, + weiterhin unveränderte fehlende Objekte löschen. + +Die Erzeugung eines neuen `ProjectDevice` verwendet weiterhin den vorhandenen +`project-device.insert`-Command. Revit-Werte füllen lediglich das sichtbare +Formular vor; erst dessen Bestätigung erzeugt die Vorlage. CSV-Vorschau und +Rückexport sind reine Leseoperationen. Append-only Exportnachweise verändern +keine Projektrevision und laufen über einen eigenen Audit-Store. + +## Snapshot-, Transfer- und Migrationsfolgen + +- Phase 14.1 führt Migration `0002` für die Konfiguration ein und erhöht das + Project-State-Snapshot-Schema additiv von 2 auf 3. Der Upgrader von Version 2 + ergänzt `externalCsvConfiguration = null`. +- Phase 14.2 führt Migration `0003` für Quelle, Batches, Raum-Mappings und + Objekte ein und erhöht das Snapshot-Schema von 3 auf 4. Der Upgrader ergänzt + leere externe Collections. +- Phase 14.3 führt die additive Row-Spalte `manual_quantity` ein. Bestehende + Werte werden einmalig aus `quantity` übernommen. +- Snapshot-Capture und Restore erhalten Konfiguration, Quelle, bestätigte + Batches, Raum-Mappings und Objekte in expliziter FK-Reihenfolge. +- Beim Projektduplikat werden alle neuen internen UUIDs und internen Links + remappt. `IfcGUID`, Quellwerte, Transportmatrix und unbekannte CSV-Inhalte + bleiben unverändert. +- Der Transfer-Envelope kann Version 1 bleiben; die enthaltene + Project-State-Schema-Version wird additiv erhöht. +- Vorhandene Migrationen und Snapshot-Upgrader werden nicht editiert. + +## Implementierungsfolge + +### 14.1 – CSV-Konfiguration und reine Vorschau + +1. Transport-Domainverträge, Dialekt- und Mappingvalidatoren sowie kleine + synthetische Fixtures ergänzen. +2. Zustandsfreien Parser und Serializer mit Round-trip-Tests für UTF-8-BOM, + CRLF, Semikolon, vollständige Quotierung, Kopfzeile in Zeile 2 sowie + Titel-, Leer-, Objekt- und Passthrough-Zeilen implementieren. +3. Konfiguration über Migration, Snapshot v3, Transfer und den Command + `external-csv-configuration.update` persistieren. +4. Vorschau-Endpunkt und deutschen Projekt-Wizard ergänzen. Der Server speichert + keinen Entwurf: Bei Bestätigung wird die Datei erneut übertragen, erneut + geparst und ihr Hash gegen die Vorschau geprüft. + +Abnahme: fokussierte Tests, vollständige Tests und alle vorgeschriebenen +Build-/Typecheck-Schritte. Für die exakte Abnahme mit 897 Objekt- und 211 +Summenzeilen wird noch die anonymisierte Referenz-CSV benötigt; sie liegt nicht +im Repository. + +### 14.2 – Persistente Objekte und Erstimport + +1. Schema, Repositories und reine Identitäts-/Matchingregeln ergänzen. +2. Snapshot v4, Restore und Projektduplikat samt UUID-Remapping ergänzen. +3. Erstimport-Command mit echten SQLite-Commit-/Rollback-Tests ergänzen. +4. Raum-, Verteilungs-, Klassifizierungs- und ProjectDevice-Schritte im Wizard + ergänzen; der Import selbst erzeugt keine CircuitDeviceRow. + +Vor Beginn werden die oben vorgeschlagenen Namen, die erneute Dateiübertragung +statt serverseitiger Entwürfe, die Konfigurationsversionierung und die +Kombination aus Originalbytes und Matrix als Entscheidungen bestätigt. + +### 14.3 – Editor und explizite Zuordnung + +1. `manualQuantity` und Mengeninvarianten migrieren und testen. +2. Commands für vorhandene Row, neue Row, neuen Circuit und Lösen ergänzen. +3. Verteilungsbezogenen Drawer, Filter und Vorschau der Mengenwirkung ergänzen. +4. Einzel- und Mehrfach-Drag-and-drop samt Warnungen, Undo/Redo und Reload + testen. + +Vor Beginn werden Drawerposition, Verhalten widersprüchlicher Mehrfachauswahl, +Warnungsdialoge und der Lebenszyklus leerer Rows festgelegt. + +### 14.4 – Strukturtreuer Rückexport + +1. Exportprojektion gegen eine bekannte Projektrevision ergänzen. +2. Nur gemappte Objektzellen in einer Kopie der akzeptierten Matrix ersetzen. +3. Dialekt, Reihenfolge, unbekannte Zellen und Passthrough-Zeilen erhalten. +4. Download und append-only Exportnachweis ergänzen. + +Zahlenformat, leere Stromkreiswerte und Dateiname werden vorher fachlich +festgelegt. + +### 14.5 – Folgeimport und Konflikte + +1. Deterministischen Diff nach `(sourceId, ifcGuid)` ergänzen. +2. Neu, geändert, unverändert, fehlend und konfliktbehaftet projizieren. +3. Einzel- und Sammelentscheidungen im Wizard ergänzen. +4. Akzeptierten Diff als einen atomaren Command mit vollständigem Undo/Redo + übernehmen. + +### 14.6 – Härtung und End-to-End-Abnahme + +1. Alle Szenarien A bis G der verbindlichen Spezifikation automatisieren. +2. Referenzdatei über Vorschau, Erstimport, Zuordnung, Export, Folgeimport, + Snapshot/Restore und Projektduplikat prüfen. +3. Abfrageindizes und große Payloads mit mehreren tausend Objekten messen. +4. Architektur-, API-, Betriebs- und Nutzerdokumentation auf den tatsächlich + ausgelieferten Stand nachziehen. + +## Risiken und Schutzmaßnahmen + +- **Mengenverlust:** `manualQuantity` trennt manuelle und externe Anteile; + Commands ändern Links und materialisierte Menge gemeinsam. +- **Stilles Überschreiben:** Quellwerte, lokale Werte und Overrides sind + getrennt; jede Übernahme benötigt eine Nutzerentscheidung. +- **ProjectDevice-Verfälschung:** Links ändern niemals die kanonische Vorlage; + deren bestehende Commands bleiben alleinige Schreibgrenze. +- **Nicht reproduzierbarer Export:** Jeder Batch hält Originalbytes, Matrix, + Dialekt, Konfiguration, Hash und Projektrevision. +- **Sehr große Undo-Payloads:** Importcommands speichern vollständige + erwartete/Zielzustände. Größe und Transaktionsdauer werden in 14.2 gemessen, + nicht durch indirekte oder nachträglich neu berechnete Payloads optimiert. +- **BMK-Drift:** Neue BMKs werden einmal bei der Planung berechnet und im + Command gespeichert; Import, Sortierung und Redo nummerieren nie implizit. +- **Unvollständige Referenzabnahme:** Die reale beziehungsweise anonymisierte + Referenz-CSV muss vor Abschluss von 14.1 als lokale Testgrundlage vorliegen. + +## Freigabepunkt + +Mit der Freigabe dieses Audits beginnt Arbeitspaket 14.1.1: reine +Transportverträge, Validatoren und synthetische CSV-Fixtures. Dieses Paket +ändert weder Datenbank noch GUI und führt keine Projektschreibvorgänge aus.