Add UploadLimits service and refactor user and media listing endpoints to use filter records for improved parameter handling. Update audio upload logic to streamline parameter passing and enhance clarity. Adjust ImageEndpoints to use HashSet for allowed extensions, and refine StreamingEndpoints to clarify token handling.
ci / build-backend (push) Successful in 1m29s
ci / build-frontend (push) Successful in 51s
ci / tests (push) Successful in 2m1s
ci / sonar (push) Successful in 4m22s

This commit is contained in:
Leonid Pershin
2026-07-26 23:05:37 +03:00
parent 0f0657e523
commit 69d1319564
7 changed files with 108 additions and 58 deletions
@@ -51,8 +51,7 @@ public static class MediaEndpoints
IMediaStorage storage,
IMediaProcessingQueue queue,
ISender sender,
IOptions<MediaOptions> mediaOptions,
IOptions<StorageOptions> storageOptions,
UploadLimits limits,
CancellationToken cancellationToken
)
{
@@ -71,7 +70,7 @@ public static class MediaEndpoints
);
var contentLength = request.ContentLength ?? 0;
if (contentLength > mediaOptions.Value.MaxUploadBytes)
if (contentLength > limits.MaxUploadBytes)
return Results.Problem(
title: MediaErrors.FileTooLarge.Code,
detail: MediaErrors.FileTooLarge.Message,
@@ -79,7 +78,7 @@ public static class MediaEndpoints
);
var free = storage.GetAvailableFreeSpaceBytes();
if (free - contentLength < storageOptions.Value.MinFreeSpaceBytes)
if (free - contentLength < limits.MinFreeSpaceBytes)
return Results.Problem(
title: MediaErrors.InsufficientStorage.Code,
detail: MediaErrors.InsufficientStorage.Message,
@@ -106,30 +105,20 @@ public static class MediaEndpoints
);
}
/// <summary>
/// Все параметры со значениями по умолчанию: обязательный <c>bool</c> в query заставлял
/// минимальный API отвечать 400 на запросы без него — например, из выборок «все готовые ассеты»,
/// которым сортировка не нужна.
/// </summary>
private static async Task<IResult> List(
[AsParameters] ListMediaFilter filter,
ISender sender,
CancellationToken cancellationToken,
int page = 1,
int pageSize = 20,
MediaAssetStatus[]? status = null,
string? search = null,
string? sort = null,
bool desc = false
CancellationToken cancellationToken
)
{
var result = await sender.Send(
new ListMediaAssetsQuery(
page <= 0 ? 1 : page,
pageSize <= 0 ? 20 : pageSize,
status ?? [],
search,
sort,
desc
filter.Page is > 0 ? filter.Page.Value : 1,
filter.PageSize is > 0 ? filter.PageSize.Value : 20,
filter.Status ?? [],
filter.Search,
filter.Sort,
filter.Desc ?? false
),
cancellationToken
);
@@ -204,6 +193,21 @@ public static class MediaEndpoints
}
}
/// <summary>
/// Фильтр и страница списка медиа. Все поля nullable намеренно: обязательный параметр в query
/// заставлял минимальный API отвечать 400 на запросы без него — например, из выборок «все готовые
/// ассеты», которым сортировка не нужна. Умолчания подставляет хендлер, а не объявление: при
/// <c>AsParameters</c> обязательность определяется nullable-типом, а не значением по умолчанию.
/// </summary>
public sealed record ListMediaFilter(
int? Page,
int? PageSize,
MediaAssetStatus[]? Status,
string? Search,
string? Sort,
bool? Desc
);
public sealed record UploadMediaResponse(Guid Id);
public sealed record ImportManualInboxBody(IReadOnlyList<ManualImportItem> Items, Guid ShowId);