Files
thebet365/apps/api/prisma/seed.ts
Mars 14e49374ac 初始化足球投注平台 MVP Monorepo
包含 NestJS 后端、三端前端、Prisma 数据模型、结算引擎测试与 PRD 文档。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 14:35:48 +08:00

183 lines
5.8 KiB
TypeScript

import { PrismaClient } from '@prisma/client';
import * as bcrypt from 'bcryptjs';
const prisma = new PrismaClient();
async function main() {
console.log('Seeding database...');
const superAdminRole = await prisma.role.upsert({
where: { code: 'SUPER_ADMIN' },
create: { code: 'SUPER_ADMIN', name: 'Super Admin', description: 'Full access' },
update: {},
});
const permCodes = [
'users.create', 'users.view', 'agents.create', 'agents.view',
'wallet.deposit', 'wallet.withdraw', 'matches.manage', 'settlement.confirm',
'cashback.confirm', 'content.manage', 'reports.view',
];
for (const code of permCodes) {
const perm = await prisma.permission.upsert({
where: { code },
create: { code, name: code, module: code.split('.')[0] },
update: {},
});
await prisma.rolePermission.upsert({
where: { roleId_permissionId: { roleId: superAdminRole.id, permissionId: perm.id } },
create: { roleId: superAdminRole.id, permissionId: perm.id },
update: {},
});
}
const hash = await bcrypt.hash('Admin@123', 10);
const agentHash = await bcrypt.hash('Agent@123', 10);
const playerHash = await bcrypt.hash('Player@123', 10);
await prisma.user.upsert({
where: { username: 'admin' },
create: {
username: 'admin',
userType: 'ADMIN',
auth: { create: { passwordHash: hash } },
adminRole: { create: { roleId: superAdminRole.id } },
},
update: {},
});
const agent1 = await prisma.user.upsert({
where: { username: 'agent1' },
create: {
username: 'agent1',
userType: 'AGENT',
agentLevel: 1,
auth: { create: { passwordHash: agentHash } },
agentProfile: { create: { level: 1, creditLimit: 100000 } },
},
update: {},
});
await prisma.agentClosure.upsert({
where: { ancestorId_descendantId: { ancestorId: agent1.id, descendantId: agent1.id } },
create: { ancestorId: agent1.id, descendantId: agent1.id, depth: 0 },
update: {},
});
await prisma.user.upsert({
where: { username: 'agent2' },
create: {
username: 'agent2',
userType: 'AGENT',
agentLevel: 2,
parentId: agent1.id,
auth: { create: { passwordHash: agentHash } },
agentProfile: { create: { level: 2, parentAgentId: agent1.id, creditLimit: 30000 } },
},
update: {},
});
await prisma.user.upsert({
where: { username: 'player1' },
create: {
username: 'player1',
userType: 'PLAYER',
parentId: agent1.id,
auth: { create: { passwordHash: playerHash } },
wallet: { create: { availableBalance: 1000 } },
preferences: { create: { locale: 'zh-CN' } },
},
update: {},
});
const messages = [
{ key: 'nav.home', zh: '首页', ms: 'Laman Utama', en: 'Home' },
{ key: 'nav.football', zh: '足球', ms: 'Bola Sepak', en: 'Football' },
{ key: 'bet.place_bet', zh: '确认下注', ms: 'Letak Pertaruhan', en: 'Place Bet' },
{ key: 'error.insufficient_balance', zh: '余额不足', ms: 'Baki tidak mencukupi', en: 'Insufficient balance' },
];
for (const m of messages) {
for (const [locale, value] of [['zh-CN', m.zh], ['ms-MY', m.ms], ['en-US', m.en]] as const) {
await prisma.i18nMessage.upsert({
where: { msgKey_locale: { msgKey: m.key, locale } },
create: { msgKey: m.key, locale, value },
update: { value },
});
}
}
const league = await prisma.league.upsert({
where: { code: 'EPL' },
create: { code: 'EPL' },
update: {},
});
await prisma.entityTranslation.upsert({
where: { entityType_entityId_locale_fieldName: { entityType: 'LEAGUE', entityId: league.id, locale: 'zh-CN', fieldName: 'name' } },
create: { entityType: 'LEAGUE', entityId: league.id, locale: 'zh-CN', fieldName: 'name', value: '英超' },
update: {},
});
for (const [code, name] of [['MUN', '曼联'], ['CHE', '切尔西']] as const) {
const team = await prisma.team.upsert({ where: { code }, create: { code }, update: {} });
await prisma.entityTranslation.upsert({
where: { entityType_entityId_locale_fieldName: { entityType: 'TEAM', entityId: team.id, locale: 'zh-CN', fieldName: 'name' } },
create: { entityType: 'TEAM', entityId: team.id, locale: 'zh-CN', fieldName: 'name', value: name },
update: { value: name },
});
}
const mun = await prisma.team.findUnique({ where: { code: 'MUN' } });
const che = await prisma.team.findUnique({ where: { code: 'CHE' } });
if (mun && che) {
const existing = await prisma.match.findFirst({ where: { homeTeamId: mun.id, awayTeamId: che.id } });
if (!existing) {
const match = await prisma.match.create({
data: {
leagueId: league.id,
homeTeamId: mun.id,
awayTeamId: che.id,
startTime: new Date(Date.now() + 86400000),
status: 'PUBLISHED',
isHot: true,
publishTime: new Date(),
},
});
await prisma.market.create({
data: {
matchId: match.id,
marketType: 'FT_1X2',
period: 'FT',
selections: {
create: [
{ selectionCode: 'HOME', selectionName: 'Home', odds: 2.5 },
{ selectionCode: 'DRAW', selectionName: 'Draw', odds: 3.2 },
{ selectionCode: 'AWAY', selectionName: 'Away', odds: 2.8 },
],
},
},
});
}
}
await prisma.content.create({
data: {
contentType: 'BANNER',
status: 'ACTIVE',
sortOrder: 1,
translations: {
create: [
{ locale: 'zh-CN', title: '欢迎投注', body: '足球赛事火热进行中' },
{ locale: 'en-US', title: 'Welcome', body: 'Football matches available' },
],
},
},
}).catch(() => {});
console.log('Seed completed! admin/Admin@123 agent1/Agent@123 player1/Player@123');
}
main().catch(console.error).finally(() => prisma.$disconnect());