feat(api): server-side album role permission checks

Task 14 (A02 foundation): PermissionsService with fresh-DB-per-call
canViewAlbum/canManageAlbum/canUploadToAlbum/canManagePhoto over the
album_members @@unique([albumId,userId]) compound key; admin bypass,
owner/collaborator matrix per requirements doc section 2, removed
members lose access on the very next call (no caching). Boolean-only
returns; callers map 404/403. AlbumsModule shell wired into app module
(controllers arrive in Task 15). jest maxWorkers=1: DB-backed specs
share one MySQL database and reset it via TRUNCATE, so parallel spec
files wipe each other's seed data.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-17 21:34:22 +08:00
parent 39cae26106
commit 2d9b9f9fad
5 changed files with 349 additions and 2 deletions
+3
View File
@@ -15,6 +15,7 @@ import {
import { APP_FILTER, APP_PIPE } from '@nestjs/core';
import { LoggerModule } from 'nestjs-pino';
import type { IncomingMessage, ServerResponse } from 'node:http';
import { AlbumsModule } from './albums/albums.module';
import { AllExceptionsFilter } from './all-exceptions.filter';
import { AuthModule } from './auth/auth.module';
import { HealthController } from './health.controller';
@@ -28,6 +29,8 @@ import type { ServerRequestWithId } from './shared/request-with-id';
// @Global:功能模块(Task 12+)直接注入 PrismaService,无需 re-import。
PrismaModule,
AuthModule,
// 相册域(Task 14 起步:PermissionsService;控制器自 Task 15 加入)。
AlbumsModule,
LoggerModule.forRoot({
pinoHttp: {
// 与 RequestIdMiddleware 共用同一解析函数:优先透传 x-request-id,