211 lines
4.3 KiB
Markdown
211 lines
4.3 KiB
Markdown
# 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.
|