- 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>
33 lines
1.1 KiB
C#
33 lines
1.1 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
using ErsatzTV.Controllers.Api.Requests;
|
|
using ErsatzTV.Core;
|
|
using ErsatzTV.Extensions;
|
|
using MediatR;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace ErsatzTV.Controllers.Api;
|
|
|
|
[ApiController]
|
|
public class MediaItemsController(IMediator mediator) : ControllerBase
|
|
{
|
|
[HttpDelete("/api/media-items", Name = "DeleteMediaItems")]
|
|
[Tags("Media Items")]
|
|
[EndpointSummary("Delete media items from the database")]
|
|
[EndpointGroupName("general")]
|
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status422UnprocessableEntity)]
|
|
public async Task<IActionResult> Delete(
|
|
[Required] [FromBody] DeleteMediaItemsRequest request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
if (request.Ids is null || request.Ids.Count == 0)
|
|
{
|
|
return BaseError.New("At least one media item id is required").ToErrorResult();
|
|
}
|
|
|
|
Either<BaseError, Unit> result = await mediator.Send(request.ToCommand(), cancellationToken);
|
|
return result.ToDeletedResult();
|
|
}
|
|
}
|