feat(ov): emergency disable channel independent of sync

P2 Task 5(海外紧急停用入口):
- ov 新增 POST /v1/internal/emergency/disable|enable(InternalSyncGuard
  HMAC,albumToken/albumId 恰好其一、都缺省 400;副本不存在 404
  ALBUM_NOT_FOUND):直写 albums_ov.emergencyDisabled(唯一 ov 本地可写
  位),独立于同步版本链——更高版本 album.updated 重放不解除(e2e 断言
  entityVersion 推进而标志保持),恢复仅经显式 enable;幂等语义
  (alreadyDisabled/wasDisabled 入审计行)
- cn 侧不感知:无对应 cn 状态位、无反向同步(契约描述文档化)
- 审计:pino child(audit=emergency 字段常驻每行)结构化日志——偏差
  登记:计划原文「写 ov 侧日志文件」落地为字段标记而非独立文件通道
  (免新增文件 transport 依赖,P5 运维按字段路由聚合);注入令牌
  EMERGENCY_AUDIT_LOGGER,测试覆写为内存目的地断言字段
- isAlbumVisibleOv 共享判定(status=active && publicEnabled &&
  !emergencyDisabled——镜像 cn 公开语义叠加本地停用位):Task 6 公开
  API / Task 7 WS subscribe 的 404 ALBUM_NOT_PUBLIC 语义单一实现,
  判定矩阵单测锁定
- 契约 [internal] 增 emergency disable/enable 操作与 schema(gen 已跑、
  redocly 通过);e2e:token/id 定位、幂等、enable 恢复、未签名 401、
  均缺省 400、未知相册 404、同步事件不解除

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-18 16:19:02 +08:00
parent 36082c5a74
commit eac8da6d6c
11 changed files with 813 additions and 3 deletions
+6 -2
View File
@@ -2,8 +2,9 @@
// 骨架 + Task 3 起装配收件箱)。与 app-cn.module.ts 同一管线骨架(日志 +
// request-id + 全局异常过滤器 + 全局校验管道 + /v1/health),但**显式挑选**
// ov 角色模块:cn 专属域(auth/albums/uploads/photos/admin——写路径与 MinIO
// 上传)不装配;P2 Task 3 加入 sync-inbox(内容事件接收 + 副本投影);公开读、
// likes/visits、WS 网关自 Task 6+ 起逐个加入。cn 模块保持原样,两入口互不影响。
// 上传)不装配;P2 Task 3 加入 sync-inbox(内容事件接收 + 副本投影);Task 5
// 加入 emergency(海外紧急停用通道,独立于同步);公开读、likes/visits、
// WS 网关自 Task 6+ 起逐个加入。cn 模块保持原样,两入口互不影响。
import {
type MiddlewareConsumer,
Module,
@@ -13,6 +14,7 @@ import {
import { APP_FILTER, APP_PIPE } from '@nestjs/core';
import { LoggerModule } from 'nestjs-pino';
import { AllExceptionsFilter } from './all-exceptions.filter';
import { EmergencyModule } from './emergency/emergency.module';
import { HealthController } from './health.controller';
import { RequestIdMiddleware } from './request-id.middleware';
import { createLoggerOptions } from './shared/logger-options';
@@ -23,6 +25,8 @@ import { SyncInboxModule } from './sync-inbox/sync-inbox.module';
LoggerModule.forRoot(createLoggerOptions()),
// ov 内容事件收件箱(P2 Task 3):POST /v1/internal/sync/content-batches。
SyncInboxModule,
// 海外紧急停用通道(P2 Task 5):POST /v1/internal/emergency/disable|enable。
EmergencyModule,
],
controllers: [HealthController],
providers: [