screentinker/server
ScreenTinker 8d37c7f5ff fix(#143): notify a screen it's paired on reconnect (recovery-critical)
Bold: screens sit on the Connect page showing the server URL = paired server-side
but never told, so the app never starts playing.

Flow / gap (Step A):
- CLIENT leaves the Connect page ONLY on the 'device:paired' event — web player
  (player/index.html) hides the setup screen; Android ProvisioningActivity.onPaired
  launches MainActivity + finish(). That event is the sole signal.
- SERVER pushes 'device:paired' to the device's room from POST /api/provision/pair
  (server.js) at pair time — but ONLY reaches a LIVE socket then. The normal
  device_id reconnect path emitted device:registered + device:playlist-update but
  NOT device:paired. So a screen paired while disconnected, or that reconnects after
  pairing (exactly the screens cycling on the Connect page), is paired server-side
  (user_id set, receiving playlists) yet never gets device:paired -> stuck on Connect.

Fix (server-only, uses the EXISTING client listener — no client update needed, which
matters because we can't push a client update to stuck screens): on the device_id
reconnect, if the device is paired (user_id set), re-emit 'device:paired'
{device_id, name}. Push-on-pair (server.js) already covers the live-at-pair-time
case; this covers paired-then-reconnect. A paired screen now leaves Connect and
plays on its next reconnect with no client change and no manual re-pair.

Tests (port 3989, real flow): provision -> pair via /api/provision/pair (socket
closed) -> reconnect RECEIVES device:paired (+name +playlist) — the stuck-screen
repro; an unpaired device gets NO device:paired (stays on the pairing flow); the fix
reuses the existing device:paired event (no new protocol). Full suite green serial
AND parallel (220); dbac699 / 404c330 / e734281 intact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 23:52:30 -05:00
..
config PiP overlay MVP: push image/web overlays to a device or group (#109) (#127) 2026-06-18 14:54:44 -05:00
db fix(#143): enforceable device block + fix the null-token auth short-circuit 2026-06-27 22:40:30 -05:00
lib fix(#143): content-ack flood control — per-device rate budget + loop-lag valve 2026-06-27 22:21:57 -05:00
middleware feat(api): per-agency-token auto-publish (#73) 2026-06-14 13:48:17 -05:00
player fix(player): composite multi-zone layouts in screenshot/stream capture 2026-06-22 23:22:12 -05:00
routes feat(#142): event-loop lag telemetry (perf_hooks) + bounded storage 2026-06-27 19:01:08 -05:00
scripts feat(scheduling): per-item schedule blocks (#74 dayparting, #75 auto-expire) 2026-06-11 15:46:41 -05:00
services fix(#143): content-ack flood control — per-device rate budget + loop-lag valve 2026-06-27 22:21:57 -05:00
test fix(#143): notify a screen it's paired on reconnect (recovery-critical) 2026-06-27 23:52:30 -05:00
ws fix(#143): notify a screen it's paired on reconnect (recovery-critical) 2026-06-27 23:52:30 -05:00
.gitignore feat(email): Microsoft Graph send + alert spam protection + preferences UI 2026-05-12 18:16:40 -05:00
config.js fix(#143): fingerprint-reclaim stuck loop — reclaim by runtime liveness, throttle log 2026-06-27 22:56:48 -05:00
package-lock.json chore(release): v1.9.2-beta2 2026-06-27 23:18:19 -05:00
package.json chore(release): v1.9.2-beta2 2026-06-27 23:18:19 -05:00
server.js feat(#142): event-loop lag telemetry (perf_hooks) + bounded storage 2026-06-27 19:01:08 -05:00
version.js chore(version): single-source VERSION, env-configurable data paths, bump tooling 2026-06-10 12:56:03 -05:00