fix: support soft-delete user uniqueness in tools
This commit is contained in:
@@ -2488,4 +2488,5 @@ git diff --check
|
|||||||
- 手机号码基础校验放宽为`^1\d{10}$`,不依赖号段更新。客户端/HTTP混合批次逐号码把非法号码、平台黑名单和企业应用黑名单记为`submit_failed/rejected`且金额0,合法号码照常冻结、入队;CMPP混合多目的提交对被拦截号码生成平台`REJECTD`失败回执,合法号码继续处理。
|
- 手机号码基础校验放宽为`^1\d{10}$`,不依赖号段更新。客户端/HTTP混合批次逐号码把非法号码、平台黑名单和企业应用黑名单记为`submit_failed/rejected`且金额0,合法号码照常冻结、入队;CMPP混合多目的提交对被拦截号码生成平台`REJECTD`失败回执,合法号码继续处理。
|
||||||
- 短信审核页只返回待人工审核及人工处理记录,自动放行/拒绝不再混入;号码数量恢复设计基线的查看入口,真实接口仅返回手机号、归属地、运营商和短信状态并支持服务端搜索/分页。
|
- 短信审核页只返回待人工审核及人工处理记录,自动放行/拒绝不再混入;号码数量恢复设计基线的查看入口,真实接口仅返回手机号、归属地、运营商和短信状态并支持服务端搜索/分页。
|
||||||
- 新待审核短信同步保存`reviewTaskId`,审核决定同时按短信直连和批次`riskTaskId`查找,修复审核任务已通过而短信仍`pending_review`。遵照要求不改写现存历史异常数据、不补发历史短信。
|
- 新待审核短信同步保存`reviewTaskId`,审核决定同时按短信直连和批次`riskTaskId`查找,修复审核任务已通过而短信仍`pending_review`。遵照要求不改写现存历史异常数据、不补发历史短信。
|
||||||
|
- 用户登录标识改为“仅未删除记录唯一”后,部署管理员初始化与真实环境冒烟脚本同步从`username`唯一`upsert`改为先查询未删除用户、再按主键更新或创建,避免迁移后Prisma拒绝旧的唯一查询。
|
||||||
- 发布前门禁阶段结果:Prisma format/generate/validate通过;风险审核+发送链定向2 suites / 108 tests通过,随后补充应用覆盖、号码分页与逐号码拦截用例;API全量26 suites / 338 tests、API TypeScript build、前端TypeScript/Vite生产构建、Gateway `go test ./...`/`go vet ./...`、依赖安全门禁通过。API保留既有Redis不可用容错告警与`--forceExit`提示,前端保留约1.95MB单chunk/584.70KB gzip提示。
|
- 发布前门禁阶段结果:Prisma format/generate/validate通过;风险审核+发送链定向2 suites / 108 tests通过,随后补充应用覆盖、号码分页与逐号码拦截用例;API全量26 suites / 338 tests、API TypeScript build、前端TypeScript/Vite生产构建、Gateway `go test ./...`/`go vet ./...`、依赖安全门禁通过。API保留既有Redis不可用容错告警与`--forceExit`提示,前端保留约1.95MB单chunk/584.70KB gzip提示。
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ function hashPassword(value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const existingUser = await prisma.user.findUnique({ where: { username } });
|
const existingUser = await prisma.user.findFirst({
|
||||||
|
where: { username, deletedAt: null },
|
||||||
|
});
|
||||||
const createPassword = configuredPassword || randomBytes(18).toString('base64url');
|
const createPassword = configuredPassword || randomBytes(18).toString('base64url');
|
||||||
const updatePassword = configuredPassword;
|
const updatePassword = configuredPassword;
|
||||||
const role = await prisma.role.upsert({
|
const role = await prisma.role.upsert({
|
||||||
@@ -27,26 +29,30 @@ async function main() {
|
|||||||
update: { name: '平台管理员', scope: 'platform' },
|
update: { name: '平台管理员', scope: 'platform' },
|
||||||
create: { code: 'platform_admin', name: '平台管理员', scope: 'platform' },
|
create: { code: 'platform_admin', name: '平台管理员', scope: 'platform' },
|
||||||
});
|
});
|
||||||
const user = await prisma.user.upsert({
|
const userData = {
|
||||||
where: { username },
|
email,
|
||||||
update: {
|
displayName: '生产平台管理员',
|
||||||
email,
|
...(updatePassword ? { passwordHash: hashPassword(updatePassword) } : {}),
|
||||||
displayName: '生产平台管理员',
|
status: 'active',
|
||||||
...(updatePassword ? { passwordHash: hashPassword(updatePassword) } : {}),
|
failedLoginCount: 0,
|
||||||
status: 'active',
|
lockedUntil: null,
|
||||||
failedLoginCount: 0,
|
deletedAt: null,
|
||||||
lockedUntil: null,
|
tenantId: null,
|
||||||
deletedAt: null,
|
};
|
||||||
tenantId: null,
|
const user = existingUser
|
||||||
},
|
? await prisma.user.update({
|
||||||
create: {
|
where: { id: existingUser.id },
|
||||||
username,
|
data: userData,
|
||||||
email,
|
})
|
||||||
displayName: '生产平台管理员',
|
: await prisma.user.create({
|
||||||
passwordHash: hashPassword(createPassword),
|
data: {
|
||||||
status: 'active',
|
username,
|
||||||
},
|
email,
|
||||||
});
|
displayName: '生产平台管理员',
|
||||||
|
passwordHash: hashPassword(createPassword),
|
||||||
|
status: 'active',
|
||||||
|
},
|
||||||
|
});
|
||||||
await prisma.userRole.upsert({
|
await prisma.userRole.upsert({
|
||||||
where: { userId_roleId: { userId: user.id, roleId: role.id } },
|
where: { userId_roleId: { userId: user.id, roleId: role.id } },
|
||||||
update: {},
|
update: {},
|
||||||
|
|||||||
@@ -25,29 +25,35 @@ async function ensureSmokeData() {
|
|||||||
create: { code: tenantCode, name: 'Smoke Test Enterprise', status: 'active' },
|
create: { code: tenantCode, name: 'Smoke Test Enterprise', status: 'active' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const user = await prisma.user.upsert({
|
const existingUser = await prisma.user.findFirst({
|
||||||
where: { username },
|
where: { username, deletedAt: null },
|
||||||
update: {
|
|
||||||
tenantId: tenant.id,
|
|
||||||
email,
|
|
||||||
phone,
|
|
||||||
displayName: 'Smoke Client Admin',
|
|
||||||
passwordHash: hashPassword(password),
|
|
||||||
status: 'active',
|
|
||||||
failedLoginCount: 0,
|
|
||||||
lockedUntil: null,
|
|
||||||
deletedAt: null,
|
|
||||||
},
|
|
||||||
create: {
|
|
||||||
tenantId: tenant.id,
|
|
||||||
username,
|
|
||||||
email,
|
|
||||||
phone,
|
|
||||||
displayName: 'Smoke Client Admin',
|
|
||||||
passwordHash: hashPassword(password),
|
|
||||||
status: 'active',
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
const user = existingUser
|
||||||
|
? await prisma.user.update({
|
||||||
|
where: { id: existingUser.id },
|
||||||
|
data: {
|
||||||
|
tenantId: tenant.id,
|
||||||
|
email,
|
||||||
|
phone,
|
||||||
|
displayName: 'Smoke Client Admin',
|
||||||
|
passwordHash: hashPassword(password),
|
||||||
|
status: 'active',
|
||||||
|
failedLoginCount: 0,
|
||||||
|
lockedUntil: null,
|
||||||
|
deletedAt: null,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
: await prisma.user.create({
|
||||||
|
data: {
|
||||||
|
tenantId: tenant.id,
|
||||||
|
username,
|
||||||
|
email,
|
||||||
|
phone,
|
||||||
|
displayName: 'Smoke Client Admin',
|
||||||
|
passwordHash: hashPassword(password),
|
||||||
|
status: 'active',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const enterpriseAdminRole = await prisma.role.upsert({
|
const enterpriseAdminRole = await prisma.role.upsert({
|
||||||
where: { code: 'enterprise_admin' },
|
where: { code: 'enterprise_admin' },
|
||||||
|
|||||||
Reference in New Issue
Block a user