Commit e75f756d by luoqi

fix(sync): reconcile 不再写死 t_default — 真实 tenant 解析 + 多 tenant 防呆

ReconcileOrchestrator 走单 tenant dispatcher,原写死 t_default 会把真实数据(如 jvs-dw ba67e6cf)写到错 tenant 造重复患者。改为从 host 已有数据解析 tenant:单 tenant 用之;多 tenant(瑞尔+瑞泰)直接 BadRequestException 拒绝并指向 `pnpm sync`(按 brand 派 tenant 的正确补数路径)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
parent aa911a69
import { Injectable, Logger, NotFoundException } from '@nestjs/common'; import { BadRequestException, Injectable, Logger, NotFoundException } from '@nestjs/common';
import { randomUUID } from 'node:crypto'; import { randomUUID } from 'node:crypto';
import { SyncDirection, SyncStatus, type PullConfig } from '@pac/types'; import { SyncDirection, SyncStatus, type PullConfig } from '@pac/types';
import { PrismaService } from '../../../prisma/prisma.service'; import { PrismaService } from '../../../prisma/prisma.service';
...@@ -40,7 +40,28 @@ export class ReconcileOrchestrator { ...@@ -40,7 +40,28 @@ export class ReconcileOrchestrator {
return { skipped: true, reason: !host.active ? 'host_inactive' : 'no_pull_config' }; return { skipped: true, reason: !host.active ? 'host_inactive' : 'no_pull_config' };
} }
const tenantId = host.name.includes('demo') || host.name.includes('mock') ? 't_demo' : 't_default'; // tenant 解析:dispatcher 是**单 tenant** 路径(patient upsert + transaction 都用一个 tenantId,
// 不按行派)。原写死 't_default' 会把真实数据(如 jvs-dw 的 ba67e6cf)写到错 tenant → 造重复患者。
// 修复:从该 host 已有数据解析真实 tenant —
// · 单 tenant → 用之(顺带修掉 t_default 的错)
// · 多 tenant(如 jvs-dw 瑞尔+瑞泰)→ 单 tenant dispatcher 无法按行派 → 拒绝,指向 `pnpm sync`
// (ColdImportService 走 buildTenantResolver 按 brand 派,是多 tenant 的正确补数路径)
// · 空 host(尚无患者)→ 退化到 demo/mock 占位(首次导入边界,reconcile 极少在空 host 上跑)
const hostTenants = await this.prisma.patient.findMany({
where: { hostId: host.id },
distinct: ['tenantId'],
select: { tenantId: true },
});
if (hostTenants.length > 1) {
throw new BadRequestException(
`host=${host.name} 存在多个 tenant(${hostTenants.map((t) => t.tenantId).join(', ')}),` +
`ReconcileOrchestrator 走单 tenant dispatcher,无法按行派 tenant → 会写错 tenant、造重复患者。` +
`请改用 \`pnpm sync -- --dir=<manifest_dir>\`(ColdImportService 按 brand 派 tenant)做时间窗补数。`,
);
}
const tenantId =
hostTenants[0]?.tenantId ??
(host.name.includes('demo') || host.name.includes('mock') ? 't_demo' : 't_default');
const windowDays = options.windowDays ?? 7; const windowDays = options.windowDays ?? 7;
const endedAt = new Date(); const endedAt = new Date();
const startedAt = new Date(endedAt.getTime() - windowDays * 86400_000); const startedAt = new Date(endedAt.getTime() - windowDays * 86400_000);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment