鉴权改为登录态回库校验,新增 tokenValidAfter 失效时间,支持密码变更与 seed 重置后旧 token 立即失效 患者字段由 idCardHash 统一迁移为 idCard,新增身份证标准化逻辑并同步 C 端生命周期查询参数 组织模块增加小组删除限制(有成员时返回 409)并补充中文错误消息 任务取消接口支持可选 reason 字段(先透传事件层) 补齐 Prisma 迁移、文档说明和 E2E 用例(含设备模块与 token 失效场景)
194 lines
5.0 KiB
TypeScript
194 lines
5.0 KiB
TypeScript
import { NotFoundException } from '@nestjs/common';
|
|
import { PrismaService } from '../../../src/prisma.service.js';
|
|
|
|
export interface E2ESeedFixtures {
|
|
hospitalAId: number;
|
|
hospitalBId: number;
|
|
departmentA1Id: number;
|
|
departmentA2Id: number;
|
|
departmentB1Id: number;
|
|
groupA1Id: number;
|
|
groupA2Id: number;
|
|
groupB1Id: number;
|
|
users: {
|
|
systemAdminId: number;
|
|
hospitalAdminAId: number;
|
|
directorAId: number;
|
|
leaderAId: number;
|
|
doctorAId: number;
|
|
doctorA2Id: number;
|
|
doctorA3Id: number;
|
|
doctorBId: number;
|
|
engineerAId: number;
|
|
engineerBId: number;
|
|
};
|
|
patients: {
|
|
patientA1Id: number;
|
|
patientA2Id: number;
|
|
patientA3Id: number;
|
|
patientB1Id: number;
|
|
};
|
|
devices: {
|
|
deviceA1Id: number;
|
|
deviceA2Id: number;
|
|
deviceA3Id: number;
|
|
deviceA4InactiveId: number;
|
|
deviceB1Id: number;
|
|
};
|
|
}
|
|
|
|
interface SeedUserScope {
|
|
id: number;
|
|
hospitalId: number | null;
|
|
departmentId: number | null;
|
|
groupId: number | null;
|
|
}
|
|
|
|
async function requireUserScope(
|
|
prisma: PrismaService,
|
|
openId: string,
|
|
): Promise<SeedUserScope> {
|
|
const user = await prisma.user.findUnique({
|
|
where: { openId },
|
|
select: {
|
|
id: true,
|
|
hospitalId: true,
|
|
departmentId: true,
|
|
groupId: true,
|
|
},
|
|
});
|
|
if (!user) {
|
|
throw new NotFoundException(`Seed user not found: ${openId}`);
|
|
}
|
|
return user;
|
|
}
|
|
|
|
async function requireDeviceId(
|
|
prisma: PrismaService,
|
|
snCode: string,
|
|
): Promise<number> {
|
|
const device = await prisma.device.findUnique({
|
|
where: { snCode },
|
|
select: { id: true },
|
|
});
|
|
if (!device) {
|
|
throw new NotFoundException(`Seed device not found: ${snCode}`);
|
|
}
|
|
return device.id;
|
|
}
|
|
|
|
async function requirePatientId(
|
|
prisma: PrismaService,
|
|
hospitalId: number,
|
|
phone: string,
|
|
idCard: string,
|
|
): Promise<number> {
|
|
const patient = await prisma.patient.findFirst({
|
|
where: { hospitalId, phone, idCard },
|
|
select: { id: true },
|
|
});
|
|
if (!patient) {
|
|
throw new NotFoundException(`Seed patient not found: ${phone}/${idCard}`);
|
|
}
|
|
return patient.id;
|
|
}
|
|
|
|
export async function loadSeedFixtures(
|
|
prisma: PrismaService,
|
|
): Promise<E2ESeedFixtures> {
|
|
const systemAdmin = await requireUserScope(
|
|
prisma,
|
|
'seed-system-admin-openid',
|
|
);
|
|
const hospitalAdminA = await requireUserScope(
|
|
prisma,
|
|
'seed-hospital-admin-a-openid',
|
|
);
|
|
const directorA = await requireUserScope(prisma, 'seed-director-a-openid');
|
|
const leaderA = await requireUserScope(prisma, 'seed-leader-a-openid');
|
|
const doctorA = await requireUserScope(prisma, 'seed-doctor-a-openid');
|
|
const doctorA2 = await requireUserScope(prisma, 'seed-doctor-a2-openid');
|
|
const doctorA3 = await requireUserScope(prisma, 'seed-doctor-a3-openid');
|
|
const doctorB = await requireUserScope(prisma, 'seed-doctor-b-openid');
|
|
const engineerA = await requireUserScope(prisma, 'seed-engineer-a-openid');
|
|
const engineerB = await requireUserScope(prisma, 'seed-engineer-b-openid');
|
|
|
|
const hospitalAId = hospitalAdminA.hospitalId;
|
|
const hospitalBId = doctorB.hospitalId;
|
|
const departmentA1Id = doctorA.departmentId;
|
|
const departmentA2Id = doctorA3.departmentId;
|
|
const departmentB1Id = doctorB.departmentId;
|
|
const groupA1Id = doctorA.groupId;
|
|
const groupA2Id = doctorA3.groupId;
|
|
const groupB1Id = doctorB.groupId;
|
|
|
|
if (
|
|
hospitalAId == null ||
|
|
hospitalBId == null ||
|
|
departmentA1Id == null ||
|
|
departmentA2Id == null ||
|
|
departmentB1Id == null ||
|
|
groupA1Id == null ||
|
|
groupA2Id == null ||
|
|
groupB1Id == null
|
|
) {
|
|
throw new NotFoundException('Seed user scope is incomplete');
|
|
}
|
|
|
|
return {
|
|
hospitalAId,
|
|
hospitalBId,
|
|
departmentA1Id,
|
|
departmentA2Id,
|
|
departmentB1Id,
|
|
groupA1Id,
|
|
groupA2Id,
|
|
groupB1Id,
|
|
users: {
|
|
systemAdminId: systemAdmin.id,
|
|
hospitalAdminAId: hospitalAdminA.id,
|
|
directorAId: directorA.id,
|
|
leaderAId: leaderA.id,
|
|
doctorAId: doctorA.id,
|
|
doctorA2Id: doctorA2.id,
|
|
doctorA3Id: doctorA3.id,
|
|
doctorBId: doctorB.id,
|
|
engineerAId: engineerA.id,
|
|
engineerBId: engineerB.id,
|
|
},
|
|
patients: {
|
|
patientA1Id: await requirePatientId(
|
|
prisma,
|
|
hospitalAId,
|
|
'13800002001',
|
|
'110101199001010011',
|
|
),
|
|
patientA2Id: await requirePatientId(
|
|
prisma,
|
|
hospitalAId,
|
|
'13800002002',
|
|
'110101199002020022',
|
|
),
|
|
patientA3Id: await requirePatientId(
|
|
prisma,
|
|
hospitalAId,
|
|
'13800002003',
|
|
'110101199003030033',
|
|
),
|
|
patientB1Id: await requirePatientId(
|
|
prisma,
|
|
hospitalBId,
|
|
'13800002001',
|
|
'110101199001010011',
|
|
),
|
|
},
|
|
devices: {
|
|
deviceA1Id: await requireDeviceId(prisma, 'SEED-SN-A-001'),
|
|
deviceA2Id: await requireDeviceId(prisma, 'SEED-SN-A-002'),
|
|
deviceA3Id: await requireDeviceId(prisma, 'SEED-SN-A-003'),
|
|
deviceA4InactiveId: await requireDeviceId(prisma, 'SEED-SN-A-004'),
|
|
deviceB1Id: await requireDeviceId(prisma, 'SEED-SN-B-001'),
|
|
},
|
|
};
|
|
}
|