io
This commit is contained in:
28
scripts/check-connections.ts
Normal file
28
scripts/check-connections.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { config } from "dotenv";
|
||||
config();
|
||||
import { Client } from "pg";
|
||||
|
||||
async function main() {
|
||||
const c = new Client({ connectionString: process.env.DATABASE_URL });
|
||||
await c.connect();
|
||||
|
||||
const r = await c.query(`
|
||||
SELECT count(*) as active,
|
||||
(SELECT setting::int FROM pg_settings WHERE name='max_connections') as max_conn
|
||||
FROM pg_stat_activity
|
||||
`);
|
||||
console.log("active connections:", r.rows[0]?.active, "/ max:", r.rows[0]?.max_conn);
|
||||
|
||||
const killed = await c.query(`
|
||||
SELECT pg_terminate_backend(pid)
|
||||
FROM pg_stat_activity
|
||||
WHERE state = 'idle'
|
||||
AND pid <> pg_backend_pid()
|
||||
AND datname = current_database()
|
||||
`);
|
||||
console.log("killed idle connections:", killed.rowCount);
|
||||
|
||||
await c.end();
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
226
scripts/reset-and-seed.ts
Normal file
226
scripts/reset-and-seed.ts
Normal file
@@ -0,0 +1,226 @@
|
||||
import { Client } from "pg";
|
||||
import bcrypt from "bcryptjs";
|
||||
import { config } from "dotenv";
|
||||
|
||||
config(); // load .env
|
||||
|
||||
const DATABASE_URL = process.env.DATABASE_URL!;
|
||||
|
||||
const DEFAULT_RULES = {
|
||||
GK: { GOAL: 10, ASSIST: 3, YELLOW_CARD: -1, RED_CARD: -3, SECOND_YELLOW: -3, CLEAN_SHEET: 6, PENALTY_SAVED: 5, PENALTY_MISSED: -2, OWN_GOAL: -2, MOTM: 3, EXTRA_TIME_BONUS: 1, INJURY_NO_SUB: -1 },
|
||||
DEF: { GOAL: 8, ASSIST: 3, YELLOW_CARD: -1, RED_CARD: -3, SECOND_YELLOW: -3, CLEAN_SHEET: 4, PENALTY_SAVED: 0, PENALTY_MISSED: -2, OWN_GOAL: -2, MOTM: 3, EXTRA_TIME_BONUS: 1, INJURY_NO_SUB: -1 },
|
||||
MID: { GOAL: 5, ASSIST: 3, YELLOW_CARD: -2, RED_CARD: -3, SECOND_YELLOW: -3, CLEAN_SHEET: 1, PENALTY_SAVED: 0, PENALTY_MISSED: -2, OWN_GOAL: -2, MOTM: 3, EXTRA_TIME_BONUS: 1, INJURY_NO_SUB: -1 },
|
||||
FWD: { GOAL: 4, ASSIST: 3, YELLOW_CARD: -1, RED_CARD: -3, SECOND_YELLOW: -3, CLEAN_SHEET: 0, PENALTY_SAVED: 0, PENALTY_MISSED: -2, OWN_GOAL: -2, MOTM: 3, EXTRA_TIME_BONUS: 1, INJURY_NO_SUB: -1 },
|
||||
};
|
||||
|
||||
const COUNTRY_FORMATIONS: Record<string, string> = {
|
||||
BRA:"4-3-3",FRA:"4-3-3",ARG:"4-3-3",ENG:"4-3-3",ESP:"4-3-3",GER:"4-2-3-1",POR:"4-3-3",NED:"4-3-3",
|
||||
BEL:"4-3-3",CRO:"4-3-3",MAR:"4-3-3",IRN:"4-5-1",URU:"4-3-3",SEN:"4-3-3",KOR:"4-3-3",JPN:"4-3-3",
|
||||
MEX:"4-3-3",USA:"4-3-3",CAN:"4-3-3",AUS:"4-3-3",POL:"4-3-3",DEN:"4-3-3",SUI:"4-2-3-1",SRB:"3-4-3",
|
||||
WAL:"5-3-2",TUN:"4-3-3",CMR:"4-3-3",GHA:"4-2-3-1",ECU:"4-3-3",QAT:"5-3-2",KSA:"4-3-3",CRC:"5-4-1",
|
||||
};
|
||||
|
||||
const COUNTRIES = [
|
||||
{name:"برزیل",code:"BRA",flag:"🇧🇷",group:"G"},{name:"سربیا",code:"SRB",flag:"🇷🇸",group:"G"},
|
||||
{name:"سوئیس",code:"SUI",flag:"🇨🇭",group:"G"},{name:"کامرون",code:"CMR",flag:"🇨🇲",group:"G"},
|
||||
{name:"فرانسه",code:"FRA",flag:"🇫🇷",group:"D"},{name:"استرالیا",code:"AUS",flag:"🇦🇺",group:"D"},
|
||||
{name:"دانمارک",code:"DEN",flag:"🇩🇰",group:"D"},{name:"تونس",code:"TUN",flag:"🇹🇳",group:"D"},
|
||||
{name:"آرژانتین",code:"ARG",flag:"🇦🇷",group:"C"},{name:"عربستان",code:"KSA",flag:"🇸🇦",group:"C"},
|
||||
{name:"مکزیک",code:"MEX",flag:"🇲🇽",group:"C"},{name:"لهستان",code:"POL",flag:"🇵🇱",group:"C"},
|
||||
{name:"ایران",code:"IRN",flag:"🇮🇷",group:"B"},{name:"انگلیس",code:"ENG",flag:"🏴",group:"B"},
|
||||
{name:"آمریکا",code:"USA",flag:"🇺🇸",group:"B"},{name:"ولز",code:"WAL",flag:"🏴",group:"B"},
|
||||
{name:"آلمان",code:"GER",flag:"🇩🇪",group:"E"},{name:"ژاپن",code:"JPN",flag:"🇯🇵",group:"E"},
|
||||
{name:"اسپانیا",code:"ESP",flag:"🇪🇸",group:"E"},{name:"کاستاریکا",code:"CRC",flag:"🇨🇷",group:"E"},
|
||||
{name:"بلژیک",code:"BEL",flag:"🇧🇪",group:"F"},{name:"کانادا",code:"CAN",flag:"🇨🇦",group:"F"},
|
||||
{name:"مراکش",code:"MAR",flag:"🇲🇦",group:"F"},{name:"کرواسی",code:"CRO",flag:"🇭🇷",group:"F"},
|
||||
{name:"پرتغال",code:"POR",flag:"🇵🇹",group:"H"},{name:"غنا",code:"GHA",flag:"🇬🇭",group:"H"},
|
||||
{name:"اروگوئه",code:"URU",flag:"🇺🇾",group:"H"},{name:"کره جنوبی",code:"KOR",flag:"🇰🇷",group:"H"},
|
||||
{name:"هلند",code:"NED",flag:"🇳🇱",group:"A"},{name:"سنگال",code:"SEN",flag:"🇸🇳",group:"A"},
|
||||
{name:"اکوادور",code:"ECU",flag:"🇪🇨",group:"A"},{name:"قطر",code:"QAT",flag:"🇶🇦",group:"A"},
|
||||
];
|
||||
|
||||
const PLAYERS_DATA = [
|
||||
{name:"آلیسون بکر",pos:"GK",code:"BRA",price:6.0,pts:42},{name:"تیاگو سیلوا",pos:"DEF",code:"BRA",price:6.5,pts:38},
|
||||
{name:"مارکینیوس",pos:"DEF",code:"BRA",price:6.0,pts:35},{name:"کاسمیرو",pos:"MID",code:"BRA",price:8.0,pts:52},
|
||||
{name:"نیمار",pos:"FWD",code:"BRA",price:11.5,pts:68},{name:"وینیسیوس جونیور",pos:"FWD",code:"BRA",price:10.5,pts:72},
|
||||
{name:"ریچارلیسون",pos:"FWD",code:"BRA",price:8.5,pts:55},{name:"هوگو لوریس",pos:"GK",code:"FRA",price:6.0,pts:40},
|
||||
{name:"رافائل واران",pos:"DEF",code:"FRA",price:6.5,pts:36},{name:"کیلیان امباپه",pos:"FWD",code:"FRA",price:12.5,pts:88},
|
||||
{name:"آنتوان گریزمان",pos:"MID",code:"FRA",price:9.5,pts:62},{name:"اولیویه ژیرو",pos:"FWD",code:"FRA",price:7.5,pts:48},
|
||||
{name:"اوسمان دمبله",pos:"FWD",code:"FRA",price:8.0,pts:44},{name:"امیلیانو مارتینز",pos:"GK",code:"ARG",price:6.5,pts:55},
|
||||
{name:"لیونل مسی",pos:"FWD",code:"ARG",price:12.5,pts:92},{name:"خولیان آلوارز",pos:"FWD",code:"ARG",price:8.5,pts:60},
|
||||
{name:"رودریگو دپاول",pos:"MID",code:"ARG",price:7.5,pts:45},{name:"نیکولاس اوتامندی",pos:"DEF",code:"ARG",price:5.5,pts:32},
|
||||
{name:"جوردن پیکفورد",pos:"GK",code:"ENG",price:5.5,pts:38},{name:"جود بلینگهام",pos:"MID",code:"ENG",price:10.5,pts:75},
|
||||
{name:"هری کین",pos:"FWD",code:"ENG",price:11.0,pts:70},{name:"بوکایو ساکا",pos:"MID",code:"ENG",price:8.5,pts:58},
|
||||
{name:"فیل فودن",pos:"MID",code:"ENG",price:9.0,pts:62},{name:"جان استونز",pos:"DEF",code:"ENG",price:6.0,pts:34},
|
||||
{name:"اونای سیمون",pos:"GK",code:"ESP",price:5.5,pts:36},{name:"پدری",pos:"MID",code:"ESP",price:9.0,pts:60},
|
||||
{name:"گاوی",pos:"MID",code:"ESP",price:8.5,pts:55},{name:"آلوارو موراتا",pos:"FWD",code:"ESP",price:7.5,pts:46},
|
||||
{name:"دنی اولمو",pos:"MID",code:"ESP",price:7.0,pts:42},{name:"مانوئل نویر",pos:"GK",code:"GER",price:6.0,pts:38},
|
||||
{name:"توماس مولر",pos:"MID",code:"GER",price:8.0,pts:50},{name:"کای هاورتز",pos:"MID",code:"GER",price:8.5,pts:52},
|
||||
{name:"یامله موسیالا",pos:"MID",code:"GER",price:9.0,pts:65},{name:"آنتونیو رودیگر",pos:"DEF",code:"GER",price:5.5,pts:30},
|
||||
{name:"دیوگو کوستا",pos:"GK",code:"POR",price:5.5,pts:35},{name:"کریستیانو رونالدو",pos:"FWD",code:"POR",price:11.0,pts:65},
|
||||
{name:"برونو فرناندز",pos:"MID",code:"POR",price:10.0,pts:70},{name:"رافائل لئائو",pos:"FWD",code:"POR",price:8.5,pts:55},
|
||||
{name:"روبن دیاز",pos:"DEF",code:"POR",price:6.0,pts:36},{name:"علیرضا بیرانوند",pos:"GK",code:"IRN",price:5.0,pts:28},
|
||||
{name:"مهدی طارمی",pos:"FWD",code:"IRN",price:8.0,pts:50},{name:"سردار آزمون",pos:"FWD",code:"IRN",price:7.5,pts:44},
|
||||
{name:"علی کریمی",pos:"MID",code:"IRN",price:6.0,pts:32},{name:"رامین رضاییان",pos:"DEF",code:"IRN",price:5.0,pts:22},
|
||||
{name:"یاسین بونو",pos:"GK",code:"MAR",price:6.5,pts:58},{name:"اشرف حکیمی",pos:"DEF",code:"MAR",price:8.0,pts:62},
|
||||
{name:"حکیم زیاش",pos:"MID",code:"MAR",price:7.5,pts:48},{name:"یوسف النصیری",pos:"FWD",code:"MAR",price:7.0,pts:45},
|
||||
{name:"دومینیک لیواکوویچ",pos:"GK",code:"CRO",price:6.0,pts:50},{name:"لوکا مودریچ",pos:"MID",code:"CRO",price:9.5,pts:68},
|
||||
{name:"ایوان پریشیچ",pos:"MID",code:"CRO",price:7.5,pts:48},{name:"آندره کراماریچ",pos:"FWD",code:"CRO",price:7.0,pts:44},
|
||||
{name:"آندریس نوپرت",pos:"GK",code:"NED",price:5.5,pts:36},{name:"ویرخیل فان دایک",pos:"DEF",code:"NED",price:7.0,pts:48},
|
||||
{name:"دنزل دامفریس",pos:"DEF",code:"NED",price:7.5,pts:52},{name:"کودی گاکپو",pos:"FWD",code:"NED",price:8.0,pts:58},
|
||||
{name:"تیبو کورتوا",pos:"GK",code:"BEL",price:6.5,pts:44},{name:"کوین دبروینه",pos:"MID",code:"BEL",price:11.0,pts:72},
|
||||
{name:"رومله لوکاکو",pos:"FWD",code:"BEL",price:9.5,pts:55},
|
||||
];
|
||||
|
||||
function cuid() {
|
||||
return 'c' + Math.random().toString(36).slice(2, 11) + Date.now().toString(36);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const client = new Client({ connectionString: DATABASE_URL });
|
||||
await client.connect();
|
||||
console.log("✅ Connected to database");
|
||||
|
||||
// ─── پاک کردن همه دادهها ────────────────────────────
|
||||
console.log("🗑️ Clearing all data...");
|
||||
await client.query(`
|
||||
TRUNCATE TABLE "Payment", "TeamPlayer", "Team", "Session",
|
||||
"MatchLineup", "MatchEvent", "PlayerMatchStat", "ScoringRule",
|
||||
"Match", "Player", "Country", "Group", "Round", "Gameweek",
|
||||
"Package", "User"
|
||||
RESTART IDENTITY CASCADE
|
||||
`);
|
||||
console.log("✅ Cleared");
|
||||
|
||||
// ─── ادمین ────────────────────────────────────────────
|
||||
console.log("👤 Creating users...");
|
||||
const adminPwd = await bcrypt.hash("admin123", 10);
|
||||
const userPwd = await bcrypt.hash("user123", 10);
|
||||
await client.query(`
|
||||
INSERT INTO "User" (id, email, name, password, role, "createdAt")
|
||||
VALUES
|
||||
($1, 'admin@worldcup.com', 'ادمین', $2, 'ADMIN', NOW()),
|
||||
($3, 'ali@test.com', 'علی احمدی', $4, 'USER', NOW()),
|
||||
($5, 'sara@test.com', 'سارا رضایی', $4, 'USER', NOW()),
|
||||
($6, 'reza@test.com', 'رضا محمدی', $4, 'USER', NOW())
|
||||
`, [cuid(), adminPwd, cuid(), userPwd, cuid(), cuid()]);
|
||||
|
||||
// ─── گروهها ──────────────────────────────────────────
|
||||
console.log("🏟️ Creating groups...");
|
||||
const groupMap: Record<string, string> = {};
|
||||
for (const name of ["A","B","C","D","E","F","G","H"]) {
|
||||
const id = cuid();
|
||||
await client.query(`INSERT INTO "Group" (id, name) VALUES ($1, $2)`, [id, name]);
|
||||
groupMap[name] = id;
|
||||
}
|
||||
|
||||
// ─── تیمهای ملی ─────────────────────────────────────
|
||||
console.log("🌍 Creating countries...");
|
||||
const countryMap: Record<string, string> = {};
|
||||
for (const c of COUNTRIES) {
|
||||
const id = cuid();
|
||||
const formation = COUNTRY_FORMATIONS[c.code] ?? "4-3-3";
|
||||
await client.query(
|
||||
`INSERT INTO "Country" (id, name, code, "flagUrl", "groupId", "defaultFormation") VALUES ($1,$2,$3,$4,$5,$6)`,
|
||||
[id, c.name, c.code, c.flag, groupMap[c.group], formation]
|
||||
);
|
||||
countryMap[c.code] = id;
|
||||
}
|
||||
|
||||
// ─── بازیکنان ─────────────────────────────────────────
|
||||
console.log("⚽ Creating players...");
|
||||
for (const p of PLAYERS_DATA) {
|
||||
const countryId = countryMap[p.code];
|
||||
if (!countryId) continue;
|
||||
await client.query(
|
||||
`INSERT INTO "Player" (id, name, position, "countryId", price, "totalPoints", "isActive", "createdAt", "updatedAt")
|
||||
VALUES ($1,$2,$3,$4,$5,$6,true,NOW(),NOW())`,
|
||||
[cuid(), p.name, p.pos, countryId, p.price, p.pts]
|
||||
);
|
||||
}
|
||||
|
||||
// ─── قوانین امتیازدهی ────────────────────────────────
|
||||
console.log("📊 Creating scoring rules...");
|
||||
for (const [pos, rules] of Object.entries(DEFAULT_RULES)) {
|
||||
for (const [eventType, points] of Object.entries(rules)) {
|
||||
await client.query(
|
||||
`INSERT INTO "ScoringRule" (id, position, "eventType", points, "updatedAt")
|
||||
VALUES ($1,$2,$3,$4,NOW())`,
|
||||
[cuid(), pos, eventType, points]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ─── دورها ────────────────────────────────────────────
|
||||
console.log("🔄 Creating rounds...");
|
||||
const rounds: Record<number, string> = {};
|
||||
const roundsData = [
|
||||
{num:1, name:"دور اول - مرحله گروهی", active:true, deadline:"2026-06-15T10:00:00Z"},
|
||||
{num:2, name:"دور دوم - مرحله گروهی", active:false, deadline:"2026-06-22T10:00:00Z"},
|
||||
{num:3, name:"دور سوم - مرحله گروهی", active:false, deadline:"2026-06-29T10:00:00Z"},
|
||||
{num:4, name:"دور چهارم - یکهشتم نهایی",active:false, deadline:"2026-07-05T10:00:00Z"},
|
||||
];
|
||||
for (const r of roundsData) {
|
||||
const id = cuid();
|
||||
await client.query(
|
||||
`INSERT INTO "Round" (id, number, name, "isActive", deadline, "createdAt") VALUES ($1,$2,$3,$4,$5,NOW())`,
|
||||
[id, r.num, r.name, r.active, r.deadline]
|
||||
);
|
||||
rounds[r.num] = id;
|
||||
}
|
||||
|
||||
// ─── بازیها ──────────────────────────────────────────
|
||||
console.log("🏆 Creating matches...");
|
||||
const matchesData = [
|
||||
{home:"QAT",away:"ECU",hS:0, aS:2, st:"FINISHED", date:"2026-06-20T16:00:00Z",r:1},
|
||||
{home:"ENG",away:"IRN",hS:6, aS:2, st:"FINISHED", date:"2026-06-21T13:00:00Z",r:1},
|
||||
{home:"ARG",away:"KSA",hS:1, aS:2, st:"FINISHED", date:"2026-06-22T10:00:00Z",r:1},
|
||||
{home:"FRA",away:"AUS",hS:4, aS:1, st:"FINISHED", date:"2026-06-22T19:00:00Z",r:1},
|
||||
{home:"GER",away:"JPN",hS:1, aS:2, st:"FINISHED", date:"2026-06-23T13:00:00Z",r:1},
|
||||
{home:"ESP",away:"CRC",hS:7, aS:0, st:"FINISHED", date:"2026-06-23T19:00:00Z",r:1},
|
||||
{home:"BEL",away:"CAN",hS:1, aS:0, st:"FINISHED", date:"2026-06-23T16:00:00Z",r:1},
|
||||
{home:"BRA",away:"SRB",hS:2, aS:0, st:"FINISHED", date:"2026-06-24T19:00:00Z",r:1},
|
||||
{home:"POR",away:"GHA",hS:3, aS:2, st:"FINISHED", date:"2026-06-24T16:00:00Z",r:1},
|
||||
{home:"MAR",away:"CRO",hS:0, aS:0, st:"FINISHED", date:"2026-06-23T10:00:00Z",r:1},
|
||||
{home:"NED",away:"SEN",hS:2, aS:0, st:"FINISHED", date:"2026-06-21T16:00:00Z",r:1},
|
||||
{home:"IRN",away:"WAL",hS:2, aS:0, st:"FINISHED", date:"2026-06-25T13:00:00Z",r:2},
|
||||
{home:"FRA",away:"DEN",hS:2, aS:1, st:"FINISHED", date:"2026-06-26T19:00:00Z",r:2},
|
||||
{home:"ARG",away:"MEX",hS:2, aS:0, st:"FINISHED", date:"2026-06-26T22:00:00Z",r:2},
|
||||
{home:"BRA",away:"SUI",hS:1, aS:0, st:"FINISHED", date:"2026-06-28T19:00:00Z",r:2},
|
||||
{home:"ENG",away:"USA",hS:0, aS:0, st:"FINISHED", date:"2026-06-25T19:00:00Z",r:2},
|
||||
{home:"BRA",away:"CMR",hS:1, aS:0, st:"SCHEDULED", date:"2026-07-02T19:00:00Z",r:3},
|
||||
{home:"FRA",away:"TUN",hS:null,aS:null,st:"SCHEDULED",date:"2026-07-01T16:00:00Z",r:3},
|
||||
{home:"NED",away:"ARG",hS:2, aS:2, st:"FINISHED", date:"2026-12-09T19:00:00Z",r:4,stage:"ROUND_OF_16"},
|
||||
{home:"FRA",away:"ENG",hS:2, aS:1, st:"FINISHED", date:"2026-12-10T19:00:00Z",r:4,stage:"ROUND_OF_16"},
|
||||
{home:"ARG",away:"FRA",hS:3, aS:3, st:"FINISHED", date:"2026-12-18T15:00:00Z",r:4,stage:"FINAL"},
|
||||
];
|
||||
for (const m of matchesData) {
|
||||
const homeId = countryMap[m.home], awayId = countryMap[m.away];
|
||||
if (!homeId || !awayId) continue;
|
||||
await client.query(
|
||||
`INSERT INTO "Match" (id,"homeTeamId","awayTeamId","homeScore","awayScore",status,stage,"matchDate","roundId","createdAt")
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,NOW())`,
|
||||
[cuid(), homeId, awayId, m.hS ?? null, m.aS ?? null, m.st, (m as any).stage ?? "GROUP", m.date, rounds[m.r]]
|
||||
);
|
||||
}
|
||||
|
||||
// ─── پکیجها ──────────────────────────────────────────
|
||||
console.log("📦 Creating packages...");
|
||||
for (const pkg of [
|
||||
{name:"پکیج نقرهای", budgetBonus:10, price:50000, desc:"۱۰ میلیون به بودجه اضافه کن"},
|
||||
{name:"پکیج طلایی", budgetBonus:20, price:90000, desc:"۲۰ میلیون به بودجه اضافه کن"},
|
||||
{name:"پکیج الماس", budgetBonus:30, price:120000,desc:"۳۰ میلیون به بودجه اضافه کن"},
|
||||
]) {
|
||||
await client.query(
|
||||
`INSERT INTO "Package" (id, name, "budgetBonus", price, description, "isActive") VALUES ($1,$2,$3,$4,$5,true)`,
|
||||
[cuid(), pkg.name, pkg.budgetBonus, pkg.price, pkg.desc]
|
||||
);
|
||||
}
|
||||
|
||||
await client.end();
|
||||
console.log("\n✅ Seed done!");
|
||||
console.log(" admin@worldcup.com / admin123");
|
||||
console.log(" ali@test.com / user123");
|
||||
}
|
||||
|
||||
main().catch(e => { console.error("❌", e); process.exit(1); });
|
||||
110
scripts/seed-quiz-sample.ts
Normal file
110
scripts/seed-quiz-sample.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { CardTier, PrismaClient } from "@prisma/client";
|
||||
|
||||
const db = new PrismaClient();
|
||||
|
||||
function buildCardTierMap(totalPlayers: number) {
|
||||
const goldCutoff = Math.max(1, Math.ceil(totalPlayers * 0.2));
|
||||
const silverCutoff = Math.max(goldCutoff, Math.ceil(totalPlayers * 0.5));
|
||||
|
||||
return (index: number): CardTier => {
|
||||
if (index < goldCutoff) return "GOLD";
|
||||
if (index < silverCutoff) return "SILVER";
|
||||
return "BRONZE";
|
||||
};
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log("Seeding sample quiz data...");
|
||||
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
const windowStart = new Date();
|
||||
windowStart.setHours(18, 0, 0, 0);
|
||||
|
||||
const windowEnd = new Date();
|
||||
windowEnd.setHours(21, 0, 0, 0);
|
||||
|
||||
const existingQuiz = await db.dailyQuiz.findUnique({ where: { date: today } });
|
||||
if (!existingQuiz) {
|
||||
const quiz = await db.dailyQuiz.create({
|
||||
data: {
|
||||
date: today,
|
||||
windowStart,
|
||||
windowEnd,
|
||||
winnersCount: 3,
|
||||
goldMinCorrect: 4,
|
||||
silverMinCorrect: 3,
|
||||
bronzeMinCorrect: 2,
|
||||
questions: {
|
||||
create: [
|
||||
{
|
||||
questionText: "کدام بازیکن بیشترین گل را در جام جهانی 2022 زده است؟",
|
||||
options: ["کیلیان امباپه", "لیونل مسی", "کریستیانو رونالدو", "نیمار"],
|
||||
correctAnswer: 0,
|
||||
order: 0,
|
||||
},
|
||||
{
|
||||
questionText: "قهرمان جام جهانی 2022 کدام تیم بود؟",
|
||||
options: ["فرانسه", "آرژانتین", "برزیل", "آلمان"],
|
||||
correctAnswer: 1,
|
||||
order: 1,
|
||||
},
|
||||
{
|
||||
questionText: "جام جهانی 2026 در کدام کشورها برگزار می شود؟",
|
||||
options: ["قطر", "آمریکا، کانادا، مکزیک", "روسیه", "برزیل"],
|
||||
correctAnswer: 1,
|
||||
order: 2,
|
||||
},
|
||||
{
|
||||
questionText: "اولین جام جهانی در چه سالی برگزار شد؟",
|
||||
options: ["1930", "1934", "1950", "1954"],
|
||||
correctAnswer: 0,
|
||||
order: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
include: { questions: true },
|
||||
});
|
||||
|
||||
console.log(`Created quiz with ${quiz.questions.length} questions`);
|
||||
} else {
|
||||
console.log("Quiz for today already exists, skipping quiz creation");
|
||||
}
|
||||
|
||||
const players = await db.player.findMany({
|
||||
orderBy: [{ totalPoints: "desc" }, { name: "asc" }],
|
||||
});
|
||||
|
||||
if (players.length > 0) {
|
||||
const resolveTier = buildCardTierMap(players.length);
|
||||
|
||||
await db.$transaction(
|
||||
players.map((player, index) =>
|
||||
db.player.update({
|
||||
where: { id: player.id },
|
||||
data: {
|
||||
cardTier: resolveTier(index),
|
||||
isGoldenCardEligible: resolveTier(index) === "GOLD",
|
||||
},
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
console.log(`Assigned card tiers to ${players.length} players based on total points`);
|
||||
} else {
|
||||
console.log("No players found for card tier assignment");
|
||||
}
|
||||
|
||||
console.log("Sample quiz data seeded successfully");
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await db.$disconnect();
|
||||
});
|
||||
Reference in New Issue
Block a user