feat: add site_admin role, casual match support, and tournament deletion

This commit is contained in:
2026-03-30 21:49:43 -07:00
parent d821dd7ce2
commit 07804b5f8f
7 changed files with 507 additions and 7 deletions
+65 -3
View File
@@ -1,7 +1,7 @@
import { getSession } from './auth-simple';
import { prisma } from './prisma';
export type UserRole = 'player' | 'tournament_admin' | 'club_admin';
export type UserRole = 'player' | 'tournament_admin' | 'club_admin' | 'site_admin';
export interface PermissionCheck {
allowed: boolean;
@@ -36,11 +36,12 @@ export async function hasRole(requiredRole: UserRole): Promise<PermissionCheck>
const userRole = user.role as UserRole;
// Role hierarchy: player < tournament_admin < club_admin
// Role hierarchy: player < tournament_admin < club_admin < site_admin
const roleHierarchy: Record<UserRole, number> = {
'player': 1,
'tournament_admin': 2,
'club_admin': 3
'club_admin': 3,
'site_admin': 4
};
const hasRequiredRole = roleHierarchy[userRole] >= roleHierarchy[requiredRole];
@@ -232,3 +233,64 @@ export async function canEditUserProfiles(): Promise<PermissionCheck> {
export async function canRecalculateElo(): Promise<PermissionCheck> {
return hasRole('club_admin');
}
/**
* Check if the user can delete tournaments
* Site admins can delete all tournaments
* Club admins can delete tournaments they can manage
* Tournament admins can only delete their own tournaments
*/
export async function canDeleteTournament(tournamentId: number): Promise<PermissionCheck> {
const session = await getSession();
if (!session) {
return { allowed: false, reason: 'Not authenticated' };
}
const userId = session.user?.id;
if (!userId) {
return { allowed: false, reason: 'User ID not found in session' };
}
// Fetch user from database to get current role
const user = await prisma.user.findUnique({
where: { id: userId },
select: { role: true }
});
if (!user) {
return { allowed: false, reason: 'User not found in database' };
}
const userRole = user.role as UserRole;
// Site admins can delete any tournament
if (userRole === 'site_admin') {
return { allowed: true };
}
// Club admins can delete tournaments they can manage
if (userRole === 'club_admin') {
return { allowed: true };
}
// Tournament admins can only delete their own tournaments
if (userRole === 'tournament_admin') {
const tournament = await prisma.event.findUnique({
where: { id: tournamentId },
select: { ownerId: true }
});
if (!tournament) {
return { allowed: false, reason: 'Tournament not found' };
}
if (tournament.ownerId === userId) {
return { allowed: true };
}
return { allowed: false, reason: 'Tournament admin can only delete their own tournaments' };
}
return { allowed: false, reason: 'Players cannot delete tournaments' };
}