The flat ScheduleItemResponseModel removed the polymorphic ProgramScheduleItemViewModel
from the API surface, which was the only path exposing the Application VMs
(WatermarkViewModel, PlaylistViewModel, FillerPresetViewModel, collection VMs, etc.).
WatermarkViewModel is no longer in v1.json, so its serializer-contract guard case is moot.
ChannelViewModel still covers the schema transformer's VM path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adversarial-review follow-ups:
- OpenApiSerializerContractTests: add a fifth case, a fully-populated
ChannelResponseModel — the only DTO with a [JsonProperty("ffmpegProfile")]
override, i.e. the attribute path of NewtonsoftSchemaNamingTransformer that
the existing four cases never exercised.
- NewtonsoftSchemaNamingTransformer: a rename colliding with an existing schema
key now throws InvalidOperationException (naming the type and keys) instead of
silently overwriting/dropping a property — the generator must never emit a
lossy spec.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The OpenAPI document is generated from System.Text.Json metadata, whose
camelCase drifted from the runtime MVC serializer (Newtonsoft via
CustomContractResolver/CustomNamingStrategy): the spec said "fFmpegProfileId"
and "fFmpegProfile" while the wire emits "ffmpegProfileId" (naming-strategy
special case) and "ffmpegProfile" (ChannelResponseModel's [JsonProperty]
override). That fed the SPA the wrong keys.
Add NewtonsoftSchemaNamingTransformer, an OpenAPI schema transformer registered
on all three documents that renames each object schema's Properties (and
Required) keys through the SAME Newtonsoft contract resolver the runtime uses,
so the spec matches the wire format by construction. Regenerate v1.json.
Guard with OpenApiSerializerContractTests: serializes fully-populated DTOs
through the runtime Newtonsoft settings and pins the v1.json schema property
sets to the emitted keys, failing if generation drifts again.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>