Adversarial review found the previous multi-flood design non-viable:
PlayoutModeSchedulerFlood never yields to a following Dynamic-start
schedule item, so only the first item ever played, and grouping
media items into a Collection silently dropped the requested order.
Redesign:
- Single-item lineup: one ProgramScheduleItemFlood referencing the
target directly (media item / collection / smart / multi / rerun /
playlist); no generated collection or playlist. Response PlaylistId
is null.
- Multi-item lineup (>= 2): one generated IsSystem Playlist in a
get-or-created IsSystem PlaylistGroup ("Channel Lineups"), one
PlaylistItem per entry in lineup order with PlayAll=true, referenced
by a single Flood schedule item. Rerun collections and playlists are
rejected (422) in multi lineups (PlaylistItem/CollectionKey lack the
fields to enumerate them).
Review fixes:
- Normalize + strict-validate MediaType<->CollectionType pairs once up
front (422 on mismatch / wrong id / not exactly one id).
- Reject MultiCollection with non-Shuffle order (mirrors
PlayoutModeMustBeValid), Mirror playout source, all via 422.
- OnDemand parity: queue TimeShiftOnDemandPlayout post-commit.
- De-collide generated ProgramSchedule and Playlist names against their
unique indexes instead of leaking a UNIQUE-constraint DbUpdateException.
- Generic 422 on save failure + ILogger; AnyAsync existence checks;
Either/Validation unwrap via Match; XML doc on request DTO + endpoint.
- Response model: ChannelId, PlaylistId (nullable), ProgramScheduleId,
PlayoutId (CollectionId removed). Regenerated OpenAPI v1.json + v1.d.ts.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>