⚠️ Watchdog-Evaluator läuft nicht. Die Monitor-Zustände sind derzeit nicht verlässlich – ein ausgefallenes System bleibt „up“, bis es sich wieder meldet. Letzter Lauf: (). Der Evaluator lief noch nie.
Empfohlen (intern):
* * * * * /usr/bin/php /cli/tick.php --quiet
Alternativ über HTTP:
* * * * * curl -fsS -H "Authorization: Bearer <SHARED_KEY>" /api/watchdog/v1/evaluate > /dev/null
Aktive Projekte
Aktive Lizenzen
Hardware Aktivierungen
Watchdog Monitore
/ /

🛡️ Watchdog System-Hierarchie & Monitore

0); $iconUrl = getMonitorIconUrl($m['icon']??null, $m['source']??null, $m['os']??null, $m['type']??null); ?>
Hierarchie / Entity Source Typ Status Version Letzte Meldung Zuletzt Gesehen
icon ()

📁 Neues Projekt anlegen / Bearbeiten

Projekte Übersicht & Verwaltung

$l['product_slug'] === $p['slug'])); $relCount = count(array_filter($releases, fn($r) => $r['product_slug'] === $p['slug'])); ?>
ID Slug Projekt Name Cache TTL Verknüpfte Lizenzen Verknüpfte Releases Aktionen
h ( Tage) Lizenzen Releases
$l['status'] === 'active')); $blockedActivations = count(array_filter($activations, static fn($a): bool => !empty($a['is_blocked']))); ?>
Lizenzen gesamt
davon aktiv
Aktivierte Systeme
Gesperrte Hardware

🔑 Neuen Lizenzschlüssel generieren

Erstellte Lizenzschlüssel

0 && $used >= $max; $licJson = e((string)json_encode($l, JSON_INVALID_UTF8_SUBSTITUTE)); ?>
Projekt Lizenzschlüssel Kunde Aktivierungen Status Ablaufdatum Aktionen
Noch keine Lizenzen angelegt.
/
📥 .lic

🖥️ Aktivierte Hardware

Projekt Lizenzschlüssel Hardware-ID / Quelle Plattform Hostname Zuletzt gesehen Status Aktionen
Noch keine Aktivierungen.
Quelle:
· v

💾 Offline-Lizenzdatei (.lic)

Für Systeme ohne Internetzugang. Die Datei wird serverseitig erzeugt und mit HMAC-SHA256 über den Schlüssel aus security.license_key signiert. Am schnellsten geht es über den 📥 .lic-Knopf direkt in der Lizenzliste.

Lizenz auswählen und auf „Vorschau erzeugen“ klicken.

Diese Vorschau dient nur der Ansicht. Die gültige, signierte Datei liefert der 📥 .lic-Knopf in der Lizenzliste.

📜 Audit-Protokoll

ID Zeitpunkt Akteur Aktion Details
Noch keine Einträge.

💻 Endpunkte & Anbindung

Die Antwort von /validate trägt den Lizenzzustand im Feld status auf oberster Ebene (valid, revoked, expired, not_found, activation_limit) — bewusst ohne den Umschlag der übrigen API, weil bereits ausgelieferte Clients dieses Format erwarten.
POST /api/license/v1/validate Content-Type: application/json { "product": "myapp", "license_key": "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX", "hardware_id": "2:win:a765bd47...", "hostname": "DESKTOP-01", "app_version": "v1.4.2", "nonce": "zufallswert" } Antwort: { "type": "validation_result", "status": "valid", "expires_at": 1786435199, "cache_ttl_hours": 168, "message": "License is valid" }

Fertige Anbindung für .NET: Deploymentcenter.Client (LicenseClient, HardwareId, verschlüsselter Offline-Cache). Ausführlich in docs/LICENSE_INTEGRATION_GUIDE.md.

Gesund / Up
Warnungen
Down / Kritisch

📁 Gruppen-Übersicht

$gData): ?>
/ OK

🌳 Watchdog System-Hierarchie

0); $iconUrl = getMonitorIconUrl($m['icon']??null, $m['source']??null, $m['os']??null, $m['type']??null); ?>
Name Typ Status Version Zuletzt gesehen Kurz-Info / Message Aktionen
icon

🖥️ Monitor Anlegen

📜 Chronologisches Event-Log

Zeitpunkt (UTC) Source Kind Severity Nachricht

Neuen Agent-Token erstellen

Agent Tokens

Token ID Bezeichnung Gebundene Source Token Value Status Aktion

📦 Veröffentlichte Software Releases

'badge-up', 'beta' => 'badge-warning', 'dev' => 'badge-stopped', default => 'badge-up' }; $sizeFormatted = !empty($r['size_bytes']) ? round($r['size_bytes'] / (1024 * 1024), 2) . ' MB' : '-'; ?>
Projekt Kanal Plattform Version Git Commit Größe Release Notes Download & SHA256 Datum
v KRITISCH UNSIGNIERT ⬇️ Download Package
SHA: ...

