Zum Inhalt springen
Abläufe

Pass-Links zurück ins ERP

Mit einem Schlüssel mit Scope read dem Änderungsfeed folgen und GS1 Digital Link, Passstatus und QR-Code jeder Einheit an ihrem Seriennummernsatz im ERP speichern.

Etiketten, Lieferscheine und Servicewerkzeuge in Ihrem ERP brauchen den Link zum Pass jeder Batterie. In diesem Ablauf folgt die Middleware mit einem Schlüssel mit Scope read dem Änderungsfeed von BatteryPass, liest Einheit und Pass und schreibt GS1 Digital Link und Passstatus an den Seriennummernsatz im ERP. In BatteryPass wird nichts geschrieben.

sequenceDiagram
  participant MW as Middleware
  participant BP as BatteryPass-API
  participant ERP
  loop alle paar Minuten
    MW->>BP: listChanges mit gespeichertem Cursor und Passtypen (Scope read)
    BP-->>MW: Änderungen, älteste zuerst, next_cursor
    MW->>BP: getBattery (Scope read)
    MW->>BP: getPassport (Scope read)
    MW->>BP: getPassportQr, wenn ein Etikett nötig ist (Scope read)
    MW->>ERP: Digital Link und Status am Seriennummernsatz speichern
    MW->>MW: next_cursor speichern, nachdem das ERP angenommen hat
  end

Auslöser: Ein Pass wird veröffentlicht, neu veröffentlicht oder zurückgezogen.

Scopes des Schlüssels: read

#WerWasOperation
1MiddlewareFragt den Änderungsfeed mit dem gespeicherten Cursor ab, etwa alle fünf Minuten, gefiltert auf Passänderungen.listChanges read
2MiddlewareLiest die Einheit, um Seriennummer und Modell zu erhalten, mit denen sie den Satz im ERP findet.getBattery read
3MiddlewareLiest den Pass der Einheit mit Status, aktueller Version und GS1 Digital Link.getPassport read
4MiddlewareLädt den QR-Code (PNG oder SVG), wenn ein Etikett gedruckt werden soll.getPassportQr read
5ERPSpeichert Digital Link und Passstatus am Seriennummern- oder Equipmentsatz; der Etikettendruck liest sie dort.
6MiddlewareSpeichert den Cursor erst, nachdem das ERP die Änderung angenommen hat; nach einem Absturz wiederholt sie Änderungen, statt sie zu verlieren.

Sicherheit

  • Ein Schlüssel nur mit dem Scope read; er kann nichts verändern.
  • Der Feed liefert dünne Ereignisse ohne Werte; die Daten holt die Middleware danach mit demselben Schlüssel, sodass ein abgefangener Feed nichts preisgibt.
  • Änderungen kommen mindestens einmal an; das Schreiben ins ERP ist idempotent (gleicher Link, gleicher Status).

Datenminimierung

  • Ins ERP gehen nur Digital Link, Passstatus und Versionsnummer, keine Passinhalte.

Der Änderungsfeed

GET /api/v1/changes liefert die Änderungen Ihrer Organisation, älteste zuerst. Jede Änderung nennt nur, was geschah und welche Entität betroffen ist; den aktuellen Stand lesen Sie an der Entität.

typesstring[]query

Kommagetrennte Änderungsarten; ohne Angabe alle. Für diesen Ablauf: passport.published, passport.republished, passport.withdrawn.

cursorstringquery
Der next_cursor Ihrer letzten Seite; ohne ihn beginnt der Feed am Anfang der Geschichte Ihrer Organisation.
limitintegerqueryStandard: 50
Höchstens 200.
200
{
  "items": [
    {
      "id": "0192f6d2-3c4e-7a5b-8c9d-0e1f2a3b4c5d",
      "occurred_at": "2026-10-24T09:12:40Z",
      "entity_type": "battery",
      "entity_id": "0192a3f0-5b7c-7d21-8e4f-6a2b9c1d3e5f",
      "action": "passport.published"
    }
  ],
  "next_cursor": "eyJ4IjoxODQ0MiwiaSI6IjAxOTJmNmQyLTNjNGUtN2E1Yi04YzlkLTBlMWYyYTNiNGM1ZCJ9"
}
actionentity_typeDanach lesen
battery.createdbatterygetBattery
passport.published, passport.republished, passport.withdrawnbattery (die Einheit)getPassport
condition.updated, lifecycle_event.recordedbatterygetCondition, listLifecycleEvents
model_version.approvedmodel_versiongetModelVersion
import.committed, import.approvedimportein Schlüssel mit Scope import: getImport

