fix(security, core): Auth-Pflicht für Ingest-APIs, 500er-Ursachen beheben, Agenten-Workflow

Sicherheit
- install_db.php war ohne Authentifizierung erreichbar und setzte bei jedem
  Aufruf das Admin-Passwort auf einen fest im Code stehenden Wert zurück.
  Jetzt Auth-Pflicht; ein Konto wird nur bei leerer Benutzertabelle angelegt.
- Stored XSS im Bugtracker-Detail-Modal: Titel, Beschreibung, Fehlermeldung,
  Stacktrace und Kommentare gingen ungefiltert durch innerHTML.
- report.php, projects.php und das Veröffentlichen von Releases verlangen jetzt
  zwingend ein Token. Publish war zuvor völlig ungeschützt.
- CSRF-Token in allen Formularen, Session-Regenerierung nach Login,
  Drosselung fehlgeschlagener Anmeldeversuche.
- Zugangsdaten aus der Versionskontrolle entfernt (Serverdaten.txt,
  config.php, .htpasswd, deploy_config.json). Historie enthält sie weiterhin,
  Rotation erforderlich (siehe docs/UPGRADE.md).
- Token-Validierung nur noch über SHA-256-Hash; expires_at wird ausgewertet.

Behobene 500er
- Audit::log() war in index.php weder eingebunden noch importiert. Jeder
  Klick auf "Aktivierung freigeben" endete in einem Fatal Error.
- Derselbe benannte PDO-Platzhalter mehrfach je Statement (:id in
  revokeToken/deleteToken, :q siebenfach in der Volltextsuche). Bei
  EMULATE_PREPARES=false ist das nicht zulässig und warf HY093.
- Migration 005 nutzte dynamisches SQL, dessen Semikolons in String-Literalen
  vom alten explode(';')-Installer als Statement-Ende gelesen wurden. Sie
  schlug still fehl, wodurch push_id/target_agent/tags dauerhaft fehlten.
- Monitor-Umbenennung ohne Transaktion, verschachtelte Transaktionen im
  RateLimiter.

Funktionale Korrekturen
- Der Watchdog-Evaluator fehlte vollständig: Monitor-Zustände änderten sich nur
  beim Eintreffen eines Heartbeats, ein ausgefallenes System blieb dauerhaft
  "up". Erster Lauf auf dem Produktivsystem: 7 von 10 Monitoren waren
  tatsächlich seit über einem Tag nicht erreichbar.
- Das Feld "os" fehlte im Monitor-Dialog, wurde aber gespeichert und löschte
  damit bei jedem Speichern das Betriebssystem.
- Der Resolve-Dialog existierte im HTML nicht; der Button war funktionslos.
- Versionsvergleich erfolgte lexikografisch, wodurch 1.9.0 als neuer galt
  als 1.10.0.
- Schreiboperationen meldeten Erfolg auch für nicht existierende IDs.
- Post/Redirect/Get gegen doppelte Einträge beim Neuladen.

Neue Struktur
- src/bootstrap.php mit PSR-4-Autoloader ersetzt die require-Ketten.
- Core: Config, Http, Csrf, ApiAuth, Logger, Migrator, ErrorReporter.
- Migrator mit zeichenweisem SQL-Parser, dc_migrations und Baseline-Verfahren,
  damit bestehende Installationen keine Beispieldaten zurückbekommen.

Agenten-Workflow
- Claim/Lease: Items werden exklusiv übernommen, damit nicht zwei Agenten am
  selben Problem arbeiten. action=next holt und reserviert in einem Zug.
- Idempotenz über client_ref, Deduplizierung auch für Feature Requests,
  Erkennung von Regressionen, automatische Eskalation des Schweregrads.
- Strukturierter Code-Kontext (repo_url, commit_sha, file_path, line_no).
- Delta-Abfragen über updated_since, Pagination, Bulk-Update.
- Beim Veröffentlichen eines Releases schließen sich Items mit passendem
  resolved_in_build selbst.
