Commit Graph

2 Commits (42ae76227b6cdaf4d5786f0129ace9cbbafafc6b)

Author SHA1 Message Date
HomeOS Bootstrap 8086a9647b fix(addons): atomic Ring device creation + invalidate ingest gate cache (R15)
Codex R15 on the Ring bridge flagged two issues:
- [P1] Concurrent first-sight messages (retained info + motion on bridge
  startup) could create duplicate devices — no uniqueness on ring_id. Added a
  partial unique index on (config->>'ring_id'); resolveDevice now creates and,
  on the unique violation, re-fetches the winner (race-safe).
- [P2] The install-gate cache was never invalidated, so ingest was dropped for
  up to 15s after install and devices kept being created for up to 15s after
  uninstall. AddonService now forgets the shared cache key on install/uninstall.

+3 tests (unique-index guard, repeated-messages-reuse-device, cache
invalidation). Suite 43 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 02:01:45 +02:00
HomeOS Bootstrap a4489ac7d3 feat(addons): Ring backend bridge — ring-mqtt ingest, cloud devices, badge
Second half of the Ring integration (handoff §12):
- RingTopics + RingNormalizer (H3): parse ring/<loc>/<cat>/<id>/<entity>/state,
  map ding/motion/contact/lock/battery; bridge status topic drives the addon
  connection state. Defensive — unknown topics are ignored, never junk devices.
- IngestRingMessage (H4, single ingest path): auto-creates cloud-flagged Ring
  devices on first sight, monotonic race-safe state upsert, broadcasts live.
  Gated on the addon being installed (cached) so a still-running bridge can't
  recreate devices after uninstall.
- Shared AppliesDeviceState trait: the monotonic upsert now lives once, used by
  both Shelly and Ring ingest (MqttTest guards the Shelly path).
- Listener subscribes ring/#. ring-mqtt container (opt-in `addons` compose
  profile) as least-privileged `ring` MQTT user (ACL: ring/# only); gen-passwd
  seeds the account. "Cloud" badge on Ring devices in list + detail.

11 Ring tests (topic parse, normalizer, bridge status, auto-create, install
gate, unknown-topic guard, out-of-order). Suite 40 green; 12/12 tabs clean.
Live-verified: real MQTT ring/.../ding + info publish → cloud device created
with ding + battery state. (Real Ring OAuth login runs in the ring-mqtt sidecar.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 01:58:40 +02:00