Neues Software-Release veröffentlichen

Clients ohne Plattformangabe sehen ausschließlich any.
Dev Bugs (Entwicklung)
Prod Bugs (Produktion)
Offene Feature Requests
💡 Ideen & Gedanken
🤖 Von Agenten belegt
Gelöst / Umgesetzt

🤖 Aktive Agenten

Item(s) · Lease bis

🐛 Bugs, Features & Ideen Treffer

Zurücksetzen
💡 FEATURE' : '🐛 BUG'; $envBadge = match ((string)$item['environment']) { 'development' => '🔵 DEV', 'production' => '🔴 PROD', default => '' . e(strtoupper((string)$item['environment'])) . '', }; $statusBadge = match ((string)$item['status']) { 'open' => 'OFFEN', 'planned' => 'GEPLANT', 'in_progress' => 'IN BEARBEITUNG', 'resolved' => 'GELÖST', 'rejected' => 'ABGELEHNT', default => '' . e(strtoupper((string)$item['status'])) . '', }; $sevBadge = match ((string)$item['severity']) { 'idea' => '💡 IDEE', 'wishlist' => '⭐ WUNSCH', 'critical' => '🔥 KRITISCH', 'high' => 'HOCH', 'medium' => 'MITTEL', default => 'NIEDRIG', }; // json_encode liefert eine gueltige JS-Literaldarstellung; das // vorherige addslashes() konnte an Zeilenumbruechen zerbrechen. $jsonItem = e((string)json_encode($item, JSON_INVALID_UTF8_SUBSTITUTE)); $jsTitle = e((string)json_encode((string)$item['title'], JSON_INVALID_UTF8_SUBSTITUTE)); $isClaimed = !empty($item['claimed_by']) && !empty($item['lease_until']) && strtotime((string)$item['lease_until'] . ' UTC') > time(); ?>
ID / Typ Umgebung Projekt & Titel Build Schweregrad Anzahl Status Aktionen
Keine Einträge für diese Filterkombination.
#
Projekt: Von: 🔒 📲 🤖 📄 🏷️
x
1): ?>
Seite von ( Einträge)

➕ Bug, Feature Request oder Idee Erfassen

Fehler (24 h)
💀 Offene Abstürze
🔇 Stummgeschaltete Gruppen
davon Vorkommnisse
0): ?>
Vorkommnisse wurden als bekannt eingestuft und aus dieser Ansicht herausgehalten — ohne sie zu verwerfen. Der Zähler bleibt erhalten, damit eine auffällige Häufung trotzdem auffällt.

⚡ Fehler-Stream Gruppen

Zurücksetzen
'💀 FATAL', 'warning' => 'ℹ️ WARN', default => '⚠️ ERROR', }; // Rate im laufenden Fenster – auffällige Häufung sichtbar machen $windowCount = (int)($item['rate_window_count'] ?? 0); $windowFresh = !empty($item['rate_window_start']) && (time() - (int)strtotime((string)$item['rate_window_start'] . ' UTC')) < 3600; ?>
Klasse Fehler Projekt / Umgebung Build Anzahl Zuletzt Aktionen
Keine Fehler für diese Filterkombination.
Stummgeschaltete Einträge sind ausgeblendet — über „Nur stummgeschaltete“ sichtbar.
🔇 stummgeschaltet 1): ?> 📈 × in dieser Stunde 📄
×
1): ?>
Seite von ( Gruppen)

🔇 Bekannte, harmlose Fehler

Ein Treffer bedeutet nicht „wegwerfen“: Der Fehler wird weiterhin erfasst und hochgezählt, bleibt aber aus der Übersicht heraus und löst keine Benachrichtigung aus. Der Zähler ist dabei der eigentliche Gewinn — dass ein bekannter Fehler auftritt, ist normal; dass er plötzlich hundertmal so oft auftritt, ist ein Signal. Dafür ist die Alarmschwelle da.

0 oder leer = nie alarmieren
Pflichtfeld: In sechs Monaten weiß sonst niemand mehr, warum hier weggeschaut wird.

Bestehende Regeln

# Projekt Muster Begründung Alarmschwelle Treffer Status Aktionen
Noch keine Regeln angelegt.
ALLE
/h
Item(s) ·

💻 Anbindung

Ein Aufruf, den man in den globalen Exception-Handler hängt. Titel und Dringlichkeit leitet der Server ab, die Regeln oben greifen automatisch.

