Watchdog-Heartbeat + LicenseLabrador-Lizenzgate im WinFormsHost

Bindet die beiden neuen Betriebsprojekte an:

- WatchdogHeartbeatService: periodischer POST /api/heartbeat an
  watchdog.mhdf.de (Dead-Man's-Switch), stopping-Event beim Beenden,
  Konfiguration ueber AppSettings-Kategorie "Watchdog". Fehler sind
  best effort und beeintraechtigen die App nie.
- LicenseGuard + LicenseDialog: Lizenzpruefung vor dem Start der
  MainForm, 12h-Revalidierung zur Laufzeit, Checksum-Haertung.
  Produkt-Slug/Endpoint/Public-Key sind einkompiliert.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-07-30 12:12:54 +02:00
co-authored by Claude Fable 5
parent 02c5a4d6f4
commit 3a82397651
8 changed files with 515 additions and 0 deletions
@@ -27,6 +27,42 @@ public class AppSettings
[Editor("System.ComponentModel.Design.MultilineStringEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor))]
public string EgressChannelsText { get => _egressChannelsText; set => _egressChannelsText = value ?? ""; }
[Category("Watchdog")]
[DisplayName("Enabled")]
[Description("Sendet periodische Heartbeats an den externen Watchdog-Server (Dead-Man's-Switch). Benötigt einen API Key.")]
[DefaultValue(true)]
public bool WatchdogEnabled { get; set; } = true;
[Category("Watchdog")]
[DisplayName("Server URL")]
[Description("Basis-URL des Watchdog-Servers.")]
[DefaultValue("https://watchdog.mhdf.de")]
public string WatchdogUrl { get; set; } = "https://watchdog.mhdf.de";
[Category("Watchdog")]
[DisplayName("API Key")]
[Description("Shared Key oder Agent-Token des Watchdog-Servers (X-Watchdog-Key). Ohne Key werden keine Heartbeats gesendet.")]
[PasswordPropertyText(true)]
public string WatchdogApiKey { get; set; } = "";
[Category("Watchdog")]
[DisplayName("Source")]
[Description("Eindeutiger Monitor-Name dieses Dienstes im Watchdog-Dashboard.")]
[DefaultValue("predictalytics")]
public string WatchdogSource { get; set; } = "predictalytics";
[Category("Watchdog")]
[DisplayName("Instance")]
[Description("Instanz-Kennung, falls mehrere Predictalytics-Instanzen laufen.")]
[DefaultValue("default")]
public string WatchdogInstance { get; set; } = "default";
[Category("Watchdog")]
[DisplayName("Interval (Sekunden)")]
[Description("Sende-Takt der Heartbeats. Der Watchdog alarmiert, wenn ~1,5× dieses Intervall + 30 s ohne Heartbeat vergehen.")]
[DefaultValue(60)]
public int WatchdogIntervalSeconds { get; set; } = 60;
private string _dbServer = "localhost";
private string _dbName = "";
private string _dbUser = "";