chore: 新增花名与等级一致性审计脚本(排查同名串档)

This commit is contained in:
chenpei 2026-08-14 18:38:54 +08:00
parent f63e04ba02
commit b2784ac279

View File

@ -0,0 +1,49 @@
/**
* 串档排查脚本(只读):
* 找出"无花名(外部/离职人员)却带有 M 级等级/负责人标志"的可疑档案。
*
* 规则(用户确认):有花名 = 正式员工;无花名 = 外部人员/离职人员。
* 正式员工才应有 M/P 等级;无花名的档案若带等级,极可能是花名册同名串档。
*
* 用法:npx tsx --env-file=.env scripts/audit-flower-mismatch.ts
*/
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
;(async () => {
console.log('=== 花名与等级一致性审计(只读)===\n')
// 有绑定且带等级但无花名的档案(疑似串档)
const suspicious = await prisma.performanceSurveyEmployeeProfile.findMany({
where: {
positionLevel: { not: null },
OR: [{ flowerName: null }, { flowerName: '' }],
},
select: {
id: true, displayName: true, realName: true, flowerName: true, jobNumber: true,
dingtalkUserId: true, departmentPath: true, positionLevel: true, levelType: true,
isLeadership: true, employmentState: true,
},
orderBy: { departmentPath: 'asc' },
})
// 过滤:只看有素材库绑定的人(无绑定的花名册人员即使无花名带等级也不是我们关注的)
const boundIds = new Set(
(await prisma.userEmployeeBinding.findMany({
where: { status: 'ACTIVE' },
select: { employeeProfileId: true },
})).map((b) => b.employeeProfileId),
)
const relevant = suspicious.filter((p) => boundIds.has(p.id))
console.log(`无花名但带等级 + 有绑定的档案: ${relevant.length} 条\n`)
for (const p of relevant) {
console.log(`【${p.displayName}】真名=${p.realName ?? '?'} 花名=${p.flowerName ?? '(无)'} 工号=${p.jobNumber ?? '?'}`)
console.log(` 部门=${p.departmentPath ?? '?'}`)
console.log(` 等级=${p.positionLevel}(${p.levelType ?? '?'}) 负责人=${p.isLeadership} 在职=${p.employmentState}`)
console.log(` 钉钉ID=${p.dingtalkUserId ?? '(无)'} 档案ID=${p.id}\n`)
}
console.log('=== 审计结束(未写入任何数据)===')
await prisma.$disconnect()
})().catch((e) => { console.error(e); process.exit(1) })