Commit graph

6 commits

Author SHA1 Message Date
Mitchell R
69e51197bf
refactor(streams): store RTSP components separately for ONVIF cameras
ONVIF-discovered camera streams now store rtsp_host, rtsp_port, and
rtsp_path as separate columns instead of baking credentials into a
pre-built URL. This fixes XML entity issues (&), special character
password breakage, and credential duplication across streams.

Bundle generation builds the final playable URL at delivery time using
components + camera row credentials with proper URL encoding. Existing
RTSP-type cameras with only rtsp_uri continue to work unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 06:51:33 +02:00
Mitchell R
cce9b51887
feat(events): add persistent ONVIF event topic subscriptions with status tracking
Add camera_event_subscriptions table to track per-camera per-topic
subscription state (inactive/pending/active/failed). Refresh-events
handler now merges discovered topics instead of replacing, so topics
are never lost when a camera goes temporarily offline. Admin UI shows
colored status dots and last-event timestamps per topic, with a
"subscribe all inactive" button to queue subscriptions for kiosk pickup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 02:38:43 +02:00
Mitchell R
3ee79b9e83
fix(db): replace enabled = 1 with enabled = true in WHERE clauses
PG BOOLEAN columns cant compare with integer literals. Five
queries used enabled = 1 in WHERE, causing boolean = integer
operator error on kiosk auth, bundle fetch, and heartbeat.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 02:08:09 +02:00
Mitchell R
c91f9cb450
feat(obs): add observability tracing throughout server
Repository _run/_get/_all now create child spans with db.statement
when an Observable is set via withObs(). Bundle generation and pairing
confirmation accept optional obs for span-based tracing. Key admin
route handlers (camera/layout/kiosk CRUD, cloud sync) log structured
info lines with actor and resource id. Kiosk API routes (heartbeat,
bundle, event, firmware check, OS check) log kiosk_id on entry.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 01:47:24 +02:00
Mitchell R
41e9991891
fix(db): replace remaining hardcoded 0/1 with boolean params
setup_state.is_complete, cluster_key_provisioned, display.is_primary,
event_log.forwarded_to_nodered all had literal 0/1 in SQL strings.
PG rejects integer for BOOLEAN columns. Changed to ? params with
true/false values — SQLite adapter coerces to 1/0 automatically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-24 05:18:43 +02:00
Mitchell R
0479cb7b4b
refactor(db): move service-store from BSB plugin to shared/db library
Each service plugin now independently initializes its own DB connection
via shared/db/init.ts instead of depending on a central service-store
plugin. This removes the inter-plugin dependency ordering and the
plugin-registry singleton, making each service self-contained.

- Move db-adapter, repository, mappers, migrations, adapters to shared/db/
- Create shared/db/config.ts (reusable dbConfigSchema) and init.ts
- Delete service-store plugin and plugin-registry
- Add db config block to each service's ConfigSchema + sec-config template
- Move event_log purge timer into service-admin-http
- Update all import paths across shared modules and plugins

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-24 02:48:32 +02:00
Renamed from server/src/plugins/service-store/repository.ts (Browse further)