# Orgatum Installations- und Updatesystem

Stand: 12.07.2026 · Zielversion 1.1.0

## Architekturentscheidung

Orgatum Desktop ist eine .NET-8-WinForms-Anwendung fuer Windows x64. Die bisherige portable Verteilung speicherte Programm und Kundendaten teilweise gemeinsam. Eingesetzt wird deshalb ein per-user Inno-Setup-Installer mit getrenntem .NET-Updater. MSIX wurde verworfen, weil Zertifikats-/App-Installer-Verteilung und Unternehmensrichtlinien fuer die aktuelle Kundengruppe mehr Betriebsaufwand erzeugen. MSI waere fuer zentral verwaltete Enterprise-Rollouts sinnvoll, ist fuer den jetzigen Self-Service-Vertrieb aber unnoetig schwergewichtig.

Vorteile der gewaehlten Loesung:

- keine Administratorrechte und keine Laufzeitinstallation notwendig (self-contained .NET 8),
- fester Installationspfad, Startmenue, optionale Desktopverknuepfung und saubere Deinstallation,
- separater Updater ueberschreibt keine laufende Anwendung,
- bestehende Daten bleiben ausserhalb des Programmordners,
- Code-Signing, SHA-256, Releasekanaele und Railway-Rollout bleiben unter eigener Kontrolle.

Nachteil ist der Betrieb eines Code-Signing-Zertifikats und eines offiziellen Objektspeichers. Das ist fuer eine kommerzielle Windows-Software unvermeidbar und sicherer als ein eigener unsignierter Updater.

## Pfade und Migration

| Inhalt | Pfad |
|---|---|
| Programm | `%LOCALAPPDATA%\Programs\Orgatum` |
| WEG-Daten und Einstellungen | `%LOCALAPPDATA%\WEGOne\Data` |
| Pre-Update- und Reset-Backups | `%LOCALAPPDATA%\WEGOne\Backups` |
| Updatezustand und Diagnose | `%LOCALAPPDATA%\WEGOne\Update` |
| Temporäre Downloads | `%TEMP%\Orgatum\Updates\<Version>` |

Beim ersten Start werden vorhandene `workspaces` und portable Stammdateien ohne Ueberschreiben aus dem alten Programmordner uebernommen. Statische Assets und Dokumentation bleiben im Installationsverzeichnis. Der Uninstaller loescht Kundendaten standardmaessig nicht und fragt zweistufig, bevor `%LOCALAPPDATA%\WEGOne` entfernt wird.

## Versionierung und Kanaele

`Version.props` ist die kanonische SemVer-Quelle fuer Assembly, Datei, Produkt, Installer und Release. `scripts/sync-version.ps1` erzeugt daraus die Node-Paketversion. Produktive Tags muessen exakt `v<Version.props>` entsprechen.

- `stable`: regulaere Kunden; fest im Produktionsclient.
- `beta`: bewusste Testinstallation als separat gekennzeichneter Build (`/p:OrgatumReleaseChannel=beta`).
- `development`: nur interne Builds (`/p:OrgatumReleaseChannel=development`); wird nie vom Stable-Client akzeptiert.

## Updatefluss

1. Orgatum prueft beim Start hoechstens alle 24 Stunden oder manuell ueber **Updates**.
2. `GET /api/updates/latest?channel=stable&deviceId=...` liefert die fuer den stabilen Rollout-Hash freigegebene Version.
3. Download ist ausschliesslich über die validierte Railway-Backendroute erlaubt; sie erzeugt nach Prüfung des veröffentlichten Releases einen fünf Minuten gültigen Link zum privaten Railway Storage Bucket.
4. Paketgroesse, SHA-256, Windows-Authenticode-Vertrauenskette und erwarteter Herausgeber `Orgatum` werden geprueft.
5. Bei offenem Sync oder ungespeicherten Remote-Aenderungen wird abgebrochen.
6. Falls das Manifest `requiresBackup` setzt, werden lokale Dateien vor dem Update archiviert.
7. `Orgatum.Updater.exe` wartet auf das vollstaendige Ende des Hauptprozesses, startet den stillen Installer und danach Orgatum neu.

Offline- oder Serverfehler blockieren den normalen Start nicht. Sicherheits- und Kompatibilitaetsupdates bleiben auch im Read-only-Lizenzmodus verfuegbar. Lizenz und Update sind getrennte Subsysteme.

## Railway

