# Monitoring mit Uptime Kuma

CluPilot registriert für jede Kundeninstanz ein Uptime-Ziel
(`https://<subdomain>/status.php`) und fragt dessen Gesundheit während der
Abnahmeprüfung ab.

## Warum eine Bridge?

Uptime Kuma hat **keine schreibende REST-API**. Monitore anlegen/löschen läuft
ausschließlich über **Socket.IO** — offiziell nur für Kumas eigenes Frontend
gedacht. Statt Socket.IO in PHP nachzubauen, läuft ein kleiner Dienst mit:

```
CluPilot (PHP)  ──REST──▶  kuma-bridge  ──Socket.IO──▶  Uptime Kuma
```

Die Bridge implementiert **exakt** den Vertrag, den `HttpMonitoringClient`
ohnehin spricht — am PHP-Code musste nichts geändert werden:

| Route | Zweck |
|---|---|
| `GET /monitors` | Liste (für Idempotenz: existiert die URL schon?) |
| `POST /monitors` | Monitor anlegen (`{friendly_name, url, type}`) |
| `GET /monitors/{id}` | Status lesen (`up` / `down` / `pending` / `maintenance`) |
| `DELETE /monitors/{id}` | Monitor entfernen (bei Kündigung) |
| `GET /health` | Liveness: 200 solange die Bridge läuft (prüft Kuma NICHT) |
| `GET /ready` | Readiness: **503**, wenn Kuma nicht erreichbar ist |

Alle Monitor-Routen erfordern `Authorization: Bearer $BRIDGE_TOKEN`.

## Einrichtung

1. **In Uptime Kuma** einen eigenen Benutzer für CluPilot anlegen (nicht den
   persönlichen Admin verwenden).

2. **`.env` ausfüllen:**

   ```dotenv
   KUMA_URL=http://kuma.dein-host.tld:3001
   KUMA_USERNAME=clupilot
   KUMA_PASSWORD=<passwort>
   KUMA_TOTP=                       # nur falls 2FA aktiv

   MONITORING_API_URL=http://kuma-bridge:8080
   MONITORING_API_TOKEN=<langes-zufälliges-token>   # = Bridge-Token
   ```

3. **Bridge starten** (eigenes Compose-Profil, läuft nicht im normalen `up`):

   ```bash
   docker compose --profile monitoring up -d --build kuma-bridge
   ```

4. **Prüfen:**

   ```bash
   docker compose exec app curl -s http://kuma-bridge:8080/health
   # {"bridge":"up"}

   # Readiness (eignet sich als Check in Kuma selbst — 503 wenn Kuma fehlt):
   docker compose exec app curl -s -o /dev/null -w '%{http_code}\n' http://kuma-bridge:8080/ready
   # 200
   ```

5. Config-Cache leeren, falls gesetzt: `clupilot artisan config:clear`

## Verhalten bei Ausfall

Monitoring ist Beobachtung, nicht das Produkt. Fällt Kuma oder die Bridge aus,
darf die Bereitstellung eines **bezahlten** Kunden nicht scheitern:

- Der Schritt `register_monitoring` versucht es genau `MONITORING_ATTEMPTS` mal (Standard 2 = 1 Versuch + 1 Wiederholung),
- danach läuft die Bereitstellung **degradiert** weiter und schreibt ein
  sichtbares `info`-Ereignis in die Admin-Konsole,
- mit `MONITORING_REQUIRED=true` wird Monitoring stattdessen erzwungen (der Lauf
  schlägt fehl, wenn es nicht erreichbar ist).

Bleibt `MONITORING_API_URL` leer, ist Monitoring komplett aus: die Bereitstellung
notiert eine stabile Kennung und die **eigenen** Gesundheitsprüfungen
(`occ status`, TLS-Zertifikat, Admin-User) entscheiden weiterhin über die Abnahme.

## Wartung

Die Bridge nutzt Kumas **interne** Socket.IO-API (über `uptime-kuma-api`). Diese
kann sich zwischen Kuma-Releases ändern:

- Nach einem Kuma-Upgrade: `GET /ready` und einen Testkunden prüfen.
- Kuma-Version notieren, gegen die getestet wurde.
- Bei Bruch ist der Ausfall dank obigem Verhalten **nicht** kundenwirksam —
  es fehlen nur neue Monitore, sichtbar als `info`-Ereignis.

## Alternativen (falls Kuma zu fragil wird)

- **Gatus** — Config-as-Code: eine YAML-Datei pro Instanz in einem gemergten
  Verzeichnis, Hot-Reload, eingebaute Statusseite. Passt zum Muster, mit dem
  CluPilot schon Traefik-Routen schreibt. Keine API nötig.
- **Kuvasz** — laut Doku vollständige REST-API; der bestehende
  `HttpMonitoringClient` wäre dann ohne Bridge nutzbar (evtl. Feld-Mapping).
