173 lines
8.9 KiB
Markdown
173 lines
8.9 KiB
Markdown
# Übergabe-API v1
|
||
|
||
Die API erstellt interne Case-Pakete und veröffentlicht sie atomar in der Inbox.
|
||
Externe Programme liefern Metadaten und Dateien; sie erzeugen und bearbeiten keine
|
||
internen Manifeste. Die API führt keine Analyse und keine LLM-Aufrufe aus. Ein
|
||
dauerhaft laufender [Analyseworker](analysis-worker.md) übernimmt anschließend die
|
||
Aufnahme und Verarbeitung. Die [Weboberfläche](web-console.md) bietet Übersicht,
|
||
Auftragsübergabe, Testerantworten und Ergebnisdownloads.
|
||
|
||
## Lokaler Start
|
||
|
||
```powershell
|
||
.\.venv\Scripts\python.exe -m pip install -e '.[api]'
|
||
Copy-Item config/api.example.toml config/api.local.toml
|
||
$env:VBA_INTAKE_TOKEN = [Convert]::ToHexString([System.Security.Cryptography.RandomNumberGenerator]::GetBytes(32))
|
||
.\.venv\Scripts\python.exe -m viano_bug_analysis.api check --config config/api.local.toml
|
||
.\.venv\Scripts\python.exe -m viano_bug_analysis.api serve --config config/api.local.toml
|
||
```
|
||
|
||
Der API-Token ist ein eigener Zugangsschlüssel, kein Gemini-Key. Programme erhalten
|
||
vorzugsweise einen Schlüssel aus der [Web-Schlüsselverwaltung](integration-keys.md).
|
||
Alternativ bleiben Clients mit Token aus einer serverseitigen Umgebungsvariable
|
||
unterstützt; der Beispielstart oben zeigt diese Variante. Der
|
||
Token benötigt 32–256 Zeichen aus `A-Z a-z 0-9 _ -`. Auf älterem Windows PowerShell
|
||
kann ein solcher Token über einen Passwortmanager erzeugt und als Variable gesetzt
|
||
werden. Der Beispielstart bindet nur an `127.0.0.1:8080`. Für entfernte Nutzung sind
|
||
HTTPS und ein passend konfigurierter Reverseproxy erforderlich. Tokens nicht in
|
||
URLs oder Git-Konfiguration ablegen. Zugriff auf das Workspace-Dateisystem bleibt
|
||
auf den Dienst und vertrauenswürdige Betreiber beschränkt.
|
||
|
||
`projects` ist die serverseitige Freigabeliste. Jeder Auftrag benennt `project_id`
|
||
und `profile_id`. Er kann keine Repository-URLs, DB-Zugänge, Budgets oder
|
||
Konfigurationspfade überschreiben. Optionale `projects.settings` halten die spätere
|
||
Worker-Konfiguration bereit; die Eingangsschicht verwendet diese Dateien nicht für
|
||
Analysen. Aktuell ist der Importadapter `vcore` für `wow/vcore` implementiert.
|
||
Weitere Projekte benötigen passende Adapter/Profile, keine separat gepflegten Forks.
|
||
|
||
## Endpunkte
|
||
|
||
| Methode/Pfad | Bedeutung |
|
||
|---|---|
|
||
| `GET /healthz` | Minimale öffentliche Erreichbarkeitsprüfung |
|
||
| `GET /v1/profiles` | Für diesen Client freigegebene Projekte/Profile |
|
||
| `GET /v1/schema` | Öffentliches JSON-Schema der Übergabemetadaten |
|
||
| `GET /v1/overview` | Projektbezogene Worker-/Fallübersicht und Tokenstatistik |
|
||
| `POST /v1/submissions` | Multipart-Upload, `201` bei neuer Einreihung, `200` bei Wiederholung |
|
||
| `GET /v1/submissions/{id}` | Quittung und aktueller verwalteter Zustand |
|
||
| `GET /v1/submissions/{id}/package` | Abgeschlossene Akte herunterladen; sonst `409` |
|
||
|
||
Alle Endpunkte außer Health benötigen `Authorization: Bearer TOKEN`.
|
||
POST benötigt zusätzlich `Idempotency-Key: frei-gewaehlte-eindeutige-id` (1–128
|
||
Zeichen, Buchstaben/Ziffern sowie Punkt, Unterstrich, Bindestrich; erstes Zeichen
|
||
alphanumerisch). Derselbe Client/Schlüssel mit denselben Metadaten und Dateiinhalten
|
||
liefert dieselbe Quittung, auch nach einem Neustart. Abweichender Inhalt ergibt
|
||
`409 API_IDEMPOTENCY_CONFLICT`. Dateinamen und Multipart-Grenzen zählen nicht als
|
||
Inhaltsänderung; Rollen und Reihenfolge der Dateien zählen. Ein zweiter neuer
|
||
Auftrag für dasselbe Projekt und dieselbe Case-ID wird zurückgewiesen.
|
||
|
||
## Neuer Auftrag
|
||
|
||
`metadata` ist ein UTF-8-JSON-Textfeld, kein Datei-Upload. Dateien: genau einmal
|
||
`wowdiag`, optional einmal `wowsrc`, optional mehrfach `attachments`. Für Vcore muss
|
||
die Case-ID dem Bug des Erfassungsarchivs entsprechen (`BUG-000020`). Beide
|
||
Erfassungsarchive müssen zueinander passen. Beispiel `submission.json`:
|
||
|
||
```json
|
||
{
|
||
"kind": "new_case",
|
||
"project_id": "viano-core",
|
||
"profile_id": "vcore",
|
||
"case_id": "BUG-000020",
|
||
"report": {
|
||
"title": "Wolpertinger fehlen",
|
||
"observations": ["Nach Questannahme waren im untersuchten Gebiet keine Tiere sichtbar."],
|
||
"expected_behavior": ["Fangbare Tiere sind im Gebiet vorhanden."]
|
||
},
|
||
"versions": {
|
||
"reported_server": "commit-des-gemeldeten-serverstands",
|
||
"capture_server": "commit-des-erfassungsstands"
|
||
}
|
||
}
|
||
```
|
||
|
||
```powershell
|
||
curl.exe --fail-with-body -H "Authorization: Bearer $env:VBA_INTAKE_TOKEN" -H "Idempotency-Key: bug20-capture-001" -F "metadata=<submission.json" -F "wowdiag=@wowdiag.tar.gz" -F "wowsrc=@wowsrc.tar.gz" http://127.0.0.1:8080/v1/submissions
|
||
```
|
||
|
||
Versionsangaben werden als unbestätigte Angaben des Einlieferers gespeichert, nicht
|
||
als verifizierte technische Fakten. Sie ersetzen keine Prüfung des Deployments.
|
||
Zusätzliche Anhänge werden unter generierten internen Namen unverändert erhalten;
|
||
sie werden nicht ausgeführt. Originalarchive bleiben ebenfalls erhalten.
|
||
|
||
## Rückläufer nach Abschluss
|
||
|
||
Dateien: genau einmal `case_package` (unveränderte abgeschlossene ZIP-Akte), optional
|
||
mehrfach `attachments`. Kein erneutes Erzeugen interner JSON-Dateien nötig:
|
||
|
||
```json
|
||
{
|
||
"kind": "case_return",
|
||
"project_id": "viano-core",
|
||
"profile_id": "vcore",
|
||
"case_id": "BUG-000020",
|
||
"feedback": {
|
||
"outcome": "patch_failed",
|
||
"summary": "Der Patch wurde getestet, das Verhalten besteht weiter.",
|
||
"observations": ["Die Tiere bleiben auch nach Neustart unsichtbar."],
|
||
"patch_id": "pr-123",
|
||
"tested_build": "commit-des-getesteten-builds"
|
||
}
|
||
}
|
||
```
|
||
|
||
```powershell
|
||
curl.exe --fail-with-body -H "Authorization: Bearer $env:VBA_INTAKE_TOKEN" -H "Idempotency-Key: bug20-patch123-feedback" -F "metadata=<return.json" -F "case_package=@case.zip" http://127.0.0.1:8080/v1/submissions
|
||
```
|
||
|
||
Zulässig sind `OUTPUT_READY`, `HANDED_OFF`, `FAILED_TO_ANALYZE`. Die API übernimmt
|
||
bei `OUTPUT_READY` die interne Übergabemarkierung, ergänzt Feedback, Bericht und
|
||
Anhänge und wechselt anschließend nach `REOPENED`. Die Paketidentität bleibt,
|
||
`analysis_revision` steigt genau einmal. Bisherige Artefakte bleiben erhalten und
|
||
der Casebuilder sieht die neuen Beobachtungen. Das neue Paket wird in die Inbox
|
||
gelegt; `QUEUED` bedeutet ausschließlich angenommen, nicht erfolgreich analysiert.
|
||
|
||
Ein verwalteter Fall darf nur mit seiner exakten aktuellen Akte zurückgegeben
|
||
werden. Veraltete/divergierende Akten und parallele Rückgaben werden abgewiesen.
|
||
Ohne lokale Fallhistorie ist eine gültige abgeschlossene, passend zugeordnete Akte
|
||
importierbar. Alte manuelle Testpakete ohne `project.id` benötigen vorerst eine
|
||
betreiberseitige Migration; sie werden nicht stillschweigend einem Projekt zugeordnet.
|
||
BLOCKED-Fälle, laufende Fälle und asynchrone Testerantworten innerhalb einer
|
||
Untersuchung sind keine Abschlussrückläufer und werden hier nicht wiedereröffnet.
|
||
|
||
## Grenzen und Wiederanlauf
|
||
|
||
Standard: 768 MiB gesamter HTTP-Body, 512 MiB je Datei, 64 KiB Metadaten, 12 Dateien,
|
||
120 Sekunden Uploadzeit und zwei gleichzeitige Uploads pro Prozess. Konfigurierbar
|
||
über `[limits]` mit den Feldnamen aus `IntakeLimits`. Die existierenden Import- und
|
||
ZIP-Validatoren setzen zusätzlich ihre eigenen Grenzen durch (Vcore-Import ist
|
||
enger begrenzt). Dies sind Betriebsschutzwerte, keine fachlichen Analysebudgets.
|
||
|
||
Uploads werden vor dem Parsen authentifiziert. Auch Requests ohne Content-Length
|
||
werden anhand tatsächlich empfangener Bytes begrenzt. Multipart-Spools werden bei
|
||
Fehler/Timeout geschlossen, eigene temporäre Arbeitskopien wieder entfernt. Der
|
||
Dienst prüft freien Speicher vor Aufnahme und Paketbau. Für den ersten Betrieb
|
||
einen einzelnen Uvicorn-Prozess verwenden; die Upload-Parallelitätsgrenze gilt pro
|
||
Prozess. Der Workspace verwendet zusätzlich OS-Dateisperren für Veröffentlichung.
|
||
|
||
Unter `runtime/intake/requests` bleiben kleine Quittungen und Hashes. Vor der
|
||
atomaren Inbox-Veröffentlichung wird eine PREPARED-Quittung mit fertigem Paket
|
||
gesichert. Beim Neustart werden solche Veröffentlichungen fortgesetzt. Nach
|
||
Einreihung wird die zusätzliche Paketkopie entfernt. Bereits vom Worker übernommene
|
||
Pakete werden über ihre Checkpoint-Kette erkannt und nicht erneut eingereiht.
|
||
Nach hartem Prozessabbruch können verwaiste Arbeitsverzeichnisse unter
|
||
`runtime/intake/staging` und Betriebssystem-Temporärdateien verbleiben; deren
|
||
betriebliche Bereinigung/Retention gehört zum folgenden Worker-/Dienst-Ausbau.
|
||
|
||
Fehlerantworten enthalten stabile Codes, keine Dateipfade oder Secrets. Wesentliche
|
||
Fälle: `401` Zugriff, `403` Projektfreigabe, `409` Konflikt/Zustand, `413` Größe,
|
||
`422` ungültige Metadaten/Archive, `503` beschäftigt/Speicherfehler, `507` freier
|
||
Speicher zu gering. Bei `503` mit demselben Idempotenzschlüssel wiederholen.
|
||
|
||
## Lokale Prüfung
|
||
|
||
```powershell
|
||
.\.venv\Scripts\python.exe -m pip install -e '.[api,api-test]'
|
||
.\.venv\Scripts\python.exe -m pytest tests/profiles/vcore/test_intake_api.py -q
|
||
```
|
||
|
||
Die Tests verwenden künstliche Erfassungsarchive und HTTP-Testtransport. Sie prüfen
|
||
auch Feedbackübernahme durch den echten Casebuilder, Idempotenz, veraltete
|
||
Rückläufer, Uploadgrenzen sowie Abstürze vor und nach Queue-Veröffentlichung. Es
|
||
finden keine kostenpflichtigen LLM-Aufrufe statt.
|