📡

RTV Planner

RTV Planner status

Status: production live. Ready for controlled broadcast operation with an operator present. Browser output has been confirmed in web player, vMix and OBS; guest lineup plates, metals, weather and calendar/event plates now use real data paths or operator-managed inputs. The main remaining product gate is final broadcast plate design plus stronger output alerts.

Current status

RTV Planner is the broadcast control room for Roxom TV. It gives operators one place to prepare content, program the daily rundown, check schedule risk, run preflight and send browser playout into OBS or vMix.

The admin workflow is now grouped by intent: Prepare for content and plates, Program for day/rundown/loop/fallback work and Operate for live output, health, runbook and recovery.

Operator map

HubRouteUse when
Prepare/admin/prepareCreate media, music, guest plates, weather and data plates.
Program/admin/programBuild the day, create loops, set fallback and fix health.
Operate/admin/operateRun output, unlock audio, monitor fallback and recover live.

The workflow is browser-output-first: the operator opens Browser Output from Admin Output, clicks Start Output once to unlock audio and captures the page in OBS/vMix. Reload recovery seeks video to the current scheduled offset so the signal can resume near the correct moment.

Implemented and applied

  • Single-tenant operator console for Roxom TV
  • Named operators, admin sessions and role guards
  • Rate limiting, CSRF protection and output token flow
  • Admin health checks and Go Live Drill
  • Daily schedule builder with schedule health polling
  • Unified Prepare, Program and Operate operator hubs
  • Schedule add-block confirmation with highlighted placement and readable time ranges
  • Loop Builder for scheduled slide loops, visual fallback carousel, or both
  • Runbook for preflight, live operation, incident notes and shutdown
  • Output overrides for urgent live cuts
  • Music preferences for slides, images and visual fallbacks
  • Dynamic Reuters HLS/RTMP stream snapshots
  • Roxom metals API integration with Pyth fallback for gold and silver plates
  • Open-Meteo weather fallback when OpenWeather is not configured
  • Supabase events table for calendar/event plates
  • Browser output for OBS/vMix capture
  • Previously Recorded bug for normal video programs with four-corner placement
  • Browser output confirmed in web player, vMix and OBS
  • Public media proxy for uploaded ads/promos stored in local Supabase Storage
  • Guest records and individualized Guest Lineup plates with URL or uploaded photo/video media
  • Time-accurate video reload resume
  • Audit identity for critical operations
  • Supabase readiness schema and fresh-project bootstrap SQL
  • Persisted smoke status for deploy/read-only smoke checks
  • OpenNext/Cloudflare Workers deploy path configured

Production verification

  • typecheck passed
  • lint passed
  • format check passed
  • i18n check passed
  • security service-role guard passed
  • audit trail guard passed
  • Vitest passed: 348 tests
  • Next production build passed
  • local production deploy passed
  • local read-only smoke passed
  • public production read-only smoke passed

Health status

  • /api/health returns ok: true after deploy checks.
  • Status can show degraded when there is no live day loaded or the persisted smoke status is stale/failing.
  • Schema, Supabase, storage, Vimeo, Reuters and output checks are healthy.
  • Uploaded local-storage assets play through /api/media/assets/<assetId>.

Next steps

  1. Provision day-to-day named operators and keep bootstrap token as emergency-only access.
  2. Remodel the visual design of cards, plates and output surfaces for final broadcast identity.
  3. Add output drift monitoring and incident prompts for silence, black output and stalled video.
  4. Finish i18n and validation copy cleanup.
  5. Smoke-test a real OpenNext/Cloudflare Workers deploy before making it production-primary.

Notes

  • Prepare, Program and Operate are the primary operator hubs. Direct routes like /admin/assets, /admin/schedule/<date> and /admin/output remain available for deep work.
  • Loop Builder can create scheduled slide blocks, update the global visual fallback carousel, or do both in one action. Fallback-only updates do not create scheduled blocks.
  • Reuters stream URLs are dynamic snapshots. Expired or rotated HLS/RTMP endpoints must be refreshed.
  • Metals plates read Roxom metals data for gold and silver and fall back to Pyth when needed. Weather uses OpenWeather when configured and Open-Meteo otherwise.
  • Calendar/event plates read the Supabase events table from supabase/migrations/20260525181000_events_calendar.sql.
  • The Previously Recorded bug is block metadata on normal video programs only. It does not render on ads, promos, slides, images, fallback, Reuters streams or manual overrides.
  • Smoke scripts require environment variables to be loaded, including OUTPUT_CAPTURE_TOKEN.
  • Supabase can remain local in production. Uploaded media should expose public app proxy URLs, not raw 127.0.0.1 storage URLs.
  • Browser output is the active playout surface. OBS/vMix capture has been confirmed for the current workflow and should be rechecked after deploy or machine changes.
  • OpenNext/Cloudflare Workers is configured as an alternate deploy path. Keep Cloudflare dashboard vars/secrets set and smoke-test a real Workers deploy before making it primary.
  • Guest lineup plates are operator-configurable, and key non-guest plates now have real data/fallback paths. The visual design still needs a broadcast-quality remodel.
  • Existing Supabase backends need the standalone guest migration at public/manual/guest-lineup-migration.sql or the normal repo migration in supabase/migrations.
  • If output reloads mid-show, the video seeks to the current schedule offset before playback resumes. Audio may still require a Start Output click after reload.

