Document backend print agent API

This commit is contained in:
2026-05-07 17:55:44 +02:00
parent 5a45aa0a93
commit feb0b384ae
2 changed files with 212 additions and 0 deletions
+210
View File
@@ -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.
+2
View File
@@ -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