121afadf1e
Co-Authored-By: Claude Code <noreply@anthropic.com>
81 lines
3.9 KiB
TypeScript
81 lines
3.9 KiB
TypeScript
// services/api/src/app-cn.module.ts
|
||
// 根模块:Prisma(@Global,封装 @photo/db-cn)、日志(nestjs-pino / pino-http)、
|
||
// request-id 中间件、全局异常过滤器、全局校验管道(Task 13 起,DTO 经
|
||
// class-validator 声明、ValidationPipe 强制,失败由过滤器映射 400 VALIDATION_FAILED)、
|
||
// /v1/health、/v1/auth/*(Task 13)。
|
||
// 功能模块(albums/uploads/photos/public)自 Task 15+ 起逐个加入。
|
||
// 过滤器/管道经 APP_FILTER/APP_PIPE、中间件经 NestModule 在模块层注册——e2e 直接
|
||
// import 本模块即可获得与生产一致的管线(全局前缀除外,由入口设置)。
|
||
import {
|
||
type MiddlewareConsumer,
|
||
Module,
|
||
type NestModule,
|
||
ValidationPipe,
|
||
} from '@nestjs/common';
|
||
import { APP_FILTER, APP_PIPE } from '@nestjs/core';
|
||
import { LoggerModule } from 'nestjs-pino';
|
||
import { AlbumsModule } from './albums/albums.module';
|
||
import { AdminModule } from './admin/admin.module';
|
||
import { AllExceptionsFilter } from './all-exceptions.filter';
|
||
import { AuthModule } from './auth/auth.module';
|
||
import { AdsModule } from './ads/ads.module';
|
||
import { EmbedModule } from './embed/embed.module';
|
||
import { HealthController } from './health.controller';
|
||
import { PhotosModule } from './photos/photos.module';
|
||
import { PrismaModule } from './prisma/prisma.module';
|
||
import { PublicModule } from './public/public.module';
|
||
import { RequestIdMiddleware } from './request-id.middleware';
|
||
import { SyncModule } from './sync/sync.module';
|
||
import { UploadsModule } from './uploads/uploads.module';
|
||
import { UserSyncModule } from './user-sync/user-sync.module';
|
||
// P2 Task 2:logger 装配选项(genReqId/redact/level)收敛至 shared,与 ov 入口
|
||
// 共用单一来源;此处仅消费,行为不变(P1 e2e 套件守护)。
|
||
import { createLoggerOptions } from './shared/logger-options';
|
||
|
||
@Module({
|
||
imports: [
|
||
// @Global:功能模块(Task 12+)直接注入 PrismaService,无需 re-import。
|
||
PrismaModule,
|
||
AuthModule,
|
||
// 相册域(Task 14 起步:PermissionsService;控制器自 Task 15 加入)。
|
||
AlbumsModule,
|
||
// 上传域(Task 18 init;Task 19 renew/complete/history)。
|
||
UploadsModule,
|
||
// 公开(观众端)域(Task 22 getPublicAlbum;Task 23 公开照片读)。
|
||
PublicModule,
|
||
// 照片管理域(Task 24:可见性生命周期 PATCH/DELETE;P1b Task 4 增补
|
||
// /albums/{albumId}/photos 管理列表)。
|
||
PhotosModule,
|
||
// 管理辅助域(P1b Task 4:/admin/users 账号前缀查询)。
|
||
AdminModule,
|
||
// 展示位管理域(P4b Task 2:/admin/embed-slots,slot-state 事件源)。
|
||
EmbedModule,
|
||
// 广告位管理域(ads-carousel Task 6 起:/admin/ads/uploads 直传初始化;
|
||
// CRUD Task 7——ad.* 事件源,仅 cn 入口装配)。
|
||
AdsModule,
|
||
// 内部同步域(P2 Task 3:/internal/sync/bootstrap|reconcile,HMAC 鉴权,
|
||
// 仅 cn 入口装配——cn 是内容同步的源端)。
|
||
SyncModule,
|
||
// 用户同步域(P4a Task 7:mock 源定期同步 + /admin/user-sync 管理端点 +
|
||
// setInterval 调度器——仅 cn 装配,ov 入口不碰)。
|
||
UserSyncModule,
|
||
LoggerModule.forRoot(createLoggerOptions()),
|
||
],
|
||
controllers: [HealthController],
|
||
providers: [
|
||
{ provide: APP_FILTER, useClass: AllExceptionsFilter },
|
||
// 全局校验管道(Task 13):whitelist 剥离 DTO 未声明的属性(契约未禁未知
|
||
// 字段,剥离而非拒绝);校验失败抛 BadRequestException → 过滤器映射
|
||
// 400 VALIDATION_FAILED。经 APP_PIPE 在模块层注册,e2e 复用同一管线。
|
||
{
|
||
provide: APP_PIPE,
|
||
useFactory: () => new ValidationPipe({ whitelist: true }),
|
||
},
|
||
],
|
||
})
|
||
export class AppCnModule implements NestModule {
|
||
configure(consumer: MiddlewareConsumer): void {
|
||
consumer.apply(RequestIdMiddleware).forRoutes('*');
|
||
}
|
||
}
|