🎛️

Operations manual

Objective

RTV Planner turns a daily broadcast plan into an operator-run signal: media library, schedule, runbook, fallbacks, live monitor and fullscreen browser output.

Standard workflow

StepRoutePrimary action
1. Prepare content/admin/prepareUpload videos, images, audio and graphics from the Prepare hub.
2. Prepare guest plates/admin/guestsCreate guest records with name, role, company, host, program, category and appearance time.
3. Program the day/admin/programCreate or open the programming day.
4. Review the schedule/admin/schedule/<date>Fix gaps.
5. Complete the runbook/admin/runbook/<date>Complete preflight before going live.
6. Go live/admin/operateActivate the correct day.
7. Operate during live/admin/operateMonitor current block, next block, fallback reason, playlist/audio state and playback errors.
8. Stop broadcast/admin/outputUse Stop broadcast.

1. Prepare content

Route: /admin/prepare

Actions:

  • Upload videos, images, audio and graphics from the Prepare hub.
  • Sync Vimeo or open the direct Vimeo route from Prepare.
  • Register remote URLs when needed.
  • Create weather city plates and data plates before scheduling.
  • Mark assets as ready only after reviewing playback, duration and fallback.

2. Prepare guest plates

Route: /admin/guests

Actions:

  • Create guest records with name, role, company, host, program, category and appearance time.
  • Use either URL fields or uploaded files for guest photos and short muted videos.
  • Create one Guest Lineup plate per editorial group, for example guests 1-4, guests 5-7 or a single featured guest.
  • Preview each guest plate before scheduling it.

3. Program the day

Route: /admin/program

Actions:

  • Create or open the programming day.
  • Add blocks in chronological order from Schedule.
  • Use Loop Builder for silent slide loops.
  • Choose scheduled loop, fallback carousel only, or both.
  • Assign an asset, slide or Reuters stream.
  • For Reuters, paste the current HLS/RTMP endpoint because those URLs are dynamic.

4. Review the schedule

Route: /admin/schedule/<date>

Actions:

  • Fix gaps.
  • Fix overlaps.
  • Resolve missing or not-ready assets.
  • Review fallback policy: block fallback, day fallback, global fallback video or visual fallback carousel.
  • Use schedule health deep links to jump directly to the affected block.

5. Complete the runbook

Route: /admin/runbook/<date>

Actions:

  • Complete preflight before going live.
  • Record live operation notes.
  • Use incident mode if there is degradation.
  • Complete shutdown after the broadcast ends.

6. Go live

Route: /admin/operate

Actions:

  • Activate the correct day.
  • Open Output from Operate.
  • Open Browser Output.
  • Click Start Output once to unlock audio.
  • Capture the browser or window in OBS/vMix.
  • Confirm that the monitor shows the expected current block and next block.

7. Operate during live

Route: /admin/operate

Actions:

  • Monitor current block, next block, fallback reason, playlist/audio state and playback errors.
  • Use Reuters live override only when the output must cut immediately to a dynamic endpoint.
  • Return to schedule when the override ends.

8. Stop broadcast

Route: /admin/output

Actions:

  • Use Stop broadcast.
  • Confirm that active overrides are cleared.
  • Complete shutdown checks.
  • Review the audit log.

Operating rules

  • Browser output is the primary playout surface.
  • OBS/vMix captures `/output/live`; operators click Start Output to unlock audio.
  • The bootstrap token remains for emergency access.
  • Normal operation must use named operators.
  • Critical changes must appear in the audit log.
  • Do not go live with critical schedule health issues without an explicit decision.

Pre-air checks

  • /api/health returns ok:true.
  • Supabase check OK.
  • Schema/migrations OK.
  • Storage buckets OK.
  • Vimeo token/playback ready.
  • Reuters readiness OK if Reuters is used.
  • OUTPUT_CAPTURE_TOKEN configured.
  • Browser output opens on the capture machine.
  • Start Output unlocks audio.
  • Reload mid-video resumes near the expected schedule offset.
  • Slide output renders in the capture runtime.
  • Fallback defined.
  • Runbook preflight complete.

Verification commands

  • rtk npm run typecheck
  • rtk npm run lint
  • rtk npm run format:check
  • rtk npm run i18n:check
  • rtk npm run security:service-role
  • rtk npm run security:audit-trail
  • rtk npm test
  • rtk npm run build
  • rtk bash scripts/local_readonly_smoke.sh
  • rtk bash scripts/prod_readonly_smoke.sh