feat(api): browse all media kinds, grouped search, delete media-items (#141, #161)

- Extend /api/library/browse to episodes, music videos, songs, other videos,
  images and remote streams (new LibraryBrowseMediaType values + hydrators);
  add optional Subtitle to LibraryBrowseItemResponseModel for leaf-item context
- Add GET /api/search: grouped per-kind results reusing the browse query/shape;
  empty query -> 422
- Add DELETE /api/media-items: body { ids }, empty -> 422, success -> 204
- Tests: SearchController, MediaItemsController, security + OpenAPI contract entries
- Regenerate openapi v1.json + web v1.d.ts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 15:23:07 +02:00
co-authored by Claude Fable 5
parent e0f36a12fb
commit 6c68c291a0
16 changed files with 914 additions and 5 deletions
@@ -19,4 +19,5 @@ public record LibraryBrowseItemResponseModel(
int? SmartCollectionId,
int? RerunCollectionId,
int? MediaItemId,
int? PlaylistId);
int? PlaylistId,
string? Subtitle = null);
@@ -11,5 +11,11 @@ public enum LibraryBrowseMediaType
SmartCollection = 6,
MultiCollection = 7,
RerunCollection = 8,
Playlist = 9
Playlist = 9,
Episode = 10,
MusicVideo = 11,
Song = 12,
OtherVideo = 13,
Image = 14,
RemoteStream = 15
}
@@ -0,0 +1,8 @@
#nullable enable
using ErsatzTV.Core.Api.LibraryBrowse;
namespace ErsatzTV.Core.Api.Search;
public record SearchResultGroupResponseModel(
int TotalCount,
List<LibraryBrowseItemResponseModel> Items);
@@ -0,0 +1,14 @@
#nullable enable
namespace ErsatzTV.Core.Api.Search;
public record SearchResultsResponseModel(
SearchResultGroupResponseModel Movies,
SearchResultGroupResponseModel Shows,
SearchResultGroupResponseModel Seasons,
SearchResultGroupResponseModel Artists,
SearchResultGroupResponseModel Episodes,
SearchResultGroupResponseModel MusicVideos,
SearchResultGroupResponseModel Songs,
SearchResultGroupResponseModel OtherVideos,
SearchResultGroupResponseModel Images,
SearchResultGroupResponseModel RemoteStreams);