Befehle für den Plattformbetrieb
Die Befehle des internen Werkzeugs szenera-ops, die nur mit einem Betreiber-Profil laufen: Geräte-Software, Approvals, Störungen, Warteschlangen, Organisationen, Betreiberkonten.
18 Minuten LesezeitCLIStand: 25.10.2026
Auf dieser Seite
- Gesundheit
- Geräte der Flotte
- Störungen und Wartungsfenster
- Warteschlangen, Cache, Ereignisse und Verbindungen
- Fehler- und Rechte-Katalog
- Organisationen
- Betreiber-Konten und Betreiber-Schlüssel
- Gerätesoftware
- Anfragen an eine zweite Person
- Plattform-Einstellungen
- App-Katalog
- Abrechnung und Artikel
- Weiterführendes
Bevor Sie loslegen
- Für wen
- Wer die Plattform betreibt — Geräte-Software freigibt, Störungen führt, Warteschlangen und Organisationen verwaltet
- Voraussetzung
- der Quellbaum der Plattform, ein Profil mit
audience: "operator"und die Rechteplatform.*aus der Spalte „Recht". Die Spalte „Schlüssel" sagt, ob ein Betreiber-Schlüsselopk_…das Recht tragen darf.
Die Befehle des Werkzeugs szenera-ops, die nur mit einem Profil vom Publikum operator laufen — einem Betreiber-Konto oder einem Betreiber-Schlüssel opk_…. Sie betreffen Kundinnen und Kunden der Plattform nicht und gehören nicht zur Kommandozeile szenera. Sie stehen hier, weil whoami, device, audit, player, playback, permission, api-key und invoice je nach Profil beide Seiten bedienen.
Das Werkzeug liegt im Quellbaum unter tools/ops-cli und wird nicht ausgeliefert. Es läuft mit pnpm -s szenera-ops <befehl> und führt alle 230 Befehle der Plattform. Profile, Umgebungsvariablen, Ausgabe und Exit-Codes sind dieselben wie bei szenera. Dazu kennt es das Publikum operator (Profilfeld audience, Umgebungsvariable SZENERA_AUDIENCE), seine eigene Profil-Datei .secrets/szenera-profile.json im Quellbaum und den Rückfall auf die Umgebungen in .secrets/umgebungen.json. Ein Befehl, der nur einer Seite dient, weist das Profil der anderen ab, bevor ein Aufruf hinausgeht.
Die Tabellen haben dieselbe Form wie unter Befehle für Ihre Organisation: Befehl, Zweck, Route und Recht, ob ein Schlüssel das Recht tragen darf, ob der Befehl etwas verändert. Betreiber-Schlüssel laufen 1 bis 365 Tage (Vorgabe 90). Welche Rechte ein solcher Schlüssel überhaupt führen darf, zeigt szenera-ops permission catalog --key-eligible unter einem Betreiber-Profil — es sind die lesenden Betriebsrouten, die Geräte-Software und das Lesen der Vermarktung. Alles andere bleibt Menschen mit Zwei-Faktor-Anmeldung vorbehalten. Von den 230 Befehlen des Werkzeugs stehen 136 unter Befehle für Ihre Organisation, es sind die Befehle von szenera. Die übrigen 94 laufen nur unter einem Betreiber-Profil und stehen hier. 21 der 136 dienen beiden Seiten: 14 davon nehmen unter einem Betreiber-Profil einen eigenen Weg (whoami, device list, device get, audit list, audit get, player get-program, playback timeline, permission catalog, die vier Befehle api-key …, invoice list und invoice get), sieben laufen unverändert (health, health public und die fünf Befehle des Notausgangs api …).
Gesundheit
| Befehl | Zweck | Route und Recht | Schlüssel | Verändert |
|---|---|---|---|---|
health deep |
Ein Urteil aus fünf Quellen, der Befehl nach dem Aufspielen. Eine rote Quelle macht den Befehl rot, eine stumme steht als unknown |
GET /health/ready, GET /v1/platform/ops/platform-health, GET …/ops/jobs/health, GET …/ops/cache/health, GET …/ops/events/dispatcher/health, GET …/ops/audit/health · platform.ops.health.read, platform.jobs.health.read, platform.cache.stats.read, platform.events.dispatcher.read, platform.audit.health.read |
teils — Cache und Prüfprotokoll nur mit Konto | nein |
Mit --json trägt die Antwort das Urteil unter verdict (green oder yellow) und je Quelle unter sources die Felder name, status und hint. Ein rotes Urteil endet stattdessen mit Exit 11. Die Gegenprobe von außen ist health public: dieselbe Auskunft, die die Statusseite zeigt, ohne Ausweis und ohne Betreiber-Profil — sie beantwortet „Was sehen unsere Kunden gerade?“ und nicht „Wie steht es wirklich?“. Der Befehl steht unter Befehle für Ihre Organisation.
Geräte der Flotte
| Befehl | Zweck | Route und Recht | Schlüssel | Verändert |
|---|---|---|---|---|
device list |
Die Geräte aller Organisationen, auch die ohne Organisation. Dazu --tenant=<tnt_…>, --all-tenants, --silent-only (seit über einer Viertelstunde stumm) |
GET /v1/platform/ops/devices · platform.ops.device.read |
ja | nein |
device get <dev_…> |
Ein Gerät in der Betriebssicht: Organisation und Seriennummer | GET /v1/platform/ops/devices/{deviceId} · platform.ops.device.read |
ja | nein |
device lookup --serial=<text> |
Ein Gerät über die Hardware-Seriennummer finden | GET /v1/platform/ops/devices/lookup · platform.ops.device.read |
ja | nein |
device get-command <dev_…> <cmd_…> |
Was aus einem Befehl an ein Gerät wurde. --wait wartet bis zum Ende (Exit 11 bei failed/timeout, Exit 12 beim Zeitlimit) |
GET /v1/platform/ops/devices/{id}/commands/{commandId} · platform.ops.device.command-read |
ja | nein |
device release <dev_…> --reason=reconnect|factory|removed --yes |
Ein Gerät freigeben, der Grund ist Pflicht. reconnect und removed lassen WLAN und Fernzugang stehen, factory nimmt beides mit. Alle Displays des Geräts gehen mit |
POST /v1/platform/ops/devices/{deviceId}/release · platform.ops.device.reset |
nein | ja |
device block <dev_…> --reason=<text> --yes |
Ein Gerät sperren: Es verliert seine Organisation, alle Displays gehen mit, jedes Zertifikat wird gesperrt, und jede Anmeldung weist die API mit 409 Device.Blocked ab. Der Grund (1 bis 500 Zeichen) ist Pflicht |
POST /v1/platform/ops/devices/{deviceId}/block · platform.ops.device.reset |
nein | ja |
device unblock <dev_…> |
Die Sperre aufheben. Das Gerät steht danach ungekoppelt und lässt sich neu koppeln | POST /v1/platform/ops/devices/{deviceId}/unblock · platform.ops.device.reset |
nein | ja |
device check-ota <dev_…> |
Ein Gerät sofort nach einem neuen OS-Stand sehen lassen. Antwort 202, --wait braucht zusätzlich platform.ops.device.command-read |
POST /v1/platform/ops/devices/{id}/ota-check · platform.ops.device.ota-check |
ja | ja |
device channel --channel=beta|stable|canary --device=<dev_…> --yes |
Den Channel mehrerer Geräte in einem Aufruf wechseln, --device darf sich bis zu 100-mal wiederholen. Jedes Gerät bekommt sein Ergebnis, ein Gerät, das scheitert, hält die übrigen nicht auf |
POST /v1/platform/ops/devices/channel · platform.ops.device.channel |
nein | ja |
player get-program <ply_…> |
Was einem Display zugewiesen ist — über alle Organisationen, protokolliert | GET /v1/platform/ops/devices/{playerId}/program · platform.ops.device.playback-read |
ja | nein |
playback timeline <ply_…> |
Die aufgelöste Abspiel-Timeline eines Displays — über alle Organisationen, protokolliert | GET /v1/platform/ops/devices/{playerId}/timeline · platform.ops.device.playback-read |
ja | nein |
Jeder Aufruf von device get-command steht im Prüfprotokoll der betroffenen Organisation. Ein Betreiber-Profil kann mit device send-command und device screenshot nichts anfangen: Diese Routen verlangen fleet.player.command.issue und weisen eine Betreiber-Identität ab. Das Werkzeug sagt das vor dem Aufruf.
Störungen und Wartungsfenster
| Befehl | Zweck | Route und Recht | Schlüssel | Verändert |
|---|---|---|---|---|
incident list |
Die Störungsmeldungen, mit --id=<inc_…> eine einzelne samt Chronik |
GET /v1/platform/ops/incidents · platform.ops.incident.list, mit --id GET …/incidents/{id} · platform.ops.incident.read |
nein | nein |
incident create --title=… --severity=sev-1…sev-4 --scope=platform|tenant|device-fleet |
Eine Störung eröffnen. --public stellt sie zugleich auf die Statusseite, ohne die Flagge bleibt sie intern |
POST /v1/platform/ops/incidents · platform.ops.incident.open |
nein | ja |
incident update <inc_…> --message=… |
Einen Eintrag in die Chronik schreiben. --status wandert zugleich weiter, --public stellt die Störung auf die Statusseite, --internal nimmt sie herunter |
PATCH /v1/platform/ops/incidents/{id} · platform.ops.incident.update |
nein | ja |
incident resolve <inc_…> |
Eine Störung abschließen, dazu --postmortem=<url> |
POST /v1/platform/ops/incidents/{id}/resolve · platform.ops.incident.resolve |
nein | ja |
maintenance-window list |
Die geplanten Wartungsfenster, mit --id=<mtw_…> ein einzelnes |
GET /v1/platform/ops/maintenance-windows · platform.ops.maintenance.list, mit --id platform.ops.maintenance.read |
nein | nein |
maintenance-window create --title=… --start=… --end=… --scope=… |
Ein Wartungsfenster planen. --banner, --notify-days=<tage>, --block-mutations hält schreibende Aufrufe der Organisationen an |
POST /v1/platform/ops/maintenance-windows · platform.ops.maintenance.create |
nein | ja |
maintenance-window update <mtw_…> |
Ein Fenster verschieben oder umschreiben | PATCH /v1/platform/ops/maintenance-windows/{id} · platform.ops.maintenance.update |
nein | ja |
maintenance-window cancel <mtw_…> --reason=… |
Ein Fenster absagen. Der Grund wandert in die Benachrichtigung | DELETE /v1/platform/ops/maintenance-windows/{id} · platform.ops.maintenance.cancel |
nein | ja |
Warteschlangen, Cache, Ereignisse und Verbindungen
| Befehl | Zweck | Route und Recht | Schlüssel | Verändert |
|---|---|---|---|---|
job queues |
Die Warteschlangen samt Kennzahlen und Zustand — aus drei Quellen, eine Tabelle | GET …/ops/jobs/queues, GET …/ops/jobs/metrics, GET …/ops/jobs/health · platform.jobs.queues.read, platform.jobs.metrics.read, platform.jobs.health.read |
ja | nein |
job pause <name> |
Eine Warteschlange pausieren. Was läuft, läuft zu Ende | POST /v1/platform/ops/jobs/queues/{queueName}/pause · platform.jobs.queues.pause |
nein | ja |
job resume <name> |
Eine angehaltene Warteschlange fortsetzen | POST /v1/platform/ops/jobs/queues/{queueName}/resume · platform.jobs.queues.resume |
nein | ja |
job failed |
Die endgültig gescheiterten Jobs, mit --not-replayed, --queue=<name>, --id=<kennung> |
GET /v1/platform/ops/jobs/dead-letter, GET …/dead-letter/{id} · platform.jobs.dead-letter.read |
ja | nein |
job replay --id=<kennung>|--all --reason=… |
Einen gescheiterten Job — oder viele — erneut einstellen. --max (Vorgabe 100) deckelt |
POST …/jobs/dead-letter/{id}/replay, POST …/jobs/dead-letter/bulk-replay · platform.jobs.replay |
nein | ja |
job kill <jobId> --queue=<name> --reason=… --yes |
Einen laufenden Job abbrechen, Antwort 202 | POST /v1/platform/ops/jobs/{queueName}/{jobId}/force-kill · platform.jobs.force-kill |
nein | ja |
job cleanup --yes |
Alte Dead-Letter-Einträge räumen | POST /v1/platform/ops/jobs/cleanup/run · platform.jobs.cleanup |
nein | ja |
cache stats |
Zustand, Trefferquote und die heißen Themen, dazu --window=1m|5m|1h |
GET …/ops/cache/health, GET …/ops/cache/stats, GET …/ops/cache/topics · platform.cache.stats.read |
nein | nein |
cache invalidate --topic=<thema>|--pattern=<glob> --reason=… --yes |
Ein Thema oder ein Muster verwerfen | POST …/ops/cache/invalidate, POST …/ops/cache/invalidate-pattern · platform.cache.invalidate |
nein | ja |
event pending |
Was noch nicht ausgeliefert ist. --metrics hängt Zahlen und Gesundheit des Verteilers an |
GET /v1/platform/ops/events/outbox/pending · platform.events.outbox.read |
ja | nein |
event failed |
Was endgültig nicht ausgeliefert wurde | GET /v1/platform/ops/events/outbox/dead-letter · platform.events.outbox.read |
ja | nein |
event get <evt_…> |
Ein Ereignis samt Nutzlast — genau das, was verschickt wurde | GET /v1/platform/ops/events/outbox/{eventId} · platform.events.outbox.read |
ja | nein |
event replay --id=<evt_…>|--all --reason=… |
Ein Ereignis — oder viele — erneut zustellen, dazu --event-type, --since, --max |
POST …/events/outbox/{eventId}/replay, POST …/events/outbox/replay-bulk · platform.events.outbox.replay |
nein | ja |
connection list |
Die offenen Echtzeit-Verbindungen: Display, Portal-Sitzung oder Renderer | GET /v1/platform/realtime/connections · platform.realtime.read |
nein | nein |
connection disconnect <id> --yes |
Eine Verbindung trennen. Der Client verbindet sich danach neu | POST /v1/platform/realtime/connections/{id}/disconnect · platform.realtime.disconnect |
nein | ja |
Der Grund bei job replay, job kill, cache invalidate und event replay ist Pflicht und mindestens zehn Zeichen lang.
Fehler- und Rechte-Katalog
| Befehl | Zweck | Route und Recht | Schlüssel | Verändert |
|---|---|---|---|---|
error catalog |
Alle Fehlercodes der API samt HTTP-Status, dazu --search=<text> |
GET /v1/platform/ops/errors/catalog · platform.errors.catalog.read |
nein | nein |
permission catalog |
Der Rechte-Katalog. --key-eligible zeigt, was ein Betreiber-Schlüssel führen darf |
GET /v1/permission-catalog, nur Anmeldung |
nicht belegt | nein |
permission drift |
Was der Bestand gegenüber dem Katalog vermissen lässt. Ändert nichts | GET /v1/platform/ops/permissions/catalog-drift · platform.permissions.catalog.read |
nein | nein |
permission reload |
Den Katalog neu einlesen — nötig, wenn App-Rechte dazukommen | POST /v1/platform/ops/permissions/catalog/reload · platform.permissions.catalog.reload |
nein | ja |
permission backfill |
Die Rollen der Organisationen an den Katalog nachziehen, dazu --tenant=<tnt_…>. --dry-run rechnet nur, --reconcile nimmt auch weg. Betreiber-Konten brauchen das nicht: Ihre Rechte folgen der Rolle |
POST …/ops/permissions/roles/backfill · platform.permissions.role.backfill |
nein | ja |
permission flush-cache --yes |
Den Cache der wirksamen Rechte verwerfen | POST /v1/platform/ops/permissions/cache/flush · platform.permissions.cache.flush |
nein | ja |
Organisationen
| Befehl | Zweck | Route und Recht | Schlüssel | Verändert |
|---|---|---|---|---|
tenant list |
Die Organisationen der Plattform (active, frozen, suspended, deleted) |
GET /v1/platform/tenants · platform.tenant.list |
nein | nein |
tenant get <tnt_…> |
Eine Organisation in der Betriebssicht | GET /v1/platform/tenants/{id} · platform.tenant.read |
nein | nein |
tenant provision --slug=… --name=… --owner-email=… --address=… |
Organisation, Abonnement, Inhaber und Einladung in einem Zug, dazu --licenses, --set=<k=v> |
POST /v1/platform/tenants/provision · platform.tenant.provision, mit --set PATCH …/tenants/{tenantId}/feature-entitlements · platform.billing.override |
nein | ja |
tenant overview <tnt_…> |
Die Betriebsakte: Flotte, Inhalte, Ansprechpartner | GET /v1/platform/tenants/{tenantId}/overview · platform.tenant.read |
nein | nein |
tenant suspend <tnt_…> --reason=… --yes |
Eine Organisation sperren — kaskadiert auf ihre Konten | POST /v1/platform/tenants/{id}/suspend · platform.tenant.suspend |
nein | ja |
tenant resume <tnt_…> |
Eine Sperre aufheben | POST /v1/platform/tenants/{id}/resume · platform.tenant.resume |
nein | ja |
tenant delete <tnt_…> --slug=… --yes |
Eine Organisation löschen, nicht umkehrbar. Der Kurzname ist die Bestätigung. Ihre Geräte werden freigegeben und zeigen danach einen Kopplungscode | DELETE /v1/platform/tenants/{id} · platform.tenant.delete |
nein | ja |
tenant entitlements <tnt_…> |
Vertragliche Fähigkeiten lesen und mit --set=<k=v> setzen (Schalter on oder off) |
GET …/tenants/{tenantId}/feature-entitlements · platform.billing.invoice.read, PATCH … · platform.billing.override |
nein | ja |
tenant licensing <tnt_…> |
Vertragslage: Lizenzen, Artikel, Sonderkonditionen | GET /v1/platform/tenants/{tenantId}/licensing · platform.billing.invoice.read |
nein | nein |
tenant price-override <tnt_…> --sku=<code> |
Eine Sonderkondition setzen (--price oder --discount, nie beides) oder mit --clear zurücknehmen |
PUT …/tenants/{tenantId}/licensing/items/{skuCode}/override · platform.billing.override |
nein | ja |
tenant sso-recovery <tnt_…> --email=… --reason=… --yes |
SSO-Notfallzugang für ein Konto ausstellen | POST /v1/platform/tenants/{tenantId}/sso-recovery · platform.tenant.sso-recovery |
nein | ja |
self-registration set |
Selbst-Registrierung lesen, mit --on/--off --reason=… schalten |
GET/PUT /v1/platform/self-registration · platform.self-registration.manage |
nein | ja |
Die Einladungs-Adresse aus tenant provision steht im Klartext in der Ausgabe (--json: inviteUrl) — die einzige Stelle, an der dieses Token die API verlässt.
Betreiber-Konten und Betreiber-Schlüssel
| Befehl | Zweck | Route und Recht | Schlüssel | Verändert |
|---|---|---|---|---|
operator list |
Die Betreiber-Konten, mit --role=owner|manager|support|viewer, --status, --search und --with-permission=<platform.…> (Konten, deren Rolle das Recht trägt) |
GET /v1/platform/operators · platform.operator.list |
nein | nein |
operator get <ops_…> |
Ein Betreiber-Konto samt Rolle und der Stufe der Rolle je Bündel | GET /v1/platform/operators/{id} · platform.operator.list |
nein | nein |
operator create --email=… --name=… --role=manager|support|viewer |
Ein Betreiber-Konto anlegen. Die Rolle ist Pflicht, owner gibt es hier nicht. Die Zwei-Faktor-Einrichtung erscheint genau einmal |
POST /v1/platform/operators · platform.operator.create |
nein | ja |
operator set-role <ops_…> --role=manager|support|viewer --yes |
Die Rolle ersetzen. Nur der Owner, nie die eigene, nie die des Owners. Die neuen Rechte gelten mit der nächsten Anfrage des Kontos | PATCH /v1/platform/operators/{id}/role · platform.operator.create |
nein | ja |
operator transfer-owner <ops_…> --totp-code=<123456> |
Den Owner übertragen, Schritt 1: Der Owner bietet dem Konto an. Das Angebot gilt sieben Tage, ein neues ersetzt das frühere. --accept --totp-code=… (Schritt 2, unter dem Profil des Ziels) nimmt an, danach ist das Ziel Owner und der bisherige Owner Manager. --status zeigt das offene Angebot |
POST /v1/platform/operators/{id}/owner-transfer, POST …/operators/owner-transfer/accept, GET …/operators/owner-transfer · platform.operator.create, bei Annahme und Stand platform.operator.list |
nein | ja |
operator suspend <ops_…> --reason=… |
Ein Betreiber-Konto sperren | POST /v1/platform/operators/{id}/suspend · platform.operator.suspend |
nein | ja |
operator reactivate <ops_…> |
Die Sperre aufheben | POST /v1/platform/operators/{id}/reactivate · platform.operator.suspend |
nein | ja |
operator reset-mfa <ops_…> --reason=… --yes |
Zwei-Faktor neu einrichten. Der bisherige Authenticator gilt nicht mehr | POST /v1/platform/operators/{id}/mfa-reset · platform.operator.mfa-reset |
nein | ja |
operator resend-onboarding <ops_…> |
Die Einrichtungs-Mail erneut verschicken. Sie gilt 72 Stunden | POST /v1/platform/operators/{id}/onboarding-resend · platform.operator.mfa-reset |
nein | ja |
api-key list |
Die Betreiber-Schlüssel des Hauses | GET /v1/platform/api-keys · platform.operator.api-key.list |
nein | nein |
api-key issue --name=… --permissions=<a,b,c> |
Einen Betreiber-Schlüssel opk_… ausstellen. --days=<1–365> (Vorgabe 90), --list-allowed zeigt die freigegebenen Rechte |
POST /v1/platform/api-keys · platform.operator.api-key.create |
nein | ja |
api-key rotate <oak_…> |
Einen Betreiber-Schlüssel erneuern, dazu --grace-hours=<0–72>, --days |
POST /v1/platform/api-keys/{id}/rotate · platform.operator.api-key.create |
nein | ja |
api-key revoke <oak_…> --yes |
Einen Betreiber-Schlüssel zurückziehen — sofort und endgültig | DELETE /v1/platform/api-keys/{id} · platform.operator.api-key.revoke |
nein | ja |
Gerätesoftware
Der Baustein ist immer das erste Wort hinter dem Befehl: os, agent, renderer, host-webos oder host-tizen. Eine Version nennt der Befehl mit der Bau-Kennung (zwölf Hex-Stellen), list zeigt sie.
| Befehl | Zweck | Route und Recht | Schlüssel | Verändert |
|---|---|---|---|---|
device-software list <baustein> |
Die Versionen in der Ablage, neueste zuerst: Anzeigename mit Welt (0.6.1-prod), Bau, Stand, die Channels, in denen sie gilt, die Zahl der Geräte und die Größe |
GET /v1/platform/ops/device-software/{component}/builds · platform.ops.device-software.read |
ja | nein |
device-software releases <baustein> |
Was in den Channels gilt, und der Verlauf der Freigaben, mit --limit und --cursor |
GET …/device-software/{component}/releases · platform.ops.device-software.read |
ja | nein |
device-software devices <baustein> |
Die Geräte, die den Baustein fahren, mit Channel, Fassung, Bau und Stand zur Freigabe (current, updating, rolled-back, outdated, no-release). Dazu --channel, --build, --state |
GET …/device-software/{component}/devices · platform.ops.device-software.read |
ja | nein |
device-software activity |
Der Verlauf über alle Bausteine: Freigaben, Importe, Löschungen, Anfragen und die Rücknahmen, die Geräte meldeten. Dazu --component=<baustein> |
GET …/device-software/activity · platform.ops.device-software.read |
ja | nein |
device-software release <baustein> <bau> --channel=… --yes |
Eine Version in einem Channel gelten lassen. --pull-along=beta,canary zieht tiefere Channels im selben Schritt nach, --note, --security. Verlangt die Plattform eine zweite Person (releaseApproval.deviceSoftware), entsteht nach stable eine Anfrage, --reason=… ist dann Pflicht |
POST …/device-software/{component}/releases · platform.ops.device-software.release |
nein | ja |
device-software promote <baustein> --from=… --to=… --yes |
Den Bau, der heute im tieferen Channel gilt, im höheren freigeben, sonst wie release |
GET und POST …/device-software/{component}/releases · platform.ops.device-software.release |
nein | ja |
device-software delete <baustein> <bau> --yes |
Die Bytes einer Version löschen, der Datensatz bleibt als Grabstein. Geschützt ist eine Version, die in einem Channel gilt oder auf die eine Anfrage zeigt (DeviceSoftware.BuildInUse, Exit 6) |
DELETE …/device-software/{component}/builds/{build} · platform.ops.device-software.delete |
nein | ja |
device-software cleanup <baustein> --dry-run|--yes |
Die Versionen jenseits der neuesten --keep-newest=<n> (ohne Angabe retention.deviceSoftware.keepNewest) löschen, die sich löschen lassen. --dry-run nennt nur, was gelöscht würde |
POST …/device-software/{component}/builds/cleanup · platform.ops.device-software.delete |
nein | ja |
device-software nudge <baustein> <dsr_…> |
Die Geräte des Channels sofort an die geltende Freigabe erinnern | POST …/device-software/{component}/releases/{id}/nudge · platform.ops.device-software.release |
nein | ja |
device-software image <bau> |
Die kurzlebige Bezugsadresse des SD-Karten-Abbilds zu einer Version von SzeneraOS | GET …/device-software/os/builds/{build}/image · platform.ops.device-software.read |
ja | nein |
Einen Bau holt das Werkzeug nicht: Die Umgebung gleicht sich alle zehn Minuten mit der Registry ab, die CI beschleunigt es mit POST …/builds/import-from-registry (platform.ops.device-software.import, mit Betreiber-Schlüssel). release und promote verlangen --yes, weil eine Freigabe die Geräte des Channels erreicht.
Anfragen an eine zweite Person
Für Gerätesoftware und Apps gleich. Ob ein Release nach stable eine zweite Person braucht, stellt der Owner mit settings set releaseApproval.deviceSoftware|apps stable.
| Befehl | Zweck | Route und Recht | Schlüssel | Verändert |
|---|---|---|---|---|
approval list |
Die Anfragen, ohne --state die offenen. Dazu --state=open|approved|withdrawn|expired, --kind=device-software|app, --package=<baustein oder app> |
GET /v1/platform/ops/approvals · platform.ops.device-software.read oder platform.app-catalog.list |
ja | nein |
approval approve <rap_…> |
Eine Anfrage als zweite Person bestätigen und damit ausführen. Die anfragende Person selbst bekommt einen Satz und Exit 4 (ReleaseApproval.SamePerson) |
POST /v1/platform/ops/approvals/{id}/approve · platform.ops.release.approve |
nein | ja |
approval withdraw <rap_…> |
Eine Anfrage zurückziehen, als andere Person ablehnen. --reason=… ist freiwillig |
POST /v1/platform/ops/approvals/{id}/withdraw · platform.ops.release.approve oder platform.ops.device-software.release oder platform.app-catalog.promote |
nein | ja |
Plattform-Einstellungen
| Befehl | Zweck | Route und Recht | Schlüssel | Verändert |
|---|---|---|---|---|
settings get |
Alle Plattform-Einstellungen vollständig, eine nicht gesetzte mit ihrer Vorgabe | GET /v1/platform/settings · platform.settings.read |
nein | nein |
settings set <einstellung> <wert> --yes |
Eine Einstellung ändern, zum Beispiel releaseApproval.apps stable oder retention.deviceSoftware.keepNewest 3. Der Wert wird gegen den Vertrag geprüft, bevor etwas hinausgeht |
PATCH /v1/platform/settings · platform.settings.manage (nur der Owner) |
nein | ja |
Die Einstellungen sind releaseApproval.deviceSoftware und releaseApproval.apps (off oder stable, Vorgabe off) sowie retention.deviceSoftware.keepNewest (1 bis 100, Vorgabe 5) und retention.deviceSoftware.auto (Vorgabe false). Dazu kommen retention.apps.keepNewest (1 bis 100, Vorgabe 5), retention.apps.unreferencedMonths (1 bis 120, Vorgabe 12) und retention.apps.auto (Vorgabe false). Jede Änderung steht mit altem und neuem Wert im Prüfprotokoll (platform.settings.changed).
App-Katalog
| Befehl | Zweck | Route und Recht | Schlüssel | Verändert |
|---|---|---|---|---|
app-release list |
Die Releases des App-Katalogs, mit --app=<app-id>, --channel=canary|beta|stable|deprecated|retired |
GET /v1/platform/app-catalog/apps, GET …/apps/{appId}/releases · platform.app-catalog.list |
nein | nein |
app-release set-notes <arl_…> --app=<app-id> --notes=… |
Die Release-Notizen ändern (max. 2000 Zeichen) | PATCH …/apps/{appId}/releases/{id} · platform.app-catalog.update |
nein | ja |
app-release promote <arl_…> --app=<app-id> --channel=beta|stable |
Nach beta oder stable heben, immer ein Schritt. Nach stable hebt der Befehl sofort, wenn die Plattform keine zweite Person verlangt (releaseApproval.apps = off), sonst legt er eine Anfrage an, und --reason=… (10 bis 500 Zeichen) ist dann Pflicht |
POST …/apps/{appId}/releases/{id}/promote · platform.app-catalog.promote |
nein | ja |
app-release restore <arl_…> --app=<app-id> --reason=… |
Die Rücknahme einer veralteten oder abgelösten Fassung nach stable. Je nach Einstellung sofort oder als Anfrage, die eine zweite Person mit approval approve bestätigt. Die bis dahin geltende Fassung geht dabei nach deprecated |
POST …/apps/{appId}/releases/{id}/restore · platform.app-catalog.promote |
nein | ja |
app-release demote <arl_…> --app=<app-id> --channel=deprecated |
Ein Release aus stable nach deprecated zurückstufen, der einzige Schritt rückwärts | POST …/apps/{appId}/releases/{id}/demote · platform.app-catalog.promote |
nein | ja |
app-release retire <arl_…> --app=<app-id> --reason=… --grace=regular|security|immediate |
Ein Release außer Betrieb nehmen. --grace wählt die Auslauffrist und hat keine Vorgabe: regular drei Monate, security einen Monat, dann ist der Sicherheitsvermerk --advisory=… für die Organisationen Pflicht, immediate keine Frist, die Plattform stellt sofort auf die nächsthöhere Fassung in stable um. Zu regular und immediate gibt es keinen Vermerk |
POST …/apps/{appId}/releases/{id}/retire · platform.app-catalog.retire |
nein | ja |
app-release grace-period <arl_…> --app=<app-id> |
Die Auslauffrist verlängern, um --months=<n> ab dem bisherigen Ende oder bis zum Ende eines Tages mit --until=<jjjj-mm-tt>, oder mit --immediately --reason=… sofort beenden. Genau eine Wahl |
POST …/releases/{id}/extend-grace, POST …/releases/{id}/force-retire · platform.app-catalog.retire |
nein | ja |
app-release delete-artifact <arl_…> --app=<app-id> --yes |
Die Bytes einer Fassung löschen, Zeile, Manifest und Historie bleiben. Geschützt ist eine Fassung in einem Kanal, mit Installation, Szene oder offener Anfrage (AppRelease.ArtifactInUse, Exit 6) |
DELETE …/apps/{appId}/releases/{id}/artifact · platform.app-catalog.delete |
nein | ja |
app-release cleanup --app=<app-id> --dry-run|--yes |
Die Bytes aller Fassungen jenseits der neuesten --keep-newest=<n> (ohne Angabe retention.apps.keepNewest) löschen, die sich löschen lassen. --dry-run nennt nur, was gelöscht würde |
POST …/apps/{appId}/releases/cleanup · platform.app-catalog.delete |
nein | ja |
app-status list |
Die Apps mit ihrem Betreiber-Status, Installationen und Ausnahmen | GET /v1/platform/app-catalog/managed-apps · platform.app-catalog.list |
nein | nein |
app-status set <app> --status=active|beta|disabled --reason=… |
Eine App plattformweit setzen | PATCH /v1/platform/app-catalog/managed-apps/{appId} · platform.app-catalog.status.manage |
nein | ja |
app-status override <app> |
Ausnahmen je Organisation lesen, mit --tenant und --status setzen, mit --clear entfernen |
GET …/managed-apps/{appId}/overrides · platform.app-catalog.list, PUT …/overrides/{tenantId}, POST …/overrides/{tenantId}/remove · platform.app-catalog.status.manage |
nein | ja |
Ob nach stable eine Person allein hebt, entscheidet die Einstellung releaseApproval.apps. Verlangt die Plattform eine zweite Person und nennt POST …/promote mit stable keine Begründung, antwortet es AppRelease.SecondPersonRequired (Exit 6). Mit Begründung entsteht eine Anfrage, die eine zweite Person mit approval approve bestätigt, sie verfällt nach sieben Tagen. Trägt die Prüfliste der Fassung eine Sperre, weisen promote (nach beta wie nach stable) und die Bestätigung einer Anfrage nach stable mit AppRelease.ReviewBlocked (Exit 6) ab, und der Befehl nennt die gesperrten Punkte: „Neu in dieser Fassung“ fehlt in der Pflichtsprache, oder ein Kundentext trägt ein Semikolon oder ein gesperrtes Wort. „Neu in dieser Fassung“ entsteht auf der Prüfung der Fassung im Betreiber-Portal, set-notes setzt nur den Text für den Betrieb.
Abrechnung und Artikel
| Befehl | Zweck | Route und Recht | Schlüssel | Verändert |
|---|---|---|---|---|
subscription set-payment-way <tnt_…> --way=invoice|stripe|none |
Den Zahlweg eines Vertrags stellen | PUT /v1/platform/tenants/{tenantId}/billing/payment-way · platform.billing.override |
nein | ja |
subscription approve-invoice <tnt_…> --yes |
Den Kauf auf Rechnung freigeben. --revoke räumt die Freigabe ab |
PUT /v1/platform/tenants/{tenantId}/billing/payment-way · platform.billing.override |
nein | ja |
subscription check-stripe <tnt_…> |
Die Bindung eines Vertrags an den Zahlungsdienstleister prüfen. Ändert nichts | GET /v1/platform/tenants/{tenantId}/billing/stripe-link · platform.billing.override |
nein | nein |
subscription relink-stripe <tnt_…> --yes |
Einen Vertrag neu an den Zahlungsdienstleister binden. Lebt der Kunde dort noch, geschieht nichts (unchanged) |
POST /v1/platform/tenants/{tenantId}/billing/relink-stripe · platform.billing.override |
nein | ja |
subscription backfill-period-prices --yes |
Die Perioden-Stückpreise des Bestands nachziehen — der Griff, wenn der Lauf beim Start der Anwendung gescheitert ist. Idempotent | POST /v1/platform/billing/period-unit-prices/backfill · platform.billing.plan.manage |
nein | ja |
invoice list --tenant=<tnt_…>|--all-tenants |
Die Rechnungen aller Organisationen | GET /v1/platform/invoices · platform.billing.invoice.read |
nein | nein |
invoice get <inv_…> |
Eine Rechnung samt Positionen | GET /v1/platform/invoices/{id} · platform.billing.invoice.read |
nein | nein |
invoice mark-paid <inv_…> --yes |
Einen Zahlungseingang buchen | POST /v1/platform/invoices/{id}/mark-paid · platform.billing.invoice.mark-paid |
nein | ja |
invoice refund <inv_…> --reason=… --yes |
Eine Rechnung erstatten | POST /v1/platform/invoices/{id}/refund · platform.billing.invoice.refund |
nein | ja |
invoice issue-documents <inv_…> --yes |
PDF und E-Rechnung eines Belegs nachholen. Ein Beleg, der seine Dokumente schon trägt, bleibt unangetastet | POST /v1/platform/invoices/{id}/issue-documents · platform.billing.invoice.refund |
nein | ja |
catalog list |
Der Artikelkatalog samt gesetzter Sonderkonditionen | GET /v1/platform/billing/catalog · platform.billing.plan.manage, GET /v1/platform/billing/overrides · platform.billing.override |
nein | nein |
catalog set [sku] |
Einen Katalog-Artikel ersetzen (alle fünf Felder) oder mit --app=<app-id> --price=<cent> den Monatspreis einer App setzen |
PUT /v1/platform/billing/catalog/{skuCode}, PUT /v1/platform/billing/app-prices/{appId} · platform.billing.plan.manage |
nein | ja |
Unter einem Betreiber-Profil laufen außerdem audit list und audit get gegen GET /v1/platform/audit und GET /v1/platform/audit/{id} (platform.audit.read). --tenant oder --all-tenants ist dort Pflicht.