- Ausgehende Webhooks mit HMAC-Signatur, /api/health, /api/openapi.json.
- Unbehandelte Fehler meldet die Plattform in ihren eigenen Bugtracker.

WebUI
- Serverseitige Filterung mit Pagination statt Rendern aller Datensätze.
- Migrations-Schranke, Evaluator-Warnung, Übersicht aktiver Agenten.

Zeitstempel liegen in der Datenbank durchgängig in UTC und werden für die
Anzeige in die App-Zeitzone umgerechnet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Deploymentcenter Bot
2026-08-07 16:17:36 +02:00
co-authored by Claude Opus 5
parent a21536f495
commit e7fbc85db4
59 changed files with 8506 additions and 2410 deletions
+343 -196
View File
@@ -1,258 +1,405 @@
# 🤖 AI Agent Integration Guide: Deployment Center Bugtracker & Provisioning API
# Deployment Center — Agenten-Handbuch
This guide defines the standardized protocol and API specifications for autonomous AI Developer Agents interacting with the **Deployment Center Bugtracker & Token Provisioning System**.
Diese Seite beschreibt, wie ein Coding-Agent den Bugtracker und den
UpdateService des Deployment Centers benutzt.
**Maschinenlesbare Fassung:** `GET /api/openapi.json`
---
## 📌 Executive Overview for AI Agents
## 0. Was sich geändert hat
As an autonomous AI agent working on software repositories, you MUST actively track all runtime errors, stack traces, planned features, and backlog items in the central Deployment Center.
Wer eine ältere Integration betreibt, muss zwei Dinge anpassen:
### Core Capabilities:
1. **Sub-Token Auto-Provisioning**: Generate restricted sub-tokens for scoped agent tasks.
2. **Automated Error Ingestion**: Report unhandled exceptions with stack traces & automatic SHA-256 deduplication.
3. **Feature & Idea Backlog**: Submit roadmap ideas (`severity: "idea"`) or backlog items (`severity: "wishlist"`).
4. **Active Workflow Management**: Fetch active bugs assigned to your agent ID, update status (`in_progress`, `resolved`), and append diagnostic comments.
| Änderung | Auswirkung |
|---|---|
| `POST /api/bugtracker/v1/report` verlangt jetzt zwingend ein Token | Aufrufe ohne Token liefern `401 unauthorized` |
| `GET /api/bugtracker/v1/projects` verlangt jetzt ein Token | dito |
| `POST` auf UpdateService-Publish verlangt `updateservice:publish` | Aufrufe ohne Token liefern `401` |
| Antwortformat vereinheitlicht | Erfolg: `{"status":"success",...}`, Fehler: `{"status":"error","error":{"code":"…","message":"…"}}` |
Der Feldname `error_hash` bleibt erhalten; zusätzlich gibt es `dedup_key`.
---
## 🔑 1. Token Provisioning API
## 1. Authentifizierung
Agents authenticate using a **Master Token** or auto-provisioned **Sub-Token**.
Alle Endpunkte akzeptieren das Token in einem dieser Header:
### Endpoint: `POST /api/tokens/v1/provision`
Header: `Authorization: Bearer <MASTER_TOKEN>`
#### Request Payload:
```json
{
"parent_token": "dc_master_myapp_dev_agent_001",
"name": "Codebase Refactoring Agent Token",
"environment": "development",
"scopes": ["bugtracker:report", "bugtracker:manage"],
"expires_in_hours": 24
}
```
Authorization: Bearer dc_sub_xxxxxxxxxxxx
X-Agent-Token: dc_sub_xxxxxxxxxxxx
```
#### Response:
```json
{
"status": "success",
"token_id": "tok_s_8912ab",
"raw_token": "dc_sub_myapp_refactor_agent_991",
"scopes": ["bugtracker:report", "bugtracker:manage"],
"environment": "development",
"expires_at": "2026-08-07 21:00:00"
}
### Token-Hierarchie
* **Master-Token** (`dc_master_…`) — wird im WebUI unter *Token-Verwaltung* erzeugt.
Langlebig, gehört auf den Rechner bzw. in die CI, nicht in ein Repository.
* **Sub-Token** (`dc_sub_…`) — erzeugt sich ein Agent selbst aus dem Master-Token.
Rechte lassen sich dabei nur **einschränken**, nie erweitern.
### Sub-Token anfordern
```bash
curl -X POST https://dc.mhdf.de/api/tokens/v1/provision \
-H "X-Master-Token: dc_master_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"client_name": "claude-code auf DEV-WORKSTATION-01",
"instance_id": "DEV-WORKSTATION-01",
"scopes": ["bugtracker:report", "bugtracker:read", "bugtracker:manage"],
"environment": "development"
}'
```
Das zurückgegebene `sub_token` wird **nur einmal** ausgeliefert.
### Rechte (Scopes)
| Scope | Erlaubt |
|---|---|
| `bugtracker:report` | Bugs, Feature Requests und Ideen melden |
| `bugtracker:read` | Items und Projekte lesen |
| `bugtracker:manage` | Übernehmen, kommentieren, Status setzen, schließen |
| `watchdog:ping` | Heartbeats senden |
| `updateservice:read` | Auf Updates prüfen |
| `updateservice:publish` | Releases veröffentlichen |
| `bugtracker:*` | alle Bugtracker-Rechte |
| `*` | alles |
Ist ein Token an ein Projekt gebunden, greifen alle Aufrufe automatisch nur
auf dieses Projekt zu — ein Zugriff auf ein anderes liefert `403 project_forbidden`.
---
## 📂 1.5. Discovering Monitored Projects API
## 2. Projekte finden
Before reporting a bug or feature request, an agent can dynamically query all registered projects monitored by the Deployment Center.
```bash
curl https://dc.mhdf.de/api/bugtracker/v1/projects \
-H "Authorization: Bearer $DC_TOKEN"
```
### Endpoint: `GET /api/bugtracker/v1/projects.php`
#### Response:
```json
{
"status": "success",
"count": 4,
"projects": [
{
"id": 1,
"slug": "myapp",
"name": "My Application Deluxe",
"notes": "Hauptanwendung für Desktop und Server"
},
{
"id": 2,
"slug": "polytrader",
"name": "PolyTrader Suite Pro",
"notes": "Trading- und Handelssystem Client"
},
{
"id": 3,
"slug": "predictalytics",
"name": "Predictalytics Engine",
"notes": "Datenanalyse und Vorhersage Dienst"
},
{
"id": 4,
"slug": "deploymentcenter",
"name": "Deployment Center",
"notes": "Zentrale Verwaltungs- & Update-Plattform"
"repo_url": "https://git.example.com/Richard/Deploymentcenter.git",
"default_agent": null,
"open_items": 3,
"critical_items": 0
}
]
}
```
If an agent discovers an issue or refactoring opportunity in any monitored system (including `deploymentcenter` itself or external dependencies), it can fetch this project list and map the issue to the appropriate `project_slug`.
> Findest du einen Fehler im Deployment Center selbst, melde ihn unter
> `project_slug: "deploymentcenter"`.
---
## 🐛 2. Reporting Bugs, Features & Ideas
## 3. Etwas melden
### Endpoint: `POST /api/bugtracker/v1/report.php`
```bash
curl -X POST https://dc.mhdf.de/api/bugtracker/v1/report \
-H "Authorization: Bearer $DC_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: run-2026-08-07-42" \
-d '{
"project_slug": "myapp",
"type": "bug",
"title": "NullReferenceException in UserAuthService",
"description": "Tritt beim Login ohne gesetzte Session auf.",
"error_message": "Object reference not set to an instance of an object.",
"stack_trace": "at MyApp.Core.UserAuthService.ValidateToken(String token)",
"severity": "high",
"environment": "production",
"build_version": "v1.4.2",
Header: `Authorization: Bearer <AGENT_TOKEN>`
### A. Reporting an Unhandled Exception / Bug
```json
{
"project_slug": "myapp",
"type": "bug",
"title": "NullReferenceException in UserAuthService.cs line 42",
"description": "Triggered when user logs in without an active session object.",
"error_message": "NullReferenceException: Object reference not set to an instance of an object.",
"stack_trace": "at MyApp.Core.UserAuthService.ValidateToken(String token) in UserAuthService.cs:line 42\nat MyApp.Controllers.AuthController.Login() in AuthController.cs:line 18",
"build_version": "v1.4.2-dev",
"environment": "development",
"severity": "high",
"push_id": "push_wf_8912",
"target_agent": "agent:code-fixer-01",
"tags": "auth, security, csharp",
"created_by": "agent:watchdog-monitor"
}
"repo_url": "https://git.example.com/me/myapp.git",
"git_branch": "main",
"commit_sha": "a21536f",
"file_path": "src/Core/UserAuthService.cs",
"line_no": 42
}'
```
### B. Submitting a Feature Request or Quick Reminder Idea (`severity: "idea"`)
```json
{
"project_slug": "myapp",
"type": "feature_request",
"title": "Automatische Datenbank-Backups vor FTP Deployments",
"description": "Gedanke für später: Vor jedem FTP-Deployment automatisch mysqldump ausführen und im Server-Archiv ablegen.",
"build_version": "v1.6.0-roadmap",
"environment": "development",
"severity": "idea",
"push_id": "push_wf_9910",
"target_agent": "agent:db-optimizer",
"tags": "database, automation, backup",
"created_by": "agent:planner"
}
```
### Felder
| Feld | Pflicht | Bedeutung |
|---|---|---|
| `title` | ja | Kurze Beschreibung, max. 255 Zeichen |
| `project_slug` | empfohlen | Aus der Projektliste; Vorgabe `default` |
| `type` | nein | `bug` (Vorgabe) oder `feature_request` |
| `severity` | nein | `idea`, `wishlist`, `low`, `medium` (Vorgabe), `high`, `critical` |
| `environment` | nein | `production` (Vorgabe), `development`, `staging`, `testing` |
| `client_ref` | empfohlen | Idempotenz-Schlüssel, alternativ Header `Idempotency-Key` |
| `repo_url`, `git_branch`, `commit_sha`, `file_path`, `line_no` | empfohlen | Code-Kontext — spart dem nächsten Agenten das Parsen des Stacktrace |
| `context` | nein | Beliebiges JSON-Objekt für Zusatzinformationen |
| `push_id`, `target_agent`, `tags` | nein | Workflow-Zuordnung |
`created_by` wird aus dem Token abgeleitet und kann nicht gesetzt werden.
### Was der Server daraus macht
* **Deduplizierung** — gleiche Fehler werden zusammengefasst und
`occurrence_count` erhöht. Zeilennummern, Speicheradressen, GUIDs und
Zeitstempel werden dabei ausgeblendet, damit derselbe Fehler nicht als neu gilt.
Feature Requests und Ideen werden über den Titel dedupliziert.
* **Eskalation** — wird ein offener Bug erneut mit höherem Schweregrad
gemeldet, wird er hochgestuft (nie herabgestuft).
* **Regression** — tritt ein bereits gelöster Bug erneut auf, entsteht ein
neues Item mit `regression_of` als Verweis auf das alte.
* **Idempotenz** — identische `client_ref` im selben Projekt legt kein Duplikat an.
### Antwort
#### Response:
```json
{
"status": "success",
"item_id": 4,
"item_id": 42,
"is_new": true,
"idempotent_hit": false,
"occurrence_count": 1,
"error_hash": "e2c918a514d89a42f",
"type": "bug",
"environment": "development",
"push_id": "push_wf_8912",
"message": "New bug reported successfully."
"dedup_key": "e2c918a514d89a42f...",
"item_status": "open",
"regression_of": null,
"message": "Bug erfasst."
}
```
---
## 📌 3. Managing Items (Fetching, Updating & Commenting)
## 4. Die Agenten-Schleife
### Base Endpoint: `/api/bugtracker/v1/manage/index.php`
Basis: `https://dc.mhdf.de/api/bugtracker/v1/manage`
Header: `Authorization: Bearer <AGENT_TOKEN>`
### 4.1 Arbeit holen und übernehmen
### A. Fetching Open Items Assigned to an Agent
```http
GET /api/bugtracker/v1/manage/index.php?project_slug=myapp&status=open&agent=agent:code-fixer-01
```
Ein Aufruf, der die nächsten offenen Items liefert **und** exklusiv für dich
reserviert — damit arbeiten nicht zwei Agenten am selben Bug:
### B. Updating Status & Details (`POST ?action=update`)
```json
{
"id": 4,
"status": "in_progress",
"severity": "high",
"push_id": "push_wf_8912",
"target_agent": "agent:code-fixer-01",
"tags": "auth, fixed_pending_test",
"author": "agent:code-fixer-01"
}
```
### C. Appending Diagnostic Timeline Comments (`POST ?action=comment`)
```json
{
"id": 4,
"comment": "Ursache identifiziert: $_SESSION['user'] war Null in line 42. Null-Check und Safe Navigation Operator wurden hinzugefügt.",
"action_taken": "code_patched",
"author": "agent:code-fixer-01"
}
```
### D. Marking as Resolved (`POST ?action=resolve`)
```json
{
"id": 4,
"resolved_in_build": "v1.4.3-dev",
"resolution_notes": "Unit tests hinzugefügt und Null-Check in ValidateToken() integriert.",
"author": "agent:code-fixer-01"
}
```
---
## 💻 4. Code Implementation Examples for Agents
### Python Example: Automatic Error Reporter Decorator
```python
import requests
import traceback
import sys
DC_API_URL = "https://dc.mhdf.de/api/bugtracker/v1/report.php"
AGENT_TOKEN = "dc_sub_myapp_agent_live_001"
def report_exception_to_dc(project_slug: str, exc: Exception, env: str = "production", push_id: str = None):
payload = {
"project_slug": project_slug,
"type": "bug",
"title": f"{type(exc).__name__}: {str(exc)}",
"error_message": str(exc),
"stack_trace": traceback.format_exc(),
"build_version": "v1.4.2",
"environment": env,
"severity": "high",
"push_id": push_id,
"created_by": "agent:python-runner"
}
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {AGENT_TOKEN}"
}
try:
r = requests.post(DC_API_URL, json=payload, headers=headers, timeout=5)
return r.json()
except Exception as e:
print(f"Failed to report to Deployment Center: {e}", file=sys.stderr)
```
### cURL Example: Submit Feature Request / Idea
```bash
curl -X POST "https://dc.mhdf.de/api/bugtracker/v1/report.php" \
-H "Authorization: Bearer dc_sub_myapp_agent_live_001" \
curl -X POST "https://dc.mhdf.de/api/bugtracker/v1/manage?action=next" \
-H "Authorization: Bearer $DC_TOKEN" \
-H "Content-Type: application/json" \
-d '{"project_slug": "myapp", "limit": 1, "severity": "critical,high"}'
```
Die Reservierung (Lease) läuft nach 30 Minuten automatisch ab. Brauchst du
länger, erneuere sie mit `action=claim` auf dieselbe ID.
### 4.2 Zwischenstand dokumentieren
```bash
curl -X POST "https://dc.mhdf.de/api/bugtracker/v1/manage?action=comment&id=42" \
-H "Authorization: Bearer $DC_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"project_slug": "myapp",
"type": "feature_request",
"title": "Erweiterte Filterung im WebUI Dashboard",
"severity": "idea",
"push_id": "push_task_1029",
"tags": "ui, dashboard",
"created_by": "agent:dev-assistant"
}'
"comment": "Ursache gefunden: Session wird vor dem Redirect nicht initialisiert.",
"action_taken": "investigated"
}'
```
Empfohlene Werte für `action_taken`: `investigated`, `fix_proposed`,
`pr_opened`, `needs_human`, `blocked`, `commented`.
### 4.3 Abschließen
```bash
curl -X POST "https://dc.mhdf.de/api/bugtracker/v1/manage?action=resolve&id=42" \
-H "Authorization: Bearer $DC_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"resolved_in_build": "v1.4.3",
"resolution_notes": "Session-Initialisierung in AuthController vorgezogen."
}'
```
### 4.4 Wieder freigeben
Kommst du nicht weiter, gib das Item zurück, statt den Lease verfallen zu lassen:
```bash
curl -X POST "https://dc.mhdf.de/api/bugtracker/v1/manage?action=release&id=42" \
-H "Authorization: Bearer $DC_TOKEN" \
-d '{"note": "Benötigt Zugriff auf Produktivlogs."}'
```
---
## 🎯 Best Practices for Developer Agents
## 5. Lesen und Filtern
1. **Always set `push_id`**: When executing automated pipelines, pass a `push_id` so all updates can be traced back to the specific execution run.
2. **Use `severity: "idea"` for thoughts**: When noticing potential refactorings or future improvements during coding, log them immediately as ideas.
3. **Comment before resolving**: Before calling `action=resolve`, write a diagnostic comment explaining **why** and **how** the fix was performed.
```bash
curl "https://dc.mhdf.de/api/bugtracker/v1/manage?action=list&project_slug=myapp&status=open,in_progress&order=severity&limit=20" \
-H "Authorization: Bearer $DC_TOKEN"
```
| Parameter | Bedeutung |
|---|---|
| `status`, `severity` | Mehrere Werte kommagetrennt |
| `type`, `environment`, `project_slug` | Einzelwert oder `all` |
| `target_agent`, `claimed_by`, `push_id` | Exakte Übereinstimmung |
| `search` | Volltext über Titel, Beschreibung, Fehlermeldung, Tags, Dateipfad |
| `unclaimed_only` | `true` — nur Items, die kein Agent bearbeitet |
| `updated_since` | ISO-8601 — **Delta-Abfrage für effizientes Polling** |
| `order` | `newest`, `oldest`, `updated`, `severity`, `occurrences` |
| `limit`, `offset` | Pagination, max. 500 pro Seite |
Die Antwort enthält `total`, `limit`, `offset` und `has_more`.
### Polling-Muster
```bash
# Nur was sich seit dem letzten Durchlauf geändert hat
curl "…/manage?action=list&updated_since=2026-08-07T09:00:00Z&order=updated" \
-H "Authorization: Bearer $DC_TOKEN"
```
---
## 6. Release veröffentlichen und Items automatisch schließen
Der Kreis schließt sich hier: Items, deren `resolved_in_build` der
veröffentlichten Version entspricht, werden beim Publish automatisch geschlossen.
```bash
curl -X POST https://dc.mhdf.de/api/updateservice/v1/publish \
-H "Authorization: Bearer $DC_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"product_slug": "myapp",
"version": "1.4.3",
"channel": "prod",
"download_url": "https://dc.mhdf.de/downloads/myapp-1.4.3.zip",
"sha256_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"git_commit": "a21536f",
"release_notes": "Behebt den Login-Fehler."
}'
```
```json
{
"status": "success",
"release_id": 12,
"created": true,
"auto_resolved": 3,
"message": "Release 1.4.3 (prod) für \"myapp\" veröffentlicht. 3 Bugtracker-Item(s) automatisch geschlossen."
}
```
Der Versionsvergleich folgt der semantischen Versionsordnung — `1.10.0` gilt
korrekt als neuer als `1.9.0`.
---
## 7. Fehlerbehandlung
Fehler tragen einen stabilen, maschinenlesbaren Code. Reagiere auf `code`,
nicht auf `message`:
```json
{
"status": "error",
"error": { "code": "already_claimed", "message": "Item #42 ist bereits vergeben." }
}
```
| Code | HTTP | Bedeutung und Reaktion |
|---|---|---|
| `unauthorized` | 401 | Token fehlt, ist abgelaufen oder hat den Scope nicht |
| `project_forbidden` | 403 | Token ist an ein anderes Projekt gebunden |
| `already_claimed` | 409 | Anderer Agent arbeitet daran — nächstes Item nehmen |
| `not_claimed` | 409 | Freigabe eines Items, das dir nicht gehört |
| `not_found` | 404 | Item existiert nicht |
| `rate_limited` | 429 | Sendefrequenz senken, später erneut |
| `invalid_json` | 400 | Request-Body ist kein gültiges JSON |
| `missing_id`, `missing_status`, `missing_build` | 400 | Pflichtfeld fehlt |
| `invalid_status`, `invalid_version`, `invalid_hash` | 400 | Wert nicht zulässig |
| `internal_error` | 500 | Serverfehler — wird automatisch selbst im Bugtracker erfasst |
**Rate-Limit:** 60 Reports pro Minute und IP. Bei `429` das Intervall verdoppeln.
---
## 8. Vollständige Beispielschleife (Python)
```python
import os, requests
BASE = "https://dc.mhdf.de/api/bugtracker/v1/manage"
HEAD = {"Authorization": f"Bearer {os.environ['DC_TOKEN']}",
"Content-Type": "application/json"}
def next_item(project):
r = requests.post(f"{BASE}?action=next", headers=HEAD,
json={"project_slug": project, "limit": 1})
r.raise_for_status()
items = r.json().get("items", [])
return items[0] if items else None
def comment(item_id, text, action="investigated"):
requests.post(f"{BASE}?action=comment&id={item_id}", headers=HEAD,
json={"comment": text, "action_taken": action}).raise_for_status()
def resolve(item_id, build, notes):
requests.post(f"{BASE}?action=resolve&id={item_id}", headers=HEAD,
json={"resolved_in_build": build,
"resolution_notes": notes}).raise_for_status()
def release(item_id, reason):
requests.post(f"{BASE}?action=release&id={item_id}", headers=HEAD,
json={"note": reason}).raise_for_status()
item = next_item("myapp")
if item is None:
print("Nichts zu tun.")
else:
print(f"#{item['id']}: {item['title']}")
if item.get("file_path"):
print(f" -> {item['file_path']}:{item.get('line_no', '?')}")
comment(item["id"], "Analyse gestartet.")
try:
# ... hier die eigentliche Arbeit ...
resolve(item["id"], "v1.4.3", "Fix in AuthController.")
except Exception as exc:
release(item["id"], f"Abbruch: {exc}")
```
---
## 9. Watchdog-Heartbeat
Läuft dein Agent als Dienst, melde dich regelmäßig:
```bash
curl -X POST https://dc.mhdf.de/api/watchdog/v1/ping \
-H "Authorization: Bearer $DC_TOKEN" \
-H "Content-Type: application/json" \
-d '{"source": "agent-worker-01", "status": "ok", "interval": 60,
"message": "Verarbeite Warteschlange", "metrics": {"queue": 3}}'
```
`interval` ist der erwartete Abstand in Sekunden. Bleibt der Heartbeat aus,
stuft der Evaluator den Monitor nach dem Doppelten auf `warning` und nach dem
Vierfachen auf `down`.
---
## 10. Verfügbarkeit prüfen
```bash
curl https://dc.mhdf.de/api/health -H "Authorization: Bearer $DC_TOKEN"
```
Meldet Datenbankzustand, ausstehende Migrationen, Bugtracker-Kennzahlen und
wann der Watchdog-Evaluator zuletzt lief.