- Auto-Recovery in adapter.js: wenn Cloud-Modus gesetzt + lokale Daten vorhanden + keine Cloud-Session → Cloud-Konfiguration wird beim nächsten App-Start automatisch zurückgenommen. Marker rapport_080_recovery verhindert wiederholte Auslösung. - UpdateNotifier wird in allen Pre-Login-Screens gerendert (BackendChoice, Setup, MigrationScreen, CloudSetup, Login) — so kann ein hängender Wizard sich via Auto-Update selbst befreien. - Tauri-Builds ignorieren VITE_SUPABASE_URL aus dem Build. Desktop-User geben die Server-URL immer aktiv im Login ein, statt eine irrelevante Default-IP vorgesetzt zu bekommen. - Anon-Key bleibt aus dem Build (kein Geheimnis, pro Cloud-Instanz fix). - BackendChoice zeigt nur dann eine vorkonfigurierte URL, wenn nicht in Tauri. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Rapport
Studio-Management für Architekturbüros. Tauri 2 + React 19 + Vite. Läuft als Desktop-App (macOS/Windows/Linux) oder als Web-App im Browser.
Daten liegen wahlweise:
- Lokal im Browser-
localStorage— Solo-Setup, kein Server nötig - Cloud auf einer eigenen Supabase-Instanz (z.B. Mac Mini im Büro) — Multi-User mit Realtime-Sync, Multi-Studio, Mitarbeiter-Einladung
Der Modus wird beim ersten Öffnen gewählt und kann später umgeschaltet werden.
Voraussetzungen
| Tool | Version |
|---|---|
| Node.js | ≥ 20 (für Vite 8) |
| npm | ≥ 10 |
| Rust toolchain | ≥ 1.77.2 (rustup) |
| Plattform-Build-Tools | siehe Tauri Prerequisites |
Plattform-spezifisch zusätzlich:
- macOS: Xcode Command Line Tools (
xcode-select --install) - Windows: Microsoft C++ Build Tools, WebView2
- Linux:
webkit2gtk-4.1,librsvg2-dev,libayatana-appindicator3-dev,build-essential
Setup
git clone http://192.168.1.247:3000/karim/RAPPORT.git
cd RAPPORT
npm install
Entwicklung
Web-Modus (HMR im Browser, schnellster Iteration-Loop für UI-Arbeit):
npm run dev # http://localhost:3000
Native Window (Tauri-Fenster mit echter Desktop-Integration):
npx tauri dev
Lint:
npm run lint
Produktion-Build
Nur Frontend (statische Files für Web-Deployment):
npm run build # → dist/
Desktop-Bundle (vollständiges Installer-Paket):
npx tauri build
Output landet in src-tauri/target/release/bundle/:
| Plattform | Verzeichnis |
|---|---|
| macOS | dmg/ und macos/ (.app) |
| Windows | msi/ (WiX) und nsis/ |
| Linux | deb/, appimage/, rpm/ |
Bundle-Name und -Version stammen aus src-tauri/tauri.conf.json (productName, version).
Versionierung
Beim Anheben der Version müssen drei Stellen synchron bleiben:
package.json—versionsrc-tauri/tauri.conf.json—versionsrc-tauri/Cargo.toml—version
Zusätzlich im UI-Changelog: src/App.jsx — Konstante CHANGELOGS, sowie version-Prop am <Login> und localStorage-Key rapport_changelog_seen.
Projektstruktur
.
├── src/ Frontend (React)
│ ├── App.jsx Root-Komponente, Routing, Auth-State, Cloud-Resume
│ ├── main.jsx React-Mount
│ ├── constants.js Default-Daten, SIA-Phasen, Statusfarben
│ ├── utils.js Hashing, Sanitizer, Formatter, Berechnungen
│ ├── storage/ Storage-Adapter (Local + Supabase) + Migrations
│ ├── components/UI.jsx Wiederverwendbare UI-Bausteine
│ ├── views/ Module (Dashboard, Time, Invoices, Setup, CloudSetup, …)
│ └── print/ Print-Komponenten (PDF/QR-Rechnung)
├── src-tauri/ Tauri-Wrapper (Rust)
│ ├── src/ main.rs + lib.rs
│ ├── capabilities/ Permission-Definitionen
│ ├── icons/ App-Icons aller Plattformen
│ └── tauri.conf.json Window, Bundle, CSP
├── supabase/ Cloud-Schema
│ ├── config.toml lokale Supabase-Konfiguration
│ └── migrations/ SQL-Migrations (~10 Files, multi-tenant + RLS)
├── deploy/ Static-Hosting der Web-App
│ ├── docker-compose.yml nginx-Container, liefert dist/ aus
│ └── nginx.conf SPA-Routing
├── public/ Statische Assets (favicon, icons.svg)
├── index.html Vite-Entry
├── DEPLOY.md Deploy-Anleitung (LAN + extern via NPM)
└── vite.config.js
Daten & Persistenz
Rapport hat zwei Storage-Backends mit einheitlicher Schnittstelle in src/storage/adapter.js:
Lokal-Modus (Standard, kein Server)
- Alles liegt unter dem Key
studio_data_v1inlocalStorage. - Beim ersten Start: BackendChoice (
Lokal / Cloud) → bei Lokal-Wahl klassischer Setup-Assistent (src/views/Setup.jsx). - Backup/Restore: Einstellungen → Daten exportieren / importieren als JSON.
Cloud-Modus (eigener Server)
- Postgres-Schema mit ~30 Tabellen, multi-tenant via
studio_id+ Row-Level-Security (siehesupabase/migrations/). - Realtime-Sync: Änderungen im Browser A erscheinen ohne Reload in Browser B.
- Multi-Studio: ein Account kann mehrere Studios verwalten, Personen zwischen Studios teilen.
- Mitarbeiter-Einladung als Admin-Aktion in den Settings — keine Self-Registrierung.
- Passwort-Reset via Email (
/auth/v1/recover). - Cloud-Setup mit Supabase auf einem Mac Mini / Docker-Host: siehe DEPLOY.md.
Erst-Einrichtung einer leeren Cloud-Instanz: 3-Schritt-Wizard (src/views/CloudSetup.jsx) erscheint automatisch, wenn der Browser auf eine Instanz ohne Studios trifft.
Sicherheit
- Lokal-Modus Passwörter: PBKDF2-SHA-256 mit 100 000 Iterationen und zufälligem Salt; Verifikation in konstanter Zeit. Legacy-Klartext-Passwörter werden beim ersten erfolgreichen Login transparent zu Hashes migriert.
- Cloud-Modus Auth: Supabase Auth (bcrypt-Passwörter, JWT-Sessions), separat von der Lokal-User-Tabelle.
- Row-Level-Security: jede Cloud-Datentabelle hat eine Policy
is_studio_member(studio_id)— DB-Ebene garantiert Tenant-Trennung. - Login-Schutz: 5 Fehlversuche → 60 s Sperre pro Tab (
sessionStorage). - HTML-Sanitizer: Brieftexte werden vor Print/Render durch eine Allowlist gefiltert (
sanitizeHtmlinsrc/utils.js) — keinjavascript:, keinon*-Handler. - Datenexport: Legacy-Klartext-Passwörter werden beim Export gestrippt; nur Hashes verlassen die App.
- CSP: definiert in
src-tauri/tauri.conf.json—default-src 'self'plus Google-Fonts-Allowlist. - Tauri-Capabilities: minimal (
core:default+core:webview:allow-print) — siehesrc-tauri/capabilities/default.json.
Release-Workflow
# 1. Versionen anheben (package.json, tauri.conf.json, Cargo.toml)
# 2. Changelog in src/App.jsx ergänzen
# 3. Commit + Tag
git tag -a 0.7.0 -m "Rapport 0.7" # ohne v-Prefix — latest.json verlinkt /releases/download/<VERSION>/
git push origin main 0.7.0
# 4. Bundle bauen
npx tauri build
# 5. Bundle als Release-Asset auf Gitea anhängen
# (nicht ins Repo committen)