- Add GET /api/clients/crashed endpoint (process_status=crashed or stale heartbeat) - Add restart_app command action with same lifecycle + lockout as reboot_host - Scheduler: crash auto-recovery loop (CRASH_RECOVERY_ENABLED flag, lockout, MQTT publish) - Scheduler: unconditional command expiry sweep per poll cycle (sweep_expired_commands) - Listener: subscribe to infoscreen/+/service_failed; persist service_failed_at + unit - Listener: extract broker_connection block from health payload; persist reconnect_count + last_disconnect_at - DB migration b1c2d3e4f5a6: service_failed_at, service_failed_unit, mqtt_reconnect_count, mqtt_last_disconnect_at on clients - Add GET /api/clients/service_failed and POST /api/clients/<uuid>/clear_service_failed - Monitoring overview API: include mqtt_reconnect_count + mqtt_last_disconnect_at per client - Frontend: orange service-failed alert panel (hidden when empty, auto-refresh, quittieren action) - Frontend: MQTT reconnect count + last disconnect in client detail panel - MQTT auth hardening: listener/scheduler/server use env credentials; broker enforces allow_anonymous false - Client command lifecycle foundation: ClientCommand model, reboot_host/shutdown_host, full ACK lifecycle - Docs: TECH-CHANGELOG, DEV-CHANGELOG, MQTT_EVENT_PAYLOAD_GUIDE, copilot-instructions updated - Add implementation-plans/, RESTART_VALIDATION_CHECKLIST.md, TODO.md
150 lines
3.4 KiB
JSON
150 lines
3.4 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://infoscreen.local/schemas/reboot-command-payload-schemas.json",
|
|
"title": "Infoscreen Reboot Command Payload Schemas",
|
|
"description": "Frozen v1 schemas for per-client command and command acknowledgement payloads.",
|
|
"$defs": {
|
|
"commandPayloadV1": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"schema_version",
|
|
"command_id",
|
|
"client_uuid",
|
|
"action",
|
|
"issued_at",
|
|
"expires_at",
|
|
"requested_by",
|
|
"reason"
|
|
],
|
|
"properties": {
|
|
"schema_version": {
|
|
"type": "string",
|
|
"const": "1.0"
|
|
},
|
|
"command_id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"client_uuid": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"action": {
|
|
"type": "string",
|
|
"enum": [
|
|
"reboot_host",
|
|
"shutdown_host"
|
|
]
|
|
},
|
|
"issued_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"expires_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"requested_by": {
|
|
"type": [
|
|
"integer",
|
|
"null"
|
|
],
|
|
"minimum": 1
|
|
},
|
|
"reason": {
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
],
|
|
"maxLength": 2000
|
|
}
|
|
}
|
|
},
|
|
"commandAckPayloadV1": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"command_id",
|
|
"status",
|
|
"error_code",
|
|
"error_message"
|
|
],
|
|
"properties": {
|
|
"command_id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"enum": [
|
|
"accepted",
|
|
"execution_started",
|
|
"completed",
|
|
"failed"
|
|
]
|
|
},
|
|
"error_code": {
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
],
|
|
"maxLength": 128
|
|
},
|
|
"error_message": {
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
],
|
|
"maxLength": 4000
|
|
}
|
|
},
|
|
"allOf": [
|
|
{
|
|
"if": {
|
|
"properties": {
|
|
"status": {
|
|
"const": "failed"
|
|
}
|
|
}
|
|
},
|
|
"then": {
|
|
"properties": {
|
|
"error_code": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"error_message": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"examples": [
|
|
{
|
|
"commandPayloadV1": {
|
|
"schema_version": "1.0",
|
|
"command_id": "5d1f8b4b-7e85-44fb-8f38-3f5d5da5e2e4",
|
|
"client_uuid": "9b8d1856-ff34-4864-a726-12de072d0f77",
|
|
"action": "reboot_host",
|
|
"issued_at": "2026-04-03T12:48:10Z",
|
|
"expires_at": "2026-04-03T12:52:10Z",
|
|
"requested_by": 1,
|
|
"reason": "operator_request"
|
|
}
|
|
},
|
|
{
|
|
"commandAckPayloadV1": {
|
|
"command_id": "5d1f8b4b-7e85-44fb-8f38-3f5d5da5e2e4",
|
|
"status": "execution_started",
|
|
"error_code": null,
|
|
"error_message": null
|
|
}
|
|
}
|
|
]
|
|
}
|