# Backend API – LabelPrintAgent Diese Datei beschreibt die Endpunkte des PaperlessManager-Backends für den LabelPrintAgent. Das Backend rendert das fertige Etikettbild (SVG → PNG via resvg-js). Der Agent ist nur lokaler Druck-Connector. ## Authentifizierung Alle Endpunkte erfordern einen Bearer Token (JWT oder API-Key): ```http Authorization: Bearer {token} ``` `/jobs/next`, `/jobs/:id/image`, `/jobs/:id/printed` und `/jobs/:id/error` benötigen **keine** spezifische Permission (nur gültigen Token). `POST /jobs` und `POST /preview` erfordern `VIEW_SCANNER`. --- ## 1. Job manuell anlegen (Frontend → Backend) ```http POST /api/label-print-agent/jobs Content-Type: application/json ``` ### Request Body ```json { "templateId": 3, "fieldValues": { "datum": "2026-05-09" } } ``` | Feld | Pflicht | Beschreibung | |---|---|---| | `templateId` | ja | ID des BarcodeTemplates | | `fieldValues` | nein | Feldwerte für Platzhalter; Datumsfelder im Format `YYYY-MM-DD` | ### Antwort ```http 201 Created ``` ```json { "jobId": "42" } ``` --- ## 2. Vorschau-Bild rendern (kein Job, keine Nummer-Reservierung) ```http POST /api/label-print-agent/preview Content-Type: application/json ``` ### Request Body Identisch mit `POST /jobs`. `{number}` wird immer als `1` gerendert — die GET-URL wird **nicht** aufgerufen. ### Antwort ```http 200 OK Content-Type: image/png ``` Body: binäres PNG-Bild. --- ## 3. Nächsten Druckjob abrufen (Agent-Polling) ```http GET /api/label-print-agent/jobs/next?agentId={agentId} ``` | Parameter | Pflicht | Beschreibung | |---|---|---| | `agentId` | nein | Eindeutige Agent-ID (z. B. Rechnername); Fallback: `"unknown"` | ### Antwort – kein Job vorhanden ```http 204 No Content ``` ### Antwort – Job vorhanden ```http 200 OK Content-Type: application/json ``` ```json { "jobId": "42", "labelImageBase64": "iVBORw0KGgoAAAANSUhEUgAA...", "labelImageContentType": "image/png", "labelWidthMm": 57, "labelHeightMm": 32 } ``` | Feld | Beschreibung | |---|---| | `jobId` | Job-ID für Rückmeldungen | | `labelImageBase64` | Base64-PNG; `null` wenn Rendering fehlgeschlagen | | `labelImageContentType` | Immer `"image/png"` | | `labelWidthMm` / `labelHeightMm` | Etikettenmaß in mm | Das Backend setzt beim Ausliefern einen Lock (5-Minuten-TTL). Jobs mit abgelaufenem Lock werden erneut angeboten. --- ## 4. Etikettbild separat abrufen Alternativ zum Base64-Feld in `jobs/next`. ```http GET /api/label-print-agent/jobs/{jobId}/image ``` ### Antwort ```http 200 OK Content-Type: image/png ``` Body: binäres PNG-Bild. ```http 404 Not Found – Job oder Bild nicht vorhanden ``` --- ## 5. 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" } ``` Alle Felder optional; Fallback jeweils `""` / `"unknown"`. ### Antwort ```http 200 OK ``` ```json { "ok": true } ``` Das Backend setzt den Job auf `printed`, speichert Zeitstempel und ruft die konfigurierte `LabelPrintedUrl` des Templates auf (`POST`). --- ## 6. Druckfehler 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 nicht verfügbar." } ``` ### Antwort ```http 200 OK ``` ```json { "ok": true } ``` Das Backend setzt den Job auf `error` und ruft die konfigurierte `LabelReleaseUrl` des Templates auf (`POST`). --- ## Job-Lebenszyklus ``` createJob() │ ▼ pending ──── jobs/next ──── Lock (5 Min TTL) │ Agent druckt │ ┌───────┴───────┐ printed error (PrintedUrl) (ReleaseUrl) ``` ## 7. Server-Sent Events – neue Druckaufträge (Push) ```http GET /api/label-print-agent/events Authorization: Bearer {token} Accept: text/event-stream ``` Der Agent verbindet sich einmalig. Sobald ein neuer Druckauftrag erstellt wird, sendet das Backend: ``` data: {"type":"label-job-available"} ``` Der Agent ruft daraufhin sofort `GET /jobs/next` auf. Polling bleibt als Fallback sinnvoll (z. B. alle 30 s), falls die SSE-Verbindung unterbrochen wurde. Es werden keine agentId-Parameter ausgewertet – alle verbundenen Agents erhalten das Event. --- ## Statuscodes | Situation | Status | |---|---| | Kein Job vorhanden | `204 No Content` | | Job / Bild vorhanden | `200 OK` | | Job erstellt | `201 Created` | | Token fehlt / ungültig | `401 Unauthorized` | | Fehlende Permission | `403 Forbidden` | | Job-ID unbekannt | `404 Not Found` | | Backend-Fehler | `500 Internal Server Error` |