feat(api): management photo list and account lookup
P1b Task 4: listAlbumPhotos (GET /albums/{albumId}/photos, tag
[photos]) + lookupUsersByAccount (GET /admin/users, tag [admin]).
- management list: all visibility states visible (unpublished/
published/hidden/deleted) for owner/admin; collaborator 403,
outsider/ghost album 404 (canView -> canManage ordering, same
anti-enumeration as members). Items = PhotoRecord + uploader
{userId, account, displayName} (flat-FK second query, redacted).
Keyset (uploadedAt,id) DESC via shared/cursor; visibility filter
validated against PhotoVisibility enum (400 otherwise), categoryId
must belong to the album (ghost/cross-album same-code 400).
pending_upload rows (uploadedAt NULL) excluded: the sort key is
both the contract-required field and the keyset predicate - NULL
can neither be shaped as PhotoRecord nor compared; in-flight
uploads are covered by the uploads history endpoint.
- account lookup (new src/admin module): prefix search over active
users only (credentialStatus=active, sourceStatus!=disabled,
!localLocked - same eligibility as SessionGuard/members.add),
account ASC, no cursor (small cap). $queryRaw LIKE prefix% with
explicit ESCAPE '!': !/%/_/\ escaped to literal matching (Prisma
startsWith escaping is not contractual); utf8mb4_0900_bin makes
the prefix match case-sensitive ('AL' misses 'alice'), documented
in contract + tests. Access policy per contract: any authenticated
staff (deviation from plan's admin/owner), unauthenticated 401.
- e2e: photos-admin (6) + users-lookup (6) cases; api e2e 136 -> 148.
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
// services/api/src/photos/photos.module.ts —— 照片管理模块(Task 24)。
|
||||
// 装配:PhotosController/PhotosService + PermissionsService(经 AlbumsModule
|
||||
// 导入复用 A02 逐次权限判定;同 uploads 模块的装配先例)。
|
||||
// services/api/src/photos/photos.module.ts —— 照片管理模块(Task 24;P1b Task 4
|
||||
// 增补管理列表控制器)。装配:PhotosController/AlbumPhotosController/
|
||||
// PhotosService + PermissionsService(经 AlbumsModule 导入复用 A02 逐次权限
|
||||
// 判定;同 uploads 模块的装配先例)。
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AlbumsModule } from '../albums/albums.module';
|
||||
import { AlbumPhotosController } from './album-photos.controller';
|
||||
import { PhotosController } from './photos.controller';
|
||||
import { PhotosService } from './photos.service';
|
||||
|
||||
@Module({
|
||||
imports: [AlbumsModule],
|
||||
controllers: [PhotosController],
|
||||
controllers: [PhotosController, AlbumPhotosController],
|
||||
providers: [PhotosService],
|
||||
})
|
||||
export class PhotosModule {}
|
||||
|
||||
Reference in New Issue
Block a user