Files
photo-live/services/api/src/photos/photos.controller.ts
T
浅念 6d61d117d5 feat(api): photo visibility lifecycle with audit and outbox events
Serializes turbo tasks (concurrency=1): api and worker e2e suites share
one MySQL/MinIO and resetDb TRUNCATEs raced when run in parallel.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-17 23:51:29 +08:00

51 lines
1.7 KiB
TypeScript

// services/api/src/photos/photos.controller.ts —— /photos 端点(Task 24)。
// 方法名与契约 operationId 一一对应(updatePhoto/deletePhoto)。控制器级
// SessionGuard:两端点全需认证(契约 bearerAuth)。职责仅透传认证用户与
// 参数;404/403/400 映射与状态机裁决在服务层。注意 DTO 值导入(非
// import type):@Body 参数类型经 emitDecoratorMetadata 进入设计期元数据。
import {
Body,
Controller,
Delete,
HttpCode,
HttpStatus,
Param,
Patch,
Req,
UseGuards,
} from '@nestjs/common';
import { userOf } from '../albums/albums.controller';
import { AuthenticatedRequest, SessionGuard } from '../auth/session.guard';
import { PhotosService, type PhotoRecord } from './photos.service';
import { PhotoVisibilityUpdateDto } from './dto';
@Controller('photos')
@UseGuards(SessionGuard)
export class PhotosController {
constructor(private readonly photosService: PhotosService) {}
/** 调整可见性(hidden↔published):按相册角色与上传人共同判定权限。 */
@Patch(':photoId')
updatePhoto(
@Param('photoId') photoId: string,
@Body() dto: PhotoVisibilityUpdateDto,
@Req() req: AuthenticatedRequest,
): Promise<PhotoRecord> {
return this.photosService.updateVisibility(
userOf(req),
photoId,
dto.visibility,
);
}
/** 软删除:行/对象保留,公开端点即刻不可见;幂等重复删除 204。 */
@Delete(':photoId')
@HttpCode(HttpStatus.NO_CONTENT)
async deletePhoto(
@Param('photoId') photoId: string,
@Req() req: AuthenticatedRequest,
): Promise<void> {
await this.photosService.remove(userOf(req), photoId);
}
}