Closes the two F9 Libraries.razor parity gaps and normalizes scan-show error
mapping to ProblemDetails.
TASK 1 — library-wide deep scan:
- QueueLibraryScanByLibraryId gains optional `bool DeepScan = false`; handler
threads it into ForceSynchronize{Plex,Jellyfin,Emby}LibraryById.
- POST /api/libraries/{id}/scan?deep=false binds it via [FromQuery].
TASK 2 — external-collections scan (new endpoints):
- POST /api/media-sources/{plex|jellyfin|emby}/{id}/scan-collections?deep=false
acquires the per-source collections lock (§3b: lock IS the running scan → 409),
enqueues Synchronize{X}Collections(id, ForceScan:true, deep) to the scanner
channel, returns 202; compensating-unlock on enqueue throw.
TASK 3 — scan-show normalization:
- New QueueShowScanResult enum; handler returns it instead of bool.
- POST /api/libraries/{id}/scan-show now maps 202/404/409/422 (all errors
ProblemDetails) instead of 200/404/400-anonymous-object.
- Updated the lone Blazor caller (TelevisionSeasonList.razor).
Tests: LibrariesController (scan deep=true, scan-show enum→status), the three
media-source controllers (scan-collections route/404/409/202/compensating-unlock),
and handler tests for both changed handlers (deep threading + show-scan outcomes).
Docs: api-conventions §3b exemplar + blazor-route-parity §5 F9 gate.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adversarial review follow-ups on the #193 rerun selection validation:
- RerunCollectionEditor.razor: remove the CollectionType.Playlist
dropdown option — RerunCollection has no PlaylistId column, so the
option previously persisted a broken row and now fails validation.
- RerunCollectionSelectionValidation: replace FindAsync with a
non-tracking AnyAsync(EF.Property<int>("Id") == id) existence check
so nothing is materialized/tracked into the save-path context.
- Tests: pin the deliberate 422-not-404 choice
(ShouldNotBeOfType<NotFoundError>) and cover the unsupported-type
default arm (Playlist -> "Unsupported collection type"), which was
reachable via the Blazor editor.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Backend plumbing for the SPA transcoding editors (#143 blocker):
- FFmpeg profile response DTO round-trip: add NormalizeAudio, NormalizeVideo,
PadMode, TargetLoudness, NormalizeColors, ResolutionId (keep Resolution name
for compat); DeinterlaceVideo now bool (was bool?). #nullable enable on the DTO.
- New GET /api/ffmpeg/hardware-acceleration-kinds wrapping
GetSupportedHardwareAccelerationKinds (returns enum names as strings).
- Filler preset CRUD: GET-by-id/POST/PUT/DELETE on FillerPresetController with
full request/response DTOs; new FillerPresetFullResponseModel +
GetFillerPresetByIdForApi. CreateFillerPreset now returns the new id
(CreateFillerPresetResult) to match sibling Create commands and enable a
201+Location; updated the one Blazor call site.
- Watermark CRUD: GET-by-id/POST/PUT/DELETE on WatermarkController with full
DTOs (path+contentType, all 15 fields); new WatermarkFullResponseModel +
GetWatermarkByIdForApi.
- Startup: register WatermarkLocation/WatermarkSize as OpenAPI string enums
(they live in ErsatzTV.FFmpeg.State and were documented as ints, mismatching
the Newtonsoft StringEnumConverter runtime serialization).
- Tests: full CRUD controller tests for filler + watermark; contract-test
entries (404/401/422) for the new mutating endpoints; regenerated v1.json.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Add Polish localization for MainLayout
* Add Polish language option to UI settings
* Add Polish to supported UI cultures
---------
Co-authored-by: Jason Dove <1695733+jasongdove@users.noreply.github.com>
* add new fields to database
* update editor
* audio and video normalization settings appear to work
* implement optional color normalization
* fix transcoding tests
* update changelog
* refactor classic and block schedules to use same alternate schedule selector
* handle start year and end year
* add migrations for classic and block schedules
* allow editing block template start and end year
* add tests that include years
* add date range editing to classic (alternate) schedules
* fix running tests locally
* restore media files load; needed for local folder scanners
* update changelog
* feedback
* Add select all controls to media lists
* Refine select-all helper and add coverage
* Adjust select-all button alignment
* Tighten select-all helper semantics
* Allow tests to access internal members
* Rename select-all helper and avoid shift tracking
* Simplify select-all reset helper
* Keep pager centered and move select-all right
* Add missing div
* create test project for main app; move and rename new tests
* remove core => main app reference
* cleanup unused imports
* Fix button behavior when the screen is small
* update changelog
---------
Co-authored-by: Jason Dove <1695733+jasongdove@users.noreply.github.com>
* handle artwork timeouts so they aren't reported
* catch some more cancellation errors
* add free space validation on startup
* add downgrade health check
* update dependencies