Two FATAL while(true) hangs in main.cpp (config load fail, camera init
fail) previously relied on the hardware watchdog to reboot the device,
leaving the cause invisible beyond a generic TWDT reset reason. Now
each path logs EVT_REBOOT with REBOOT_FATAL_CONFIG or REBOOT_FATAL_CAMERA
before hanging, so the next heartbeat's recent_events surfaces which
branch hung. Server-side decoder updated for the two new enum values.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The real server lives in a separate repo; this repo carries reference
stubs for each endpoint (see camera_endpoint.py precedent). Adds the
Pydantic extension, persistence helper, migration 005, and tests that
the real server can copy when adding diagnostic-field support.
Matches the firmware v1.1.0 heartbeat payload shape. Old-shape
payloads (firmware v1.0.0) continue to parse cleanly with the new
fields defaulting to None.
Self-contained server stub and pytest tests for the /api/v1/camera/events/batch
endpoint, mirroring the BLE batch pattern with idempotent INSERT on
(device_id, period_start).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>