- `update_releases`: Kanal, Version, Mindestversion, Schweregrad, SHA-256, Paketgroesse, Notes, Rollout, Backupbedarf und Status.
- `update_history`: technische Installationshistorie ohne WEG-Inhalte.
- `schema_migrations`: ausgefuehrte Backendmigrationen.
- `UPDATE_RELEASE_ADMIN_KEY`: Geheimnis fuer Release-Publikation und Rueckzug; nur Railway und GitHub-Environment.

Releaseverwaltung:

- `PUT /api/updates/releases/:channel/:version`
- `POST /api/updates/releases/:channel/:version/withdraw`

Die stabile Rolloutgruppe wird deterministisch aus einem SHA-256-Hash der DeviceId bestimmt. Ein Release kann mit `paused` oder `withdrawn` sofort von der Neuverteilung ausgeschlossen werden. Downgrades erfolgen nicht automatisch.

## Releasepipeline

`.github/workflows/release-desktop.yml` wird nur von einem stabilen SemVer-Tag ausgelöst. Sie prueft Version, Backend und Update-Domaene, erzeugt self-contained Builds, signiert EXE/DLL mit Zeitstempel, baut und signiert den Installer, erzeugt SHA-256, lädt ihn in den privaten Railway Storage Bucket, publiziert das Railway-Manifest mit initial 5 Prozent Rollout und erzeugt zusätzlich ein unveränderliches GitHub Release. Downloads werden ausschließlich durch das Backend geprüft und über fünf Minuten gültige signierte Bucket-Links ausgeliefert.

Erforderliche GitHub-Environment-Secrets:

- `SIGNING_CERTIFICATE_BASE64`
- `SIGNING_CERTIFICATE_PASSWORD`
- `RAILWAY_RELEASE_BUCKET_ACCESS_KEY_ID`, `RAILWAY_RELEASE_BUCKET_SECRET_ACCESS_KEY`
- `RAILWAY_RELEASE_BUCKET_ENDPOINT`, `RAILWAY_RELEASE_BUCKET_NAME`, `RAILWAY_RELEASE_BUCKET_REGION`
- `UPDATE_RELEASE_ADMIN_KEY`

Das private Zertifikat wird nur temporaer auf dem isolierten Windows Runner geschrieben und immer geloescht. Fehlende Signatur-, Storage- oder Railway-Konfiguration stoppt die Veroeffentlichung.

## Backup, Migration und Rollback

Lokale Daten bestehen aktuell aus versionierten JSON-/WEG-Dateien, nicht aus einer lokalen SQL-Datenbank. Deshalb wird vor als kritisch markierten Releases ein ZIP mit Versionsmanifest erstellt. Railway-Schemaerweiterungen sind additiv und werden in `schema_migrations` protokolliert. Ein Programmrollback ist nur erlaubt, solange keine rueckwaertsinkompatible Datenmigration erfolgt ist. Andernfalls wird nicht blind zurueckgesetzt, sondern Backup-/Supportmodus verwendet.

## Tests und offene Go-live-Punkte

Automatisiert geprueft werden Versionsvergleich, Pflichtupdate, Kanaltrennung, zurueckgezogene Releases, stabile Rolloutzuordnung, offizielle Domain und schemaabhaengiges Rollback. Der lokale Installer wird aus dem vollstaendigen Publish-Build erzeugt und auf das Fehlen von Kundendateien kontrolliert.

Vor dem ersten Kundenrelease bleiben externe Voraussetzungen:

1. OV- oder EV-Code-Signing-Zertifikat auf den finalen Firmennamen beschaffen.
2. GitHub-Environment `production-release` mit Pflichtfreigabe und den genannten Secrets einrichten.
3. Railway `UPDATE_RELEASE_ADMIN_KEY` identisch konfigurieren.
4. Railway-Bucket-Zugangsdaten ausschließlich im Backend und im GitHub-Environment hinterlegen und regelmäßig rotieren.
5. Upgrade-Matrix auf sauberen Windows-VMs fuer 1.0.0→1.1.0 sowie spaetere Major-Pfade ausfuehren.
6. Vor kommerzieller Produktion eine Inno-Setup-Single-User-Lizenz einplanen; die Softwarelizenz erlaubt kommerzielle Nutzung, der Hersteller bittet kommerzielle Nutzer jedoch ausdruecklich um den Kauf.

Der lokal erzeugte Installer ist ein technischer Testbuild und darf wegen fehlender Authenticode-Signatur nicht an Kunden verteilt werden.
