493 lines
22 KiB
Markdown
493 lines
22 KiB
Markdown
# 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
|
||
|
||
Umsetzungsstand R7: Der Stromkreislisteneditor lädt die kompakte Projektliste
|
||
gemeinsam mit dem Baum, gruppiert unzugeordnete Objekte des aktuellen
|
||
Verteilers im Client und bietet Gruppen sowie einzelne Worksharing-IDs als
|
||
Drag-Quelle an. Drop auf Row, Circuit und freien Gruppenbereich verwendet die
|
||
drei persistenten Zuordnungscommands. Row-Badges zeigen die Linkzahl; Lösen
|
||
kopiert die aktuellen Row-Planungswerte als Overrides. Row-, Circuit- und
|
||
Gruppenlöschungen speichern die vollständigen Linkübergänge im Forward- und
|
||
Inverse-Command. Raum- und Verteilerlöschungen prüfen externe Referenzen
|
||
explizit.
|
||
|
||
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
|
||
|
||
Umsetzungsstand R8: Die Revit-Objekttabelle bietet alle drei Rückgabeumfänge
|
||
an und lädt eine aus dem letzten vollständigen Import erzeugte XLSX herunter.
|
||
Die Serverprojektion verwendet für verknüpfte Objekte die aktuellen Row- und
|
||
Circuit-Werte, für freie Objekte die Planungswerte und schreibt Zahlen als
|
||
Excel-Zahlen. Hinweise zu nicht berechenbaren Werten und fehlenden optionalen
|
||
Spalten werden nach dem Download angezeigt. Der append-only Exportnachweis
|
||
liegt außerhalb von Projektrevision, Undo/Redo, Snapshots und Transfer.
|
||
|
||
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.
|
||
|
||
Die korrigierte R2-Rückgabedatei wurde am 30.09.2026 erfolgreich in Linear
|
||
eingelesen. Damit ist diese Abnahme erfüllt und R3 freigegeben.
|
||
|
||
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.
|
||
|
||
Umsetzungsstand R9: Der sechsstufige Folgeimportwizard, die erneute
|
||
Apply-Prüfung, die getrennte Rückgabeabweichungsanzeige und der atomare
|
||
`external-import.apply-follow-up`-Command sind umgesetzt. Akzeptierte
|
||
Mengenänderungen aktualisieren verknüpfte Row-Summen im selben Command.
|
||
Fehlende Objekte bleiben zunächst samt Link und Menge erhalten und erscheinen
|
||
in der virtuellen Objekttabelle als `fehlend`. Ihre gesondert bestätigte
|
||
Löschung verwendet `external-model-object.delete-missing`; Undo stellt
|
||
Objekte, Links und Row-Mengen exakt wieder her.
|
||
|
||
## 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).
|