Drei Regeln machen das Abfragen verlässlich:

  • next_cursor ist gesetzt, sobald die Seite Einträge hat, auch auf der letzten Seite. Speichern Sie ihn und senden Sie ihn beim nächsten Mal. Eine leere Seite hat next_cursor: null: Behalten Sie den gesendeten Cursor.
  • Eine Änderung erscheint erst, wenn jede ältere Transaktion beendet ist. Ein Cursor springt deshalb nie über eine Änderung, die spät festgeschrieben wurde. Eine Änderung kann einige Sekunden nach dem Ereignis erscheinen.
  • Speichern Sie den Cursor erst, nachdem das ERP die Änderungen der Seite angenommen hat. Nach einem Absturz sehen Sie dieselben Änderungen erneut (mindestens einmal); denselben Link und Status zweimal zu schreiben, schadet nicht.

Abfragen und zurückschreiben

curl -sS "$BATTERYPASS_URL/api/v1/changes?types=passport.published,passport.republished,passport.withdrawn&limit=100&cursor=$CURSOR" \
  -H "Authorization: Bearer $BATTERYPASS_READ_KEY"

curl -sS "$BATTERYPASS_URL/api/v1/batteries/0192a3f0-5b7c-7d21-8e4f-6a2b9c1d3e5f/passport" \
  -H "Authorization: Bearer $BATTERYPASS_READ_KEY" | jq '{status, passport_id, gs1_digital_link, version: .current_version.version_no}'

curl -sS -o etikett.svg "$BATTERYPASS_URL/api/v1/batteries/0192a3f0-5b7c-7d21-8e4f-6a2b9c1d3e5f/passport/qr?format=svg" \
  -H "Authorization: Bearer $BATTERYPASS_READ_KEY"

Der Pass trägt, was das ERP braucht: serial_number und gtin, um den Satz zu finden, gs1_digital_link für das Etikett ({resolver}/01/{gtin}/21/{serial}), status (published, update_needed, withdrawn, …), passport_id und current_version.version_no. Ein Etikettendrucker holt den QR-Code mit getPassportQr (format=png mit size oder format=svg); er enthält denselben Digital Link. getBattery ergänzt Modell, Modellversion und Daten, wenn Ihr ERP-Satz sie braucht.

Der erste Lauf ohne Cursor geht durch Ihre gesamte Geschichte; filtern Sie mit types und lassen Sie ihn einmal laufen, bevor Sie ihn einplanen. Wie der Digital Link aufgelöst wird, beschreibt Digital Link auflösen.

Was ins ERP gehört

Nur Digital Link, Passstatus und Versionsnummer. Passinhalte bleiben in BatteryPass: Die öffentliche Seite und das öffentliche JSON hinter dem Digital Link sind immer aktuell, und eingeschränkte Daten dürfen nicht in Systeme mit größerem Leserkreis kopiert werden.

Fehlerbehandlung

AntwortBedeutungWas tun
400 validation_error auf cursorDer gespeicherte Cursor ist nicht verwendbarLöschen; der nächste Lauf beginnt am Anfang und wiederholt Änderungen, was nicht schadet, weil derselbe Link zweimal nichts ändert.
400 validation_error auf typesEine unbekannte ÄnderungsartListe korrigieren.
401 unauthenticatedSchlüssel fehlt, ist unbekannt oder widerrufenGeheimnis prüfen; Alarm auslösen.
403 forbiddenDem Schlüssel fehlt der Scope readDen Lese-Schlüssel verwenden.
404 not_found bei einer EinheitDie Einheit gehört nicht zu Ihrer OrganisationÜberspringen und die ID der Änderung protokollieren.
409 conflict bei getPassportQrDie Kennungen sind noch nicht festgelegtNach dem nächsten passport.published erneut fragen.
429 rate_limitedZu viele AnfragenRetry-After Sekunden warten; Cursor behalten.
5xx, ZeitüberschreitungErgebnis unbekanntMit Backoff wiederholen; der Cursor zeigt noch vor die Seite.

Auf dieser Seite