Files
photo-live/services/api/src/uploads/uploads.controller.ts
T

81 lines
2.6 KiB
TypeScript
Raw Normal View History

// services/api/src/uploads/uploads.controller.ts —— /uploads 端点(Task 18 起;
// Task 19 增补 listUploads/renewUploadCredential/completeUpload)。方法名与契约
// operationId 一一对应。控制器级 SessionGuard:端点全需认证。职责:透传认证
// 用户 + 查询参数规整(parseLimit/parseCursor 复用相册控制器导出,同契约 bounds)。
// 注意 DTO 必须值导入(非 import type):@Body 参数类型经 emitDecoratorMetadata
// 进入设计期元数据,import type 会令参数在管线中被置为 undefined(Task 18 实测)。
import {
Body,
Controller,
Get,
HttpCode,
HttpStatus,
Param,
Post,
Query,
Req,
UseGuards,
} from '@nestjs/common';
import {
parseCursor,
parseLimit,
userOf,
} from '../albums/albums.controller';
import { AuthenticatedRequest, SessionGuard } from '../auth/session.guard';
import { UploadsService } from './uploads.service';
import type {
UploadCompleteResponse,
UploadInitResponse,
UploadSessionListResponse,
} from './uploads.service';
import { UploadInitRequestDto } from './dto';
@Controller('uploads')
@UseGuards(SessionGuard)
export class UploadsController {
constructor(private readonly uploadsService: UploadsService) {}
/** 契约 201(幂等重复调用返回原会话,同 201)。 */
@Post()
initUpload(
@Body() dto: UploadInitRequestDto,
@Req() req: AuthenticatedRequest,
): Promise<UploadInitResponse> {
return this.uploadsService.init(userOf(req), dto);
}
/** 上传历史:当前用户自己的会话,新在前,(createdAt,id) 键集游标。 */
@Get()
listUploads(
@Query('cursor') cursor: string | undefined,
@Query('limit') limit: string | undefined,
@Req() req: AuthenticatedRequest,
): Promise<UploadSessionListResponse> {
return this.uploadsService.list(
userOf(req),
parseCursor(cursor),
parseLimit(limit),
);
}
/** 续签:仅 pending 会话;返回结构同 initUpload(credential 为新值)。 */
@Post(':uploadId/renew')
@HttpCode(HttpStatus.OK)
renewUploadCredential(
@Param('uploadId') uploadId: string,
@Req() req: AuthenticatedRequest,
): Promise<UploadInitResponse> {
return this.uploadsService.renew(userOf(req), uploadId);
}
/** 完成核验:幂等(重复调用返回相同结果,不重复建 job)。 */
@Post(':uploadId/complete')
@HttpCode(HttpStatus.OK)
completeUpload(
@Param('uploadId') uploadId: string,
@Req() req: AuthenticatedRequest,
): Promise<UploadCompleteResponse> {
return this.uploadsService.complete(userOf(req), uploadId);
}
}