POST /api/errors/v1/report Authorization: Bearer <DC_TOKEN> Content-Type: application/json { "project_slug": "polytrader", "exception": "PDOException", "message": "SQLSTATE[23000]: Duplicate entry '...' for key 'uq_market'", "stack_trace": "...", "level": "error", // fatal = Prozess beendet "build": "v2.0.1", "environment": "production", "file": "src/Market/Importer.php", "line": 142 } Antwort: { "status": "success", "item_id": 42, "ignored": true, "occurrence_count": 3841, "rate_alerted": false, "message": "Als bekannt eingestuft, gezaehlt, nicht gemeldet." }

👑 Master-Tokens (Selbst-Provisionierung für Client-Apps & Host-Skripte)

Token ID Bezeichnung Typ / Identität Projekt / Lizenz Rechte (Scopes) Sub-Tokens Token Key Aktionen

Lic: ' . htmlspecialchars($mTok['license_key']) . '' : '' ?> Sub-Tokens
WIDERUFEN

🔑 Aktive Sub-Tokens (Per Provisioning API Erstellt)

$t['type'] === 'sub'); foreach ($subTokens as $sTok): $scopesArr = json_decode($sTok['scopes'], true) ?: []; $sRaw = !empty($sTok['raw_token']) ? $sTok['raw_token'] : $sTok['token_id']; $sMasked = (strlen($sRaw) > 12) ? substr($sRaw, 0, 12) . '••••••••••••••••' : $sRaw; ?>
Token ID Parent Master ID Bezeichnung / Client Umgebung Scopes Token Key Zuletzt Genutzt Status Aktionen

➕ Neuen Master-Token Erstellen

Stärkere Rechte schließen die schwächeren ein: bugtracker:manage umfasst Lesen und Melden, updateservice:publish auch Lesen. Für einen Coding-Agenten genügt daher Bugtracker verwalten.

['🌟 Alle Rechte', 'Uneingeschränkter Zugriff'], 'bugtracker:manage' => ['⚙️ Bugtracker verwalten', 'Übernehmen, kommentieren, schließen — schließt Lesen und Melden ein'], 'bugtracker:report' => ['🐛 Bugtracker melden', 'Nur Einträge anlegen — schließt Lesen ein'], 'bugtracker:read' => ['👁️ Bugtracker lesen', 'Nur Abfragen'], 'watchdog:ping' => ['🛡️ Watchdog Heartbeat', 'Statusmeldungen senden'], 'watchdog:read' => ['📊 Watchdog lesen', 'Monitore und Ereignisse abfragen'], 'updateservice:read' => ['📦 Updates prüfen', 'Auf neue Releases prüfen'], 'updateservice:publish' => ['🚀 Releases veröffentlichen', 'Neue Releases einstellen — schließt Prüfen ein'], ]; foreach ($scopeChoices as $value => $labels): ?>
Leer lassen für unbegrenzte Gültigkeit. Abgelaufene Tokens werden ab sofort tatsächlich abgewiesen — die Spalte existierte zuvor, wurde aber nie geprüft.

⚙️ Server & Umgebung

🩺 Systemzustand

PrüfungZustandHinweis
Watchdog-Evaluator Letzter Lauf: () Noch nie gelaufen — ohne ihn bleiben ausgefallene Monitore „up“.
Log-Verzeichnis beschreibbar var/log/ — Fehlerprotokolle
Konfiguration ausserhalb Git OK config/config.php ist per .gitignore ausgeschlossen

📖 API-Dokumentation

Die Schnittstelle beschreibt sich selbst. Der frühere fest im Quelltext hinterlegte Textblock ist durch eine maschinenlesbare OpenAPI-Beschreibung ersetzt — ein Agent kann sie abrufen und sich daran orientieren, ohne dass eine Prompt-Vorlage gepflegt werden muss.

Kernendpunkte im Überblick BUGTRACKER (Token mit bugtracker:report / :read / :manage) POST /api/bugtracker/v1/report Bug, Feature oder Idee melden GET /api/bugtracker/v1/projects Projekt-Discovery GET /api/bugtracker/v1/manage?action=list Filtern, Pagination, updated_since POST /api/bugtracker/v1/manage?action=next Nächstes Item holen UND übernehmen POST /api/bugtracker/v1/manage?action=comment&id=42 POST /api/bugtracker/v1/manage?action=resolve&id=42 UPDATESERVICE GET /api/updateservice/v1/check?product=myapp&version=1.0.0 POST /api/updateservice/v1/publish (Token mit updateservice:publish) schliesst automatisch alle Items mit passendem resolved_in_build WATCHDOG POST /api/watchdog/v1/ping Heartbeat (watchdog:ping) GET /api/watchdog/v1/evaluate Zustandsbewertung (Cron, Shared Key) TOKENS POST /api/tokens/v1/provision Sub-Token aus Master-Token SYSTEM GET /api/health Verfügbarkeit & Schema-Status GET /api/openapi.json Vollständige Spezifikation

🗄️ Datenbank-Migration

Führt ausstehende Migrationen aus. Bereits angewendete Versionen werden in dc_migrations vermerkt und übersprungen.

Hinweis zur Sicherheit: Dieser Endpunkt war zuvor ohne Anmeldung erreichbar und setzte bei jedem Aufruf das Administrator-Passwort auf einen fest im Quelltext stehenden Wert zurück. Er verlangt jetzt eine angemeldete Sitzung oder den Shared Key und legt ein Konto nur an, wenn noch keines existiert.
Migration jetzt ausführen