screentinker/server
Claude e3b01a5c7f Make a content-only schedule actually put that content on the screen
The schedule dialog offers "Content (single item, optional)". The value was cross-tenancy validated
and stored faithfully, and then read by nothing. services/scheduler.js acts on exactly two columns,
layout_id and playlist_id; content_id is consulted nowhere in the codebase. So picking a file and
saving produced a schedule that fired and changed nothing — while the calendar drew a block labelled
with that filename, as confirmation that it would.

Rather than thread a third override type through the engine and every player, the schedule now gets
a playlist containing that one item. That is the shape the entire pipeline already understands:
publish, assign, push, snapshot, offline cache and all four players work on it unchanged.

It is published through the shared publishPlaylist path rather than by hand-rolling the snapshot,
because players read denormalized fields out of published_snapshot (filename, mime_type, filepath,
remote_url, per-item schedules) and a second copy of that shape here would rot the first time it
changed.

An explicit playlist override still wins and no throwaway playlist is created; a schedule with
neither content nor playlist is untouched.

5 tests covering all of those, including that the generated playlist lands in the right workspace and
that its snapshot carries the fields the players need rather than just the id.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
2026-07-30 22:26:58 -05:00
..
config fix(logging): gate CF-Connecting-IP on a Cloudflare peer, not any trusted proxy 2026-07-26 10:23:04 -05:00
db Keep a workspace on schedules that outlive their device group 2026-07-30 20:53:21 -05:00
lib Apply a saved device snapshot only inside the workspace it was taken in 2026-07-30 20:56:59 -05:00
middleware Merge branch 'fix/recovery-grants' into release/auth-campaign 2026-07-26 16:22:59 -05:00
player Apply a playlist change even when the outgoing item never advances 2026-07-30 21:17:44 -05:00
routes Make a content-only schedule actually put that content on the screen 2026-07-30 22:26:58 -05:00
scripts fix(content+android): rotation-aware media — portrait upright on dashboard AND player (#170) (#172) 2026-07-12 22:05:11 -05:00
services Make a recurring schedule respect its start and end dates 2026-07-30 22:22:59 -05:00
test Make a content-only schedule actually put that content on the screen 2026-07-30 22:26:58 -05:00
ws Treat an empty device_info as "nothing new", not as "forget what you know" 2026-07-30 21:09:11 -05:00
.gitignore feat(email): Microsoft Graph send + alert spam protection + preferences UI 2026-05-12 18:16:40 -05:00
config.js Add an operator override for self-update on MDM-managed panels 2026-07-28 23:07:30 -05:00
package-lock.json chore(release): v1.9.27 2026-07-30 19:16:55 -05:00
package.json chore(release): v1.9.27 2026-07-30 19:16:55 -05:00
server.js Serve a beta APK alongside the stable one, and let a display move between them 2026-07-30 19:12:46 -05:00
smoke-ui.js Keep the smoke test out of npm test, and update the lockfile 2026-07-28 20:34:34 -05:00
version.js chore(version): single-source VERSION, env-configurable data paths, bump tooling 2026-06-10 12:56:03 -05:00