Files
photo-live/services/api/test/reset-ov.ts
T
浅念 3d6e9ce175 feat(ov): ov schema, entry skeleton and compose profile
P2 Task 2 ov 数据层:
- compose ov profile:mysql-ov(mysql:8.4,127.0.0.1:3309,库级
  utf8mb4_0900_bin)+ redis-ov(6381),cn 侧默认 up 不受影响
  (3307/3308 已被其它本机项目占用,端口决策 3309)
- @photo/db-ov:9 表 schema(albums_ov/photos_ov 副本、sync_inbox/
  sync_state 同步账本(水位行同表标志位)、like_batches/album_stats/
  visit_sessions/visit_requests 互动域、outbox_stat_events 回传队列);
  迁移 20260918060102_init_ov 走固化校对手决流程,information_schema
  复核全部业务表/列 utf8mb4_0900_bin(_prisma_migrations 同 cn 先例
  保持 unicode_ci)
- generator 独立 output(包内 generated/):pnpm 将两包 @prisma/client
  提升为同一 store 实例,默认 .prisma/client 输出会被双 schema 互相
  覆盖,ov 客户端独立产出经 src/index.ts 转出口
- ov 入口骨架:main-ov.ts(PORT_OV 默认 8081)+ app-ov.module.ts
  (仅管线骨架 + /v1/health,feature modules 后续任务装配);logger
  装配选项抽取至 shared/logger-options.ts 供 cn/ov 双入口共用(行为
  不变,P1 套件守护)
- test/reset-ov.ts:ov 库 truncate-if-exists 隔离工具(无 MinIO 清理)
- 根脚本:db:generate 双库齐跑,新增 db-ov:migrate/db-ov:generate/dev:ov

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-18 14:11:41 +08:00

53 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// services/api/test/reset-ov.ts —— ov 库(photo_ov)e2e 隔离工具(P2 Task 2)。
// 与 reset.ts 镜像但独立成文件:两库连接串不同(DATABASE_URL_OV vs _CN),
// RESET_TABLES 互不重叠,cn/ov spec 各自 beforeAll 调用,互不清对方的数据。
// 与 reset.ts 的两点差异:
// 1. 无 MinIO 清理——ov 侧 P2 只读对象(签名 URL 指向同一 MinIO,上传仍归
// cn 侧 e2e 的前缀清理负责);
// 2. truncate-if-exists——经 information_schema 取「库中实际存在的待重置表」
// 再逐表 TRUNCATE(MySQL 无 TRUNCATE IF EXISTS):首次迁移前的空库上
// 调用是 no-op 而非报错,ov 库生命周期独立于 cn 库(compose profile ov)。
// ov 全库扁平字符串外键、无 FK 约束,FOREIGN_KEY_CHECKS 包裹仅沿用 reset.ts
// 的防御性约定(后续如引入约束同样安全);表序仍按逻辑依赖排列(子表在前)。
import { PrismaClient } from '@photo/db-ov';
export const RESET_TABLES_OV: readonly string[] = [
// 统计回传队列与互动流水(Task 7-9 的幂等锚点)。
'outbox_stat_events',
'visit_requests',
'visit_sessions',
'like_batches',
'album_stats',
// 同步账本(Task 4 inbox 消费)。
'sync_inbox',
'sync_state',
// 副本域(photos 先于 albums)。
'photos_ov',
'albums_ov',
];
/** TRUNCATE photo_ov 中 RESET_TABLES_OV 里**实际存在**的表(空库安全)。 */
export async function resetOvDb(): Promise<void> {
const prisma = new PrismaClient();
try {
const placeholders = RESET_TABLES_OV.map(() => '?').join(', ');
const existing = await prisma.$queryRawUnsafe<
{ tableName: string }[]
>(
`SELECT TABLE_NAME AS tableName FROM information_schema.TABLES ` +
`WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME IN (${placeholders})`,
...RESET_TABLES_OV,
);
await prisma.$executeRawUnsafe('SET FOREIGN_KEY_CHECKS = 0');
try {
for (const { tableName } of existing) {
await prisma.$executeRawUnsafe(`TRUNCATE TABLE \`${tableName}\``);
}
} finally {
await prisma.$executeRawUnsafe('SET FOREIGN_KEY_CHECKS = 1');
}
} finally {
await prisma.$disconnect();
}
}