# Architektur-Pivot: Tauri + Rust-Backend (2026-07-01)

## Entscheidung

**Alte Welt:** Browser-CAD (React/Vite + WebGL/three.js)  
**Neue Welt:** Desktop Tauri-App (React/Vite Frontend + Rust-Backend + **wgpu 3D-Rendering**)

**Grund:** Komplexe Möbel mit vielen Polygonen (100k+) + mehrere parallele rechenintensive Ops → WebGL/three.js wird zum Bottleneck. **wgpu** (low-level GPU-API auf Vulkan/Metal/DX12) + Rust-Compute skaliert native.

**Scope:** Desktop-only Release (Milestone 1). WASM-Fallback für Browser später wenn gebraucht.

---

## Post-Migration Stack

### Frontend (React/Vite — Komponenten + State, unverändert)

```
src/
  App.tsx                    ← Shell-Komponente
  compute/index.ts           ← Compute-Boundary (neu)
  model/types.ts             ← Semantisches Modell
  commands/                  ← Befehlssystem
  panels/                    ← UI-Panels
  plan/PlanView.tsx          ← 2D-SVG-Rendering
  viewport/Viewport3D.tsx    ← three.js 3D-Display
  ui/                        ← Topbar, Dialogs, etc.
  state/                     ← Redux-Slices (project, selection, view, layout)
  ...
```

**Rolle:** User-Input-Handling, 2D/3D-Darstellung (Display-Layer), State-Management.

### Backend (Rust/Tauri — neu)

```
src-tauri/
  src/
    main.rs                  ← Tauri window + invoke-handler registration
    geometry.rs              ← compute_joins(), kernel2d(), etc.
    parsers/
      dwg.rs                 ← DXF/DWG-Geometrie-Parsing
      dxf.rs
    sia/
      room_detection.rs      ← detectRooms() (SIA-416)
    ...
  Cargo.toml                 ← Dependencies (serde, tauri, …)
```

**Rolle:** Rechenintensive Ops, Geometrie-Kernel, Parsing, SIA-Raumerkennung.

### IPC: Tauri invoke (async, serde)

```typescript
// Frontend ruft Rust auf
const result = await invoke<JoinInfo[]>('compute_joins', { walls, joints });

// Rust bearbeitet + serialisiert Ergebnis
#[tauri::command]
async fn compute_joins(input: JoinInput) -> Result<JoinOutput, String> {
  geometry::compute_joins(input).map_err(|e| e.to_string())
}
```

---

## Compute-Boundary (Key Design)

**Neue Datei:** `src/compute/index.ts` — einziger Eingang für rechenintensive Ops.

```typescript
// Beispiel-Schnittstellen
export async function computeJoins(walls: Wall[], joints: Array<[number, number]>): Promise<JoinInfo[]> { … }
export async function computeKernel2D(op: 'offset'|'trim', geom: Polyline, …): Promise<Polyline[]> { … }
export async function detectRooms(…): Promise<Room[]> { … }
export async function parseShapeFromDwg(…): Promise<DwgGeometry> { … }
```

**Hinter der Boundary:**
1. Versuche Tauri invoke zu Rust (`#[tauri::command]`)
2. Fallback auf lokale TS-Impl wenn Rust nicht verfügbar (während Migration)

**Effekt:** Aufrufort im Code bleibt stabil; Caller sieht nicht, ob Op schon in Rust ist oder noch TS.

**Migrationsfluss:**
```
1. TS-Impl existiert (z.B. src/model/joins.ts)
2. Neue Op in Compute-Boundary mit Invoke+Fallback
3. Parallel: Rust-Impl in src-tauri/src/geometry.rs
4. Tests: Rust-Output == TS-Output (Parität)
5. TS-Impl bleibt (Fallback, wird nicht entfernt bis Rust stable)
6. Eventuell: TS-Impl löschen wenn Rust bewährt
```

---

## Dev-Workflow (post-Tauri)

### Development

```bash
# Terminal 1: Vite dev-server
npm run dev  # localhost:5173

# Terminal 2: Tauri dev
npm run tauri:dev  # öffnet Tauri-Fenster, zeigt auf localhost:5173
                    # Rust hot-reload + TS hot-reload gleichzeitig
```

**Voraussetzungen:**
- Node.js + npm (wie heute)
- Rust + Cargo (neu)
- Tauri CLI: `npm install -D @tauri-apps/cli`

### Build

```bash
# Single command
npm run tauri:build

# Erzeugt: 
# - Windows: src-tauri/target/release/cad.exe
# - macOS: src-tauri/target/release/bundle/macos/cad.app
# - Linux: src-tauri/target/release/bundle/deb/cad_*.deb (oder Flatpak)
```

### Testing

```bash
# Rust-Unit-Tests
cargo test  # in src-tauri/

# TS-Tests (unverändert)
npm run test

# Integration-Test: App starten + Aktion prüfen
npm run tauri:dev  # manuell testen oder Puppeteer-Probe erweitern
```

---

## GPU-Strategy (für später)

**Milestone 1 (jetzt):** CPU-Ops in Rust (kernel2d, joins, parsing, SIA).

**Milestone 2 (später):** GPU-Compute via wgpu
- Tauri + wgpu Renderer (optional, nicht erforderlich)
- ODER drei.js bleibt, Rust handelt CPU-Ops, three.js handelt Display
- GPU-Heavy-Ops (z.B. große Boolean-Operationen) können in wgpu laufen, aber MVP braucht das nicht

**Aktueller Plan:** three.js bleibt für 3D-Display (skaliert ausreichend für Möbel-Geometrie mit Instancing + LOD).

---

## Migration Strategy: Ops nach Priorisierung

