# STATUS — Codebase-Analyse > Stand: 2026-07-21 · Vollständige Bestandsaufnahme von Code + Dokumentation. > Ersetzt NICHT [ROADMAP.md](ROADMAP.md)/[ARCHITECTURE.md](ARCHITECTURE.md) (die wurden > im gleichen Zug überarbeitet), sondern begründet die Überarbeitung mit Zahlen und > Befunden. [HANDOVER.md](HANDOVER.md) und [PENDENZEN.md](PENDENZEN.md) bleiben die > laufenden Arbeitsprotokolle (nicht rückwirkend umgeschrieben). ## 0. TL;DR „Dossier" (Arbeitstitel `cad`, Rhino-Vorbild `DOSSIER`) ist in **3 Wochen** (erster Commit 2026-06-30, 362 Commits bis 2026-07-20) von einem Risiko-Spike zu einem **funktionsreichen Desktop-CAD/BIM-Tool** gewachsen: eigenes semantisches Gebäudemodell, zwei eigene Rust/WASM-Rendering-Engines („Nordstern"), ein Rhino-artiges Kommandosystem, IFC/DXF/PDF/STL/OBJ-Export, Swisstopo-Import, SIA-416-Flächen, Materialbibliothek (statisch + live von ambientCG), Layouts/ Plansätze, Ausschnitte, native Tauri-Fenster. **~125.000 Zeilen Code** (TS+Rust, inkl. Tests), gebaut über viele autonome Agent-Sessions. Die drei zentralen Vision-Dokumente (ARCHITECTURE.md, README.md, ROADMAP.md) stammen aus der **allerersten Woche** (Stand 28./29.6.) und beschreiben einen Plan, der in der Zwischenzeit an vielen Stellen überholt, anders gelöst oder längst umgesetzt wurde (z. B. HLR/OCCT→eigene Rust-Schnitt-Pipeline, „Booleans noch offen"→teilweise längst gelöst). Diese Doku-Drift war der Auslöser für diese Analyse; die Docs sind im gleichen Zug revidiert worden. ## 1. Kennzahlen ### Code-Umfang | Bereich | Dateien | LOC (ohne Tests) | Tests | |---|---:|---:|---:| | `src/` (TypeScript, gesamt) | ~230 | 87.736 | 869 (Vitest, 71 Dateien) / 16.855 LOC | | `src-tauri/render3d` („Nordstern" 3D) | 14 | 10.246 | 97 `#[test]` | | `src-tauri/render2d` (2D-WGSL-Renderer) | 11 | 3.530 | 18 `#[test]` | | `src-tauri/kernel2d` (Rust-Geometriekern, Paritätstest) | 1 | 3.383 | 18 `#[test]` | | `src-tauri/geometry` (Wand-Join-Mathe, **unbenutzt**) | 1 | 1.057 | 8 `#[test]` | | `src-tauri/trucksolid` (CSG/Extrusion, `truck`+`csgrs`) | 2 | 758 | 15 `#[test]` | | `src-tauri/dwgimport` (DXF-Parser-Spike, **unbenutzt**) | 1 | 284 | 1 `#[test]` | | `src-tauri/src` (Tauri-Host: Fenster, Dialoge, Lock) | 4 | 1.044 | — | | **Gesamt** | | **~108.000** (ohne Tests) / **~125.000** (mit Tests) | 869 Vitest + 157 Rust-Tests | Größte TS-Bereiche: `plan/` (23.626 LOC — Plan-Ableitung + 3 Renderer), `ui/` (12.897 LOC — App-Shell, ResourceManager, Ribbon), `panels/` (9.538 LOC), `model/` (7.043 LOC inkl. Tests), `commands/` (6.973 LOC), `io/` (5.299 LOC), `state/` (5.297 LOC), `geometry/` (5.559 LOC), `viewport/` (5.165 LOC), `export/` (4.280 LOC). `src/App.tsx` allein ist **7.130 Zeilen**. ### Tempo 362 Commits in 3 Wochen; Woche 27 (30.6.–6.7.): 233 Commits, Woche 28: 126, danach starker Rückgang (Woche 30 bislang 3) — die Session-Dichte hat spürbar abgenommen, nicht das Projekt gestoppt (siehe PENDENZEN.md, weiterhin aktiv). ## 2. Architektur, wie sie WIRKLICH ist (nicht wie geplant) ### 2.1 Datenmodell — kein `Element[]`-Union, sondern typisierte Arrays `ARCHITECTURE.md` (alt) plante eine diskriminierte Union `Element = Wall | Door | Window | …`. Tatsächlich hält `Project` (`src/model/types.ts:2095`) **pro Bauteiltyp ein eigenes optionales Array**: `walls`, `ceilings?`, `roofs?`, `doors`, `openings?` (Fenster/Türen gehostet in Wänden, `kind:"window"|"door"`), `stairs?`, `rooms?`, `columns?`, `extrudedSolids?`, `drawings2d`, `context?` (Importe/Terrain), plus die Bibliotheks-/Typtabellen (`lineStyles`, `hatches`, `components`, `wallTypes`, `roofTypes?`, `doorTypes?`, …) und die Dokument-Ebene (`viewSnapshots?`, `layouts?`, `masterLayouts?`, …). Der Typ-Alias `Element` (types.ts:1601) existiert zwar noch, wird aber **nirgends** verwendet (Element-Baum/Selektion arbeiten direkt auf den typisierten Arrays). Praktisch funktioniert das gut (jeder Bauteiltyp hat sein eigenes, spezifisches Interface), ist aber eine bewusste Abweichung vom ursprünglichen Uniform-Union-Plan. ### 2.2 State — kein Zustand/Redux/Immer, sondern ein Eigenbau `docs/design/state-architecture.md` empfahl **Zustand**. Gebaut wurde stattdessen ein **abhängigkeitsfreier Store auf `useSyncExternalStore`** (`src/state/store.ts`, gleiches Muster wie `src/i18n`). `createStore()` komponiert Slice-Fabriken (`projectSlice` inkl. Undo/Redo, `historySlice`, `selectionSlice`, `viewSlice`, `layoutSlice`, `siteSlice`, `notifySlice`) über eine gemeinsame `RootState`. Funktioniert, aber: der geplante Folgeschritt „App.tsx wird dünne Shell, View-Routing nach `src/views/`, Kontextmenüs nach `src/menus/`" ist **nicht** passiert — `src/views/` und `src/menus/` existieren nicht, View-Umschaltung und Kontextmenü-Aufbau liegen weiterhin inline in `App.tsx` (7.130 Zeilen). Das ist der deutlichste Doku-vs-Code-Widerspruch im ganzen Repo (CONVENTIONS.md verlangt explizit das Gegenteil). ### 2.3 Rendering — drei 2D-Pfade, zwei 3D-Viewports **2D-Plan:** es gibt tatsächlich **drei** koexistierende Renderer, nicht einen: 1. `PlanView.tsx` (SVG) — Referenz-/Fallback-Pfad, bleibt IMMER im DOM für Hit-Testing/Grips, unabhängig davon was zeichnet. 2. `plan/glPlan/` — eigener TypeScript-WebGL2-Renderer (`glPlanCompile/-Render/ -Shaders/-Hatch.ts`). 3. `useWasmPlanRenderer.ts` → Rust-`render2d`-Crate (WGSL, nativ via wgpu, Web via WebGPU/WebGL2-Fallback, inkl. echtem Text-Rendering via `glyphon`). Beide GPU-Pfade fallen bei Initialisierungsfehler still auf SVG zurück. **3D:** ebenfalls zwei Viewports: `Viewport3D.tsx` (three.js, „Free"-Stufe) und `Wasm3DViewport.tsx` (Rust/wgpu „Nordstern", editierbar, **Default**). Ein Settings-Schalter wählt die Engine. ### 2.4 Schnitt/Section — NICHT über HLR, sondern eigene Rust-Pipeline `src/section/hlr.ts` + `occt.ts` (der ursprüngliche OpenCascade.js-HLR-Spike aus Phase 0) hat **keinen einzigen Aufrufer mehr** im gesamten `src/` — toter Code. Der tatsächliche, funktionierende Live-Schnitt läuft über einen völlig anderen, analytischen Mechanismus: `App.tsx` (`section3dCutId`/`section3dPlane`) → `Wasm3DViewport.tsx` (`section3d`-Prop → `setSectionPlane`) → `src-tauri/render3d/src/{section.rs, section_boolean.rs, section_fill.rs}`. Die Rust-Seite nutzt aus, dass jedes Bauteil ein Prisma mit konstantem Querschnitt ist — eine Schnittebene liefert dadurch immer ein achsparalleles Rechteck, nie ein Trapez; `section_boolean.rs` ist ein 1:1-Port von `toSection.ts::subtractDominantBands`, damit 2D-Plan-Schnitt und 3D-Live-Schnitt exakt übereinstimmen. Kein Worker, kein Comlink (beides war geplant, keines existiert) — läuft synchron/GPU-seitig. ### 2.5 Öffnungen als Löcher — echt, aber kein Mesh-Boolean Fenster/Türen schneiden echte achsparallele Rechteck-Löcher aus dem Wandkörper (`plan/toWalls3d.ts` `RHole`/`subtractSpans`, gespiegelt in `render3d/{mesh.rs,section.rs}`) — funktioniert, ist aber KEIN generisches Mesh-Boolean. Ein echtes CSG-Boolean existiert bereits (`trucksolid::boolean_mesh`, `csgrs`-basiert, 15 Rust-Tests) und wird von `src/engine/truckSolid.ts` für das Extrusions-Kommando genutzt — ist aber **nicht** an die Wand/Öffnungs-Pipeline angeschlossen (bestätigt: `booleanMesh` hat ausserhalb von `truckSolid.ts` keinen Aufrufer). ### 2.6 Rust-Workspace: sechs unabhängige Crates, nicht ein Workspace `src-tauri/Cargo.toml` bindet nur den Tauri-Host (`cad-tauri`) als Workspace- Mitglied; `render2d/render3d/geometry/kernel2d/trucksolid/dwgimport` sind **eigenständige Cargo-Packages**, die dem Host nur optional (Features `native2d`/`native3d`, standardmässig AUS) als Path-Dependency zugespielt werden. Jedes Crate muss headless (`cargo test`) UND per `wasm-pack --features web` bauen, ohne den Tauri-Toolchain-Zwang zu erben — bewusst so geschnitten. Geteilte Abhängigkeiten: `wgpu 29`/`naga 29` (render2d+render3d, versionsgekoppelt wegen `glyphon 0.11`), `truck-modeling`+`csgrs`(gepinnter Git-Rev)+`nalgebra` nur in `trucksolid`. ### 2.7 Zwei Desktop-Rahmen: Tauri (macOS) + Electron (Linux) Die App läuft plattformabhängig in **zwei verschiedenen nativen Rahmen** — das ist Absicht, kein Wildwuchs, und hängt an **WebGPU**: - **macOS → Tauri.** WKWebView unterstützt WebGPU, das die render2d/render3d- WASM-Engines brauchen. `src-tauri/tauri.conf.json` (Identifier `ch.dossier.cad`, eigene Titelleiste, `trafficLightPosition`) + `isTauriRuntime()`-Gates an 6+ Stellen in `App.tsx` + vier eigene native Zusatzfenster (`src/native/`: Resources, Settings, DrawingLevels, LayerSettings, ContextImport). - **Linux → Electron.** Tauris Linux-Webview **WebKitGTK unterstützt WebGPU nicht zuverlässig** → dort läuft die App über eine Electron/Chromium-Shell (`scripts/electron-main.cjs` + `electron-preload.cjs`, gestartet via `npm run electron`). Der Kommentar in `electron-main.cjs` sagt es explizit: „Ersetzt WebKitGTK durch Chromium, damit WebGPU zuverlässig läuft." Beide teilen sich **dieselbe** React-App und dieselbe randlose eigene Titelleiste; die Laufzeit erkennt den Host über `window.__TAURI__` (Tauri) bzw. `window.dossierWindow` (Electron, per `contextBridge` injiziert). Die Fenstersteuerung (`src/ui/WindowControls.tsx`) ist an beide Wege angebunden. Kein Rust-Backend nötig auf dem Electron-Pfad — `computeJoins` hat einen TS-Fallback (`src/compute/index.ts`). Electron ist also **kein** totes Gleis, sondern der aktive Linux-Zielrahmen. ## 3. Feature-Inventar (was tatsächlich funktioniert) ### Modell & Bauteile - Mehrschichtige Wände (`WallType.layers[]`) mit L-Eck-Gehrung UND Prioritäts-T-/X-Stössen (`joinPriority` am Component) — **fertig**, in 2D-Plan, 3D-Viewport UND 3D-Live-Schnitt konsistent (Rust-Port `section_boolean.rs`). - Parametrische Wände (`ParametricWall`: Grid/Modul/Sequenz/Referenzlinie/ bedingte Dicke) lösen sich zu konkreten `Wall[]` auf. - Decken (Slabs, `ceilings?`) mit Aussparungen, eigenem Typkatalog. - Türen/Fenster gehostet in Wänden, mit Rahmen/Zarge/Blockrahmen, Kämpfer, Oberlicht, Detailgrad grob/mittel/fein (2D UND 3D), Schwenkbogen; daneben existiert weiterhin ein **älteres, separates `Door[]`** neben `Opening[]` — laut PENDENZEN.md explizit als offene Doppelspur/Aufräum-Punkt vermerkt. - Treppen (gerade/L/Wendel), geschossübergreifend, 2D-Symbol mit Lauflinie/Pfeil. - Dächer (Flach/Pult/Sattel/Walm/Mansarde/Zelt) über Rechteck-Umriss, First/ Traufe/Grat im 2D-Plan. - Stützen (Column) mit Profilbibliothek (Quadrat/Rechteck/Rund/I/Rohr). - Räume (SIA-416: HNF/NNF/VF/FF/GF/AGF) mit automatischer Bilanz + CSV-Export, Raumstempel-Editor (Drag&Drop-Felder). - Extrudierte Volumenkörper (truck-Integration: konkave Profile, Verjüngung). - Kontext-Layer (Terrain-TIN, importierte Meshes, Konturen) — semantisch getrennt. ### Zeichnen & Bedienung - Rhino-artiges Kommandosystem (`commands/`): getippte Koordinaten (`5,3`/`r5,3`/`5<45`), Tab-Feld-Zyklus für Präzisionseingabe (`src/ui/CommandLine.tsx`), Alias/Autocomplete, ~25 Kommandos (wall, ceiling, opening, stair, column, roof, room, line/polyline/rect/circle/arc, text, move/mirror/copy/offset/trim/join, extrude, import, terrain, measure, Schnittlinie, Georef). - Snapping (Endpunkt/Mitte/Schnittpunkt/Lot/Raster/Ortho), Grips, Array, Trim/Split/Join, 2D-Booleans (Union/Subtract/Intersect via `polygon-clipping`). - Messwerkzeug (Polygonzug, Länge + Fläche). - Rich-Text-Annotationen (Bold/Kursiv/Hoch-/Tiefstellung). ### Darstellung / Ressourcen - Resource Manager: Line/Hatch/Component-Manager, Wand-/Decken-/Tür-/Fenster-/ Treppen-/Dach-Typeditoren — als eigenständiges natives Fenster (nicht als Dock-Panel). - Materialbibliothek: 13 fest gebündelte PBR-Starter (ambientCG, lokale Texturen) **plus** Live-Suche der kompletten ambientCG-Bibliothek (Auflösung 1K/2K/4K, on-demand Download+Entpacken via `jszip`, Proxy wegen CORS) — heute bereinigt (siehe Commit-Historie dieser Session). - Regelbasierte Overrides (Bedingung → Farbe/Strichstärke/Schraffur/Sichtbarkeit). - Detailgrad grob/mittel/fein je Bauteil + Dokument-Override. - Hell-/Dunkel-Theme, Akzentfarben. ### Pläne / Output - Ausschnitte (View-Snapshots: Kamera, Massstab, Detailgrad, Sichtbarkeiten, Override-Preset) in Ordnerstruktur. - Layout-Blätter (Plansätze): Papierformat/-grösse, mehrere Viewports pro Blatt, Masterlayout-Vererbung (Titelblock), Ordnerstruktur, freie 2D-Annotationen. - Vektor-Export: PDF (Einzelblatt UND **Mehrseiten pro Ordner**, `layoutPdf.ts::buildFolderPdf`), DXF, IFC4 (mit echten Fenster-/Tür-Löchern, deterministischen GUIDs), STL, OBJ, CSV-Bauteil-Schedule (volles Element-Set). - Kamera-Presets (Kardinal + Iso), Norden-Rotation. ### Import / Kontext - DXF (Konturen), DWG (`@mlightcad/libredwg-web`, WASM), `.lin`/`.pat`. - Swisstopo: swissBUILDINGS3D (radiusgenau zugeschnitten, nicht die ganze STAC-Kachel), swissALTI3D, SWISSIMAGE-Orthofoto-Draping, LV95↔WGS84, Georeferenzierung über EINEN Vermessungspunkt (E/N/H, `geoAnchor`). - OSM/Overpass-Kontextimport (7 Kategorien). - Terrain-Mesh-Generator. ### Desktop-Integration (Tauri) - Eigene randlose Fenster mit nativer Titelleiste (macOS-Ampel-Position). - Native Speichern/Öffnen-Dialoge (`plugin-fs`/`plugin-dialog`), eigenes `.obp`-Projektdateiformat. - OS-Level-Exklusiv-Lock gegen Doppelöffnen desselben Projekts (`fs4`-Crate). - Vier eigenständige native Zusatzfenster (Resources, Settings, DrawingLevels, LayerSettings, ContextImport) statt Overlay/Modal. - Native macOS-Menüleiste. - i18n de/en durchgängig, eigener `t()`-Mechanismus (kein i18next). ## 4. Mist-Liste — Befunde, Doku-Widersprüche, offene Fäden ### 4.1 Verwaiste WASM-Crates (gebaut, aber nirgends importiert) - **`src-tauri/geometry`** (1.057 LOC, 8 Tests) → `pkgGeometry` — **null** Importstellen in `src/`. Wand-Join-Mathe existiert redundant als TS (`src/model/joins.ts`) UND als Rust-Port, aber nur die TS-Version läuft. - **`src-tauri/dwgimport`** (284 LOC) → `pkgDwgImport` — **null** Importstellen; DWG-Import läuft stattdessen über `@mlightcad/libredwg-web` (npm-Paket). - **`src-tauri/kernel2d`** (3.383 LOC, 18 Tests) → `pkgKernel2d` — wird nur von einem Paritätstest (`kernel2d.parity.test.ts`) konsumiert, nicht produktiv. Die TS-Version `src/geometry/kernel2d.ts` (886 Zeilen) ist die tatsächlich laufende Implementierung. Laut PENDENZEN.md bewusst so belassen: ein Join-Benchmark zeigte WASM unter ~100 Wänden **langsamer** als die naive TS-Routine. Kein Bug, aber die drei Crates zusammen sind ~4.700 Zeilen Rust (+44 Tests), die aktuell nichts zur Laufzeit beitragen ausser einem Korrektheits-Cross-Check für kernel2d. **Empfehlung:** entweder (a) `geometry`- und `dwgimport`-Crate + ihre `build:*`-Scripts entfernen (kein Nutzen, nur Wartungslast), oder (b) explizit als „Referenzimplementierung/Zukunftsoption" in ARCHITECTURE.md dokumentieren, damit niemand sie für aktiv hält. ### 4.2 Toter Code - `src/section/hlr.ts` + `occt.ts` + `occt-wasm.d.ts` (473 LOC) — OCCT-WASM- HLR-Spike aus Phase 0, **keine Aufrufer mehr**. Ersetzt durch die analytische Rust-Schnitt-Pipeline (§2.4). `opencascade.js` bleibt als npm-Dependency bestehen, obwohl nur noch dieser tote Code sie importiert. - `src/export/planToPrintSvg.ts` — Kommentar im Code selbst sagt „ERSETZT durch `sceneToPrintSvg.ts`", ist aber noch im Baum. - `Element`-Typalias (`src/model/types.ts:1601`) — definiert, nirgends benutzt. ### 4.3 Das grösste Doku-vs-Code-Problem: App.tsx CONVENTIONS.md verlangt seit Tag 1 „App.tsx bleibt dünner Shell, keine Geschäftslogik". `docs/design/state-architecture.md` plante explizit die Extraktion nach `src/views/` (View-Routing) und `src/menus/` (Kontextmenü-Aufbau). Beide Ordner **existieren nicht**. `App.tsx` ist mit **7.130 Zeilen** die grösste Einzeldatei des Projekts und enthält weiterhin View-Umschaltung und Kontextmenü-Konstruktion inline. Das ist der genaue „God-Component"-Zustand, den die Doku von Anfang an vermeiden wollte. ### 4.4 Bekannte Doppelspur: `Door[]` vs. `Opening[]` `Project` führt sowohl ein älteres `doors: Door[]` als auch das neuere, allgemeinere `openings?: Opening[]` (`kind:"door"|"window"`). Laut PENDENZEN.md ist das erkannt und als Aufräum-Punkt vorgemerkt, aber nicht konsolidiert. ### 4.5 Doku-Widersprüche (README/ARCHITECTURE/CONVENTIONS vs. Realität) | Dokument | Behauptung | Realität | |---|---|---| | README.md | Shell = Electron, Tauri „ausrangiert" | Falsch andersrum gedacht: **beide** sind aktiv — Tauri auf macOS (WKWebView+WebGPU), Electron auf Linux (WebKitGTK kann kein WebGPU); siehe §2.7 | | README.md | „HLR noch nicht ans UI verdrahtet, Views sind Stubs" | Der OCCT-HLR-Pfad stimmt (tot), aber Schnitte/Ansichten funktionieren real über eine andere, eigene Rust-Pipeline | | README.md | „Prioritäts-T-/X-Stösse … Risiko #1" unter „bewusst offen" | Seit 7.7. erledigt, inkl. Rust-Port | | README.md | „PDF-Export ist noch single-sheet" | `layoutPdf.ts::buildFolderPdf` erzeugt echte Mehrseiten-PDFs pro Ordner | | README.md | Engine-Liste nennt nur render2d/render3d | Es gibt 6 Rust-Crates (+kernel2d/geometry/trucksolid/dwgimport) | | CONVENTIONS.md | Struktur-Ziel `src/views/`, `src/menus/` | Existieren nicht; Logik liegt in `App.tsx` | | CONVENTIONS.md | Dev-Port 5173 | Tatsächlich 5187 (`vite.config.ts`, `tauri.conf.json`) | | ARCHITECTURE.md | Ziel-Struktur `store/`, `sheets/`, `workers/geometry.worker.ts` (Comlink) | Tatsächlich `state/`, `panels/layoutModel.ts`; kein Worker/Comlink irgendwo im Projekt | | ARCHITECTURE.md | HLR „im Web Worker (Comlink)" | Kein Comlink im Projekt; Schnitt läuft synchron GPU-seitig in Rust | | HANDOVER.md | Neuester Block: „Stand 2026-07-09" | Jüngster Commit + PENDENZEN.md sind vom 17.–20.7. — 8+ Tage/mehrere Sessions veraltet | ### 4.6 Codequalität — besser als der Tempo vermuten lässt Trotz 3 Wochen / 362 Commits über viele autonome Sessions: **keine** FIXME/HACK/ XXX-Marker im ganzen Projekt; nur 2 TODOs (beide bekannt/harmlos: Geländer in `Viewport3D.tsx:2649`, Kanten-Tiefe in `toSection.ts:1093`); `eslint-disable` fast ausschliesslich `react-hooks/exhaustive-deps` (bewusst); keine `_v2`/`_old`/`_backup`-Dateileichen. Die eigentliche Aufgabenliste lebt diszipliniert in PENDENZEN.md statt in Code-Kommentaren verstreut — gesünder als der Durchschnitt für dieses Bau-Tempo. ### 4.7 Genuine offene Punkte (Auszug aus PENDENZEN.md, Details dort) - Geo-Block: Layer-Zuordnung für importierte Gebäude/Terrain, reale Höhen + Projekt-müM-Draping, SWISSIMAGE-Draping. - 3D-Feinschliff: Fensterrahmen-Ecken bei „fein" überlappen (kein Gehrungs- Union), Dach-First/Grat hat unverschmolzene Dreiecke, unerklärte Vertikalstreifen auf oberen Wandflächen (undiagnostiziert). - truck-Boolean nicht an die Wand/Öffnungs-Pipeline angeschlossen (Scope- Entscheid mit Nutzer ausstehend). - Feld-Controller (Tab-Zyklus) fehlt für Body-Move und für 3D-Griffe generell (nur 2D-Einzelpunkt-Drag hat ihn); 3D-Griff-Drag hat gar kein Snapping. - `make2D`-Kommando (3D→flacher 2D-Plan mit Füllungen) ungebaut. - Ribbon-3D-Tab leer; einige Punkte visuell noch nicht in Tauri abgenommen (u. a. Materialfarben-Textur-Array, Schraffur-Schnittfüllung — laut PENDENZEN als „[~] implementiert, aber unverifiziert" markiert). - DWG/DXF-Domänen-Mapping (Entitäten → Wände/Öffnungen) unbegonnen; DWG-Schreiben fehlt (Lesen über `libredwg-web` vorhanden). - Teamwork/Kollaboration (Supabase) bewusst nicht begonnen, gilt als späte Phase. ## 5. Vergleich: Tag-1-Vision vs. heute | Vision (28./29.6.) | Heute | |---|---| | Three.js als einziger 3D-Renderer, OpenCascade.js für Booleans/HLR | Eigene Rust/WASM-Engines („Nordstern") für 2D+3D; three.js nur noch „Free"-Fallback; OCCT-Pfad tot | | Ein `Element[]`-Union | Typisierte Arrays pro Bauteiltyp auf `Project` | | Zustand-Store | Eigener `useSyncExternalStore`-Store | | Web Worker + Comlink für HLR | Synchrone, analytische Rust-GPU-Schnitt-Pipeline | | „Booleans: Entscheidung in Phase 0" | Trucksolid/csgrs-CSG existiert, ist getestet, aber nicht an Wände angeschlossen | | web-ifc für IFC | Eigener IFC4-Writer (`exportIfc.ts`) | | Phase 2–5 grösstenteils „Backlog" | Treppen, Dächer, Stützen, SIA-416, Swisstopo, OSM, Kamera-Presets, Layouts, Ausschnitte, Terrain — alles bereits gebaut | Kurz: die **Prinzipien** (ein Modell, viele Ableitungen; Darstellung erst beim Rendern; keine Cache-Stale-Bugs) haben gehalten und wurden korrekt umgesetzt. Die **konkreten Technologie-Entscheidungen** sind fast durchgängig anders gelaufen als geplant — meist zugunsten einer eigenen, schnelleren Rust/WASM- Lösung statt einer Drittbibliothek.