9.7 KiB
Scheduler Overhaul — Phase 5 Verification Results
Prepared during Phase 5 against a locally running Portal on a fresh database.
This records what was actually executed and observed. It is a companion to
scheduler-overhaul-release-notes.md (rollout steps) and
schedule-api-contract.md (the contract). Where a scenario could not be run
without real Kiosk hardware or an interactive display, the row is marked and the
equivalent automated coverage is cited.
Environment:
- Portal dev server (
npm run dev) onhttp://localhost:5173, pointed at a fresh scratch database (rwportal_p5) created and migrated for this phase. - Kiosk schedule logic exercised through the C++ test harness
(
test_schedule_engine) and the Kiosk API client's JSON parsing. - No display/Xvfb available, so the SDL Kiosk UI was not driven interactively; see the manual checklist in the release notes.
Legend: PASS = executed, AUTO = verified by automated test (not interactively), MANUAL = requires a human on hardware/display.
| # | Scenario | Result | Evidence / notes |
|---|---|---|---|
| a | Kiosk shows AM/PM everywhere; System Settings contains Email, License Key, System Name, Schedule toggle, WiFi, Timezone, Date Format | AUTO | test_date_format (12h conversion), test_settings_menu (exactly the 7 entries incl. System Name + Schedule). UI rendering itself is MANUAL. |
| b | Validate a License Key, name the Kiosk, see the name read-only on the Portal | PASS + MANUAL | HTTP: validation without name → 200 unchanged; with name → 200 ok. Portal render is MANUAL (release-notes checklist). |
| c | Two systems in one account: duplicate name in any casing rejected and reverted on the Kiosk | PASS | HTTP: case-insensitive duplicate → validation 200 conflict; PUT duplicate → 409 name_taken; blank → 400 invalid_name; unknown → 404 unknown_license. Kiosk revert covered by test_license_service/test_system_name. |
| d | Rename a system on the Kiosk; its Schedule stays attached (License Key reference) | AUTO | Schedules are keyed by licenseKeyId; naming only touches systemName. Portal schedule-copy/service tests operate purely on License Key IDs. |
| e | Create a daily Schedule via the Portal picker; Kiosk fetches and applies it | PASS | Opt-in integration spec: daily schedule with 2 blocks created via the service; key-only GET returns it; captured live payload parsed and evaluated by the Kiosk (SchedulePortalParityTest). |
| f | Weekly: Block boundaries, adjacent (end 7:00 / start 7:00), midnight-crossing, Sunday→Monday spillover | PASS + AUTO | Integration spec: weekly sun crossing + adjacent mon blocks, Sunday spillover collision rejected. Engine tests: adjacency boundary, midnight self-wrap, Sunday→Monday spillover. |
| g | Gap plays local Proclamations; dynamicAudio true → dynamic, false → local |
AUTO | Engine tests: gaps return no block; per-block dynamicAudio flag; ScrollerPage::effectiveDynamicAudio honored via playback wiring (build passes). |
| h | Schedule toggle Off stops schedule effects; On resumes | AUTO | ScheduleManagerTest.DisabledReturnsNoBlock; toggle stored in config.yaml (schedule_enabled, default on). |
| i | Schedules assigned to system A never affect system B | PASS | Integration spec: A daily, B weekly simultaneously; independent payloads. |
| j | Copy a Schedule to another named system; that Kiosk picks it up | PASS | Integration spec: copy A→second system yields daily with 2 blocks; independence confirmed; target ETag differs. Portal schedule-copy.spec covers overwrite/multi-target/rollback/new IDs. |
| k | Offline uses cached Schedule; corrupt cache ignored; timezone change re-evaluates | AUTO | ScheduleCacheTest (round-trip, corrupt ignored), ScheduleManagerTest (offline cache, 304 handled). Timezone is passed as wall-clock minutes (wall-clock means DST-safe). |
| l | Portal shows geoip/fallback timezone with kiosk-timezone note; manual minute entry alongside 5-minute options | AUTO | UI note is browser-fallback (no external dep); TimeInput tests cover 5-minute options and typed minutes. Visual render MANUAL. |
Additional checks
| Check | Result | Notes |
|---|---|---|
Old-Kiosk compatibility (validate without systemName; legacy schedule endpoint) |
PASS | 200 unchanged; name never cleared; legacy GET /api/v2/schedule still returns email + blocks; modern vs legacy version equal. |
| Cross-account isolation | PASS | Legacy schedule with another account's key → 400; copy rejects non-owned source/targets. |
| Conditional GET | PASS | Matching If-None-Match → 304; stale ETag → 200; unknown key → 404. |
| Migration up | PASS | Applied cleanly to a fresh DB (29 migrations); fresh seed succeeded. |
| Migration down/up on realistic data | PASS (with caveat) | Phase 2 and Phase 3 down/up round-tripped structurally on a clone; the Phase 3 down path is lossy (deletes per-License-Key schedules). Documented in the contract (Open item 22) and release notes. |
Portal svelte-check / ESLint / tests |
PASS | 0 errors/warnings; 394 passed, 4 skipped (opt-in integration). |
| Kiosk build + tests | PASS | Full build; 21 test binaries pass. |
| Formatters | PASS | Portal Prettier clean except the pre-existing .gitea/workflows/deploy.yaml (unchanged from before this branch). Kiosk follows .clang-format (no binary available to run). |
Not verified here (requires hardware/display)
The interactive SDL Kiosk UI (rendering, key handling, onboarding walkthrough)
was not driven; all Kiosk behavior above is covered by the engine/client/cache
tests and by parsing live Portal payloads. See the manual checklist in
scheduler-overhaul-release-notes.md.