**Phase 1 (aktuell — Tauri-Shell + Proof-of-Concept):**
- [ ] `computeJoins` (Wand-Eckverbindungen) → Rust
  - Gründe: klein, häufig, zeigt invoke-Flow

**Phase 2 (nächst):**
- [ ] `kernel2d` (Offset/Trim/Extend/Fillet) → Rust
  - Gründe: Rechenlast ⭐⭐, Frequenz hoch
- [ ] DXF/DWG-Parser → Rust (Geometrie-Extraktion)
  - Gründe: Rechenlast ⭐⭐, Frequenz mittel (Import-Dialog)

**Phase 3 (später):**
- [ ] `detectRooms` (SIA-416 Raumerkennung) → Rust
  - Gründe: Rechenlast ⭐, async-freundlich
- [ ] `booleanOps` (Union/Differenz/Schnitt) → Rust
  - Gründe: Rechenlast ⭐⭐, Frequenz gering (ad-hoc)

---

## Folgen für bestehenden Code

### Was ändert sich NICHT

- `src/model/types.ts` — semantisches Modell bleibt in TS (Frontend kennt es)
- `src/state/` — Redux-Store unverändert
- `src/ui/` — Komponenten unverändert
- `src/plan/PlanView.tsx` — SVG-Rendering unverändert
- `src/viewport/Viewport3D.tsx` — three.js-Rendering unverändert
- `src/commands/` — Befehlssystem unverändert

### Was ändert sich

- **Neue `src/compute/index.ts`** — alle rechenintensiven Ops laufen durch hier
- **Neue `src-tauri/`** — Rust-Backend
- **Vite-Config:** Tauri plugin hinzufügen
- **Package.json:** tauri scripts hinzufügen
- **Build-Prozess:** `npm run tauri:build` statt `npm run build`

### Was wird migriert (schrittweise)

- `src/model/joins.ts` → `src-tauri/src/geometry.rs` (Phase 1)
- `src/geometry/kernel2d.ts` → `src-tauri/src/geometry.rs` (Phase 2)
- `src/io/{dxfParser, dwgParser}.ts` → `src-tauri/src/parsers/` (Phase 2)
- `src/geometry/{roomArea, roomBoundary}.ts` → `src-tauri/src/sia/room_detection.rs` (Phase 3)
- `src/editors/booleanOps.ts` → `src-tauri/src/geometry.rs` (Phase 3)

**Wichtig:** TS-Versionen bleiben als Fallback (nicht gelöscht).

---

## Distribution (später)

### Desktop Binaries (post-Tauri)

- **Windows:** `.exe` (standalone executable)
- **macOS:** `.app` bundle (code-signed)
- **Linux:** `.deb` package ODER **Flatpak** (preferred)
  - Flatpak = moderne WebKitGTK6 immer dabei, unabhängig von Distro-Alter

### Browser (wenn gebraucht)

- **WASM-Fallback** für `src/compute/` Ops (Rust → WASM via wasm-bindgen)
- Later-phase feature, nicht Milestone 1

---

## Technische Details

### Serialisierung (TS ↔ Rust)

**serde + serde_json** für Geometrie-Typen:

```rust
// Rust
#[derive(Serialize, Deserialize)]
pub struct Vec2 { pub x: f64, pub y: f64 }

#[derive(Serialize, Deserialize)]
pub struct Wall {
    pub id: String,
    pub start: Vec2,
    pub end: Vec2,
    // …
}
```

```typescript
// TS (type-safe invoke)
interface Vec2 { x: number; y: number }
interface Wall { id: string; start: Vec2; end: Vec2; /* … */ }

await invoke<JoinInfo[]>('compute_joins', { walls: Wall[] })
```

### Tauri Security (default)

- Invoke-Handler sind Rust-side validiert
- Whitelist-Makro (`#[tauri::command]`) registered nur explizit erlaubte Functions
- CORS/CSP Policy default secure
- Keine arbitrary-Script-Execution (native app)

---

## Abhängigkeiten (neu post-Tauri)

### Frontend (npm)
- Bestehende: react, vite, three.js, redux, etc.
- Neu: `@tauri-apps/api` (JS-SDK für invoke)
- Optional später: `@tauri-apps/cli` dev-dependency (bereits in package.json)

### Backend (Cargo)
```toml
[dependencies]
tauri = { version = "2", features = ["webkit2gtk-6.0"] }  # GTK4
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
# später: wgpu, delaunator, opencascade-sys, etc.
```

### System
- Rust 1.70+
- GTK4 dev libraries (Linux only, auto-handled by Tauri)
- Xcode Command Line Tools (macOS, auto-checked)

---

## Next Steps (Koordination)

**Aufgabe für nächste Phase:**
→ Siehe `docs/design/tauri-migration-plan.md` (Schritt-für-Schritt, vier parallele Agents)

**HANDOVER.md:** wird aktualisiert nach Tauri-Shell stabil.

---

## FAQ

**Q: Läuft die App noch im Browser?**  
A: Nein (Milestone 1). Desktop-only. WASM-Fallback für Browser später wenn gebraucht.

**Q: Was passiert mit dem existing TS-Code?**  
A: Bleibt unverändert (außer neue Compute-Boundary). TS-Implementierungen = Fallback bis Rust stabil.

**Q: Muss ich Rust können um das Projekt zu verstehen?**  
A: Nein. Frontend bleibt React/TS. Rust ist "blackbox" hinter invoke. Aber bei Rust-Bugs muss man rein.

**Q: Wann ist Tauri-Shell fertig?**  
A: Nach den vier Agents (Schritt 1–4 in tauri-migration-plan.md), ~1–2 Wochen.

**Q: Kann ich lokal testen?**  
A: Ja, `npm run tauri:dev` öffnet lokale App. Alles wie heute, nur Rust hinten dran.
