diff --git a/BACKEND_API.md b/BACKEND_API.md new file mode 100644 index 0000000..fa48065 --- /dev/null +++ b/BACKEND_API.md @@ -0,0 +1,210 @@ +# Backend API für LabelPrintAgent + +Diese Datei beschreibt die Endpunkte, die der PaperlessManager bereitstellen muss, damit der LabelPrintAgent Etiketten abholen, drucken und das Ergebnis zurückmelden kann. + +Der LabelPrintAgent rendert keine Layouts selbst. Das Backend liefert ein fertiges Etikettbild. + +## Authentifizierung + +Alle Endpunkte sollten denselben Bearer Token akzeptieren: + +```http +Authorization: Bearer {apiToken} +``` + +Der Token wird im Agent lokal verschlüsselt gespeichert. + +## 1. Nächsten Druckjob abrufen + +```http +GET /api/label-print-agent/jobs/next?agentId={agentId} +``` + +Der Agent ruft diesen Endpunkt alle X Sekunden auf. + +### Query-Parameter + +| Name | Pflicht | Beschreibung | +| --- | --- | --- | +| `agentId` | ja | Eindeutige ID des Agents, z. B. Rechnername | + +### Antwort, wenn kein Job vorhanden ist + +```http +204 No Content +``` + +### Antwort mit Bild direkt im JSON + +```http +200 OK +Content-Type: application/json +``` + +```json +{ + "jobId": "12345", + "labelImageBase64": "iVBORw0KGgoAAAANSUhEUgAA...", + "labelImageContentType": "image/png", + "labelWidthMm": 57, + "labelHeightMm": 32 +} +``` + +### Antwort mit separater Bild-URL + +```json +{ + "jobId": "12345", + "labelImageUrl": "/api/label-print-agent/jobs/12345/image", + "labelImageContentType": "image/png", + "labelWidthMm": 57, + "labelHeightMm": 32 +} +``` + +### Felder + +| Feld | Pflicht | Beschreibung | +| --- | --- | --- | +| `jobId` | ja | Eindeutige Job-ID für Rückmeldungen | +| `labelImageBase64` | bedingt | Base64-kodiertes Etikettbild | +| `labelImageUrl` | bedingt | URL zum Nachladen des Etikettbilds | +| `labelImageContentType` | empfohlen | z. B. `image/png` | +| `labelWidthMm` | ja | Etikettenbreite in mm, z. B. `57` | +| `labelHeightMm` | ja | Etikettenhöhe in mm, z. B. `32` | + +`labelImageBase64` oder `labelImageUrl` muss gesetzt sein. + +## 2. Etikettbild nachladen + +Nur erforderlich, wenn `labelImageUrl` verwendet wird. + +```http +GET /api/label-print-agent/jobs/{jobId}/image +``` + +### Antwort + +```http +200 OK +Content-Type: image/png +``` + +Body: Binärdaten des fertigen Etikettbilds. + +Empfehlung: PNG, schwarz/weiß, passend zum Etikettenformat, z. B. 57 x 32 mm bei 300 dpi. + +## 3. Erfolgreichen Druck melden + +```http +POST /api/label-print-agent/jobs/{jobId}/printed +Content-Type: application/json +``` + +### Request Body + +```json +{ + "agentId": "PC-BUERO", + "printerName": "DYMO LabelWriter 450" +} +``` + +### Antwort + +```http +200 OK +``` + +oder: + +```http +204 No Content +``` + +Das Backend sollte den Job erst hier endgültig als gedruckt markieren. + +## 4. Fehler melden + +```http +POST /api/label-print-agent/jobs/{jobId}/error +Content-Type: application/json +``` + +### Request Body + +```json +{ + "agentId": "PC-BUERO", + "printerName": "DYMO LabelWriter 450", + "errorMessage": "Drucker ist nicht verfügbar." +} +``` + +### Antwort + +```http +200 OK +``` + +oder: + +```http +204 No Content +``` + +Das Backend entscheidet danach, ob der Job erneut angeboten wird oder auf Fehler bleibt. + +## Backend-Verhalten + +Empfohlener Ablauf im Backend: + +1. Job erstellen und serverseitig Layout, Nummern, QR-Code und Bild erzeugen. +2. Job bleibt wartend, bis ein Agent ihn abholt. +3. `jobs/next` liefert jeweils höchstens einen Job. +4. Backend reserviert oder lockt den Job beim Ausliefern, damit zwei Agents ihn nicht parallel drucken. +5. Agent druckt lokal. +6. Agent meldet `printed` oder `error`. +7. Backend setzt den finalen Status. + +## Empfohlene Statuscodes + +| Situation | Status | +| --- | --- | +| Kein Job vorhanden | `204 No Content` | +| Job vorhanden | `200 OK` | +| Token fehlt/ungültig | `401 Unauthorized` | +| Agent darf nicht drucken | `403 Forbidden` | +| Job-ID unbekannt | `404 Not Found` | +| Backend-Fehler | `500 Internal Server Error` | + +## Server-Sent Events optional + +Später kann das Backend zusätzlich einen Event-Endpunkt anbieten: + +```http +GET /api/label-print-agent/events?agentId={agentId} +Accept: text/event-stream +``` + +Beispiel: + +```text +event: label-job-available +data: {"count":1} +``` + +Der Agent könnte dann bei einem Event sofort `jobs/next` aufrufen. Polling bleibt trotzdem als Fallback sinnvoll. + +## Wichtige Designentscheidung + +Der Agent kennt keine fachlichen Layouts mehr: + +- keine `layout_key` +- keine lokalen LabelTemplates +- keine MySQL-Verbindung +- keine Nummernreservierung +- kein QR-Code-Rendering + +Das Backend liefert ein fertiges Bild. Der Agent ist nur noch lokaler Windows-Druck-Connector. diff --git a/README.md b/README.md index bac43a1..5415d88 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ Optional kann später statt Polling Server-Sent Events ergänzt werden. Der aktu ## Backend-Vertrag +Die ausführliche API-Beschreibung liegt in [BACKEND_API.md](BACKEND_API.md). + Der Agent fragt standardmäßig: ```http