feat: WC2026 赛事 seed、生产上线初始化脚本与目录归档
重构 seed 为 WC2026 72 场小组赛与 48 强优胜盘;新增 production 模式仅保留 admin 与赛事示例;提供 prod-init-db 全量重置脚本;管理端 i18n 分包与赛事归档能力。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -482,4 +482,37 @@ export class UsersService {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async softDeletePlayer(playerId: bigint) {
|
||||
const user = await this.prisma.user.findFirst({
|
||||
where: { id: playerId, deletedAt: null },
|
||||
});
|
||||
if (!user) throw appNotFound('USER_NOT_FOUND');
|
||||
if (user.userType !== 'PLAYER') {
|
||||
throw appBadRequest('NOT_PLAYER');
|
||||
}
|
||||
// Block deletion when the player has any unresolved bets
|
||||
const betCount = await this.prisma.bet.count({
|
||||
where: {
|
||||
userId: playerId,
|
||||
status: 'PENDING',
|
||||
},
|
||||
});
|
||||
if (betCount > 0) {
|
||||
throw appBadRequest('PLAYER_HAS_PENDING_BETS');
|
||||
}
|
||||
// Block deletion when wallet still has balance
|
||||
const wallet = await this.prisma.wallet.findUnique({ where: { userId: playerId } });
|
||||
if (wallet) {
|
||||
const available = new Decimal(wallet.availableBalance);
|
||||
const frozen = new Decimal(wallet.frozenBalance);
|
||||
if (available.gt(0) || frozen.gt(0)) {
|
||||
throw appBadRequest('PLAYER_HAS_BALANCE');
|
||||
}
|
||||
}
|
||||
return this.prisma.user.update({
|
||||
where: { id: playerId },
|
||||
data: { deletedAt: new Date(), status: 'SUSPENDED' },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user