---
name: project_tauri_loader
description: "Tauri-Desktop-Loader (Win/Mac/Linux) — Architektur, Stand, offene Punkte (2026-06-03)"
metadata: 
  node_type: memory
  type: project
  originSessionId: c4e04d11-9b40-4c6a-9333-ce3bbf949ba2
---

**Branch `feature/tauri-loader`** (NICHT auf development; lokal committet, **Push macht Marcus** —
Sandbox hat keine GitHub-Creds). Ziel: Desktop-App als fixe, einmal signierte Exe + lokal
austauschbare ("swapbare") Web-Assets, offline-fähig, Win/Mac/Linux.

**Architektur:**
- `apps/plato-customer-desktop/src-tauri` (Tauri v2): Loader serviert Assets via `platoasset://`
  aus **`~/.plato/app`**, prüft Manifest-Signatur (ed25519, Public Key in `loader.rs`) + je Datei
  den Hash → fail closed. Asset-Bundle (FE-Build + `manifest.json`+`manifest.sig`) signiert mit
  `tools/loader/sign-assets.mjs` (Key `loader-signing-key.pem`, gitignored).
- **Daten-Root `~/.plato`** (Schwester von `app/`): `plato5/`, `sync/`, `settings/`, `customer/`.
  FE-Storage im Tauri-Zweig über `store_fs.rs` (statt File-System-Access-API, die im WebView fehlt).
- **Auth (cross-origin, kein Cookie):** OIDC bleibt serverseitig; BE stellt nach Login ein
  HMAC-Token (`TokenService`) aus, Guard akzeptiert `Authorization: Bearer`. Desktop-Login öffnet
  `<BE>/auth/login` im Tauri-Fenster (`desktop_login.rs`), fängt nach Callback die saubere
  `/`-Landung ab → `/auth/desktop` → Token. `authToken` (localStorage) + axios-Interceptor.
- **Endpoint-Picker** beim Start (DEV ocp-dev01 / localhost:3000); Token wird bei Wechsel verworfen.
- **Migration** im Desktop: `migrateIfPresent` liest `plato5/crm.sqlite` via `tauri-plugin-fs`
  (Binär), lädt token-auth zum BE.

**Stand:** Login-Flow gegen localhost verifiziert (inkl. 2FA → Token → UI mit Daten). BE-Build/
FE-Build/Rust-Build grün. Migration gebaut, **GUI noch nicht getestet**.

**Lokales Setup:** Rust via rustup installiert; WebKitGTK-Deps via `scripts/setup-tauri-linux-deps.sh`
(Fedora, sudo). Build: `cargo build` in src-tauri; FE→app: `npx nx build plato-customer-fe &&
node tools/loader/sign-assets.mjs dist/apps/plato-customer-fe loader-signing-key.pem &&
cp -r dist/apps/plato-customer-fe/. ~/.plato/app/`.

**Offen:** (1) Branch pushen (Marcus). (2) Migration-GUI testen. (3) BE auf DEV deployen
(branch-deploy) — Auth-Änderung vorher reviewen, `AUTH_TOKEN_SECRET` auf DEV setzen, CORS ist
`origin:true`. (4) Exe-Verteilung via `tauri-release`-CI + Code-Signing (intern oder Azure Trusted
Signing). (5) `crm.sqlite` ggf. in .gitignore.

⚠️ **Wichtig (während der Desktop-Arbeit gelöscht):** Ein `rm -rf ~/.plato/*` hat lokale Daten
(plato5/sync/settings/customer) gelöscht — daher liegt die crm.sqlite neu in `~/.plato/plato5`.
Beim Asset-Tausch NIE den ganzen Ordner leeren, nur `app/`. Siehe [[project_test_infra]] (deleteAll
ist bewusst global) und [[project_login_loop_rootcause]].
