WinForms-Host durch die Avalonia-Shell abgeloest
Merge von main: die dort entstandene Deployment-Center-Integration (Lizenz, Heartbeat mit DB-Health-Check, Fehler-Stream, UpdateService) ist jetzt Teil des plattformneutralen Kerns. Predictalytics.WinFormsHost ist entfernt. Nach Predictalytics.Hosting gezogen: - DcConfig, DcApiClient, DcErrorSink, DcHeartbeatService, DcUpdateService unveraendert - sie waren bereits plattformneutral - DcErrorReporter ohne Application.ThreadException und MessageBox; der UI-Thread-Handler liegt jetzt beim Host und ruft ReportUiThreadException - LicenseGuard/LicenseSession ohne Dialog und ohne WinForms-Timer. Neu: TryUseCachedAsync, ActivateAsync, StartPeriodicRevalidation ueber PeriodicTimer. Die Unterscheidung transienter Fehler und die Warnung vor ablaufender Gnadenfrist sind unveraendert uebernommen. - Dc-Einstellungen von AppSettings nach PredictalyticsOptions; die Watchdog-Einstellungen entfallen - DcErrorSink im LoggingSetup, Startbanner nutzt DcConfig.AppVersion BuildInfo.targets wird jetzt von Predictalytics.Hosting importiert. In der Avalonia-Shell nachgezogen: - Menue Deployment Center mit Update-Suche und Lizenzstatus - Einstellungsgruppe Deployment Center statt Watchdog, Update-Kanal als ComboBox, Server-URL nur zur Anzeige - Heartbeat-Snapshot mit SELECT-1-Probe wie in der WinForms-Fassung - Update-Pruefung still beim Start und interaktiv ueber das Menue, mit NotifyStopping vor dem Start des Update-Agenten - Lizenzfenster wertet IsTransient aus: bei fehlender Serververbindung wird nicht behauptet, die Lizenz sei ungueltig - TextBox.Watermark auf PlaceholderText (in Avalonia 12 veraltet) Build: 0 Fehler, 8 Warnungen (alle vorbestehend). Tests: 100 bestanden, 0 Fehler, 1 uebersprungen. Verifiziert: --license-status meldet gueltig samt Gnadenfrist; die GUI startet durch, prueft die Lizenz und laeuft gegen den UpdateService. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
# Betrieb: Deployment Center
|
||||
|
||||
Das **Deployment Center** (`https://dc.mhdf.de`, Schwester-Repo
|
||||
`J:\Softwareprojekte\Deploymentcenter`) hat die beiden früheren Einzelserver abgelöst:
|
||||
|
||||
| Vorher | Jetzt |
|
||||
|---|---|
|
||||
| WatchDog auf `watchdog.mhdf.de`, `POST /api/heartbeat`, Header `X-Watchdog-Key` | Deployment Center, `POST /api/watchdog/v1/ping`, `Authorization: Bearer` |
|
||||
| LicenseLabrador auf `license.mhdf.de`, Ed25519-signierte Envelopes | Deployment Center, `POST /api/license/v1/validate`, Hardware-ID v2 |
|
||||
| — | UpdateService, Fehler-Stream und Bugtracker (neu) |
|
||||
|
||||
Die Anbindung sitzt im `Predictalytics.WinFormsHost` und referenziert das
|
||||
C#-SDK `Deploymentcenter.Client` aus dem Schwester-Repo:
|
||||
|
||||
```
|
||||
..\..\..\..\Deploymentcenter\client-dotnet\Deploymentcenter.Client\Deploymentcenter.Client.csproj
|
||||
```
|
||||
|
||||
Das Repo muss also neben dem Predictalytics-Checkout liegen. `LicenseLabrador`
|
||||
und `WatchDog` werden nicht mehr gebraucht.
|
||||
|
||||
---
|
||||
|
||||
## 0. Was einmalig zu tun ist
|
||||
|
||||
1. Im Deployment Center unter **Token-Verwaltung → Master-Token erstellen** ein
|
||||
Token mit den Rechten **`watchdog:ping`** und **`bugtracker:report`** anlegen.
|
||||
2. Im Host unter **Settings → Deployment Center → API Token** eintragen.
|
||||
Der alte `X-Watchdog-Key` funktioniert nicht mehr — es ist ein anderer Server.
|
||||
3. Beim ersten Start erscheint einmalig der Lizenzdialog: der Lizenzschlüssel muss
|
||||
erneut eingegeben werden, weil die Aktivierung jetzt am Deployment Center hängt.
|
||||
4. Serverseitig muss der **Evaluator-Cron** laufen — ohne ihn bleibt ein
|
||||
abgestürzter Dienst dauerhaft grün:
|
||||
```
|
||||
* * * * * curl -fsS -H "Authorization: Bearer <SHARED_KEY>" https://dc.mhdf.de/api/watchdog/v1/evaluate > /dev/null
|
||||
```
|
||||
|
||||
Der Token landet in der `settings.json` neben der Exe (nicht im Git).
|
||||
|
||||
---
|
||||
|
||||
## 1. Konfiguration (PropertyGrid, Kategorie „Deployment Center")
|
||||
|
||||
| Feld | Default | Bedeutung |
|
||||
|---|---|---|
|
||||
| `Server URL` | `https://dc.mhdf.de` | **schreibgeschützt**, siehe unten |
|
||||
| `API Token` | *(leer)* | `Authorization: Bearer`. Ohne Token: keine Heartbeats, keine Fehlermeldungen. |
|
||||
| `Heartbeat aktiv` | `true` | Dead-Man's-Switch an/aus |
|
||||
| `Monitor Source` | `Predictalytics` | Monitor-Name im Dashboard (Auto-Registrierung beim ersten Ping) |
|
||||
| `Monitor Instance` | `default` | falls mehrere Instanzen laufen |
|
||||
| `Heartbeat-Intervall (Sekunden)` | `60` | `warning` nach 2×, `down` nach 4× |
|
||||
| `Fehler melden` | `true` | Error/Fatal an den Fehler-Stream |
|
||||
| `Update-Prüfung beim Start` | `true` | prüft nur, installiert nichts von selbst |
|
||||
| `Update-Kanal` | `prod` | `prod`, `beta` oder `dev` |
|
||||
|
||||
**Warum ist die Server-URL nicht einstellbar?** Sie entscheidet, wohin die
|
||||
Lizenzprüfung geht und woher Update-Pakete kommen. Ein einstellbarer Endpoint
|
||||
würde erlauben, die App auf einen gefälschten Lizenz- oder Update-Server zu
|
||||
zeigen. Sie steht als Konstante in `Services/DcConfig.cs`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Watchdog (Dead-Man's-Switch)
|
||||
|
||||
`Services/DcHeartbeatService.cs` sendet alle *n* Sekunden einen
|
||||
`POST /api/watchdog/v1/ping`. Beim regulären Schließen geht ein Ping mit
|
||||
`status: "stopped"` raus — der Evaluator lässt einen so beendeten Monitor in
|
||||
Ruhe, bis wieder ein normaler Heartbeat eintrifft. Ohne das folgt wenige Minuten
|
||||
nach jedem geordneten Beenden ein Fehlalarm.
|
||||
|
||||
**Ein Ausfall des Deployment Centers darf Predictalytics nie beeinträchtigen.**
|
||||
Alle Aufrufe sind best effort; der erste Fehlschlag wird als Warnung geloggt,
|
||||
Folgefehler nur noch auf Debug-Level (keine Log-Flut). Wird das Token abgelehnt
|
||||
(`401`/`403`), stellt der Dienst die Versuche ganz ein — Wiederholen kann daran
|
||||
nichts ändern.
|
||||
|
||||
### Mitgesendeter Gesundheitszustand
|
||||
|
||||
Ein Heartbeat beweist nur, dass ein Timer läuft. Deshalb schickt die App ihren
|
||||
selbst ermittelten Zustand mit:
|
||||
|
||||
| `checks` | Bedeutung |
|
||||
|---|---|
|
||||
| `db` | `SELECT 1` gegen die konfigurierte MySQL, gedeckelt auf 5 s. Schlägt sie fehl, stuft der Server den Heartbeat auf `warning`. |
|
||||
|
||||
| `metrics` | Bedeutung |
|
||||
|---|---|
|
||||
| `uptime_sec` | Laufzeit des Prozesses |
|
||||
| `workers_running` | 0/1 — Hintergrund-Worker gestartet |
|
||||
| `webserver_running` | 0/1 — eingebetteter Kestrel gestartet |
|
||||
| `memory_mb` | verwalteter Heap |
|
||||
| `db_size_mb` | zuletzt ermittelte Datenbankgröße |
|
||||
|
||||
Zusätzlich geht seit Server 2.1 das Feld `version` mit — im Dashboard ist damit
|
||||
sichtbar, welcher Build läuft, und ein Ausfall lässt sich einem Rollout zuordnen.
|
||||
|
||||
Gestoppte Worker sind **bewusst kein** fehlgeschlagener Check: das ist ein
|
||||
gewollter Betriebszustand und würde den Monitor sonst dauerhaft auf `warning`
|
||||
halten. Der Zustand steckt als Metrik drin und lässt sich dort auswerten.
|
||||
|
||||
Metriken werden serverseitig 14 Tage lang mit Verlauf gehalten
|
||||
(`GET /api/watchdog/v1/metrics?source=Predictalytics`).
|
||||
|
||||
### Maschine mit überwachen
|
||||
|
||||
Der Heartbeat deckt nur *diesen* Prozess ab. Für die Maschine selbst gehört
|
||||
zusätzlich ein OS-Agent auf den Host (siehe
|
||||
`Deploymentcenter/docs/WATCHDOG_INTEGRATION_GUIDE.md`). Läuft beides, sollte im
|
||||
WebUI unter **WatchDog → System-Hierarchie** die *Übergeordnete Entität* des
|
||||
Predictalytics-Monitors auf den Host gesetzt werden — dann erzeugt ein
|
||||
Maschinenausfall eine Meldung statt zwei.
|
||||
|
||||
---
|
||||
|
||||
## 3. Lizenzierung
|
||||
|
||||
`Services/LicenseGuard.cs` prüft beim Start, ob eine nutzbare Lizenz vorliegt;
|
||||
`Program.Main` bricht sonst ab, bevor die MainForm entsteht. Ohne gültige Lizenz
|
||||
erscheint `Services/LicenseDialog.cs` zur Key-Eingabe.
|
||||
|
||||
- **Produkt-Slug:** `predictalytics`
|
||||
- **Hardware-ID v2:** `2:win:<sha256>` aus `HKLM\...\Cryptography\MachineGuid`.
|
||||
Der Rechnername steckt **nicht** im Hash — Umbenennen kostet keinen
|
||||
Aktivierungsplatz.
|
||||
- **Offline-Cache:** AES-256-GCM + DPAPI unter `%AppData%\predictalytics\license\state.dat`
|
||||
(Schema 3 seit SDK 2.1, Schema 2 wird noch gelesen). Dort liegt auch der
|
||||
Lizenzschlüssel — `LicenseClient.TryGetCachedKey()` holt ihn beim Start, damit
|
||||
ohne Dialog revalidiert werden kann.
|
||||
- **Revalidierung zur Laufzeit:** alle 12 h.
|
||||
- **Gemeldete Version:** `LicenseClient.DefaultAppVersion` wird in `Program.Main`
|
||||
auf `BuildInfo.Version` gesetzt; ohne das trüge jede Installation in der
|
||||
Aktivierungsliste dieselbe „1.0.0".
|
||||
|
||||
### Offline-Gnadenfrist
|
||||
|
||||
Seit Server 2.1 ist sie **echt begrenzt**: der Server liefert `cache_ttl_hours`
|
||||
(je Projekt im WebUI, Standard 168 h = 7 Tage). Vorher galt faktisch das
|
||||
Lizenz-Ablaufdatum, bei einer Lizenz bis 2040 also unbegrenzt.
|
||||
|
||||
Läuft die Frist in weniger als 48 h ab, warnt der Host beim Start und bei jeder
|
||||
Revalidierung. Die verbleibende Frist zeigt **Deployment Center → Lizenzstatus
|
||||
anzeigen**. Falls Predictalytics planmäßig länger offline laufen soll, muss die
|
||||
TTL im WebUI für das Projekt `predictalytics` heraufgesetzt werden.
|
||||
|
||||
### Wann die App sich beendet — und wann nicht
|
||||
|
||||
Maßgeblich ist `LicenseValidationResult.IsTransient`:
|
||||
|
||||
| | Zustände | Reaktion |
|
||||
|---|---|---|
|
||||
| `IsValid` | `valid`, `valid_offline` | weiter |
|
||||
| `IsTransient` | `server_unavailable`, `cache_expired` | **kein Urteil, nur eine gescheiterte Verbindung** — weiterlaufen, beim nächsten Durchlauf erneut versuchen |
|
||||
| sonst | `revoked`, `expired`, `not_found`, `activation_limit`, `suspended`, `clock_rollback` | Meldung und Beenden |
|
||||
|
||||
`cache_expired` beendet die laufende Sitzung also nicht — der **nächste Start**
|
||||
bleibt aber am Lizenzdialog hängen, weil `IsValid` dann falsch ist. Der Host
|
||||
loggt diesen Fall deshalb als Error, nicht bloß als Warnung.
|
||||
|
||||
### Deaktivierung bei PC-Wechsel
|
||||
|
||||
`POST /api/license/v1/deactivate` verlangt den `shared_key` aus der
|
||||
Server-Konfiguration. Der gehört **nicht** in die ausgelieferte Anwendung,
|
||||
deshalb ist die Funktion hier nicht verdrahtet. Übliche Route: im WebUI unter
|
||||
**Lizenzen → Hardware-Liste → „Freigeben"**. Die Hardware-ID zeigt der Host unter
|
||||
**Deployment Center → Lizenzstatus anzeigen**.
|
||||
|
||||
---
|
||||
|
||||
## 4. Fehler-Stream
|
||||
|
||||
`Services/DcErrorReporter.cs` meldet Laufzeitfehler an
|
||||
`POST /api/errors/v1/report`. Zwei Wege führen dorthin:
|
||||
|
||||
1. **Globale Handler** — `Application.ThreadException` (UI-Thread),
|
||||
`AppDomain.UnhandledException` (Level `fatal`, wird blockierend gesendet, weil
|
||||
der Prozess gleich weg ist) und `TaskScheduler.UnobservedTaskException`.
|
||||
2. **Serilog-Sink** (`Services/DcErrorSink.cs`) — jedes `Log.Error`/`Log.Fatal`,
|
||||
auch aus Worker und Kestrel.
|
||||
|
||||
Lokale Bremse, damit das Rate-Limit (60/min und IP) nicht verbrannt wird:
|
||||
höchstens 20 Meldungen pro Minute, derselbe Fehler höchstens alle 5 Minuten.
|
||||
Serverseitig werden gleiche Fehler ohnehin gruppiert und hochgezählt;
|
||||
betriebsbedingtes Rauschen gehört in die **Ignore-Regeln** des WebUI — ein
|
||||
Treffer zählt weiter, meldet aber nicht.
|
||||
|
||||
> Der Serilog-Filter in `Program.cs` wirft `Duplicate entry`-Ausnahmen schon
|
||||
> vorher weg; die erreichen den Stream also gar nicht.
|
||||
|
||||
---
|
||||
|
||||
## 5. Updates
|
||||
|
||||
`Services/DcUpdateService.cs` fragt beim Start
|
||||
`GET /api/updateservice/v1/check` ab (ohne Token). Gefunden wird nur — installiert
|
||||
wird nichts von selbst:
|
||||
|
||||
- Kein Update: Info ins Log.
|
||||
- Update verfügbar: Warnung ins Log, Hinweis in der Statusleiste.
|
||||
- **Kritisches** Update: zusätzlich ein Dialog.
|
||||
- Menü **Deployment Center → Nach Updates suchen** prüft jederzeit von Hand.
|
||||
|
||||
Liegt `update-agent.exe` neben der Anwendung, bietet der Dialog an, ihn zu
|
||||
starten; die Anwendung meldet dann vorher `stopped` und beendet sich. Fehlt der
|
||||
Agent, weist der Dialog auf die manuelle Installation hin.
|
||||
|
||||
Seit SDK 2.1 liefert auch der API-Zweig vollständige Release-Daten
|
||||
(Download-Adresse, Prüfsumme, Changelog, Kritikalität) — der Dialog zeigt die
|
||||
Release Notes also auch dann, wenn die statische `latest.json` fehlt.
|
||||
|
||||
### Versionsstand
|
||||
|
||||
`Predictalytics.WinFormsHost.csproj` importiert `Deploymentcenter.BuildInfo.targets`
|
||||
und erzeugt daraus zur Übersetzungszeit `Predictalytics.WinFormsHost.BuildInfo`
|
||||
mit `Version`, `GitCommit`, `GitCommitShort`, `BuildDateUtc`, `Channel` und
|
||||
`Summary`. Quelle ist `<Version>` in derselben csproj — beim Release dort
|
||||
hochziehen und mit
|
||||
|
||||
```
|
||||
pack-and-deploy --project predictalytics --version <x> --channel prod
|
||||
```
|
||||
|
||||
veröffentlichen. Dieselbe Version geht an die Lizenz-Aktivierungsliste, an den
|
||||
Heartbeat und als `build` an den Fehler-Stream; `GitCommitShort` reist im
|
||||
`context` jeder Fehlermeldung mit.
|
||||
|
||||
---
|
||||
|
||||
## 6. Bugtracker
|
||||
|
||||
Der Agenten-Workflow ist in [`../CLAUDE.md`](../CLAUDE.md) beschrieben.
|
||||
Projekt-Slug: `predictalytics`. Items, deren `resolved_in_build` einer
|
||||
veröffentlichten Version entspricht, schließen sich beim Publish von selbst.
|
||||
@@ -1,82 +0,0 @@
|
||||
# Betrieb: Watchdog-Überwachung & LicenseLabrador-Lizenzierung
|
||||
|
||||
Beide Integrationen sitzen im `Predictalytics.WinFormsHost` (dem Produktiv-Host) und
|
||||
binden zwei eigenständige Schwester-Projekte an:
|
||||
|
||||
| Projekt | Pfad | Rolle |
|
||||
|---|---|---|
|
||||
| Watchdog | `J:\Softwareprojekte\WatchDog` | PHP/MySQL-Server auf `watchdog.mhdf.de`, empfängt Heartbeats |
|
||||
| LicenseLabrador | `J:\Softwareprojekte\LicenseLabrador` | PHP-Lizenzserver auf `license.mhdf.de` + C#-SDK |
|
||||
|
||||
---
|
||||
|
||||
## 1. Watchdog (Dead-Man's-Switch)
|
||||
|
||||
`Services/WatchdogHeartbeatService.cs` sendet alle *n* Sekunden einen
|
||||
`POST /api/heartbeat` an den Watchdog. Bleiben die Heartbeats aus — weil die App
|
||||
abgestürzt ist oder die ganze Maschine weg ist — schlägt der Watchdog Alarm.
|
||||
Beim regulären Schließen geht ein `POST /api/event` mit `kind=stopped_graceful`
|
||||
raus, damit ein geplantes Beenden nicht als Crash alarmiert wird.
|
||||
|
||||
> **Nicht auf `kind=stopping` ändern.** Der Watchdog akzeptiert den Wert im
|
||||
> Router, aber `event_log.kind` ist ein ENUM ohne `stopping`. Der Server setzt
|
||||
> dann zwar noch den Zustand auf `stopped`, scheitert aber am Insert und liefert
|
||||
> HTTP 500 — das Event fehlt in der Historie. Verifiziert am 2026-07-30.
|
||||
|
||||
**Wichtig:** Ein Ausfall des Watchdogs darf Predictalytics nie beeinträchtigen.
|
||||
Alle Aufrufe sind best effort; der erste Fehlschlag wird als Warnung geloggt,
|
||||
Folgefehler nur noch auf Debug-Level (keine Log-Flut).
|
||||
|
||||
### Konfiguration (PropertyGrid im Host, Kategorie „Watchdog")
|
||||
|
||||
| Feld | Default | Bedeutung |
|
||||
|---|---|---|
|
||||
| `Enabled` | `true` | Heartbeats an/aus |
|
||||
| `Server URL` | `https://watchdog.mhdf.de` | Basis-URL |
|
||||
| `API Key` | *(leer)* | `X-Watchdog-Key` — Shared Key **oder** Agent-Token. Ohne Key passiert nichts. |
|
||||
| `Source` | `Predictalytics` | Monitor-Name im Dashboard (Auto-Registrierung beim ersten Beat) |
|
||||
| `Instance` | `default` | falls mehrere Instanzen laufen |
|
||||
| `Interval (Sekunden)` | `60` | Sende-Takt; Alarm nach ca. `Intervall × 1,5 + 30 s` |
|
||||
|
||||
Der Key landet in der `settings.json` neben der Exe (nicht im Git).
|
||||
|
||||
### PolyTrader-Maschine mit überwachen
|
||||
|
||||
Der Heartbeat aus Predictalytics deckt nur *diesen* Prozess ab. Damit auch die
|
||||
Maschine überwacht wird, auf der PolyTrader läuft, gehört dort zusätzlich der
|
||||
OS-Agent hin: `WatchDog\agents\windows\watchdog-agent.ps1` als Scheduled Task
|
||||
(inkl. Shutdown-Hook), bzw. `agents/linux/watchdog-agent.sh` per systemd-Timer.
|
||||
|
||||
---
|
||||
|
||||
## 2. LicenseLabrador (Kopierschutz)
|
||||
|
||||
`Services/LicenseGuard.cs` prüft beim Start, ob eine nutzbare Lizenz vorliegt
|
||||
(`Program.Main` bricht sonst ab, bevor die MainForm überhaupt entsteht).
|
||||
Ohne gültige Lizenz erscheint `Services/LicenseDialog.cs` zur Key-Eingabe.
|
||||
|
||||
Produkt-Slug, Endpoint und der Ed25519-Public-Key sind **bewusst einkompiliert**
|
||||
und nicht konfigurierbar — ein einstellbarer Endpoint würde erlauben, die App auf
|
||||
einen gefälschten Lizenzserver zu zeigen.
|
||||
|
||||
- **Produkt-Slug:** `predictalytics`
|
||||
- **Offline-Gnadenfrist:** 168 h (7 Tage) — danach ist Serverkontakt nötig
|
||||
- **Revalidierung zur Laufzeit:** alle 12 h; bei Widerruf/Ablauf beendet sich die App
|
||||
- **Härtung:** `VerifyChecksum` (HMAC über State + Key + Hardware-ID) gegen Memory-Patches;
|
||||
Nonce-Reflexion und Signaturprüfung übernimmt das SDK
|
||||
|
||||
### Status
|
||||
|
||||
Produkt `predictalytics` und Lizenzschlüssel sind angelegt; die Aktivierung wurde
|
||||
am 2026-07-30 gegen den Produktivserver verifiziert (`Valid`, gültig bis
|
||||
2040-12-31, Checksum-Prüfung bestanden). Der einkompilierte Public Key passt zum
|
||||
`signing.pub` des Servers — sonst käme `TamperSuspected` statt `Valid`.
|
||||
|
||||
Die Aktivierung ist an die Hardware-ID der jeweiligen Maschine gebunden. Auf
|
||||
einem neuen Rechner erscheint einmalig der Dialog; der Cache liegt danach unter
|
||||
`%AppData%\predictalytics\license`.
|
||||
|
||||
### Deaktivierung bei PC-Wechsel
|
||||
|
||||
`LicenseClient.DeactivateAsync()` gibt die Aktivierung wieder frei. Aktuell nicht
|
||||
in der UI verdrahtet — bei Bedarf als Menüpunkt ergänzen.
|
||||
@@ -443,8 +443,60 @@ Lizenzdialog.
|
||||
|
||||
---
|
||||
|
||||
## 5b. WinForms-Host abgelöst ✅ (2026-08-08)
|
||||
|
||||
`main` brachte eine vollständige Deployment-Center-Integration mit (Lizenz, Heartbeat mit
|
||||
DB-Health-Check, Fehler-Stream, UpdateService), die im WinForms-Host entstanden war. Diese
|
||||
wurde nach `feature/linux-net10` gemerged und dabei in den plattformneutralen Kern gezogen.
|
||||
**`Predictalytics.WinFormsHost` ist entfernt** — die Avalonia-Shell ist ab jetzt die einzige
|
||||
Bedienoberfläche.
|
||||
|
||||
### Was nach `Predictalytics.Hosting` wanderte
|
||||
|
||||
| Datei | Anmerkung |
|
||||
|---|---|
|
||||
| `DcConfig`, `DcApiClient`, `DcErrorSink`, `DcHeartbeatService`, `DcUpdateService` | unverändert, waren bereits plattformneutral |
|
||||
| `DcErrorReporter` | `Application.ThreadException` + `MessageBox` entfernt; stattdessen `ReportUiThreadException(Exception)`, das der Host aufruft. Avalonia hängt sich über `Dispatcher.UIThread.UnhandledException` ein. |
|
||||
| `LicenseGuard` + `LicenseSession` | Dialogaufruf und `System.Windows.Forms.Timer` entfernt. Neu: `TryUseCachedAsync()`, `ActivateAsync()` und `StartPeriodicRevalidation(session, onUnusable)` über `PeriodicTimer`. Die Unterscheidung transienter Fehler und die Gnadenfrist-Warnung sind unverändert übernommen. |
|
||||
| Dc-Einstellungen | aus `AppSettings` nach `PredictalyticsOptions`; die Watchdog-Einstellungen entfielen |
|
||||
| `DcErrorSink` in Serilog | in `LoggingSetup` aufgenommen, Startbanner nutzt jetzt `DcConfig.AppVersion` |
|
||||
|
||||
`Deploymentcenter.BuildInfo.targets` wird nun von `Predictalytics.Hosting` importiert;
|
||||
`BuildInfo` entsteht damit im Namensraum `Predictalytics.Hosting`.
|
||||
|
||||
### Was in der Avalonia-Shell nachgezogen wurde
|
||||
|
||||
* Menü **Deployment Center** mit „Nach Updates suchen" und „Lizenzstatus anzeigen"
|
||||
* Einstellungsgruppe **Watchdog → Deployment Center** (Token, Heartbeat, Fehler-Reporting,
|
||||
Update-Kanal als ComboBox; die Server-URL wird nur angezeigt, nicht editiert)
|
||||
* Heartbeat-Snapshot samt `SELECT 1`-DB-Probe, identisch zur WinForms-Fassung
|
||||
* Update-Prüfung beim Start (still) und über das Menü (interaktiv), inklusive
|
||||
`NotifyStopping()` vor dem Start des Update-Agenten
|
||||
* Lizenzfenster nutzt `IsTransient`: bei fehlender Serververbindung wird nicht behauptet,
|
||||
die Lizenz sei ungültig
|
||||
|
||||
### Verifiziert
|
||||
|
||||
```
|
||||
🔑 Lizenz geprüft: valid (HWID 2:win:a765bd47…, Quelle machine-guid)
|
||||
Shell initialisiert. Bereit.
|
||||
🐕 Heartbeat ist aktiviert, aber es fehlt das Deployment-Center-Token
|
||||
Update-Prüfung: v1.0.0 ist aktuell (Kanal prod)
|
||||
```
|
||||
|
||||
`--license-status` meldet gültig samt Offline-Gnadenfrist. Build 0 Fehler, 100 Tests grün.
|
||||
**Noch offen:** Heartbeat und Fehler-Stream laufen erst mit gesetztem DC-Token; die
|
||||
Wartungsaktionen brauchen DB-Zugangsdaten.
|
||||
|
||||
---
|
||||
|
||||
## 5a. Zusatz — Umstellung auf das Deploymentcenter-Lizenzsystem ✅ (2026-08-07)
|
||||
|
||||
> **Überholt durch 5b.** Der hier beschriebene eigene `LicenseGuard` gegen
|
||||
> `Deploymentcenter.Client` war ein Provisorium und wurde durch die reifere Fassung aus
|
||||
> `main` ersetzt (`LicenseSession`, `IsTransient`, `TryGetCachedKey`, Gnadenfrist-Warnung).
|
||||
> Die Begründungen zur Hardware-ID v2 und zum AES-GCM-Cache gelten unverändert.
|
||||
|
||||
**Nicht ursprünglich geplant.** Beim Aktivieren der neuen Lizenz stellte sich heraus, dass
|
||||
Predictalytics noch am alten Lizenzsystem hing (LicenseLabrador, `license.mhdf.de`),
|
||||
während die Lizenzen inzwischen im Deploymentcenter (`dc.mhdf.de`) gepflegt werden.
|
||||
|
||||
Reference in New Issue
Block a user