Files
tessera-ctl/.planning/phases/18-desktop-client-fertigstellen/18-04-SUMMARY.md
T

172 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
phase: 18-desktop-client-fertigstellen
plan: 04
subsystem: infra
tags: [tauri, rust, desktop-client, opener-plugin, autostart]
# Dependency graph
requires:
- phase: 18-desktop-client-fertigstellen (Plan 01)
provides: "GET /desktop/latest (@Public), DesktopLatestResponse-Form, Basislinie 1.1.0"
- phase: 18-desktop-client-fertigstellen (Plan 03)
provides: "Route /settings/general/desktop, GET /desktop/latest ueber /api-proxy/* im Web-Container"
provides:
- "Rust-Kommandos check_server/save_server_url fuer die Erststart-Seite (kein Modul-Import mehr)"
- "Versionspruefung gegen /api-proxy/desktop/latest mit Benachrichtigung + Tray-Update-Eintrag"
- "Tray-Menue: Öffnen · Update herunterladen · Autostart-Haken · Beenden, echte Umlaute"
- "Echtes App-Icon (Tessera-Zeichen) in allen Bundle-Groessen"
- "Lokal gebautes AppImage (Tessera-1.1.0.AppImage) als D-16-Beweis"
affects: [18-05-windows-cross-bau-pipeline-beweis, 18-06-freigabe-release-anhang]
actuals:
tokens: 4547
tasks: 2
commits: 2
plan_head_before: 82312ef691c86dedd08f3c71225d3b8be63630df
tech-stack:
added:
- "tauri-plugin-opener 2.5.5 (offizielles Tauri-Plugin, Legitimitaet in 18-RESEARCH.md geprueft: OK)"
patterns:
- "api_url(server, path) als einzige Stelle, die den Next.js-Rewrite-Praefix /api-proxy kennt — alle Rust-seitigen API-Aufrufe (check_server, Versionspruefung) laufen ausschliesslich darueber"
- "Erststart-Seite spricht nur noch ueber window.__TAURI__.core.invoke() mit Rust-Kommandos statt ueber einen ES-Modul-Import eines Tauri-Plugins — vermeidet den 'Failed to resolve module specifier'-Fehler im gebauten Client (kein Bundler/keine Importmap vorhanden)"
key-files:
created: []
modified:
- apps/desktop/src-tauri/src/lib.rs
- apps/desktop/src-tauri/Cargo.toml
- apps/desktop/src-tauri/Cargo.lock
- apps/desktop/src-tauri/capabilities/default.json
- apps/desktop/src-tauri/tauri.conf.json
- apps/desktop/src/setup.html
- apps/desktop/src-tauri/icons/icon.png
- apps/desktop/src-tauri/icons/icon.ico
- apps/desktop/src-tauri/icons/128x128.png
- apps/desktop/src-tauri/icons/128x128@2x.png
- apps/desktop/src-tauri/icons/32x32.png
key-decisions:
- "cargo add tauri-plugin-opener@2 ausgefuehrt statt Cargo.toml/Cargo.lock von Hand zu pflegen — Cargo.lock bleibt damit fuer den echten Dependency-Graphen konsistent (Cargo hat zusaetzlich open, is-docker, is-wsl als transitive Abhaengigkeiten des Plugins aufgeloest)."
- "Autostart-Umschaltung setzt den Haken im Fehlerfall bewusst auf den vor dem Klick gemessenen Ist-Zustand zurueck (set_checked(currently_on) statt eines optimistischen Toggles), damit der Haken nie eine falsche Systemwahrheit anzeigt, wenn enable()/disable() fehlschlaegt."
- "Versionspruefung liest die Zieladresse jetzt ausschliesslich ueber die neue api_url()-Hilfsfunktion, damit /health/version (im Kommando check_server) und /desktop/latest (im Setup-Block) denselben Rewrite-Praefix garantiert konsistent verwenden."
patterns-established: []
requirements-completed: [DESK-01, DESK-02, DESK-05]
coverage:
- id: D1
description: "Versionspruefung gegen /api-proxy/desktop/latest mit Benachrichtigung 'Neue Version X.Y.Z verfuegbar' und freigeschaltetem, umbenanntem Tray-Eintrag 'Update herunterladen', der die Einstellungsseite im Systembrowser oeffnet"
requirement: "DESK-05"
verification:
- kind: other
ref: "grep-Batterie (fn api_url, /desktop/latest, settings/general/desktop, tauri_plugin_opener::init()) + cargo check/cargo clippy gruen"
status: pass
human_judgment: true
rationale: "Das tatsaechliche Ausloesen der Benachrichtigung und das Umschalten des Tray-Eintrags laesst sich nur gegen einen laufenden Server mit abweichender Version und einer grafischen Sitzung beobachten — beides stand in dieser Ausfuehrungsumgebung nicht zur Verfuegung (kopflos, kein Display). Die Bedienprobe macht der Nutzer laut Plan-Verifikation Punkt 4 in 18-06."
- id: D2
description: "Erststart-Seite prueft die Adresse ueber das Rust-Kommando check_server (kein Modul-Import mehr), speichert sie ueber save_server_url und fuehrt zur Tessera-Anmeldung; Sie-Form, Tessera-Farben/-Zeichen, kein vorbelegter Wert"
requirement: "DESK-02"
verification:
- kind: other
ref: "grep-Batterie (SETUP-OK: __TAURI__.core, invoke('check_server'/'save_server_url'), kein import, kein unpkg.com, keine vorbelegte Adresse, Label vorhanden)"
status: pass
human_judgment: true
rationale: "Der volle Ablauf (Adresse eingeben, echten Server erreichen, zur Anmeldeseite navigieren) braucht ein gestartetes AppImage mit grafischer Sitzung und einen laufenden Tessera-Server — nicht Teil dieses Plans (kein Pflichtschritt laut Action-Abschnitt), Bedienprobe folgt in 18-06."
- id: D3
description: "Tray-Menue in der Reihenfolge Öffnen · Update herunterladen · Autostart-Haken (Windows: 'Mit Windows starten', sonst 'Beim Anmelden starten') · Beenden, mit echten Umlauten; Autostart-Haken spiegelt beim Start den Systemzustand"
requirement: "DESK-05"
verification:
- kind: other
ref: "grep-Batterie (\"Öffnen\", \"Mit Windows starten\", CheckMenuItemBuilder::with_id(\"autostart\") je genau 1 Treffer) + cargo check/cargo clippy gruen"
status: pass
human_judgment: true
rationale: "Die sichtbare Tray-Darstellung (Reihenfolge, Umlaute im echten Rendering, Haken-Zustand) laesst sich nur in einer grafischen Sitzung mit laufender App pruefen, nicht headless. Bedienprobe folgt in 18-06."
- id: D4
description: "Client traegt das Tessera-Zeichen als App-/Fenster-Icon in allen Bundle-Groessen (512 PNG, 128/128@2x/32 PNG, ICO 16-256); cargo check, cargo clippy und ein lokaler AppImage-Bau laufen durch"
requirement: "DESK-05"
verification:
- kind: other
ref: "cargo check/cargo clippy (Finished, 0 Warnungen) + magick identify (icon.png 512x512, icon.ico 6 Groessen) + lokaler Bau pnpm --filter @tessera/desktop exec tauri build --bundles appimage + desktop-collect.sh --require linux (Tessera-1.1.0.AppImage im Manifest)"
status: pass
human_judgment: false
duration: 9min
completed: 2026-09-16
status: complete
---
# Phase 18 Plan 04: Client-Fertigstellung — Update-Hinweis, Tray-Autostart, Erststart-Seite, echtes Icon Summary
**`lib.rs` bekommt zwei neue Rust-Kommandos (`check_server`/`save_server_url`) fuer eine modul-import-freie Erststart-Seite, die Versionspruefung laeuft jetzt ueber `/api-proxy/desktop/latest` mit Benachrichtigung und einem sich selbst umbenennenden Tray-Eintrag, das Tray traegt echte Umlaute und einen Autostart-Haken, und der Client hat erstmals ein echtes Tessera-Icon statt der flachen gelben Platzhalter-Quadrate — ein frischer lokaler AppImage-Bau (103 MB) beweist, dass alles zusammen kompiliert und buendelt.**
## Performance
- **Duration:** 9 min
- **Started:** 2026-09-16T14:32:35Z
- **Completed:** 2026-09-16T14:41:21Z
- **Tasks:** 2
- **Files modified:** 15 (davon 4 durch `git rm -r` entfernt)
## Accomplishments
- `lib.rs`: `tauri-plugin-opener` eingebunden, neue Hilfsfunktion `api_url()` als einzige Stelle mit dem `/api-proxy`-Rewrite-Praefix, zwei neue Kommandos `check_server` (prueft `/api-proxy/health/version` mit 8s-Zeitlimit, deutsche Sie-Form-Fehlermeldungen) und `save_server_url` (normalisiert, speichert im Store, navigiert das Fenster); beide ueber `invoke_handler` registriert.
- Versionspruefung beim Start laeuft jetzt gegen `/api-proxy/desktop/latest` statt `/health/version`; bei Abweichung erscheint die Benachrichtigung "Tessera-Update" / "Neue Version X.Y.Z verfuegbar – Download ueber das Symbol im Infobereich." und der Tray-Eintrag "Update herunterladen" wird umbenannt ("Version X.Y.Z herunterladen") und freigeschaltet.
- Tray-Menue neu geordnet: Öffnen · Update herunterladen · — · Autostart-Haken (Windows: "Mit Windows starten", sonst "Beim Anmelden starten") · — · Beenden — mit echten Umlauten (vorher "Oeffnen"/"Beenden"). Der Update-Eintrag oeffnet `{server}/settings/general/desktop` per `tauri-plugin-opener` im Systembrowser; der Autostart-Haken spiegelt beim Start `autolaunch().is_enabled()` und schaltet bei Klick um, faellt bei einem Fehlschlag von `enable()`/`disable()` auf den tatsaechlichen Zustand zurueck.
- `setup.html` spricht nur noch ueber `window.__TAURI__.core.invoke` (kein `<script type="module"> import` mehr — der bisherige Import des Store-Plugins scheiterte im gebauten Client ohne Bundler/Importmap mit "Failed to resolve module specifier"). Texte in Sie-Form, Tessera-Zeichen als inline-SVG, Markengelb/-Olive, keine vorbelegte Server-Adresse mehr.
- Neuer Icon-Satz aus `apps/web/src/app/icon.svg` erzeugt (512 PNG, 128/128@2x/32 PNG, ICO mit 16-256) statt der bisherigen 105-Byte-Platzhalter-Quadrate; CSP ohne `unpkg.com`, da nichts mehr von aussen geladen wird; versehentlich verschachteltes `apps/desktop/src-tauri/apps/`-Verzeichnis aus Phase 6 entfernt.
- `cargo check` und `cargo clippy` liefen beide ohne Fehler und ohne Warnungen durch; ein lokaler `pnpm --filter @tessera/desktop exec tauri build --bundles appimage`-Lauf (Rust-Kompilierung 55,64s, Gesamtlauf rund 1 Minute) erzeugte `Tessera_1.1.0_amd64.AppImage` (107.366.904 Bytes, SHA-256 `41b70efe...`), von `desktop-collect.sh --require linux` erfolgreich eingesammelt und im Manifest als `Tessera-1.1.0.AppImage` gefuehrt.
## Task Commits
Each task was committed atomically:
1. **Task 1: lib.rs — Kommandos fuer die Erststart-Seite, Versionspruefung gegen /desktop/latest, Tray mit Update und Autostart** - `8b130fd` (feat)
2. **Task 2: Erststart-Seite in Tessera-Gestalt und Sie-Form, echtes App-Icon, lokaler AppImage-Beweis** - `2d55f07` (feat)
**Plan metadata:** commit pending (this SUMMARY + STATE.md/ROADMAP.md/REQUIREMENTS.md)
## Files Created/Modified
- `apps/desktop/src-tauri/src/lib.rs` - `api_url`, `check_server`, `save_server_url`, Versionspruefung gegen `/api-proxy/desktop/latest`, Tray mit `update`/`autostart`-Eintraegen, Umlaut-Texte
- `apps/desktop/src-tauri/Cargo.toml` / `Cargo.lock` - `tauri-plugin-opener = "2"` (plus transitive `open`, `is-docker`, `is-wsl`)
- `apps/desktop/src-tauri/capabilities/default.json` - `opener:allow-open-url` mit `http`/`https`-Scope
- `apps/desktop/src-tauri/tauri.conf.json` - CSP ohne `unpkg.com`, `bundle.icon` um `32x32.png`/`128x128.png`/`128x128@2x.png` erweitert
- `apps/desktop/src/setup.html` - `invoke`-basierte Erststart-Seite, Sie-Form, Tessera-Gestalt
- `apps/desktop/src-tauri/icons/{icon.png,icon.ico,128x128.png,128x128@2x.png,32x32.png}` - Neuer Icon-Satz aus `icon.svg`
- `apps/desktop/src-tauri/apps/` (entfernt) - versehentlich verschachteltes Verzeichnis aus Phase 6
## Decisions Made
- `cargo add tauri-plugin-opener@2` statt manueller Cargo.toml/Cargo.lock-Pflege — Cargo aufgeloest transitive Abhaengigkeiten (`open`, `is-docker`, `is-wsl`) korrekt, Lockfile bleibt konsistent zum echten Dependency-Graphen.
- Autostart-Umschaltung setzt den Haken bei einem Fehlschlag von `enable()`/`disable()` explizit auf den vorher gemessenen Ist-Zustand zurueck statt optimistisch umzuschalten — der Haken zeigt nie eine falsche Systemwahrheit.
- Sowohl `check_server` (`/health/version`) als auch die Versionspruefung im Setup-Block (`/desktop/latest`) laufen jetzt ausschliesslich ueber dieselbe `api_url()`-Hilfsfunktion, damit der Rewrite-Praefix `/api-proxy` an genau einer Stelle im Code steht.
## Deviations from Plan
None - plan executed exactly as written.
## Issues Encountered
None. Weder `cargo check` noch `cargo clippy` meldeten Warnungen — es blieb keine Clippy-Warnung bewusst stehen.
## Baudaten (Auftrag des Output-Abschnitts)
- **AppImage:** `Tessera_1.1.0_amd64.AppImage`, 107.366.904 Bytes (~103 MB), SHA-256 `41b70efe1c03ab30b5914e327ee000c1c1f733ec980a53243506618e0204b6a8`.
- **Baudauer:** Rust-Kompilierung 55,64s laut `cargo`-Ausgabe (release-Profil); Gesamtlauf inkl. Bundling rund 1 Minute Wanduhrzeit (Bau gestartet 14:37:58Z, AppImage fertig 14:40:59Z laut Manifest-`buildTime`).
- **Grafische Probe:** Nicht moeglich — diese Ausfuehrungsumgebung ist kopflos (kein Display, kein X11/Wayland-Socket). Das AppImage wurde nicht gestartet; die Bedienprobe (Erststart-Seite, Tray, Anmeldung) macht der Nutzer laut Plan-Verifikation Punkt 4 in 18-06.
- **Clippy-Warnungen:** Keine — `cargo clippy` endete ohne jede Warnung, nichts musste bewusst stehen bleiben.
## User Setup Required
None - no external service configuration required.
## Next Phase Readiness
- `lib.rs`, `setup.html`, Icon-Satz und Capabilities sind auf dem Stand, den 18-05 fuer den Windows-Cross-Bau (`cargo-xwin`, NSIS) uebernehmen kann — derselbe Code, nur ein anderes Bau-Target.
- `desktop-dist/manifest.json` steht lokal auf `Tessera-1.1.0.AppImage`; der naechste `desktop-collect.sh`-Lauf in der Pipeline (18-05) ueberschreibt es mit dem CI-gebauten Paar aus Linux+Windows.
- Kein Blocker. Die grafische Bedienprobe (Tray-Umlaute im echten Rendering, Update-Benachrichtigung gegen einen Server mit abweichender Version, Erststart-Ablauf bis zur Anmeldung) ist laut Plan kein Pflichtschritt dieses Plans und wird in 18-06 durchgefuehrt.
---
*Phase: 18-desktop-client-fertigstellen*
*Completed: 2026-09-16*
## Self-Check: PASSED
All modified/created files verified on disk (`lib.rs`, `Cargo.toml`, `capabilities/default.json`, `tauri.conf.json`, `setup.html`, alle fuenf Icon-Dateien). Verschachteltes `apps/desktop/src-tauri/apps/` bestaetigt entfernt. Beide Task-Commits (`8b130fd`, `2d55f07`) im `git log` gefunden. Plan-Verifikation erneut ausgefuehrt: `RUST-OK` (`cargo check`/`cargo clippy`, beide `Finished`, 0 Warnungen), `WIRING-OK` (Kommandos, Rewrite-Praefix, Umlaut-Label, Autostart-Haken, Update-Link, Capability, Abhaengigkeit), `SETUP-OK` (kein Modul-Import, kein Fremdhost in der CSP, Icon-Groessen/-Anzahl korrekt, verschachteltes Verzeichnis entfernt), `APPIMAGE-OK` (frisches AppImage neuer als `lib.rs`, `desktop-collect.sh` liefert `Tessera-1.1.0.AppImage`).