import { Body, Controller, Get, Param, Post, Query } from "@nestjs/common" import { ApiBadRequestResponse, ApiConflictResponse, ApiCreatedResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiParam, ApiQuery, ApiTags, } from "@nestjs/swagger" import { AssetsService } from "./assets.service" import { AssetResponseDto, AssetVariantsResponseDto, AssetsListResponseDto } from "./asset-response.dto" import { CreateAssetVariantsRequestDto, CreateAssetVariantsResponseDto } from "./create-asset-variants.dto" import { CreateAssetRequestDto, CreateAssetResponseDto } from "./create-asset.dto" @ApiTags("assets") @Controller("assets") export class AssetsController { constructor(private readonly assets: AssetsService) {} @Get() @ApiOperation({ summary: "получить список assets", description: "Возвращает последние зарегистрированные assets вместе с source URL текущей версии.", }) @ApiQuery({ description: "Максимальное количество assets в ответе.", example: 50, name: "limit", required: false }) @ApiQuery({ description: "Смещение для простого paging.", example: 0, name: "offset", required: false }) @ApiOkResponse({ description: "Список assets возвращён.", type: AssetsListResponseDto }) listAssets(@Query("limit") limit?: string, @Query("offset") offset?: string): Promise { return this.assets.listAssets({ limit, offset }) } @Post() @ApiOperation({ summary: "зарегистрировать исходное изображение", description: "Создаёт asset и первую версию source image. Source URL сохраняется в PostgreSQL, а публичный image URL строится через Gateway без раскрытия исходной ссылки клиенту.", }) @ApiCreatedResponse({ description: "Asset создан, версия source image зарегистрирована.", type: CreateAssetResponseDto }) @ApiBadRequestResponse({ description: "Некорректный sourceUrl, publicId или source host запрещён настройками." }) @ApiConflictResponse({ description: "Asset с таким publicId уже существует." }) createAsset(@Body() request: CreateAssetRequestDto): Promise { return this.assets.createAsset(request) } @Get(":publicId") @ApiOperation({ summary: "получить asset по publicId", description: "Возвращает metadata asset и source URL текущей версии.", }) @ApiParam({ description: "Публичный идентификатор asset.", example: "asset_demo", name: "publicId" }) @ApiOkResponse({ description: "Asset найден.", type: AssetResponseDto }) @ApiNotFoundResponse({ description: "Asset не найден." }) getAsset(@Param("publicId") publicId: string): Promise { return this.assets.getAsset(publicId) } @Get(":publicId/variants") @ApiOperation({ summary: "получить variants asset", description: "Возвращает variants asset: preset/custom параметры, status, S3 key, public URL и ошибку генерации, если она была.", }) @ApiParam({ description: "Публичный идентификатор asset.", example: "asset_demo", name: "publicId" }) @ApiQuery({ description: "Версия source image. Если не передана, возвращаются variants всех версий.", example: 1, name: "version", required: false }) @ApiOkResponse({ description: "Variants возвращены.", type: AssetVariantsResponseDto }) @ApiNotFoundResponse({ description: "Asset не найден." }) listAssetVariants( @Param("publicId") publicId: string, @Query("version") version?: string, ): Promise { return this.assets.listAssetVariants(publicId, version) } @Post(":publicId/variants") @ApiOperation({ summary: "поставить generation jobs для variants", description: "Business endpoint для явной подготовки variants. В режиме `single` создаёт один variant, в режиме `family` создаёт набор variants preset по всем разрешённым widths/formats. Endpoint не ждёт bytes, а возвращает созданные/переиспользованные rows и public URLs.", }) @ApiParam({ description: "Публичный идентификатор asset.", example: "asset_demo", name: "publicId" }) @ApiCreatedResponse({ description: "Variants созданы или переиспользованы, jobs поставлены при необходимости.", type: CreateAssetVariantsResponseDto }) @ApiBadRequestResponse({ description: "Некорректный preset/custom transform config." }) @ApiNotFoundResponse({ description: "Asset или version не найдены." }) createAssetVariants( @Param("publicId") publicId: string, @Body() request: CreateAssetVariantsRequestDto, ): Promise { return this.assets.createAssetVariants(publicId, request) } }