Document Linear Excel integration
This commit is contained in:
parent
ae318a51ac
commit
d4803a18d2
16 changed files with 932 additions and 2316 deletions
|
|
@ -532,36 +532,34 @@ Acceptance criteria:
|
|||
|
||||
## Phase 14: External Model Round-Trip
|
||||
|
||||
**Zurückgestellt:** Die weitere Revit-Arbeit wird später angegangen, dann
|
||||
über den CSV-Export/-Import des Linear-Plugins in Revit statt über Dynamo.
|
||||
Details: [Revit-CSV-Anforderungen, Abschnitt 1](revit-csv-integration-requirements.md).
|
||||
Status: R0 ist mit Korrekturen freigegeben; R1 stellt die Dokumentation auf
|
||||
Linear-XLSX und Worksharing-ID um. Die frühere CSV-Planung 14.0–14.6 ist
|
||||
abgelöst und wird nicht fortgeschrieben.
|
||||
|
||||
Status: Phase 14.2 (persistente externe Objekte und bestätigter Erstimport) ist
|
||||
implementiert. Editor-Zuordnung, Rückexport und Folgeimport folgen. 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).
|
||||
Verbindliche Quellen:
|
||||
|
||||
Goal:
|
||||
- [Revit-Integration über Linear-Excel](revit-excel-integration-requirements.md)
|
||||
- [R0–R10-Plan](revit-excel-phase-14-plan.md)
|
||||
- [R0-Bestandsaudit](revit-excel-r0-audit.md)
|
||||
|
||||
Exchange model objects and planning parameters with Revit through CSV (Linear plugin export/import).
|
||||
Die Umsetzung erfolgt ausschließlich in den Paketen R0–R10. R2 endet mit
|
||||
einer aus der realen Musterdatei erzeugten Rückgabedatei. Der Nutzer muss sie
|
||||
erfolgreich in Linear importieren, bevor R3 beginnt. Bei einem Fehlschlag wird
|
||||
zuvor eine direkte OOXML-Änderung des Originalworkbooks als Alternative
|
||||
vorgelegt.
|
||||
|
||||
Tasks:
|
||||
Kernabnahme der Phase:
|
||||
|
||||
- model external sources, import batches and stable IFCGUID objects
|
||||
- stage and validate imports before applying them
|
||||
- show additions, changes, missing objects and conflicts
|
||||
- link external objects explicitly to project-domain entities
|
||||
- apply an import as one auditable project revision
|
||||
- configure inbound and outbound parameter mappings
|
||||
- export against a known project revision while preserving IFCGUID
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- repeated imports match objects deterministically by source and IFCGUID
|
||||
- imports never silently overwrite local planning values
|
||||
- users approve the diff before it changes the project
|
||||
- exported data can be assigned back to the correct Revit objects
|
||||
- Worksharing-ID ist der exakte, case-sensitive externe Schlüssel;
|
||||
- XLSX-Kopfkommentare, Struktur, Formate und unbekannte Spalten bleiben beim
|
||||
Rückexport erhalten;
|
||||
- Import erzeugt keine Rows und überschreibt keine lokale Planung still;
|
||||
- Zuordnung, Löschung, Folgeimport und Undo/Redo sind atomar und nach Neustart
|
||||
reproduzierbar;
|
||||
- Undo/Redo liest keine Excel-Datei;
|
||||
- nur der letzte Importbatch enthält Workbook und Matrix vollständig;
|
||||
- mehrere Tausend Objekte bleiben über eine clientseitig gefilterte,
|
||||
virtualisierte Liste bedienbar.
|
||||
|
||||
PostgreSQL should be introduced when shared multi-user operation, background jobs or operational scale justify it. External-object count alone does not require an immediate migration.
|
||||
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ ProjectDevices and device rows (#20).
|
|||
3. [x] Snapshot-to-revision descriptions and history presentation.
|
||||
4. [x] Distribution-board power summary and project column layout.
|
||||
|
||||
The Revit/CSV/IFCGUID round-trip follows the distribution-board component
|
||||
foundation as a separate jointly planned phase and must not be inferred from
|
||||
these tasks. It is currently deferred and will later use the CSV
|
||||
export/import of the Linear plugin in Revit, not Dynamo.
|
||||
The Revit/Linear-XLSX round-trip is now the separately planned active Phase 14.
|
||||
It uses exact Worksharing-ID identity and must not be inferred from these
|
||||
unrelated backlog tasks. See
|
||||
[the R0–R10 plan](revit-excel-phase-14-plan.md).
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,406 +1,8 @@
|
|||
# Phase 14: Audit- und Implementierungsplan für die Revit-CSV-Anbindung
|
||||
# Abgelöst: alter Phase-14-CSV-Plan
|
||||
|
||||
## Status
|
||||
Die Phasen 14.0–14.6 und ihre Erledigt-Markierungen sind abgelöst. Für die
|
||||
Umstellung auf Linear-Excel gelten der [R0–R10-Plan](revit-excel-phase-14-plan.md)
|
||||
und die [neuen Anforderungen](revit-excel-integration-requirements.md).
|
||||
|
||||
**Zurückgestellt:** Die weitere Revit-Arbeit wird später angegangen, dann
|
||||
über den CSV-Export/-Import des Linear-Plugins in Revit statt über Dynamo.
|
||||
Details: [Revit-CSV-Anforderungen, Abschnitt 1](revit-csv-integration-requirements.md).
|
||||
|
||||
Phase 14.0 ist abgeschlossen und freigegeben. Dieses Dokument beschreibt den
|
||||
gegen den aktuellen Code geprüften Zielzuschnitt. Phase 14.1 ist abgeschlossen.
|
||||
Phase 14.2 hat mit den externen Domänenverträgen, Identitätsregeln und dem
|
||||
additiven Persistenzschema begonnen; eine bestätigte Importübernahme existiert
|
||||
noch nicht.
|
||||
|
||||
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`;
|
||||
- der zuletzt bestätigte Importbatch wird aus der geordneten Batchhistorie
|
||||
abgeleitet und nicht als redundanter Zeiger gespeichert.
|
||||
|
||||
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;
|
||||
- verwendete monotone Konfigurationsversion und vollständiger
|
||||
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-object.update-row-assignment`: Ein oder mehrere Objekte einer
|
||||
bestehenden Row zuweisen, zwischen bestehenden Rows verschieben oder lösen
|
||||
und alle betroffenen materialisierten Mengen atomar aktualisieren.
|
||||
- `external-object.assign-to-new-row`: stabile neue Row einfügen,
|
||||
Objekte verknüpfen und gegebenenfalls den Reserve-Status aktualisieren.
|
||||
- `external-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.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. **Erledigt.**
|
||||
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. **Erledigt für
|
||||
synthetische Testdaten; die Referenzdatei steht noch aus.**
|
||||
3. Konfiguration über Migration, Snapshot v3, Transfer und den Command
|
||||
`external-csv-configuration.update` persistieren. **Erledigt.**
|
||||
4. Vorschau-Endpunkt und deutschen Projekt-Wizard ergänzen. **Erledigt:**
|
||||
Konfigurations-Read/Write- und zustandsfreier Vorschau-Endpunkt sowie das
|
||||
deutsche Konfigurations-/Vorschaumodal. Der Server speichert keinen Entwurf: Bei
|
||||
Bestätigung wird die Datei erneut übertragen, erneut geparst und ihr Hash
|
||||
gegen die Vorschau geprüft.
|
||||
|
||||
**Phase 14.1 ist damit technisch abgeschlossen.** Die fachliche GUI-Abnahme
|
||||
erfolgt vor Beginn der persistenten externen Objekte aus Phase 14.2.
|
||||
|
||||
Abnahme: fokussierte Tests, vollständige Tests und alle vorgeschriebenen
|
||||
Build-/Typecheck-Schritte. Die lokal bereitgestellte Referenz-CSV wird mit
|
||||
`npm run revit:verify-reference` auf 897 Objektzeilen, 211 nichtleere
|
||||
Passthrough-Summenzeilen und einen bytegleichen Round-trip geprüft. Da die
|
||||
Referenzdatei reale Modelldaten enthalten kann, wird sie nicht automatisch in
|
||||
einen Commit aufgenommen.
|
||||
|
||||
### 14.2 – Persistente Objekte und Erstimport
|
||||
|
||||
1. Schema, Repositories und reine Identitäts-/Matchingregeln ergänzen.
|
||||
**Erledigt:** Migration `0003`, vollständiger externer Read-State sowie
|
||||
exaktes IFCGUID-, Raum- und Familie-und-Typ-Matching sind vorhanden. Es gibt
|
||||
weiterhin keinen Import-Write außerhalb eines Commands.
|
||||
2. Snapshot v4, Restore und Projektduplikat samt UUID-Remapping ergänzen.
|
||||
**Erledigt:** Version 3 wird mit leerem externem Zustand hochgestuft;
|
||||
Capture, Restore, Undo/Redo und beide Transfermodi erhalten Originalbytes,
|
||||
Matrix und sämtliche internen Links. Duplikate remappen alle internen UUIDs,
|
||||
lassen IFCGUID und Quelltransport jedoch unverändert.
|
||||
3. Erstimport-Command mit echten SQLite-Commit-/Rollback-Tests ergänzen.
|
||||
**Erledigt:** `external-import.apply-initial` wechselt ausschließlich
|
||||
zwischen leerem und vollständig bestätigtem externem Zustand. Er prüft
|
||||
Konfigurationsversion, Original-Hash, erneut geparste Matrix, vollständige
|
||||
IFCGUID-Menge, Quellwerte, explizite Overrides und projektinterne Links.
|
||||
Der Command verbietet CircuitDeviceRow-Links, ist ein atomarer Undo-Schritt
|
||||
und verwendet für Redo dieselben UUIDs und Bytes. Migration `0004` ergänzt
|
||||
die zuvor noch fehlende monotone Konfigurationsversion am Batch; `0003`
|
||||
bleibt unverändert.
|
||||
4. Raum-, Verteilungs-, Klassifizierungs- und ProjectDevice-Schritte im Wizard
|
||||
ergänzen; der Import selbst erzeugt keine CircuitDeviceRow. **Erledigt:**
|
||||
Der zustandsfreie Planungs-Endpunkt liefert gruppierte Quellräume mit
|
||||
exaktem Raumnummernvorschlag, Familie-und-Typ-Gruppen, Objektvorschläge,
|
||||
Warnungszahlen sowie vorhandene Ebenen, Räume, Verteilungen und
|
||||
ProjectDevices. Er blockiert nach einem bereits bestätigten Erstimport und
|
||||
schreibt weder Entwurf noch Projektzustand. Der dedizierte
|
||||
Endpunkt verlangt denselben Datei-Hash und Konfigurationsstand wie die
|
||||
Planung, vollständige Entscheidungen für alle Quellräume und exakten
|
||||
Familie-und-Typ-Gruppen und baut daraus serverseitig stabile UUIDs. Nicht
|
||||
klassifizierte Familien blockieren. Raum-/Standardverteiler- und optionale
|
||||
ProjectDevice-Links werden bestätigt, Stromkreis- und Row-Links bleiben
|
||||
ausgeschlossen. Das breite Projektmodal zeigt Raumtreffer und Warnungen,
|
||||
bietet die vorhandenen Raum-, Verteiler- und ProjectDevice-Kataloge an und
|
||||
verlangt vor der atomaren Übernahme eine ausdrückliche Bestätigung. Fehlende
|
||||
Räume und ProjectDevices lassen sich über die regulären, vorausgefüllten
|
||||
Projektformulare anlegen und werden danach unmittelbar ausgewählt. Diese
|
||||
Kataloganlagen bleiben eigenständige, rückgängig machbare Projektrevisionen.
|
||||
|
||||
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.
|
||||
**Erledigt:** Migration `0005` übernimmt für jede bestehende Gerätezeile
|
||||
`manualQuantity = quantity`. Neue normale Zeilen und Mengenänderungen führen
|
||||
beide Werte gemeinsam; Snapshot/Transfer v5 erhält den Anteil und stuft v4
|
||||
verlustfrei hoch. Die reine Mengenregel validiert den materialisierten Wert
|
||||
als manuellen Anteil plus Summe der unteilbaren externen Objektmengen.
|
||||
2. Commands für vorhandene Row, neue Row, neuen Circuit und Lösen ergänzen.
|
||||
**Teilweise erledigt:** `external-object.update-row-assignment` deckt
|
||||
Zuweisung zu vorhandenen Rows, Verschieben zwischen vorhandenen Rows und
|
||||
Lösen ab. Der Command prüft Projekt, Verteilung, Gruppenkategorie, Raum,
|
||||
Selektionskennzeichen und Planungswerte, verlangt für bestätigbare
|
||||
Planungsabweichungen eine explizite Objektliste und aktualisiert Links und
|
||||
Gesamtmengen in einer SQLite-Transaktion. Seine exakte Gegenrichtung ist
|
||||
dauerhaft Undo/Redo-fähig. Beim Lösen bleibt die Row mit ihrem manuellen
|
||||
Mengenanteil bestehen. `external-object.assign-to-new-row` ergänzt die
|
||||
Zuordnung ungebundener Objekte als neue Row in einem vorhandenen Circuit.
|
||||
Diese Row erhält eine stabile ID und `manualQuantity = 0`; ihr historischer
|
||||
Gegenbefehl entfernt sie nur, solange Row und Objektlinks vollständig
|
||||
unverändert sind. Ein direktes Löschen über diesen internen Gegenbefehl ist
|
||||
als Nutzeraktion gesperrt. `external-object.assign-to-new-circuit` schließt
|
||||
den dritten Zielpfad: Ein serverseitig vorgeplanter Circuit mit festem BMK,
|
||||
Standardschutz und genau einer externen Row wird gemeinsam mit den
|
||||
Objektlinks eingefügt. Seine Historiengegenrichtung prüft den vollständigen
|
||||
Circuit-Snapshot und die exakte Linkmenge, bevor sie den Teilbaum entfernt.
|
||||
BMK und UUIDs bleiben bei Redo unverändert. Damit ist die persistente
|
||||
Command-Grundlage dieses Schritts abgeschlossen; API-Planung und UI folgen.
|
||||
3. Verteilungsbezogenen Drawer, Filter und Vorschau der Mengenwirkung ergänzen.
|
||||
**Begonnen:** Die reine Read-Projektion und der projekt-/listenbezogene
|
||||
GET-Endpunkt liefern ausschließlich Objekte des zugehörigen Verteilers,
|
||||
unzugeordnete Objekte zuerst, einschließlich Quellraum, Selektionsmarker,
|
||||
Planungswerten und aktuellem Row-Link. API-Client und DTOs sind vorhanden;
|
||||
Drawer, Filter und Mengenwirkung folgen.
|
||||
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.
|
||||
- **Vertrauliche Referenzdaten:** Der Referenzprüfer läuft lokal gegen die
|
||||
bereitgestellte CSV. Vor einer Aufnahme dieser Datei in Git ist gesondert zu
|
||||
klären, ob sie ausreichend anonymisiert und zur Weitergabe freigegeben ist.
|
||||
|
||||
## 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.
|
||||
Der historische Inhalt bleibt im Git-Verlauf bis einschließlich Commit
|
||||
`ae318a5` erhalten und darf nicht fortgeschrieben werden.
|
||||
|
|
|
|||
463
docs/spec/revit-excel-integration-requirements.md
Normal file
463
docs/spec/revit-excel-integration-requirements.md
Normal file
|
|
@ -0,0 +1,463 @@
|
|||
# Revit-Integration über Linear-Excel – verbindliche Anforderungen
|
||||
|
||||
Stand: 29.09.2026. Dieses Dokument ist die fachliche und technische
|
||||
Arbeitsgrundlage für die neue Phase 14. Es ersetzt die frühere CSV-/IfcGUID-
|
||||
Spezifikation. Der Umsetzungsstand steht im
|
||||
[R0–R10-Plan](revit-excel-phase-14-plan.md); der geprüfte Ausgangszustand im
|
||||
[R0-Audit](revit-excel-r0-audit.md).
|
||||
|
||||
## 1. Ziel und Grenzen
|
||||
|
||||
Der Austausch mit Revit erfolgt ausschließlich über den XLSX-Export/-Import
|
||||
des Linear-Plugins. Eine vollständige Revit-Bauteilliste wird importiert, in
|
||||
Leistungsbilanz geplant und mit gleichem Tabellenaufbau an Linear
|
||||
zurückgegeben. Linear ordnet enthaltene Zeilen anhand der Worksharing-ID zu.
|
||||
|
||||
Nicht Teil dieser Phase sind Dynamo, Revit-API, JSON-Transport, automatische
|
||||
Stromkreisbildung, Übernahme vorhandener Revit-Stromkreiswerte,
|
||||
Teilimporte, mehrere Modellquellen, PostgreSQL und neue Rollen/Rechte.
|
||||
|
||||
Die Integration bleibt optional. Manuelle Projekte, Räume, ProjectDevices,
|
||||
Stromkreise und Gerätezeilen funktionieren ohne externes Modell. Der
|
||||
Circuit-First-Aufbau, stabile interne UUIDs und BMKs, ausdrückliche
|
||||
Neunummerierung sowie die gemeinsame Project-Command-Transaktionsgrenze
|
||||
bleiben unverändert.
|
||||
|
||||
## 2. Verbindliche fachliche Regeln
|
||||
|
||||
- Import erzeugt keine `CircuitDeviceRow`, keinen `Circuit` und kein BMK.
|
||||
- Quellwerte, lokale Planungswerte und Overrides bleiben getrennt.
|
||||
- Ein Folgeimport überschreibt keine lokale Planung still.
|
||||
- Fehlende Objekte werden markiert und erst nach ausdrücklicher Bestätigung
|
||||
entfernt.
|
||||
- Mehrfachsteckdosen sind unteilbare externe Objekte. Ihre wirksame Menge kann
|
||||
größer als eins sein.
|
||||
- Die Row-Menge ist
|
||||
`manualQuantity + Summe(effectiveQuantity der verknüpften Objekte)`.
|
||||
- Nach einer Row-Zuordnung ist die `CircuitDeviceRow` die Planungsebene für
|
||||
alle verknüpften Objekte.
|
||||
- Bestehende ProjectDevices bleiben kanonische Vorlagen und werden durch
|
||||
Importe nie verändert.
|
||||
- Sortieren, Filtern, Importieren, Zuordnen und Verschieben nummeriert keine
|
||||
Stromkreise automatisch neu.
|
||||
|
||||
## 3. Linear-XLSX-Profil
|
||||
|
||||
Die lokale Referenzdatei `docs/spec/kbp-Stromkreis.xlsx` enthält vertrauliche
|
||||
Projektdaten. Sie wird nicht committed und nicht in Tests eingebettet. Tests
|
||||
erzeugen synthetische Workbooks. Der lokale Referenzprüfer erhält den Pfad als
|
||||
Argument.
|
||||
|
||||
Beobachtetes Profil:
|
||||
|
||||
- genau ein Arbeitsblatt; Blattname nach Excel-Regel maximal 31 Zeichen;
|
||||
- Kopfzeile in Zeile 1, Zeile 2 leer, Daten ab Zeile 3, erste Datenspalte A;
|
||||
- Spalte A `Worksharing-ID` im Format `<GUID>-<8 Hex>`;
|
||||
- Parameterbindungen stehen als klassische Excel-Kommentare in den übrigen
|
||||
Kopfzellen;
|
||||
- Zahlen sind typisierte Excel-Zahlen; importierte Werte bleiben unverändert,
|
||||
fachlich verwendete Leistung wird auf 0,01 W projiziert;
|
||||
- Objektzeilen dürfen keinen MEP-Raum besitzen;
|
||||
- eine Schluss-/Summenzeile ohne ID kann vorkommen und wird weder importiert
|
||||
noch zurückgegeben.
|
||||
|
||||
Die Referenzdatei enthält 487 Objektzeilen, eindeutige Worksharing-IDs und
|
||||
keine doppelten nichtleeren IfcGUIDs bei exaktem, case-sensitivem Vergleich.
|
||||
Ihre Summenzeile steht in Spalte B (`CAx_Auswahlkenner`), während
|
||||
`Familie und Typ` leer ist.
|
||||
|
||||
### Zeilen ohne Worksharing-ID
|
||||
|
||||
Nur eine Zeile ohne Worksharing-ID, aber mit befülltem Feld
|
||||
`Familie und Typ`, gilt als verdächtige Objektzeile. Sie erzeugt einen Hinweis
|
||||
und wird übersprungen; sie blockiert den Import nicht. Andere Zeilen ohne ID,
|
||||
einschließlich einer nur in Spalte B befüllten Summenzeile, werden ohne Hinweis
|
||||
übersprungen. Eine Objektzeile ist für den Import eine Zeile mit nichtleerer
|
||||
Worksharing-ID.
|
||||
|
||||
Worksharing-ID und IfcGUID werden stets exakt, ordinal und mit
|
||||
Groß-/Kleinschreibung verglichen. Es findet kein Trimmen, Normalisieren oder
|
||||
Case-Folding für die Identität statt. Eine nichtleere Worksharing-ID mit
|
||||
unerlaubten äußeren Leerzeichen oder falschem Format blockiert. Doppelte
|
||||
Worksharing-IDs blockieren. IfcGUID ist optional, kein Schlüssel und darf
|
||||
doppelt vorkommen; Duplikate erzeugen lediglich einen Hinweis.
|
||||
|
||||
## 4. Upload und Transportadapter
|
||||
|
||||
Der Server akzeptiert ausschließlich Dateien mit Endung `.xlsx` bis 10 MiB.
|
||||
`.xls` und `.xlsm` werden abgelehnt. Parsing findet serverseitig statt. Nach
|
||||
dem Einlesen gelten feste Zeilen-, Spalten- und Zellgrenzen, die in R2 anhand
|
||||
synthetischer Grenztests festgelegt und zentral definiert werden. Es gibt in
|
||||
dieser Phase keinen eigenen ZIP-Prüfer und keinen Parser-Worker.
|
||||
|
||||
Der Adapter unter `src/external-model/xlsx` liest eine transportneutrale
|
||||
Zellmatrix. Eine Zelle ist `string`, `number`, `boolean` oder `empty`.
|
||||
Zusätzlich werden Blattname, Originalzeilennummer, Kopfzeilenkommentare,
|
||||
Spaltenbreiten und die für Hinweise nötigen Formelmetadaten erfasst.
|
||||
Domain-Services kennen weder ExcelJS noch XLSX, React oder SQLite.
|
||||
|
||||
Formeln werden niemals ausgeführt. Ist ein gecachter skalarer Wert vorhanden,
|
||||
wird er verwendet und als Hinweis ausgewiesen. Fehlt er oder ist er ein
|
||||
Fehlerwert, bleibt das Feld leer; bei der Worksharing-ID oder einem anderen
|
||||
Pflichtfeld blockiert dies die betreffende Objektzeile beziehungsweise den
|
||||
Import.
|
||||
|
||||
Genau eine gepflegte Bibliothek wird ergänzt. Vorgesehen ist `exceljs`, sofern
|
||||
R2 die Node-24-Verträglichkeit und den Roundtrip von Kopfkommentaren,
|
||||
Blattname, Spaltenbreiten, Formaten und Zelltypen bestätigt.
|
||||
|
||||
## 5. Projektkonfiguration
|
||||
|
||||
Die Konfiguration ist projektweit, revisionssicher und besitzt keine eigene
|
||||
Versionszählung. Jeder Plan und jedes Apply tragen `expectedRevision`.
|
||||
Da die Projektrevision auch bei Undo/Redo strikt steigt, wird ein alter Plan
|
||||
automatisch ungültig. Jeder Importbatch speichert eine vollständige Kopie der
|
||||
beim Import verwendeten Konfiguration.
|
||||
|
||||
Das Einstellungsmodal auf der Revit-Seite erkennt aus einer zustandslos
|
||||
hochgeladenen Musterdatei Kopfzeile, erste Datenzeile und erste Datenspalte.
|
||||
Diese Werte bleiben editierbar; Standard ist 1 / 3 / A. Es gibt nur ein Feld
|
||||
für die Identitätsspalte: `columns.worksharingId`. Ein separates
|
||||
`layout.idColumn` existiert nicht.
|
||||
|
||||
Zielvertrag:
|
||||
|
||||
```ts
|
||||
interface ExternalModelConfiguration {
|
||||
schemaVersion: 1;
|
||||
layout: {
|
||||
headerRow: number;
|
||||
firstDataRow: number;
|
||||
firstDataColumn: number;
|
||||
};
|
||||
circuitMode: "combined" | "separate";
|
||||
columns: {
|
||||
worksharingId: string;
|
||||
ifcGuid: string | null;
|
||||
roomNumber: string | null;
|
||||
roomName: string | null;
|
||||
familyAndType: string;
|
||||
selectionMarker: string | null;
|
||||
socketCount: string | null;
|
||||
sourceRemark: string | null;
|
||||
circuitCombined: string | null;
|
||||
boardName: string | null;
|
||||
circuitIdentifier: string | null;
|
||||
designation: string | null;
|
||||
electricalPowerW: string | null;
|
||||
voltageV: string | null;
|
||||
currentA: string | null;
|
||||
};
|
||||
deviceTypes: DeviceTypeConfiguration[];
|
||||
familyTypeRules: FamilyTypeRule[];
|
||||
}
|
||||
```
|
||||
|
||||
Standardzuordnung:
|
||||
|
||||
| Schlüssel | Bedeutung | Standardspalte |
|
||||
| --- | --- | --- |
|
||||
| `worksharingId` | externe Identität, Pflicht | `Worksharing-ID` |
|
||||
| `ifcGuid` | optionale Redundanz | `IfcGUID` |
|
||||
| `roomNumber` | Raumnummer | `MEP-Raum: Nummer` |
|
||||
| `roomName` | Raumname | `MEP-Raum: Name` |
|
||||
| `familyAndType` | Familie und Typ, Pflicht | `Familie und Typ` |
|
||||
| `selectionMarker` | CAx-Auswahlkenner | `CAx_Auswahlkenner` |
|
||||
| `socketCount` | Anzahl Einzelsteckdosen | `CAX_AnzahlObjekte` |
|
||||
| `sourceRemark` | Anmerkung | `CAx_Anmerkung` |
|
||||
| `circuitCombined` | Stromkreis gesamt | `kbp_Stromkreisnummer` |
|
||||
| `boardName` | Verteiler | `kbp-E-Verteiler` |
|
||||
| `circuitIdentifier` | Stromkreis-BMK | `kbp-E-Stromkreis` |
|
||||
| `designation` | Bezeichnung | `kbp-E-Bezeichnung` |
|
||||
| `electricalPowerW` | elektrische Leistung [W] | `kbp-E-Elektrische Leistung` |
|
||||
| `voltageV` | Spannung [V] | `kbp-E-Spannung` |
|
||||
| `currentA` | Stromstärke [A] | `kbp-E-Stromstärke` |
|
||||
|
||||
`worksharingId` und `familyAndType` sind Pflichtmappings. Im Modus
|
||||
`combined` ist `circuitCombined` für den Rückexport Pflicht; im Modus
|
||||
`separate` sind `boardName` und `circuitIdentifier` Pflicht. Fehlende optionale
|
||||
Rückgabespalten `designation`, `electricalPowerW`, `voltageV` und `currentA`
|
||||
werden mit Hinweis übersprungen und blockieren den Export nicht.
|
||||
|
||||
Jedes interne Feld besitzt im Modal ein Dropdown aus den Kopfzellen und eine
|
||||
freie Eingabe. Exakte kbp-Standardnamen werden vorbelegt. Typ und Einheit aus
|
||||
dem Linear-Kommentar werden angezeigt. Nicht gemappte Spalten bleiben beim
|
||||
Rückexport unverändert.
|
||||
|
||||
## 6. Gerätearten und Familie-und-Typ-Regeln
|
||||
|
||||
Eine Geräteart besitzt stabile interne UUID, Name, Kategorie
|
||||
`lighting | single_phase | three_phase` sowie optionale Standardwerte für
|
||||
Leistung je Einheit in W, GZF, cosPhi und Kostengruppe. Jede exakte
|
||||
`Familie und Typ`-Regel verweist auf genau eine Geräteart und verwendet die
|
||||
Mengenregel `1` oder `socketCount`.
|
||||
|
||||
Mehrere Revit-Familien dürfen auf dieselbe Geräteart zeigen. Jedes Revit-
|
||||
Objekt bleibt trotzdem einzeln über seine Worksharing-ID nachverfolgbar.
|
||||
Unbekannte Familien müssen im Importwizard zugeordnet oder über eine neue
|
||||
Geräteart klassifiziert werden; andernfalls blockiert Apply.
|
||||
|
||||
Planungsstartwerte folgen dieser Reihenfolge:
|
||||
|
||||
1. ausdrücklich verknüpftes ProjectDevice;
|
||||
2. Geräteart-Standard;
|
||||
3. leer.
|
||||
|
||||
Der Anzeigename wird aus CAx-Auswahlkenner, dann Geräteartname, dann
|
||||
`Familie und Typ` vorgeschlagen. Ein fehlender GZF wird mit `1` vorbelegt,
|
||||
ohne zusätzliche Bestätigung. Standardwerte sind Startwerte, keine dauerhafte
|
||||
Synchronisierung.
|
||||
|
||||
## 7. Persistenter externer Zustand
|
||||
|
||||
Pro Projekt existiert genau eine implizite Revit-XLSX-Quelle. Ein externes
|
||||
Objekt besitzt eine interne UUID und ist je `(sourceId, worksharingId)`
|
||||
eindeutig. `worksharingId` ist NOT NULL; `ifcGuid` ist nullable und nicht
|
||||
eindeutig. Interne Relationen verwenden ausschließlich interne UUIDs.
|
||||
|
||||
Gespeichert werden:
|
||||
|
||||
- akzeptierte Quellwerte einschließlich aller Rückgabefelder;
|
||||
- lokale Planungswerte und Override-Felder;
|
||||
- Geräteart;
|
||||
- optionales Raum-Mapping, abweichender Verteiler, ProjectDevice und
|
||||
`CircuitDeviceRow`;
|
||||
- Anwesenheitsstatus und Verweis auf den zuletzt relevanten Import;
|
||||
- effektive Menge als fachlicher Wert des unteilbaren Objekts.
|
||||
|
||||
Der effektive Verteiler eines verknüpften Objekts ist immer der Verteiler
|
||||
seiner Row. Für ein unzugeordnetes Objekt gilt zuerst die explizite
|
||||
Objektabweichung, danach der Standardverteiler seines Raum-Mappings. Ändert
|
||||
sich der Standardverteiler eines Raums, betrifft das nur unzugeordnete
|
||||
Objekte; verknüpfte Objekte bleiben über ihre Row unverändert und die Änderung
|
||||
wird deshalb nicht gesperrt.
|
||||
|
||||
## 8. Importbatch-Aufbewahrung, Snapshot und Transfer
|
||||
|
||||
Der aktive Projektzustand enthält den letzten Importbatch vollständig:
|
||||
Originalbytes, klassifizierte Matrix, Dateiname, SHA-256, Zeitpunkt,
|
||||
Objektzahl, Importart, Projektrevision und Konfigurationskopie. Ältere Batches
|
||||
werden zu Metadaten reduziert: Datum, Dateiname, SHA-256 und Objektzahl.
|
||||
Sie enthalten keine Originalbytes, Matrix oder Konfigurationskopie mehr.
|
||||
|
||||
Snapshot-Schema 10 und portabler Projekttransfer übernehmen genau diese
|
||||
Aufteilung. Beim Duplizieren werden alle internen UUIDs und Links remapped;
|
||||
Worksharing-IDs, optionale IfcGUIDs, Quellwerte und das letzte Workbook bleiben
|
||||
unverändert.
|
||||
|
||||
Versionen 1–9 ohne externe CSV-Daten werden verlustfrei auf Version 10
|
||||
hochgestuft. Enthält ein alter Stand eine CSV-Konfiguration oder einen nicht
|
||||
leeren CSV-Zustand, wird er mit klarer deutscher Fehlermeldung abgelehnt.
|
||||
Alte CSV-History-Commands werden ebenfalls vor jedem Write abgelehnt und nie
|
||||
stillschweigend übersprungen.
|
||||
|
||||
## 9. Erstimport
|
||||
|
||||
Der Ablauf ist Upload → zustandslose Vorschau/Planung → erneute
|
||||
Dateiübertragung bei Apply. Apply prüft SHA-256, `expectedRevision`,
|
||||
Konfigurationskopie, Matrix und sämtliche Entscheidungen erneut. Nur Apply
|
||||
liest die Excel-Datei erneut ein.
|
||||
|
||||
Undo und Redo lesen keine Excel-Datei und parsen keine gespeicherten Bytes.
|
||||
Sie arbeiten ausschließlich auf den im Command gespeicherten vollständigen
|
||||
Vorher-/Nachher-Zuständen. Dadurch bleiben sie nach Neustart deterministisch
|
||||
und unabhängig vom Parser.
|
||||
|
||||
Der Wizard umfasst:
|
||||
|
||||
1. Vorschau mit Objektzahl, übersprungenen und verdächtigen Zeilen,
|
||||
doppelten Worksharing-IDs, doppelten IfcGUID-Hinweisen, unbekannten
|
||||
Familien, nicht lesbaren Zahlen und Formeln;
|
||||
2. Räume anlegen oder vorhandenen Räumen/Ebenen zuordnen;
|
||||
3. Standardverteiler je Raum, Sammelzuordnung, Objektabweichungen und Objekte
|
||||
ohne Raum;
|
||||
4. Familien exakt Gerätearten und einer Mengenregel zuordnen;
|
||||
5. optional vorhandene oder neu angelegte ProjectDevices verknüpfen;
|
||||
6. Zusammenfassung und ausdrückliche Bestätigung.
|
||||
|
||||
Die Übernahme ist ein atomarer Command und ein Undo-Schritt. Im Import
|
||||
entstehen keine Rows. Neu angelegte Räume und ProjectDevices verwenden ihre
|
||||
vorhandenen Commands und bleiben eigene Undo-Schritte.
|
||||
|
||||
## 10. Objektplanung und Revit-Seite
|
||||
|
||||
Route: `/projects/:projectId/revit`, erreichbar aus der Projektnavigation.
|
||||
Der Revit-Button und das CSV-Modal auf der Projektübersicht entfallen.
|
||||
|
||||
Die Seite besitzt:
|
||||
|
||||
- Statuskarte mit letztem Import, Objektzahl, ohne Verteiler, ohne
|
||||
Stromkreis, fehlend und Abweichung zu Revit;
|
||||
- Aktionen `Import`, `Rückgabe-Excel`, `Einstellungen`;
|
||||
- einklappbare Geräteart-/Familienregel-Übersicht;
|
||||
- kompakte Objekttabelle mit Suche, Spaltenfiltern, Sortierung,
|
||||
Mehrfachauswahl und Sammelzuordnung für Verteiler, ProjectDevice und
|
||||
Planungswerte.
|
||||
|
||||
Die kompakte Liste wird einmal geladen, vollständig im Client gefiltert und
|
||||
sortiert und virtualisiert dargestellt. Es gibt keine Server-Pagination.
|
||||
Originalbytes, Matrix und Command-Payloads gehören nicht in dieses DTO.
|
||||
|
||||
Vor Row-Zuordnung lassen sich Leistung je Einheit, GZF, cosPhi,
|
||||
Kostengruppe, Anzeigename und Bemerkung einzeln oder gesammelt ändern.
|
||||
Geänderte Felder werden Overrides. Nach Row-Zuordnung werden diese Werte im
|
||||
Grid an der Row bearbeitet. Beim ausdrücklichen Lösen erhält das Objekt die
|
||||
aktuellen Row-Werte als Planungswerte und entsprechende Overrides.
|
||||
|
||||
## 11. Editor-Zuordnung und Löschen
|
||||
|
||||
Der rechte, überlagernde Editorbereich zeigt unzugeordnete konfliktfreie
|
||||
Objekte des aktuellen Verteilers. Gruppierungsschlüssel sind interner Raum,
|
||||
Auswahlkenner, Geräteart, Kategorie, identische Planungswerte und kompatibler
|
||||
ProjectDevice-Link. Die Anzeige nennt Summe der wirksamen Mengen und Zahl der
|
||||
externen Objekte. Gruppen sind aufklappbar; Einzel- und Mehrfachauswahl sowie
|
||||
Filter bleiben möglich.
|
||||
|
||||
Drag-and-drop:
|
||||
|
||||
- auf vorhandene Row: genau diese Row;
|
||||
- auf Circuit: neue Row mit `manualQuantity = 0`;
|
||||
- auf freien Bereich: neuer Circuit, Schutz und Row in einem Command.
|
||||
|
||||
Neue IDs und BMK werden einmal geplant; Redo rechnet sie nicht neu. Neue Rows
|
||||
übernehmen den bestätigten Gruppenzustand und die Summe der effektiven Mengen.
|
||||
An Rows zeigt ein Hinweis die Zahl verknüpfter Revit-Objekte; einzelne Objekte
|
||||
können ausdrücklich gelöst werden.
|
||||
|
||||
Wird eine Row, ein Circuit oder eine Gruppe mit verknüpften Revit-Objekten
|
||||
gelöscht, zeigt die UI vor Bestätigung:
|
||||
`X Revit-Objekte werden wieder unzugeordnet`. Derselbe Löschcommand löst die
|
||||
Objekte, entfernt die Struktur und speichert alle Links in seiner Inversen.
|
||||
Undo stellt Struktur und Links exakt wieder her. Diese Löschungen werden nicht
|
||||
gesperrt.
|
||||
|
||||
Das Löschen eines Verteilers oder Raums mit referenzierten externen Objekten
|
||||
bleibt gesperrt. Der Nutzer muss die Verknüpfungen beziehungsweise Zuordnungen
|
||||
zuvor ausdrücklich ändern. Die Regel gilt auch für Unterbaum- und History-
|
||||
Pfade.
|
||||
|
||||
## 12. Rückgabe-Excel
|
||||
|
||||
Der Export ist eine Leseoperation ohne Projektrevision. Ein append-only
|
||||
Nachweis speichert Projektrevision, zugrunde liegenden letzten Import,
|
||||
Zeitpunkt, Dateiname, SHA-256, Konfigurationskopie beziehungsweise ihren Hash
|
||||
und Objektzahl.
|
||||
|
||||
Umfang:
|
||||
|
||||
- alle im letzten Import vorhandenen Objekte (Standard);
|
||||
- nur Objekte mit Abweichung zum zuletzt importierten Revit-Wert;
|
||||
- Auswahl aus der Objekttabelle.
|
||||
|
||||
Die Rückgabe basiert auf einer Kopie des zuletzt importierten Workbooks.
|
||||
Zeilen oberhalb der ersten Datenzeile, Kopfkommentare, Formate,
|
||||
Spaltenbreiten, Blattname und Spaltenreihenfolge bleiben erhalten. Danach
|
||||
folgen nur die gewählten Objektzeilen in ihrer Originalreihenfolge. Alle
|
||||
Spalten bleiben enthalten; Summenzeilen entfallen.
|
||||
|
||||
Stromkreiswerte:
|
||||
|
||||
- `combined`: `DistributionBoard.name + Circuit.equipmentIdentifier`, ohne
|
||||
Trennzeichen;
|
||||
- `separate`: Verteilername und unverändertes BMK in getrennten Spalten;
|
||||
- ohne Circuit: Stromkreisfeld beziehungsweise beide Felder leer.
|
||||
|
||||
Die Wahl des Verteilerwerts liegt in genau einer Funktion und verwendet
|
||||
zunächst `DistributionBoard.name`.
|
||||
|
||||
Weitere Rückgabewerte:
|
||||
|
||||
- Bezeichnung = Row-`displayName`, ohne Row Planungs-Anzeigename;
|
||||
- Leistung [W] = effektive Menge × Einzelleistung, ohne GZF;
|
||||
- Spannung = Circuit-Spannung, sonst Projektstandard der Kategorie;
|
||||
- Strom = `P / (U × cosPhi)` beziehungsweise
|
||||
`P / (sqrt(3) × U × cosPhi)`, auf 0,01 A;
|
||||
- nicht berechenbar = leere Zelle plus Hinweis.
|
||||
|
||||
Zahlen werden als Excel-Zahlen geschrieben. Fehlende optionale Zielspalten
|
||||
werden mit Hinweis ausgelassen. Nur fehlende Stromkreisspalten des gewählten
|
||||
Modus blockieren. Dateiname:
|
||||
`<Projektname>_Revit-Rueckgabe_<YYYY-MM-DD>.xlsx`.
|
||||
|
||||
## 13. Verbindliche R2-Abnahme mit Linear
|
||||
|
||||
R2 endet mit einer Rückgabedatei, die aus der lokalen realen Musterdatei
|
||||
erzeugt wurde und einige klar identifizierbare Rückgabewerte verändert. Diese
|
||||
Datei wird nicht committed. Der Nutzer testet sie in Linear. R3 darf erst nach
|
||||
erfolgreichem Linear-Rückimport beginnen.
|
||||
|
||||
Scheitert der Linear-Import, wird vor R3 eine Alternative zur Freigabe
|
||||
vorgelegt: Die Original-XLSX wird direkt auf OOXML-Ebene kopiert und nur die
|
||||
erforderlichen Zellwerte/-typen sowie Zeilenbereiche angepasst. Die
|
||||
Alternative bleibt hinter demselben transportneutralen Adaptervertrag.
|
||||
|
||||
## 14. Folgeimport
|
||||
|
||||
Jeder Import ist eine vollständige Projektbauteilliste. Matching erfolgt
|
||||
ausschließlich über exakt und case-sensitiv verglichene Worksharing-ID.
|
||||
|
||||
- neu: Wizard-Schritte nur für neue Objekte und unbekannte Familien;
|
||||
- geänderte Quellwerte: Einzel- oder Sammelentscheidung;
|
||||
- akzeptierte Mengenänderung: verknüpfte Row-Menge im selben Command;
|
||||
- fehlend: markieren, Link und Menge zunächst beibehalten;
|
||||
- Löschen: erst nach gesonderter Bestätigung;
|
||||
- abweichende Rückgabefelder: Hinweis `in Revit noch nicht aktualisiert`,
|
||||
keine Übernahmeentscheidung.
|
||||
|
||||
`external-import.apply-follow-up` ist atomar und ein Undo-Schritt.
|
||||
Unveränderte Objekte erzeugen keine unnötigen Objekt- oder Row-Änderungen.
|
||||
Der neue vollständige Batch wird letzter Batch; der zuvor letzte Batch wird
|
||||
auf Metadaten reduziert.
|
||||
|
||||
## 15. Commands, Persistenz und Sicherheit
|
||||
|
||||
Projektbezogene Writes verwenden typisierte Commands mit vollständiger
|
||||
Gegenrichtung, `expectedRevision`, Anmeldung, CSRF-Header und
|
||||
`project-command-transaction.persistence.ts`. Dazu gehören mindestens:
|
||||
|
||||
- `external-model-configuration.update`;
|
||||
- `external-import.apply-initial`;
|
||||
- `external-import.apply-follow-up`;
|
||||
- `external-model-object.update-planning`;
|
||||
- `external-model-object.update-distribution-board`;
|
||||
- `external-model-room-mapping.update`;
|
||||
- `external-model-object.update-project-device-link`;
|
||||
- `external-object.update-row-assignment`;
|
||||
- `external-object.assign-to-new-row`;
|
||||
- `external-object.assign-to-new-circuit`;
|
||||
- `external-model-object.delete-missing`;
|
||||
- die erweiterten Row-/Circuit-/Gruppen-Löschcommands mit Objekt-Link-
|
||||
Transitionen.
|
||||
|
||||
Die Konfiguration selbst ist Teil der erwarteten/gewünschten Snapshots, aber
|
||||
hat keinen eigenen monotonen Zähler. Importbatches halten eine unveränderliche
|
||||
Konfigurationskopie. Preview/Plan sind zustandslos. Apply überträgt und parst
|
||||
die Datei erneut; Undo/Redo führt nur gespeicherte Zustandsübergänge aus.
|
||||
|
||||
Neue Migrationen sind additiv. Vor Anwendung wird die Datenbank gesichert und
|
||||
das generierte SQL geprüft. Da nur Entwicklungsdaten existieren, darf die
|
||||
Migration alte externe CSV-Daten verwerfen. Vor dem Löschen externer Objekte
|
||||
werden betroffene Row-Mengen auf `manualQuantity` zurückgesetzt. Der Verlust
|
||||
des alten externen Entwicklungszustands wird dokumentiert.
|
||||
|
||||
## 16. Abnahme und Leistung
|
||||
|
||||
Die Oberfläche muss mehrere Tausend Objekte flüssig bedienen. R10 misst
|
||||
Import, Command-/Snapshot-Größe, Speicherbedarf und Client-Interaktion mit
|
||||
synthetischen großen Workbooks. Die virtualisierte Tabelle rendert nur den
|
||||
sichtbaren Ausschnitt, während Filterung, Sortierung und Auswahl auf der einmal
|
||||
geladenen kompakten Liste arbeiten.
|
||||
|
||||
Jedes Paket R1–R10 führt fokussierte Tests sowie aus:
|
||||
|
||||
```text
|
||||
npm test
|
||||
npm run build:api
|
||||
npm run build:web
|
||||
npm run typecheck:scripts
|
||||
npx tsc --noEmit -p tsconfig.next.json
|
||||
```
|
||||
|
||||
Jedes Paket erhält einen eigenen knappen imperativen Commit. Die konkrete
|
||||
Paketfolge und ihre Freigabepunkte stehen im
|
||||
[R0–R10-Plan](revit-excel-phase-14-plan.md).
|
||||
173
docs/spec/revit-excel-phase-14-plan.md
Normal file
173
docs/spec/revit-excel-phase-14-plan.md
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
# Phase 14 neu – Plan für die Linear-Excel-Anbindung
|
||||
|
||||
Verbindliche Fachgrundlage:
|
||||
[Revit-Integration über Linear-Excel](revit-excel-integration-requirements.md).
|
||||
Der alte CSV-Plan 14.0–14.6 ist abgelöst und wird nicht fortgeschrieben.
|
||||
|
||||
## Status
|
||||
|
||||
| Paket | Status | Ergebnis / Freigabepunkt |
|
||||
| --- | --- | --- |
|
||||
| R0 | abgeschlossen und freigegeben | Bestandsaudit, Zielmodell, Migration und Risiken; Freigabekorrekturen in R1 eingearbeitet. |
|
||||
| R1 | abgeschlossen | Anforderungen, Plan und Architektur auf Excel/Worksharing-ID umgestellt; alle Pflichtprüfungen bestanden. |
|
||||
| R2 | offen | XLSX-Adapter, Parser, synthetische Fixtures, lokaler Referenzprüfer und reale Rückgabedatei. Danach zwingende Linear-Abnahme durch den Nutzer. |
|
||||
| R3 | gesperrt bis R2-Abnahme | Konfiguration, Identität, Migration, Snapshot 10, Transfer und Backend-CSV-Entfernung. |
|
||||
| R4 | offen | Revit-Seite, Navigation, Einstellungen, altes Projektseitenmodal entfernen. |
|
||||
| R5 | offen | Erstimportwizard mit Gerätearten, Familienregeln und optionalen ProjectDevices. |
|
||||
| R6 | offen | Virtualisierte Objekttabelle und Sammelzuordnungen. |
|
||||
| R7 | offen | Editorbereich, Gruppierung, Drag-and-drop, Lösen und integrierte Löschübergänge. |
|
||||
| R8 | offen | Rückgabe-Excel und append-only Exportnachweis. |
|
||||
| R9 | offen | Vollständiger Folgeimport nach Worksharing-ID. |
|
||||
| R10 | offen | Ende-zu-Ende-Härtung, große Datenmengen und Abschlussdokumentation. |
|
||||
|
||||
## R0 – Audit
|
||||
|
||||
Ergebnis: [R0-Audit](revit-excel-r0-audit.md). Die Freigabe vom 29.09.2026
|
||||
enthält 13 Korrekturen. Bei Abweichungen zwischen dem historischen Audit und
|
||||
der aktuellen Anforderung gilt das neue Anforderungsdokument.
|
||||
|
||||
## R1 – Dokumentation
|
||||
|
||||
Lieferumfang:
|
||||
|
||||
- neues verbindliches Excel-Anforderungsdokument;
|
||||
- dieser R0–R10-Plan;
|
||||
- alte CSV-Anforderungen und alter Plan als kurze Ablösungshinweise;
|
||||
- LLM-Kontext auf die neue Quelle der Wahrheit kürzen;
|
||||
- `AGENTS.md`, aktuelle Architektur, History-/External-Model-Architektur,
|
||||
Roadmap, README, Dokumentationsindex und bekannte Einschränkungen anpassen;
|
||||
- reale Musterdatei per `.gitignore` vom Commit ausschließen;
|
||||
- alle internen Links auf die neuen Dokumente umstellen.
|
||||
|
||||
Keine Laufzeit-, Schema- oder UI-Änderung. Abnahme: keine aktive Dokumentation
|
||||
nennt CSV/IfcGUID als künftigen Transport beziehungsweise Schlüssel; der
|
||||
aktuell noch vorhandene Legacy-Code bleibt als solcher klar benannt.
|
||||
|
||||
## R2 – XLSX-Transportadapter
|
||||
|
||||
Dateien/Module: neues `src/external-model/xlsx`, synthetische Testfixtures und
|
||||
ein auf XLSX umgestellter Referenzprüfer mit Dateipfadargument. Eine neue
|
||||
direkte Bibliothek (`exceljs`, vorbehaltlich der Tests), keine DB-Änderung.
|
||||
|
||||
Abnahme:
|
||||
|
||||
- Kopfzeilenkommentare, Blattname, Spaltenbreiten, Formate und Zelltypen
|
||||
überleben einen strukturellen Roundtrip;
|
||||
- erste Datenzeile/-spalte und Mappings funktionieren ohne separates
|
||||
`layout.idColumn`;
|
||||
- Worksharing-ID/IfcGUID werden exakt und case-sensitiv behandelt;
|
||||
- Zeile ohne ID und ohne `Familie und Typ` wird übersprungen, die Muster-
|
||||
Summenzeile B490 blockiert nicht;
|
||||
- Zeile ohne ID mit `Familie und Typ` erzeugt Hinweis und wird übersprungen;
|
||||
- maximal 10 MiB, nur `.xlsx`, Zeilen-/Spaltengrenzen nach dem Einlesen;
|
||||
- keine Formelausführung;
|
||||
- lokale Referenzprüfung bestätigt 487 Objekte und keine ID-Duplikate;
|
||||
- aus der realen Musterdatei entsteht lokal eine nicht versionierte
|
||||
Rückgabedatei mit einigen geänderten Werten.
|
||||
|
||||
Danach stoppt die Arbeit. Der Nutzer testet diese Datei in Linear. Erst sein
|
||||
erfolgreicher Rückimport gibt R3 frei. Scheitert er, wird vor R3 ein konkreter
|
||||
OOXML-Patchadapter vorgeschlagen, der das Originalworkbook direkt ändert.
|
||||
|
||||
## R3 – Datenmodell und Backend-Cutover
|
||||
|
||||
- Konfiguration ohne eigene Versionszählung;
|
||||
- `worksharing_id NOT NULL`, Unique je Quelle; `ifc_guid` nullable ohne Unique;
|
||||
- additive Migration nach vorherigem DB-Backup; alte externe Entwicklungsdaten
|
||||
verwerfen und Row-Mengen vorher auf `manualQuantity` zurücksetzen;
|
||||
- Batch-Aufbewahrung: nur letzter Batch vollständig, ältere nur Metadaten;
|
||||
- Snapshot 10, Restore und Transfer; alte CSV-Zustände/History klar ablehnen;
|
||||
- Backend-CSV-Parser, Endpunkte und Verträge entfernen;
|
||||
- Apply parst erneut; Undo/Redo verwenden ausschließlich gespeicherte
|
||||
Vorher-/Nachher-Zustände.
|
||||
|
||||
Risiken: Migration mit verknüpften Row-Mengen, alte History-Spitzen und
|
||||
vollständiges UUID-Remapping. Pflicht: echte SQLite-Commit-/Rollback-Tests.
|
||||
|
||||
## R4 – Revit-Seite und Einstellungen
|
||||
|
||||
- Route `/projects/:projectId/revit` und Navigationseintrag;
|
||||
- Status-/Aktionsgrundgerüst;
|
||||
- Einstellungsmodal mit Musterdateierkennung, Layout und Feldzuordnung;
|
||||
- Stromkreismodus `combined | separate`;
|
||||
- Projektseiten-Button und `revit-csv-modal.tsx` entfernen;
|
||||
- nur deutsche UI-Texte und bestehende Icon-/Kartenregeln.
|
||||
|
||||
## R5 – Erstimport
|
||||
|
||||
- Vorschau und Plan mit erneuter Dateiübertragung beim Apply;
|
||||
- Räume, Verteiler, Gerätearten, exakte Familienregeln und optionale
|
||||
ProjectDevices;
|
||||
- fehlender GZF als sichtbarer Startwert `1`, ohne Zusatzbestätigung;
|
||||
- Warn-/Überspringregel für ID-lose Zeilen;
|
||||
- ein atomarer Importcommand, keine Row-/Circuit-Erzeugung;
|
||||
- Undo/Redo aus Commandzuständen ohne Workbook-Parsing.
|
||||
|
||||
## R6 – Objekttabelle und Sammelaktionen
|
||||
|
||||
- kompakte Objektliste einmal laden;
|
||||
- clientseitig suchen, filtern und sortieren;
|
||||
- virtualisierte Darstellung ohne Server-Pagination;
|
||||
- stabile Mehrfachauswahl und Sammelaktionen für Verteiler, ProjectDevice und
|
||||
Objektplanungswerte;
|
||||
- Standardverteileränderung wirkt nur auf unzugeordnete Objekte; verknüpfte
|
||||
Objekte folgen unverändert ihrer Row.
|
||||
|
||||
## R7 – Stromkreislisteneditor
|
||||
|
||||
- gruppierter rechter Revit-Bereich mit Anzahl-Badge;
|
||||
- Drop auf Row, Circuit oder freien Bereich über vorhandene, angepasste
|
||||
Commands;
|
||||
- Row-Indikator, Objektanzeige und Lösen mit Übernahme aktueller Row-Werte;
|
||||
- Row-/Circuit-/Gruppen-Löschcommands lösen verknüpfte Objekte atomar und
|
||||
zeigen `X Revit-Objekte werden wieder unzugeordnet`;
|
||||
- Undo stellt Objektlinks exakt wieder her;
|
||||
- nur Raum-/Verteilerlöschung mit externen Referenzen bleibt gesperrt.
|
||||
|
||||
## R8 – Rückgabe-Excel
|
||||
|
||||
- alle / abweichende / ausgewählte Objekte;
|
||||
- zuletzt importiertes Workbook als strukturelle Grundlage;
|
||||
- Stromkreisfelder des gewählten Modus sind Pflicht;
|
||||
- fehlende optionale Bezeichnung-/Leistung-/Spannung-/Stromspalten nur als
|
||||
Hinweis überspringen;
|
||||
- typisierte Zahlen, gemeinsame Export-/Abweichungsprojektion;
|
||||
- append-only Exportnachweis ohne Projektrevision.
|
||||
|
||||
R8 baut auf der in R2 durch Linear bestätigten Transportstrategie auf.
|
||||
|
||||
## R9 – Folgeimport
|
||||
|
||||
- exaktes, case-sensitives Matching nach Worksharing-ID;
|
||||
- neu, geändert, unverändert, fehlend und Rückgabefeldabweichungen;
|
||||
- Entscheidungen nur für fachliche Quelländerungen;
|
||||
- akzeptierte Mengenänderungen und Row-Summen atomar;
|
||||
- fehlende Objekte nicht automatisch lösen oder löschen;
|
||||
- neuer letzter Vollbatch, vorheriger Batch auf Metadaten reduzieren;
|
||||
- ein persistenter Undo-Schritt ohne Excel-Parsing bei Undo/Redo.
|
||||
|
||||
## R10 – Härtung
|
||||
|
||||
Ende-zu-Ende-Test:
|
||||
|
||||
```text
|
||||
Import → Objektplanung → Row-Zuordnung → Rückgabe → Folgeimport
|
||||
→ Snapshot/Restore → Projektduplikat → Undo/Redo nach Neustart
|
||||
```
|
||||
|
||||
Zusätzlich: mehrere Tausend synthetische Objekte, virtualisierte UI,
|
||||
Speicher-/Payload-/Transaktionsmessungen, Löschwarnungen samt Link-Inversen,
|
||||
alte CSV-Ablehnungen und Dokumentation auf den ausgelieferten Stand.
|
||||
|
||||
## Pflichtprüfungen je Paket R1–R10
|
||||
|
||||
```text
|
||||
fokussierte Tests
|
||||
npm test
|
||||
npm run build:api
|
||||
npm run build:web
|
||||
npm run typecheck:scripts
|
||||
npx tsc --noEmit -p tsconfig.next.json
|
||||
```
|
||||
|
||||
Jedes Paket wird mit einer knappen imperativen Commit-Message abgeschlossen.
|
||||
|
|
@ -2,12 +2,17 @@
|
|||
|
||||
Stand: 29.09.2026. Geprüfter Code: `cf022b2`.
|
||||
|
||||
**Status: R0 abgeschlossen, Freigabe für R1–R10 ausstehend.** Dieser Bericht
|
||||
**Status: R0 abgeschlossen und mit Korrekturen für R1 freigegeben.** Dieser Bericht
|
||||
ist ein Umsetzungsvorschlag, kein Nachweis einer bereits implementierten
|
||||
Excel-Anbindung. Der neue Nutzerauftrag ersetzt die CSV-/IfcGUID-Vorgaben und
|
||||
die alte Phasenliste 14.0–14.6. R1 bereinigt die bestehenden Dokumente; R0
|
||||
ändert weder Laufzeitcode noch Datenbank noch Oberfläche.
|
||||
|
||||
Die 13 Freigabekorrekturen vom 29.09.2026 sind in den
|
||||
[verbindlichen Anforderungen](revit-excel-integration-requirements.md) und im
|
||||
[R0–R10-Plan](revit-excel-phase-14-plan.md) eingearbeitet. Bei Abweichungen
|
||||
gelten diese beiden R1-Dokumente.
|
||||
|
||||
## 1. Geprüfter Bestand und Keep/Change/Remove
|
||||
|
||||
Gelesene Grundlagen: `AGENTS.md`, `docs/current-architecture.md`,
|
||||
|
|
@ -90,7 +95,7 @@ Die Datei ist unversioniert und darf nicht committed werden.
|
|||
| Objektidentitäten | 487 syntaktisch passende Worksharing-IDs, keine Duplikate |
|
||||
| Kopfzeilenkommentare | 14, zu den 14 Spalten nach der ID-Spalte |
|
||||
| Fehlende Raumangaben | 67 Objekte ohne Raumnummer und Raumname |
|
||||
| IfcGUID-Duplikate | 2 Gruppen nichtleerer doppelter Werte |
|
||||
| IfcGUID-Duplikate | Keine bei exaktem, case-sensitivem Vergleich |
|
||||
| Formeln | Keine; synthetische Tests dafür erforderlich |
|
||||
| Spaltendefinitionen | 16, obwohl nur 15 Datenspalten vorhanden sind |
|
||||
|
||||
|
|
@ -100,9 +105,15 @@ gekürzt werden. Das Muster enthält die neuen getrennten Stromkreisfelder und
|
|||
die Bezeichnung noch nicht. Fehlende Rückgabespalten werden angezeigt; sie
|
||||
dürfen nicht ohne Linear-Parameterbindung erfunden werden.
|
||||
|
||||
Die frühere Angabe von zwei IfcGUID-Duplikatgruppen war falsch: PowerShells
|
||||
standardmäßiges Gruppieren verglich ohne Beachtung der Groß-/Kleinschreibung.
|
||||
Ein erneuter ordinaler, case-sensitiver Vergleich ergab keine Duplikate. Die
|
||||
Summenzeile hat nur in B490 einen Wert; `Familie und Typ` ist leer.
|
||||
|
||||
Nicht nachgewiesen: erfolgreicher Rückimport in Linear, dessen genaue
|
||||
Auswertung der Kommentar-/VML-Metadaten und der ExcelJS-Roundtrip. R2 prüft
|
||||
die Struktur, R8/R10 benötigen zusätzlich einen realen Linear-Abnahmelauf.
|
||||
Auswertung der Kommentar-/VML-Metadaten und der ExcelJS-Roundtrip. R2 endet
|
||||
deshalb mit einer aus der Musterdatei erzeugten Rückgabedatei und einem
|
||||
verbindlichen Linear-Test durch den Nutzer vor R3.
|
||||
|
||||
## 3. Bibliothek, Adapter und Uploadgrenzen
|
||||
|
||||
|
|
@ -123,18 +134,12 @@ Blocker wird die Bibliotheksentscheidung neu vorgelegt.
|
|||
|
||||
Vorgeschlagene Grenzen, zentral konfiguriert und synthetisch getestet:
|
||||
|
||||
- ausschließlich `.xlsx`, passender OOXML-Inhalt und ZIP-Signatur; kein
|
||||
`.xlsm`, verschlüsseltes Archiv, VBA, ActiveX oder externe Workbook-Links;
|
||||
- maximal 10 MiB Upload, 100 MiB tatsächlich entpackte Daten, 2.000 ZIP-
|
||||
Einträge, 50.000 Zeilen, 256 Spalten und 2 Millionen materialisierte Zellen;
|
||||
- genau ein Arbeitsblatt; keine Formelausführung, kein Nachladen von URLs;
|
||||
- ZIP-Vorprüfung vor ExcelJS: Verzeichniseinträge, doppelte Pfade,
|
||||
Kompressionsverfahren und tatsächliche entpackte Bytezahl prüfen.
|
||||
Zentralverzeichnisangaben allein schützen nicht vor manipulierten Archiven.
|
||||
Begrenzte Dekompression mit Node-Bordmitteln, keine zweite direkte Library;
|
||||
- Parser in begrenztem Worker mit Zeit-/Speichergrenze; Abbruch ohne DB-
|
||||
Schreibvorgang. API-Body-Limit auf Uploadgrenze einschließlich Base64-
|
||||
Overhead abstimmen, statt global beliebige Requestgrößen zuzulassen.
|
||||
- ausschließlich `.xlsx`, kein `.xls` oder `.xlsm`;
|
||||
- maximal 10 MiB Upload;
|
||||
- genau ein Arbeitsblatt und keine Formelausführung;
|
||||
- feste Zeilen-, Spalten- und Zellgrenzen nach dem Einlesen.
|
||||
|
||||
Es gibt keinen eigenen ZIP-Prüfer und keinen Parser-Worker.
|
||||
|
||||
Neutrale Matrix: Blattname, Kopfzeilen-/Startpositionen, Spaltenmetadaten
|
||||
(Index, Name, Kommentartext, erkannter Parametertyp/Einheit), geordnete
|
||||
|
|
@ -144,11 +149,14 @@ optionale Transportmetadaten; fachlich zählt nur der gecachte skalare Wert.
|
|||
Fehlender Cache oder Fehlerwert erzeugt einen Hinweis bzw. bei Pflichtfeldern
|
||||
einen Blocker. Originalbytes bleiben unverändert gespeichert.
|
||||
|
||||
Fehlende ID bei sonstigen Objektdaten blockiert; Leer-/eindeutige Summenzeilen
|
||||
werden ignoriert. Nicht passende nichtleere IDs blockieren ebenfalls.
|
||||
Worksharing-ID bleibt als Quelltext erhalten, Matching ist exakt; ungültige
|
||||
Leerzeichen/uneindeutige Schreibweisen werden gemeldet statt still korrigiert.
|
||||
IfcGUID wird optional gespeichert, doppelte Werte sind nur Hinweise.
|
||||
Eine Zeile ohne Worksharing-ID ist nur verdächtig, wenn `Familie und Typ`
|
||||
gefüllt ist. Sie erzeugt einen Hinweis und wird übersprungen, ohne zu
|
||||
blockieren. Andere ID-lose Zeilen, auch die Summenzeile mit Inhalt in B,
|
||||
werden still übersprungen. Nicht passende nichtleere IDs blockieren.
|
||||
Worksharing-ID und IfcGUID bleiben als Quelltext erhalten und werden exakt,
|
||||
ordinal und case-sensitiv verglichen; ungültige äußere Leerzeichen werden
|
||||
gemeldet statt still korrigiert. IfcGUID wird optional gespeichert, doppelte
|
||||
Werte sind nur Hinweise.
|
||||
Numerische Projektion rundet Leistung auf 0,01 W, nicht die gespeicherte
|
||||
Quellzelle. Mengen aus `socketCount` müssen positive ganze Zahlen sein.
|
||||
|
||||
|
|
@ -170,8 +178,7 @@ Neuer neutraler Vertrag `ExternalModelConfiguration`, Schema-Version 1:
|
|||
{
|
||||
schemaVersion: 1,
|
||||
layout: {
|
||||
headerRow: 1, firstDataRow: 3, firstDataColumn: 1,
|
||||
idColumn: "Worksharing-ID"
|
||||
headerRow: 1, firstDataRow: 3, firstDataColumn: 1
|
||||
},
|
||||
circuitMode: "combined" | "separate",
|
||||
columns: {
|
||||
|
|
@ -200,8 +207,8 @@ Neuer neutraler Vertrag `ExternalModelConfiguration`, Schema-Version 1:
|
|||
```
|
||||
|
||||
Zeilen/Spalten sind intern 1-basiert; UI stellt Spalten als A, B, … dar.
|
||||
`layout.idColumn` und `columns.worksharingId` werden gemeinsam gesetzt und
|
||||
müssen übereinstimmen. Jede gemappte Kopfzeile muss eindeutig auflösbar sein;
|
||||
Es gibt nur `columns.worksharingId` und kein separates `layout.idColumn`.
|
||||
Jede gemappte Kopfzeile muss eindeutig auflösbar sein;
|
||||
doppelte Ausgabebelegungen werden abgelehnt. Freie Eingabe bleibt zulässig,
|
||||
aber ein nicht existierender Name erzeugt vor Import/Export einen konkreten
|
||||
Fehler. Erkennung und Vorbelegung nutzen die exakten Standardnamen aus dem
|
||||
|
|
@ -217,8 +224,8 @@ Referenzierte Gerätearten können nicht kommentarlos entfernt werden.
|
|||
Startwerte: je Feld ProjectDevice vor Geräteart vor leer. Anzeigename:
|
||||
Auswahlkenner, sonst Geräteartname, sonst Familie/Typ. Quellleistung bleibt
|
||||
Quelle; eine Übernahme geschieht nur als sichtbare Planungsentscheidung.
|
||||
Fehlender GZF bleibt vor Zuordnung leer; verlangt der Row-Vertrag einen Wert,
|
||||
wird `1` sichtbar vorgeschlagen und ausdrücklich bestätigt. Geräteart-
|
||||
Fehlender GZF wird sichtbar mit `1` vorbelegt, ohne zusätzliche Bestätigung.
|
||||
Geräteart-
|
||||
Änderungen schreiben keine vorhandenen Objekt-Overrides oder Rows um.
|
||||
|
||||
## 5. Konkretes Persistenzschema
|
||||
|
|
@ -228,20 +235,21 @@ Bestehende UUID-/Projekt-FKs und Eigentumsprüfungen werden beibehalten.
|
|||
|
||||
| Tabelle | Zielspalten / Constraints |
|
||||
| --- | --- |
|
||||
| `external_model_configurations` (ersetzt CSV-Tabelle) | `id TEXT PK`, `project_id TEXT NOT NULL UNIQUE FK projects`, `configuration_version INTEGER NOT NULL CHECK > 0`, `configuration JSON NOT NULL`. Enthält obiges vollständiges Aggregat. |
|
||||
| `external_model_configurations` (ersetzt CSV-Tabelle) | `id TEXT PK`, `project_id TEXT NOT NULL UNIQUE FK projects`, `configuration JSON NOT NULL`. Enthält obiges vollständiges Aggregat; keine eigene Versionszählung. |
|
||||
| `external_model_sources` | `id`, `project_id UNIQUE`, `name`, `source_type = revit_xlsx`. Genau eine implizite Quelle je Projekt. |
|
||||
| `external_import_batches` | Bestehende IDs, Importart, Zeit, Dateiname, SHA-256, `applied_project_revision`, `configuration_version`, `configuration_snapshot JSON`, `original_bytes BLOB`, `document JSON`; Matrix jetzt typisiert und transportneutral. Unveränderlich innerhalb des aktiven Zustands; Undo/Restore darf ganze Batches entfernen/wiederherstellen. |
|
||||
| `external_import_batches` | Letzter Batch vollständig mit IDs, Importart, Zeit, Dateiname, SHA-256, Objektzahl, `applied_project_revision`, `configuration_snapshot JSON`, `original_bytes BLOB`, `document JSON`; ältere Batches nur als Metadaten Datum, Dateiname, SHA-256 und Objektzahl. |
|
||||
| `external_room_mappings` | Vorhandene Felder einschließlich normalisiertem Quellraumschlüssel, `room_id`, `default_distribution_board_id`; UNIQUE `(source_id, normalized_source_room_key)` bleibt. |
|
||||
| `external_model_objects` | Bestehende interne IDs/Links; neu `worksharing_id TEXT NOT NULL`, UNIQUE `(source_id, worksharing_id)`; `ifc_guid TEXT NULL`, ohne Unique; `device_type_id TEXT NOT NULL` als validierter Verweis in das Konfigurationsaggregat. |
|
||||
| Objektzustand | `accepted_source_values JSON` mit rohen typisierten Werten für Raum, Familie/Typ, Marker, Menge, Bemerkung und alle Rückgabefelder; `planning_values JSON` mit Anzeigename, Kategorie, Anschlussart, effektiver Menge, Einzelleistung W, nullable GZF/cosPhi/Kostengruppe/Bemerkung; `overridden_fields JSON`; bisherige Batch-/Raum-/Board-/ProjectDevice-/Row-Verweise und `presence_status` bleiben. |
|
||||
| `external_export_batches` (neu) | `id TEXT PK`, `project_id FK`, `project_revision INTEGER`, `import_batch_id TEXT`, `exported_at_iso TEXT`, `file_name TEXT`, `sha256 TEXT`, `configuration_version INTEGER`, `scope TEXT`, `object_count INTEGER`. Append-only Audit-Store. |
|
||||
| `external_export_batches` (neu) | `id TEXT PK`, `project_id FK`, `project_revision INTEGER`, `import_batch_id TEXT`, `exported_at_iso TEXT`, `file_name TEXT`, `sha256 TEXT`, `configuration_snapshot/hash`, `scope TEXT`, `object_count INTEGER`. Append-only Audit-Store. |
|
||||
|
||||
`import_batch_id` des Exportnachweises ist absichtlich eine historische UUID
|
||||
ohne löschenden FK: Undo eines Imports oder Snapshot-Restore darf den Nachweis
|
||||
nicht entfernen. Exportnachweise liegen außerhalb rücksetzbarer Fachsnapshots
|
||||
und werden beim Projektduplikat nicht als dort erfolgte Exporte ausgegeben.
|
||||
Sie bleiben beim Originalprojekt erhalten; diese Abgrenzung wird in R1
|
||||
dokumentiert. Importbatches selbst gehören vollständig zu Snapshot/Transfer.
|
||||
dokumentiert. Nur der letzte Importbatch gehört mit Bytes und Matrix zu
|
||||
Snapshot/Transfer; ältere Batches werden dort nur als Metadaten erhalten.
|
||||
|
||||
Indices: bisherige Projekt-/Presence-, Board- und Row-Indices behalten;
|
||||
zusätzlich `(project_id, device_type_id)`, `external_room_mapping_id`,
|
||||
|
|
@ -252,9 +260,9 @@ Transaktion; bloße Existenz eines UUID-FK genügt nicht.
|
|||
Effektiver Verteiler: ein gemeinsamer Resolver verwendet bei verknüpften
|
||||
Objekten die Row/Circuit-Verteilung, sonst die Objektabweichung, sonst die
|
||||
Raumvorgabe. `distributionBoardId = null` bedeutet Raumvorgabe verwenden;
|
||||
bei fehlender Vorgabe ist das Objekt ohne Verteiler. Room-/Board-
|
||||
Sammeländerungen prüfen alle betroffenen Row-Links und lehnen inkonsistente
|
||||
Umbuchungen ab, bis diese ausdrücklich gelöst/verschoben sind.
|
||||
bei fehlender Vorgabe ist das Objekt ohne Verteiler. Eine Änderung des
|
||||
Raum-Standardverteilers betrifft nur unzugeordnete Objekte; verknüpfte Objekte
|
||||
folgen immer der Row-Verteilung und blockieren diese Änderung nicht.
|
||||
|
||||
Planungswerte bleiben von Quellwerten getrennt. Nach Row-Zuordnung sind
|
||||
Objekt-Planungswerte eingefrorene Startwerte; Anzeige, Abweichung und Export
|
||||
|
|
@ -272,7 +280,7 @@ Snapshots der betroffenen Datensätze, keine ungesicherten Teilpatches.
|
|||
|
||||
| Command | Payload-Skizze und Gegenrichtung |
|
||||
| --- | --- |
|
||||
| `external-model-configuration.update` v1 | `{ expected, target }` einschließlich Layout, Mapping, Gerätearten und Regeln. Inverse tauscht Fachinhalt; Versionsgeneration siehe unten. |
|
||||
| `external-model-configuration.update` v1 | `{ expected, target }` einschließlich Layout, Mapping, Gerätearten und Regeln. Inverse tauscht den vollständigen Fachinhalt; keine eigene Konfigurationsversion. |
|
||||
| `external-import.apply-initial` v2 | `{ expectedConfiguration, targetConfiguration, expected, target }`. Quelle, Batch, Mapping, Objekte und neue Regeln zusammen; Inverse stellt leeren externen und vorherigen Konfigurationsinhalt wieder her. Keine Rows. |
|
||||
| `external-import.apply-follow-up` v1 | `{ configuration: transition, batch: transition, roomMappings: transitions, objects: transitions, rows: quantityTransitions, decisions }`; Server erzeugt deterministischen Diff und alle UUIDs. Inverse tauscht alle betroffenen Zustände. |
|
||||
| `external-model-object.update-planning` v1 | `{ objects: transitions }`; nur ungebundene Objekte; geänderte Felder in Overrides. Einzel-/Sammelbearbeitung identischer Regeln. |
|
||||
|
|
@ -290,32 +298,29 @@ Entwürfe und werden erst mit dem Import atomar persistiert. Nach separater
|
|||
Kataloganlage aktualisiert der Wizard die Projektrevision und plant neu,
|
||||
ohne lokale Entscheidungen zu verlieren.
|
||||
|
||||
Konfigurationsgeneration: `configurationVersion` erhält bei jedem
|
||||
Konfigurationswechsel einschließlich Undo/Redo/Restore die neu entstehende
|
||||
Projektrevision. Sie ist damit strikt steigend, aber nicht lückenlos.
|
||||
Historienbefehle vergleichen den erwarteten Fachinhalt und die aktuelle
|
||||
Projektversion; die administrative Generation wird serverseitig neu erzeugt.
|
||||
Die Inverse restauriert alle Fachwerte exakt, nicht einen alten Zählerstand.
|
||||
Importbatches behalten ihre ursprüngliche Generation und ihren Snapshot.
|
||||
Ein Restore/Projekttransfer erhält diese Herkunft; die aktive Konfiguration
|
||||
wird an die Revision des Zielprojekts gebunden. Prüfen: Änderung → Undo →
|
||||
anderer Zweig darf niemals denselben Vorschau-Token wieder gültig machen.
|
||||
Die Konfiguration hat keine eigene Versionszählung. Vorschau und Apply binden
|
||||
sich an `expectedRevision`; weil auch Undo/Redo neue, strikt steigende
|
||||
Projektrevisionen erzeugen, wird ein veralteter Plan eindeutig ungültig.
|
||||
Importbatches speichern eine vollständige Konfigurationskopie. Prüfen:
|
||||
Änderung → Undo → anderer Zweig darf niemals denselben Plan wieder gültig
|
||||
machen.
|
||||
|
||||
XLSX wird vor der synchronen SQLite-Transaktion in einer serverinternen
|
||||
Vorbereitung geparst. Apply überträgt Bytes erneut; Hash, Matrix und
|
||||
Entscheidungen werden erneut validiert. Im Store werden Revision,
|
||||
Konfigurationsinhalt/-generation, erwartete Objekte, Links und vollständiger
|
||||
Konfigurationsinhalt, erwartete Objekte, Links und vollständiger
|
||||
vorbereiteter Plan atomar geprüft. Vorbereitete Daten sind keine vom Client
|
||||
behauptete Validierung: Generic-Command-Requests dürfen Importcommands nicht
|
||||
an dieser serverseitigen Vorbereitung vorbeischleusen. Undo/Redo benutzen
|
||||
denselben Prüfdienst für persistierte Bytes vor der Transaktion. Keine
|
||||
asynchronen Callbacks in `better-sqlite3`-Transaktionen.
|
||||
an dieser serverseitigen Vorbereitung vorbeischleusen. Undo/Redo lesen und
|
||||
parsen keine Excel-Datei; sie wenden ausschließlich die gespeicherten
|
||||
Vorher-/Nachher-Zustände an. Keine asynchronen Callbacks in
|
||||
`better-sqlite3`-Transaktionen.
|
||||
|
||||
Allgemeine Row-/Circuit-/Gruppen-/Board-/Raum-/ProjectDevice-Löschungen
|
||||
erhalten Guards, solange externe Referenzen betroffen sind. Nutzer lösen die
|
||||
Referenzen zuvor ausdrücklich über die passenden Commands. Guards gelten
|
||||
auch in Unterbaum- und History-only-Pfaden. Dadurch werden vorhandene
|
||||
Commands nicht unbemerkt zu unvollständigen externen Löschcommands.
|
||||
Row-/Circuit-/Gruppen-Löschcommands erfassen verknüpfte Objekte vollständig.
|
||||
Nach der Warnung `X Revit-Objekte werden wieder unzugeordnet` lösen sie die
|
||||
Links im selben Command; ihre Inverse stellt sie exakt wieder her. Sperren
|
||||
bleiben nur für das Löschen referenzierter Verteiler und Räume und gelten auch
|
||||
in Unterbaum- und History-only-Pfaden.
|
||||
|
||||
## 7. Migration, Snapshot 10, History und Transfer
|
||||
|
||||
|
|
@ -351,7 +356,8 @@ allgemeine Commands können nach dem Reset zusätzlich an ihren exakten
|
|||
Vorbedingungen scheitern; das bleibt eine sichere, sichtbare Ablehnung.
|
||||
|
||||
Snapshot v10 enthält aktive Excel-Konfiguration, Gerätearten/Regeln, Quelle,
|
||||
alle Batches mit Originalbytes/Matrix, Raum-Mappings, Objekte und Links.
|
||||
den letzten Batch mit Originalbytes/Matrix, ältere Batches nur als Metadaten
|
||||
sowie Raum-Mappings, Objekte und Links.
|
||||
Upgrade v1–9: bestehende nicht-externe Upgrader erhalten. Nur wenn
|
||||
`externalCsvConfiguration` fehlt/null ist **und** der externe Zustand leer
|
||||
ist, verlustfrei auf v10 heben. Auch eine gespeicherte CSV-Konfiguration
|
||||
|
|
@ -389,12 +395,13 @@ separater append-only Audit-Write, ohne Projektrevision oder Undo-Schritt.
|
|||
Bei Auditfehler kein Erfolg/download; ein Eintrag belegt Dateierzeugung,
|
||||
nicht einen tatsächlich abgeschlossenen Browserdownload.
|
||||
|
||||
Die Revit-Seite zeigt Status, Aktionen und eine paginierte Objekttabelle
|
||||
(Vorschlag: 100 Zeilen pro Seite). Filter-/Sortierzustand, UUID-Auswahl und
|
||||
Sammelaktionen sind unabhängig vom DOM. „Alle gefilterten“ verwendet eine
|
||||
explizit aufgelöste Auswahl zur bekannten Revision; keine Mutation anhand
|
||||
eines inzwischen veränderten Filters. Große Auswahlmengen werden nicht in
|
||||
getrennte Undo-Schritte aufgeteilt. Kein vollständiges Batch-Blob im DTO.
|
||||
Die Revit-Seite lädt einmal eine kompakte Objektliste. Filterung und Sortierung
|
||||
laufen im Client; die Tabelle wird virtualisiert und verwendet keine Server-
|
||||
Pagination. Filter-/Sortierzustand, UUID-Auswahl und Sammelaktionen sind
|
||||
unabhängig vom DOM. „Alle gefilterten“ wird vor einer Mutation zu einer
|
||||
expliziten ID-Auswahl an der aktuellen Revision aufgelöst. Große Auswahlmengen
|
||||
werden nicht in getrennte Undo-Schritte aufgeteilt. Kein vollständiges
|
||||
Batch-Blob im DTO.
|
||||
|
||||
Einstellungen verwenden Musterdatei-Erkennung mit editierbaren Positionen,
|
||||
Feld-Dropdowns/freier Eingabe und Kommentar-Typ-/Einheitenanzeige. Regeln
|
||||
|
|
@ -430,10 +437,10 @@ gegen den **zuletzt importierten**, nicht den zuletzt exportierten Stand.
|
|||
Umfang: alle im letzten Batch vorhandenen Objekte / abweichende / explizite
|
||||
Auswahl. Fehlende Objekte haben keine aktuelle Originalzeile und werden
|
||||
nicht künstlich wieder eingefügt. Alle Spalten bleiben, nicht ausgegebene
|
||||
Parameter behalten importierte Werte. Fehlende benötigte Zielspalten bzw.
|
||||
Linear-Bindungen blockieren die betreffende Exportkonfiguration mit Hinweis
|
||||
auf einen neuen vollständigen Linear-Export. Dateiname gemäß Auftrag mit
|
||||
bereinigtem Projektnamen und Tagesdatum.
|
||||
Parameter behalten importierte Werte. Fehlende optionale Spalten für
|
||||
Bezeichnung, Leistung, Spannung und Strom werden mit Hinweis übersprungen.
|
||||
Nur fehlende Stromkreisspalten des gewählten Modus blockieren. Dateiname gemäß
|
||||
Auftrag mit bereinigtem Projektnamen und Tagesdatum.
|
||||
|
||||
Folgeimport matcht ausschließlich Worksharing-ID. Ein neuer Batch speichert
|
||||
immer den vollständigen letzten Quellstand. Unveränderte Objekte werden
|
||||
|
|
@ -457,12 +464,12 @@ nach Freigabe; keine Fortschreibung der alten 14.0–14.6-Liste.
|
|||
| Paket | Arbeit und entscheidende Abnahme |
|
||||
| --- | --- |
|
||||
| R1 | Neue Excel-Anforderungen und R0–R10-Plan; alte Dokumente archivieren/auf Verweise kürzen; AGENTS, Architektur, History-Doku, Phase-14-Abschnitt, LLM-Kontext und alle Links nachziehen. Referenzdatei gezielt ignorieren. |
|
||||
| R2 | XLSX-Adapter und lokaler Referenzprüfer mit Pfadargument. Synthetischer Roundtrip für Kommentare, Blattname, Spaltenbreiten, Typen, Header-/Startpositionen, unbekannte Spalten, Auswahl und Summenausschluss; ZIP-/Formelgrenzen. Keine DB-Änderung. |
|
||||
| R2 | XLSX-Adapter und lokaler Referenzprüfer mit Pfadargument. Synthetischer Roundtrip für Kommentare, Blattname, Spaltenbreiten, Typen, Header-/Startpositionen, unbekannte Spalten, Auswahl und Summenausschluss. Aus der lokalen Musterdatei entsteht eine Rückgabedatei mit geänderten Werten. Danach Nutzerabnahme in Linear; R3 bleibt bis zum Erfolg gesperrt. Bei Fehlschlag vor R3 OOXML-Direktänderung als Alternative vorlegen. Keine DB-Änderung. |
|
||||
| R3 | Neue Konfiguration/Identität, additive Migration, Snapshot 10, Transfer und History-Ablehnungen; Backend-CSV entfernen. Parser-Vorbereitung von synchroner Transaktion trennen. |
|
||||
| R4 | Revit-Seite, Navigation, Einstellungen; Projektseitenmodal und dessen CSV-Frontend-Verträge entfernen. |
|
||||
| R5 | Erstimport mit atomaren Regeln, Geräten, Raum-/Board- und Objektentscheidungen; ProjectDevice-Vorbelegung nach Priorität; ein Import-Undo-Schritt. |
|
||||
| R6 | Objekt-Reads, Paging/Filter, Sammel-Commands und Overrides; verwandte Lösch-/Referenzguards vollständig absichern. |
|
||||
| R7 | Gruppierung, Drag-and-drop, Row-Indikatoren und Lösen inklusive aktueller Row-Werte; drei Drop-Ziele und Reload/Undo/Redo. |
|
||||
| R6 | Kompakte Objekt-Reads, clientseitige Filter/Sortierung, Virtualisierung, Sammel-Commands und Overrides. |
|
||||
| R7 | Gruppierung, Drag-and-drop, Row-Indikatoren und Lösen inklusive aktueller Row-Werte; drei Drop-Ziele, atomare Objektlösung beim Row-/Circuit-/Gruppen-Löschen und Reload/Undo/Redo. |
|
||||
| R8 | Drei Exportumfänge, gemeinsame Abweichungsprojektion, typisierte Rückgabe, append-only Nachweis und Linear-Strukturabnahme. |
|
||||
| R9 | Kontrollierter Folgeimport, fehlende Objekte, explizites Löschen, mengenwirksame Entscheidungen und atomare Inverse. |
|
||||
| R10 | Vollständige synthetische Ende-zu-Ende-Kette einschließlich Neustart, Snapshot/Restore und Duplikat; mehrere Tausend Objekte; Doku auf ausgelieferten Stand. |
|
||||
|
|
@ -492,19 +499,19 @@ Zusätzlich erforderliche neue Prüfungen:
|
|||
- Migration mit externen Row-Anteilen; keine Phantomlast und unveränderte BMKs.
|
||||
- v1–9 ohne CSV verlustfrei, mit CSV klare Ablehnung; alte Command-Inversen
|
||||
und alte Restore-Payloads ebenfalls ohne Teilwrites ablehnen.
|
||||
- Config-Änderung/Undo/Neuzweig invalidiert alte Pläne; Apply mit anderem
|
||||
- Config-Änderung/Undo/Neuzweig invalidiert alte Pläne über `expectedRevision`; Apply mit anderem
|
||||
Dateiinhalt, fehlenden Entscheidungen oder fremden UUIDs rollt vollständig
|
||||
zurück. Später Historyfehler rollt auch Regeln, Links und Mengen zurück.
|
||||
- Gebundene Row ändern → Export → Lösen → Undo/Redo behält fachliche Werte.
|
||||
- Mehrfachsteckdosen: unterschiedliche effektive Mengen, identische
|
||||
Einzelwerte, richtige Gruppierung und objektweise Rückgabeleistung.
|
||||
- Löschen über alle Unterbaum-/History-Pfade kann externe FKs nicht still
|
||||
nullen. Fremde Verteilungen/Räume/Kategorien und Gerätearten blockieren.
|
||||
- Row-/Circuit-/Gruppen-Löschen löst externe Links im Command und stellt sie
|
||||
per Undo wieder her. Raum-/Verteilerlöschen mit Referenzen blockiert.
|
||||
- Export-Audit scheitert: keine fachliche Revision; SHA-256 entspricht exakt
|
||||
den gelieferten Bytes. Snapshot/Restore entfernt keine Exportnachweise.
|
||||
- 5.000/10.000 synthetische Objekte: Parserzeit, Peak-Speicher, Payloadgröße,
|
||||
Command-/Snapshot-Dauer und UI-Reaktionszeit messen; höchstens eine
|
||||
paginierte Seite im DOM, stabile Auswahl über Seitenwechsel.
|
||||
Command-/Snapshot-Dauer und UI-Reaktionszeit messen; nur sichtbare Zeilen im
|
||||
DOM, stabile Auswahl über virtuelle Bereiche.
|
||||
|
||||
Wesentliche Restrisiken: Linear-Kommentarbindung ist nur anhand des
|
||||
Exports beobachtet; ExcelJS-Releasepflege und Roundtrip sind in R2 zu
|
||||
|
|
@ -515,7 +522,7 @@ externen Zustand begrenzt und nur nach verifiziertem Backup zulässig.
|
|||
Fehlende Zielparameter im Muster verlangen einen neuen vollständigen
|
||||
Linear-Export, keine geratenen GUID-Kommentare.
|
||||
|
||||
**Freigabepunkt:** Der Nutzerauftrag verlangt wörtlich
|
||||
„R0. Audit (danach stoppen und Freigabe abwarten)“.
|
||||
Mit Freigabe dieses Vorschlags beginnt R1; R0 selbst autorisiert keine
|
||||
Installation, Migration oder Implementierung von R1–R10.
|
||||
**Freigabepunkt:** R0 wurde am 29.09.2026 mit den in R1 dokumentierten
|
||||
Korrekturen freigegeben. R2 besitzt einen neuen verbindlichen Freigabepunkt:
|
||||
Vor Beginn von R3 muss der Nutzer die in R2 erzeugte Rückgabedatei erfolgreich
|
||||
in Linear getestet haben.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue