Auto-Tune DetailPanel backend (#385), additive half. The create request
`AutoTunedChannelRequest` gains three optional per-channel fields, all
backward-compatible (omit = PR1 behavior):
- `templateId` — overrides the batch template per channel
- `advanced` — reuses the manual Channel Builder's
`CreateChannelFromLineupAdvancedOptionsRequest` verbatim (24-field override
set, `advanced.X ?? template.X` stamp contract). Axis default fills
`PlaybackOrder` only when the caller leaves it null.
- `logo` — uploaded channel image, `Sanitized()` at the request boundary
(#283 stored-XSS defense), forwarded to `CreateChannelFromLineup.Logo`
Resolved per channel inside `CreateAutoTunedChannelsHandler.CreateOne`, so one
channel's bad override still yields a per-channel Failed/Skipped without
aborting the batch.
Per-source rotation weights + query corrections are split out to #425 (they
need a MultiCollection-of-per-source-SmartCollections redesign — #70's
WeightedShuffle reads weights only off MultiCollection join rows, and an
auto-tuned channel is one SmartCollection). Bug-initials/colour generated logo
also deferred (needs persisted Channel state + FFmpeg-pipeline wiring).
Tests: handler override-threading (per-channel wins, axis default preserved,
no-override baseline) + request `ToCommand()` logo sanitization. OpenAPI trio
regenerated. Docs: decisions.md, api-conventions.md, domain-model.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>