Commit graph

7 commits

Author SHA1 Message Date
Mitchell R
936e6170a6
feat(store): Postgres adapter foundation + BF_DB selector (phase 1)
Lays groundwork for sqlite|postgres backend selection without yet
converting Repository. Adds:

- db-adapter.ts: async DbAdapter interface (run/get/all/exec/transaction)
- sqlite-adapter.ts: wraps node:sqlite sync API in Promise-returning shape,
  caches prepared statements
- pg-adapter.ts: pg Pool + ? → $N placeholder rewrite + RETURNING-id
  capture + savepoint-nested transactions
- service-store config: driver (sqlite|postgres), pgUrl
- BF_DB env override, plumbed via envStr

Selecting BF_DB=postgres throws at init() until the Repository is
converted off DatabaseSync. This commit ships the foundation only.

Next phases (separate commits):
  2. Convert Repository methods sync → async via DbAdapter
  3. Update every caller to await
  4. Split MIGRATIONS into sqlite + portable / pg-specific sets
  5. UUIDv7 IDs for new tables on PG path

Adds deps: pg ^8.13.1, uuidv7 ^1.0.2, @types/pg ^8.20.0
2026-05-18 22:50:48 +02:00
Mitchell R
17f8c7ce02 feat(server): generic MQTT telemetry bridge (off by default) 2026-05-14 07:46:56 +02:00
Mitchell R
b83782b8e0 feat: Node-RED custom nodes + dashboard entity type
Node-RED nodes (nodered/):
- bf-config: shared server URL + admin API key
- bf-event-in: filter kiosk events by topic glob
- bf-layout-switch: POST display layout-switch
- bf-power: kiosk wake/standby
- bf-fan: kiosk fan control
- bf-cameras: query camera list
- Drag-droppable from Node-RED palette

Server:
- Admin Bearer API key auth on /admin/* (NodeRED can call admin API)
- GET /api/admin/cameras for bf-cameras node
- Dashboard entity type:
  - entities.type CHECK adds 'dashboard'
  - entities.dashboard_id column
  - shared/nodered-bridge.ts listDashboards() polls /nrdp/flows
  - Bundle resolves dashboard entity → web cell at /dash/<id>
  - POST /admin/entities/sync-dashboards mirrors Node-RED tabs
  - EntitiesPage shows Dashboards section + Sync button
  - EntityEditPage for dashboard: read-only + "Open in Node-RED"
  - No create/delete from BF UI — managed in Node-RED
- sec-config: noderedUrl on admin-http (was already on api-http)
2026-05-13 01:47:53 +02:00
Mitchell R
3be1a9a624 feat: entities (unified content pool) + ONVIF discovery flow
Entities:
- New entities table — id, name, type (camera|html|web), camera_id,
  html_content, web_url
- Auto-create entity per camera on createCamera
- Layout cells reference entity_id (replaces inline content_type/
  camera_id/html_content/web_url)
- Bundle resolves entities back to legacy cell fields for kiosk compat
  (Rust kiosk unchanged)
- Full CRUD: /admin/entities, /admin/entities/new, /admin/entities/:id
- Cell editor: single entity dropdown with type badges

ONVIF discovery:
- /admin/cameras/discover — host/port/user/pass form
- Server queries ONVIF device, lists profiles with name/resolution/
  encoding/framerate
- "Add" creates camera + main stream from chosen profile
- shared/onvif.ts: minimal SOAP+UsernameToken+PasswordDigest client
  (no external dep)
- Camera new form simplified to RTSP-only with discover link
2026-05-10 23:18:44 +02:00
Mitchell R
16ab165b06 feat: live updates via WebSocket — server pushes, kiosk reloads
Server side:
- service-coordinator-ws: full WS implementation using ws package
- Auth via ?token=<kiosk_key> query param
- Coordinator registry for cross-plugin notification
- Admin mutations call notifyKiosks() → server pushes reload-bundle
- 30s ping/pong heartbeat

Kiosk side:
- Rust ws_client with tokio runtime + tokio-tungstenite
- Auto-reconnect with exponential backoff (1s → 60s cap)
- On reload-bundle: re-fetches bundle, re-renders layout
- Pong replies to server pings

Also fix: auto-suffix kiosk name on UNIQUE collision (re-pair with
same hostname no longer fails).
2026-05-10 22:15:58 +02:00
Mitchell R
83f598f187
build fixes for bsb 2026-05-10 01:46:11 +02:00
Mitchell R
2fd2502b85
adding initial project 2026-05-10 01:09:13 +02:00