Test
This commit is contained in:
86
scripts/addTeams.js
Normal file
86
scripts/addTeams.js
Normal file
@@ -0,0 +1,86 @@
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
// Get number of teams from command line argument, default to 10
|
||||
const numTeams = parseInt(process.argv[2]) || 10;
|
||||
|
||||
// Generate team names dynamically
|
||||
const teamNames = [
|
||||
'Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta', 'Theta', 'Iota', 'Kappa',
|
||||
'Lambda', 'Mu', 'Nu', 'Xi', 'Omicron', 'Pi', 'Rho', 'Sigma', 'Tau', 'Upsilon',
|
||||
'Phi', 'Chi', 'Psi', 'Omega'
|
||||
];
|
||||
|
||||
// Generate SVG logo based on team name
|
||||
function generateSVGLogo(teamName, size = 40) {
|
||||
// Use team name to generate consistent colors and patterns
|
||||
let hash = 0;
|
||||
for (let i = 0; i < teamName.length; i++) {
|
||||
hash = teamName.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
|
||||
const hue = hash % 360;
|
||||
const saturation = 60 + (hash % 30);
|
||||
const lightness = 40 + (hash % 30);
|
||||
const color = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
||||
|
||||
// Generate secondary color
|
||||
const secondaryHue = (hue + 180) % 360;
|
||||
const secondaryColor = `hsl(${secondaryHue}, ${saturation}%, ${lightness}%)`;
|
||||
|
||||
// Choose a logo pattern based on hash
|
||||
const pattern = hash % 4;
|
||||
const initials = teamName.split(' ').map(w => w[0]).join('').toUpperCase().slice(0, 2);
|
||||
|
||||
let svgContent = '';
|
||||
|
||||
switch (pattern) {
|
||||
case 0: // Circle with initials
|
||||
svgContent = `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><circle cx="${size/2}" cy="${size/2}" r="${size/2}" fill="${color}" stroke="${secondaryColor}" stroke-width="2"/><text x="50%" y="55%" text-anchor="middle" font-size="${size/3}" fill="white" font-family="Arial, sans-serif" font-weight="bold">${initials}</text></svg>`;
|
||||
break;
|
||||
|
||||
case 1: // Square with diagonal
|
||||
svgContent = `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><rect x="2" y="2" width="${size-4}" height="${size-4}" fill="${color}" stroke="${secondaryColor}" stroke-width="2"/><line x1="0" y1="0" x2="${size}" y2="${size}" stroke="${secondaryColor}" stroke-width="3"/><text x="50%" y="55%" text-anchor="middle" font-size="${size/3}" fill="white" font-family="Arial, sans-serif" font-weight="bold">${initials}</text></svg>`;
|
||||
break;
|
||||
|
||||
case 2: // Triangle
|
||||
svgContent = `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><polygon points="${size/2},5 ${size-5},${size-5} 5,${size-5}" fill="${color}" stroke="${secondaryColor}" stroke-width="2"/><text x="50%" y="60%" text-anchor="middle" font-size="${size/3}" fill="white" font-family="Arial, sans-serif" font-weight="bold">${initials}</text></svg>`;
|
||||
break;
|
||||
|
||||
case 3: // Diamond
|
||||
svgContent = `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><polygon points="${size/2},5 ${size-5},${size/2} ${size/2},${size-5} 5,${size/2}" fill="${color}" stroke="${secondaryColor}" stroke-width="2"/><text x="50%" y="55%" text-anchor="middle" font-size="${size/3}" fill="white" font-family="Arial, sans-serif" font-weight="bold">${initials}</text></svg>`;
|
||||
break;
|
||||
}
|
||||
|
||||
return svgContent;
|
||||
}
|
||||
|
||||
const teams = [];
|
||||
for (let i = 0; i < numTeams; i++) {
|
||||
const teamName = `Team ${teamNames[i]}`;
|
||||
teams.push({
|
||||
name: teamName,
|
||||
logo: generateSVGLogo(teamName)
|
||||
});
|
||||
}
|
||||
|
||||
async function addTeams() {
|
||||
for (const team of teams) {
|
||||
try {
|
||||
const res = await fetch('http://localhost:4000/api/teams', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name: team.name, logo: team.logo })
|
||||
});
|
||||
const data = await res.json();
|
||||
if (res.ok) {
|
||||
console.log(`Added: ${team.name} with SVG logo`);
|
||||
} else {
|
||||
console.log(`Failed to add ${team.name}: ${data.error}`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(`Error adding ${team.name}:`, err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addTeams();
|
||||
16
scripts/checkAdmin.js
Normal file
16
scripts/checkAdmin.js
Normal file
@@ -0,0 +1,16 @@
|
||||
const { PrismaClient } = require('../generated/prisma');
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function checkAdmin() {
|
||||
try {
|
||||
const admins = await prisma.adminUser.findMany();
|
||||
console.log('Admin users in database:', admins);
|
||||
} catch (err) {
|
||||
console.error('Error:', err);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
checkAdmin();
|
||||
13
scripts/clearMatches.js
Normal file
13
scripts/clearMatches.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const { PrismaClient } = require('../generated/prisma');
|
||||
|
||||
async function main() {
|
||||
const prisma = new PrismaClient();
|
||||
// Delete all results first (if results depend on matches)
|
||||
const deletedResults = await prisma.result.deleteMany();
|
||||
// Delete all matches
|
||||
const deletedMatches = await prisma.match.deleteMany();
|
||||
console.log(`Deleted ${deletedResults.count} results and ${deletedMatches.count} matches.`);
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
|
||||
main().catch(e => { console.error(e); process.exit(1); });
|
||||
14
scripts/clearPlayers.js
Normal file
14
scripts/clearPlayers.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const { PrismaClient } = require('../generated/prisma');
|
||||
|
||||
async function main() {
|
||||
const prisma = new PrismaClient();
|
||||
const deletedResults = await prisma.result.deleteMany();
|
||||
const deletedMatches = await prisma.match.deleteMany();
|
||||
const deletedStages = await prisma.tournamentStage.deleteMany();
|
||||
const deletedTeams = await prisma.team.deleteMany();
|
||||
const deletedPlayers = await prisma.player.deleteMany();
|
||||
console.log(`Deleted ${deletedResults.count} results, ${deletedMatches.count} matches, ${deletedStages.count} tournament stages, ${deletedTeams.count} teams, and ${deletedPlayers.count} players.`);
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
|
||||
main().catch(e => { console.error(e); process.exit(1); });
|
||||
31
scripts/clearStages.js
Normal file
31
scripts/clearStages.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const { PrismaClient } = require('../generated/prisma');
|
||||
|
||||
async function main() {
|
||||
const prisma = new PrismaClient();
|
||||
// Find all single elimination stages
|
||||
const singleElimStages = await prisma.tournamentStage.findMany({ where: { type: 'SINGLE_ELIM' } });
|
||||
if (!singleElimStages.length) {
|
||||
console.log('No single elimination stages found.');
|
||||
await prisma.$disconnect();
|
||||
return;
|
||||
}
|
||||
let totalDeletedMatches = 0;
|
||||
let totalDeletedResults = 0;
|
||||
for (const stage of singleElimStages) {
|
||||
// Find all matches for this stage
|
||||
const matches = await prisma.match.findMany({ where: { stageId: stage.id } });
|
||||
const matchIds = matches.map(m => m.id);
|
||||
// Delete all results for these matches
|
||||
const deletedResults = await prisma.result.deleteMany({ where: { matchId: { in: matchIds } } });
|
||||
// Delete all matches for this stage
|
||||
const deletedMatches = await prisma.match.deleteMany({ where: { stageId: stage.id } });
|
||||
// Delete the stage itself
|
||||
await prisma.tournamentStage.delete({ where: { id: stage.id } });
|
||||
totalDeletedMatches += deletedMatches.count;
|
||||
totalDeletedResults += deletedResults.count;
|
||||
}
|
||||
console.log(`Deleted ${singleElimStages.length} SINGLE_ELIM stages, ${totalDeletedMatches} matches, and ${totalDeletedResults} results.`);
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
|
||||
main().catch(e => { console.error(e); process.exit(1); });
|
||||
28
scripts/createAdmin.js
Normal file
28
scripts/createAdmin.js
Normal file
@@ -0,0 +1,28 @@
|
||||
const { PrismaClient } = require('../generated/prisma');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function createAdmin() {
|
||||
try {
|
||||
const username = 'admin';
|
||||
const password = 'admin123';
|
||||
const hash = await bcrypt.hash(password, 10);
|
||||
|
||||
const admin = await prisma.adminUser.create({
|
||||
data: { username, passwordHash: hash },
|
||||
});
|
||||
|
||||
console.log('Admin created successfully:', { id: admin.id, username: admin.username });
|
||||
} catch (err) {
|
||||
if (err.code === 'P2002') {
|
||||
console.log('Admin already exists');
|
||||
} else {
|
||||
console.error('Error creating admin:', err);
|
||||
}
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
createAdmin();
|
||||
17
scripts/deleteAdmins.js
Normal file
17
scripts/deleteAdmins.js
Normal file
@@ -0,0 +1,17 @@
|
||||
const { PrismaClient } = require('../generated/prisma');
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function deleteAdmins() {
|
||||
try {
|
||||
console.log('Deleting all admin users...');
|
||||
const result = await prisma.adminUser.deleteMany();
|
||||
console.log(`Deleted ${result.count} admin users`);
|
||||
} catch (err) {
|
||||
console.error('Error:', err);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
deleteAdmins();
|
||||
12
scripts/fullTournamentReset.js
Normal file
12
scripts/fullTournamentReset.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const { PrismaClient } = require('../generated/prisma');
|
||||
|
||||
async function main() {
|
||||
const prisma = new PrismaClient();
|
||||
const deletedResults = await prisma.result.deleteMany();
|
||||
const deletedMatches = await prisma.match.deleteMany();
|
||||
const deletedStages = await prisma.tournamentStage.deleteMany();
|
||||
console.log(`Deleted ${deletedResults.count} results, ${deletedMatches.count} matches, and ${deletedStages.count} tournament stages.`);
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
|
||||
main().catch(e => { console.error(e); process.exit(1); });
|
||||
73
scripts/generateTeamLogos.js
Normal file
73
scripts/generateTeamLogos.js
Normal file
@@ -0,0 +1,73 @@
|
||||
const { PrismaClient } = require('../generated/prisma');
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
// Generate random SVG logo based on team name
|
||||
function generateSVGLogo(teamName, size = 40) {
|
||||
// Use team name to generate consistent colors and patterns
|
||||
let hash = 0;
|
||||
for (let i = 0; i < teamName.length; i++) {
|
||||
hash = teamName.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
|
||||
const hue = hash % 360;
|
||||
const saturation = 60 + (hash % 30);
|
||||
const lightness = 40 + (hash % 30);
|
||||
const color = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
||||
|
||||
// Generate secondary color
|
||||
const secondaryHue = (hue + 180) % 360;
|
||||
const secondaryColor = `hsl(${secondaryHue}, ${saturation}%, ${lightness}%)`;
|
||||
|
||||
// Choose a logo pattern based on hash
|
||||
const pattern = hash % 4;
|
||||
const initials = teamName.split(' ').map(w => w[0]).join('').toUpperCase().slice(0, 2);
|
||||
|
||||
let svgContent = '';
|
||||
|
||||
switch (pattern) {
|
||||
case 0: // Circle with initials
|
||||
svgContent = `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><circle cx="${size/2}" cy="${size/2}" r="${size/2}" fill="${color}" stroke="${secondaryColor}" stroke-width="2"/><text x="50%" y="55%" text-anchor="middle" font-size="${size/3}" fill="white" font-family="Arial, sans-serif" font-weight="bold">${initials}</text></svg>`;
|
||||
break;
|
||||
|
||||
case 1: // Square with diagonal
|
||||
svgContent = `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><rect x="2" y="2" width="${size-4}" height="${size-4}" fill="${color}" stroke="${secondaryColor}" stroke-width="2"/><line x1="0" y1="0" x2="${size}" y2="${size}" stroke="${secondaryColor}" stroke-width="3"/><text x="50%" y="55%" text-anchor="middle" font-size="${size/3}" fill="white" font-family="Arial, sans-serif" font-weight="bold">${initials}</text></svg>`;
|
||||
break;
|
||||
|
||||
case 2: // Triangle
|
||||
svgContent = `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><polygon points="${size/2},5 ${size-5},${size-5} 5,${size-5}" fill="${color}" stroke="${secondaryColor}" stroke-width="2"/><text x="50%" y="60%" text-anchor="middle" font-size="${size/3}" fill="white" font-family="Arial, sans-serif" font-weight="bold">${initials}</text></svg>`;
|
||||
break;
|
||||
|
||||
case 3: // Diamond
|
||||
svgContent = `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><polygon points="${size/2},5 ${size-5},${size/2} ${size/2},${size-5} 5,${size/2}" fill="${color}" stroke="${secondaryColor}" stroke-width="2"/><text x="50%" y="55%" text-anchor="middle" font-size="${size/3}" fill="white" font-family="Arial, sans-serif" font-weight="bold">${initials}</text></svg>`;
|
||||
break;
|
||||
}
|
||||
|
||||
return svgContent;
|
||||
}
|
||||
|
||||
async function updateTeamLogos() {
|
||||
try {
|
||||
const teams = await prisma.team.findMany();
|
||||
console.log(`Found ${teams.length} teams to update`);
|
||||
|
||||
for (const team of teams) {
|
||||
const svgLogo = generateSVGLogo(team.name);
|
||||
|
||||
await prisma.team.update({
|
||||
where: { id: team.id },
|
||||
data: { logo: svgLogo }
|
||||
});
|
||||
|
||||
console.log(`Updated ${team.name} with SVG logo`);
|
||||
}
|
||||
|
||||
console.log('✅ All team logos updated successfully!');
|
||||
} catch (err) {
|
||||
console.error('Error updating team logos:', err);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
updateTeamLogos();
|
||||
101
scripts/resetTournament.js
Normal file
101
scripts/resetTournament.js
Normal file
@@ -0,0 +1,101 @@
|
||||
const { PrismaClient } = require('../generated/prisma');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
// Generate SVG logo based on team name
|
||||
function generateSVGLogo(teamName, size = 40) {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < teamName.length; i++) {
|
||||
hash = teamName.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
|
||||
const hue = Math.abs(hash) % 360;
|
||||
const saturation = 60 + (Math.abs(hash) % 30);
|
||||
const lightness = 40 + (Math.abs(hash) % 30);
|
||||
const color = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
||||
|
||||
const secondaryHue = (hue + 180) % 360;
|
||||
const secondaryColor = `hsl(${secondaryHue}, ${saturation}%, ${lightness}%)`;
|
||||
|
||||
const pattern = Math.abs(hash) % 4;
|
||||
const initials = teamName.split(' ').map(w => w[0]).join('').toUpperCase().slice(0, 2);
|
||||
|
||||
let svgContent = '';
|
||||
|
||||
switch (pattern) {
|
||||
case 0: // Circle with initials
|
||||
svgContent = `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><circle cx="${size/2}" cy="${size/2}" r="${size/2}" fill="${color}" stroke="${secondaryColor}" stroke-width="2"/><text x="50%" y="55%" text-anchor="middle" font-size="${size/3}" fill="white" font-family="Arial, sans-serif" font-weight="bold">${initials}</text></svg>`;
|
||||
break;
|
||||
case 1: // Square with diagonal
|
||||
svgContent = `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><rect x="2" y="2" width="${size-4}" height="${size-4}" fill="${color}" stroke="${secondaryColor}" stroke-width="2"/><line x1="0" y1="0" x2="${size}" y2="${size}" stroke="${secondaryColor}" stroke-width="3"/><text x="50%" y="55%" text-anchor="middle" font-size="${size/3}" fill="white" font-family="Arial, sans-serif" font-weight="bold">${initials}</text></svg>`;
|
||||
break;
|
||||
case 2: // Triangle
|
||||
svgContent = `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><polygon points="${size/2},5 ${size-5},${size-5} 5,${size-5}" fill="${color}" stroke="${secondaryColor}" stroke-width="2"/><text x="50%" y="60%" text-anchor="middle" font-size="${size/3}" fill="white" font-family="Arial, sans-serif" font-weight="bold">${initials}</text></svg>`;
|
||||
break;
|
||||
case 3: // Diamond
|
||||
svgContent = `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"><polygon points="${size/2},5 ${size-5},${size/2} ${size/2},${size-5} 5,${size/2}" fill="${color}" stroke="${secondaryColor}" stroke-width="2"/><text x="50%" y="55%" text-anchor="middle" font-size="${size/3}" fill="white" font-family="Arial, sans-serif" font-weight="bold">${initials}</text></svg>`;
|
||||
break;
|
||||
}
|
||||
|
||||
return svgContent;
|
||||
}
|
||||
|
||||
async function resetTournament() {
|
||||
try {
|
||||
console.log('🗑️ Deleting all existing data...');
|
||||
|
||||
// Delete all data in the correct order (due to foreign key constraints)
|
||||
await prisma.result.deleteMany();
|
||||
await prisma.match.deleteMany();
|
||||
await prisma.tournamentStage.deleteMany();
|
||||
await prisma.tournament.deleteMany();
|
||||
await prisma.team.deleteMany();
|
||||
|
||||
console.log('✅ All existing data deleted');
|
||||
|
||||
// Create new tournament
|
||||
console.log('🏆 Creating new tournament...');
|
||||
const tournament = await prisma.tournament.create({
|
||||
data: {
|
||||
name: 'Championship Tournament',
|
||||
date: new Date(),
|
||||
location: 'Main Arena'
|
||||
}
|
||||
});
|
||||
console.log(`✅ Tournament created: ${tournament.name}`);
|
||||
|
||||
// Create 15 teams
|
||||
console.log('👥 Creating 15 teams...');
|
||||
const teamNames = [
|
||||
'Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta', 'Theta', 'Iota', 'Kappa',
|
||||
'Lambda', 'Mu', 'Nu', 'Xi', 'Omicron'
|
||||
];
|
||||
|
||||
const teams = [];
|
||||
for (let i = 0; i < 15; i++) {
|
||||
const teamName = `Team ${teamNames[i]}`;
|
||||
const team = await prisma.team.create({
|
||||
data: {
|
||||
name: teamName,
|
||||
logo: generateSVGLogo(teamName)
|
||||
}
|
||||
});
|
||||
teams.push(team);
|
||||
console.log(`✅ Created ${team.name} with SVG logo`);
|
||||
}
|
||||
|
||||
console.log(`\n🎉 Tournament reset complete!`);
|
||||
console.log(`📊 Tournament: ${tournament.name}`);
|
||||
console.log(`👥 Teams: ${teams.length}`);
|
||||
console.log(`📅 Date: ${tournament.date.toLocaleDateString()}`);
|
||||
console.log(`📍 Location: ${tournament.location}`);
|
||||
|
||||
} catch (err) {
|
||||
console.error('❌ Error resetting tournament:', err);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
resetTournament();
|
||||
60
scripts/scheduleAndFillResults.js
Normal file
60
scripts/scheduleAndFillResults.js
Normal file
@@ -0,0 +1,60 @@
|
||||
const fetch = require('node-fetch');
|
||||
const readline = require('readline');
|
||||
|
||||
async function prompt(question) {
|
||||
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
||||
return new Promise(resolve => rl.question(question, ans => { rl.close(); resolve(ans); }));
|
||||
}
|
||||
|
||||
function getRandomScore() {
|
||||
// No draws allowed, so scores must be different
|
||||
let a = Math.floor(Math.random() * 10);
|
||||
let b = Math.floor(Math.random() * 10);
|
||||
while (a === b) {
|
||||
b = Math.floor(Math.random() * 10);
|
||||
}
|
||||
return [a, b];
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const username = process.env.ADMIN_USERNAME || await prompt('Admin username: ');
|
||||
const password = process.env.ADMIN_PASSWORD || await prompt('Admin password: ');
|
||||
|
||||
// Login as admin
|
||||
const loginRes = await fetch('http://localhost:4000/api/admin/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username, password })
|
||||
});
|
||||
const loginData = await loginRes.json();
|
||||
if (!loginRes.ok || !loginData.token) {
|
||||
console.error('Admin login failed:', loginData.error || loginRes.statusText);
|
||||
process.exit(1);
|
||||
}
|
||||
const token = loginData.token;
|
||||
console.log('Admin login successful. Filling in match results...');
|
||||
|
||||
// Fetch all matches
|
||||
const matchesRes = await fetch('http://localhost:4000/api/matches');
|
||||
const matches = await matchesRes.json();
|
||||
for (const match of matches) {
|
||||
if (match.result) continue; // Skip if result already exists
|
||||
const [team1Score, team2Score] = getRandomScore();
|
||||
const resultRes = await fetch(`http://localhost:4000/api/admin/matches/${match.id}/result`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({ team1Score, team2Score })
|
||||
});
|
||||
if (resultRes.ok) {
|
||||
console.log(`Filled result for match ${match.id}: ${team1Score} - ${team2Score}`);
|
||||
} else {
|
||||
const err = await resultRes.json();
|
||||
console.log(`Failed to fill result for match ${match.id}:`, err.error || resultRes.statusText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
49
scripts/scheduleRoundRobin.js
Normal file
49
scripts/scheduleRoundRobin.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const fetch = require('node-fetch');
|
||||
const readline = require('readline');
|
||||
|
||||
async function prompt(question) {
|
||||
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
||||
return new Promise(resolve => rl.question(question, ans => { rl.close(); resolve(ans); }));
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const username = process.env.ADMIN_USERNAME || await prompt('Admin username: ');
|
||||
const password = process.env.ADMIN_PASSWORD || await prompt('Admin password: ');
|
||||
let minTeamsPerPool = 3;
|
||||
const minTeamsInput = await prompt('Minimum teams per pool (default 3): ');
|
||||
if (minTeamsInput && !isNaN(parseInt(minTeamsInput))) {
|
||||
minTeamsPerPool = parseInt(minTeamsInput);
|
||||
}
|
||||
|
||||
// Login as admin
|
||||
const loginRes = await fetch('http://localhost:4000/api/admin/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username, password })
|
||||
});
|
||||
const loginData = await loginRes.json();
|
||||
if (!loginRes.ok || !loginData.token) {
|
||||
console.error('Admin login failed:', loginData.error || loginRes.statusText);
|
||||
process.exit(1);
|
||||
}
|
||||
const token = loginData.token;
|
||||
console.log('Admin login successful. Scheduling round robin matches...');
|
||||
|
||||
// Call schedule round robin endpoint
|
||||
const scheduleRes = await fetch('http://localhost:4000/api/admin/schedule/roundrobin', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ minTeamsPerPool })
|
||||
});
|
||||
const scheduleData = await scheduleRes.json();
|
||||
if (scheduleRes.ok) {
|
||||
console.log('Round robin scheduled:', scheduleData);
|
||||
} else {
|
||||
console.error('Failed to schedule round robin:', scheduleData.error || scheduleRes.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
40
scripts/scheduleSingleElim.js
Normal file
40
scripts/scheduleSingleElim.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const fetch = require('node-fetch');
|
||||
const readline = require('readline');
|
||||
|
||||
async function prompt(question) {
|
||||
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
||||
return new Promise(resolve => rl.question(question, ans => { rl.close(); resolve(ans); }));
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const username = process.env.ADMIN_USERNAME || await prompt('Admin username: ');
|
||||
const password = process.env.ADMIN_PASSWORD || await prompt('Admin password: ');
|
||||
|
||||
// Login as admin
|
||||
const loginRes = await fetch('http://localhost:4000/api/admin/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username, password })
|
||||
});
|
||||
const loginData = await loginRes.json();
|
||||
if (!loginRes.ok || !loginData.token) {
|
||||
console.error('Admin login failed:', loginData.error || loginRes.statusText);
|
||||
process.exit(1);
|
||||
}
|
||||
const token = loginData.token;
|
||||
console.log('Admin login successful. Scheduling single elimination bracket...');
|
||||
|
||||
// Call schedule single elimination endpoint
|
||||
const scheduleRes = await fetch('http://localhost:4000/api/admin/schedule/singleelim', {
|
||||
method: 'POST',
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
const scheduleData = await scheduleRes.json();
|
||||
if (scheduleRes.ok) {
|
||||
console.log('Single elimination scheduled:', scheduleData);
|
||||
} else {
|
||||
console.error('Failed to schedule single elimination:', scheduleData.error || scheduleRes.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
24
scripts/setPlayerUsernames.js
Normal file
24
scripts/setPlayerUsernames.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const { PrismaClient } = require('../generated/prisma');
|
||||
|
||||
async function main() {
|
||||
const prisma = new PrismaClient();
|
||||
const players = await prisma.player.findMany();
|
||||
const usedUsernames = new Set();
|
||||
|
||||
for (const player of players) {
|
||||
let base = player.email.split('@')[0];
|
||||
let username = base;
|
||||
let i = 1;
|
||||
// Ensure uniqueness
|
||||
while (usedUsernames.has(username) || await prisma.player.findUnique({ where: { username } })) {
|
||||
username = `${base}${i}`;
|
||||
i++;
|
||||
}
|
||||
usedUsernames.add(username);
|
||||
await prisma.player.update({ where: { id: player.id }, data: { username } });
|
||||
console.log(`Set username for ${player.email}: ${username}`);
|
||||
}
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
|
||||
main().catch(e => { console.error(e); process.exit(1); });
|
||||
57
scripts/startTournament.js
Normal file
57
scripts/startTournament.js
Normal file
@@ -0,0 +1,57 @@
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
async function startTournament() {
|
||||
try {
|
||||
// 1. Login as admin with .env credentials
|
||||
console.log('Logging in as admin...');
|
||||
const loginRes = await fetch('http://localhost:4000/api/admin/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: 'admin',
|
||||
password: '0000'
|
||||
})
|
||||
});
|
||||
|
||||
if (!loginRes.ok) {
|
||||
const error = await loginRes.json();
|
||||
console.error('Login failed:', error);
|
||||
return;
|
||||
}
|
||||
|
||||
const { token } = await loginRes.json();
|
||||
console.log('✅ Login successful!');
|
||||
|
||||
// 2. Start round robin
|
||||
console.log('Starting round robin...');
|
||||
const scheduleRes = await fetch('http://localhost:4000/api/admin/schedule/roundrobin', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (scheduleRes.ok) {
|
||||
const data = await scheduleRes.json();
|
||||
console.log('✅ Round robin started successfully!');
|
||||
console.log('Pools created:', data.pools);
|
||||
console.log('Matches created:', data.matchesCreated);
|
||||
|
||||
// 3. Check the created matches
|
||||
console.log('Checking created matches...');
|
||||
const matchesRes = await fetch('http://localhost:4000/api/matches');
|
||||
if (matchesRes.ok) {
|
||||
const matches = await matchesRes.json();
|
||||
console.log(`✅ Found ${matches.length} matches created`);
|
||||
}
|
||||
} else {
|
||||
const error = await scheduleRes.json();
|
||||
console.error('❌ Failed to start round robin:', error);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error:', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
startTournament();
|
||||
44
scripts/testEnvLogin.js
Normal file
44
scripts/testEnvLogin.js
Normal file
@@ -0,0 +1,44 @@
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
async function testEnvLogin() {
|
||||
try {
|
||||
console.log('Testing admin login with .env credentials...');
|
||||
console.log('Username: admin, Password: 0000');
|
||||
|
||||
const loginRes = await fetch('http://localhost:4000/api/admin/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: 'admin',
|
||||
password: '0000'
|
||||
})
|
||||
});
|
||||
|
||||
console.log('Response status:', loginRes.status);
|
||||
const data = await loginRes.json();
|
||||
console.log('Response data:', data);
|
||||
|
||||
if (loginRes.ok) {
|
||||
console.log('✅ Login successful! Token received');
|
||||
|
||||
// Test the token by calling a protected endpoint
|
||||
console.log('Testing protected endpoint...');
|
||||
const teamsRes = await fetch('http://localhost:4000/api/teams', {
|
||||
headers: { 'Authorization': `Bearer ${data.token}` }
|
||||
});
|
||||
|
||||
if (teamsRes.ok) {
|
||||
const teams = await teamsRes.json();
|
||||
console.log(`✅ Token works! Found ${teams.length} teams`);
|
||||
} else {
|
||||
console.log('❌ Token validation failed');
|
||||
}
|
||||
} else {
|
||||
console.log('❌ Login failed:', data.error);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error:', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
testEnvLogin();
|
||||
30
scripts/testLogin.js
Normal file
30
scripts/testLogin.js
Normal file
@@ -0,0 +1,30 @@
|
||||
const fetch = require('node-fetch');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
async function testLogin() {
|
||||
try {
|
||||
console.log('Testing admin login...');
|
||||
const loginRes = await fetch('http://localhost:4000/api/admin/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: 'admin',
|
||||
password: 'admin123'
|
||||
})
|
||||
});
|
||||
|
||||
console.log('Response status:', loginRes.status);
|
||||
const data = await loginRes.json();
|
||||
console.log('Response data:', data);
|
||||
|
||||
if (loginRes.ok) {
|
||||
console.log('Login successful! Token:', data.token);
|
||||
} else {
|
||||
console.log('Login failed:', data.error);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error:', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
testLogin();
|
||||
34
scripts/verifyPassword.js
Normal file
34
scripts/verifyPassword.js
Normal file
@@ -0,0 +1,34 @@
|
||||
const { PrismaClient } = require('../generated/prisma');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function verifyPassword() {
|
||||
try {
|
||||
const admin = await prisma.adminUser.findUnique({ where: { username: 'admin' } });
|
||||
if (!admin) {
|
||||
console.log('Admin not found');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Admin found:', { id: admin.id, username: admin.username });
|
||||
console.log('Password hash:', admin.passwordHash);
|
||||
|
||||
const password = 'admin123';
|
||||
const isValid = await bcrypt.compare(password, admin.passwordHash);
|
||||
console.log('Password valid:', isValid);
|
||||
|
||||
// Test with a new hash
|
||||
const newHash = await bcrypt.hash(password, 10);
|
||||
console.log('New hash for same password:', newHash);
|
||||
const isValidNew = await bcrypt.compare(password, newHash);
|
||||
console.log('New hash valid:', isValidNew);
|
||||
|
||||
} catch (err) {
|
||||
console.error('Error:', err);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
verifyPassword();
|
||||
Reference in New Issue
Block a user