import { Router } from 'express'; import { TournamentMatchController } from '../controllers/tournamentMatch.controller'; import { authenticate, authorize } from '../middleware/auth'; import { validate, validateQuery } from '../middleware/validate'; import { UserRole, TournamentMatchStatus } from '../utils/constants'; import { z } from 'zod'; const router = Router({ mergeParams: true }); // Schema para query params de filtros const matchFiltersSchema = z.object({ round: z.string().regex(/^\d+$/).optional().transform(Number), status: z.enum([ TournamentMatchStatus.PENDING, TournamentMatchStatus.SCHEDULED, TournamentMatchStatus.IN_PROGRESS, TournamentMatchStatus.FINISHED, TournamentMatchStatus.CANCELLED, TournamentMatchStatus.BYE, ]).optional(), courtId: z.string().uuid().optional(), playerId: z.string().uuid().optional(), fromDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(), toDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(), }); // Schema para actualizar partido const updateMatchSchema = z.object({ courtId: z.string().uuid().optional(), scheduledDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(), scheduledTime: z.string().regex(/^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/).optional(), status: z.enum([ TournamentMatchStatus.PENDING, TournamentMatchStatus.SCHEDULED, TournamentMatchStatus.IN_PROGRESS, TournamentMatchStatus.CANCELLED, ]).optional(), notes: z.string().optional(), }); // Schema para asignar cancha const assignCourtSchema = z.object({ courtId: z.string().uuid('ID de cancha inválido'), date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Fecha debe ser YYYY-MM-DD'), time: z.string().regex(/^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/, 'Hora debe ser HH:MM'), }); // Schema para registrar resultado const recordResultSchema = z.object({ team1Score: z.number().int().min(0, 'El puntaje no puede ser negativo'), team2Score: z.number().int().min(0, 'El puntaje no puede ser negativo'), }); // Schema para cancelar partido const cancelMatchSchema = z.object({ reason: z.string().optional(), }); // Schema para params de IDs const matchIdSchema = z.object({ matchId: z.string().uuid('ID de partido inválido'), }); // Listar partidos del torneo router.get( '/matches', authenticate, validateQuery(matchFiltersSchema), TournamentMatchController.getMatches ); // Obtener mis partidos en el torneo router.get( '/my-matches', authenticate, TournamentMatchController.getMyMatches ); // Obtener partidos de un participante específico router.get( '/participants/:participantId/matches', authenticate, TournamentMatchController.getParticipantMatches ); // Obtener un partido específico router.get( '/matches/:matchId', authenticate, validate(z.object({ matchId: z.string().uuid() })), TournamentMatchController.getMatch ); // Actualizar partido (solo admins) router.put( '/matches/:matchId', authenticate, authorize(UserRole.ADMIN, UserRole.SUPERADMIN), validate(updateMatchSchema), TournamentMatchController.updateMatch ); // Asignar cancha (solo admins) router.put( '/matches/:matchId/assign-court', authenticate, authorize(UserRole.ADMIN, UserRole.SUPERADMIN), validate(assignCourtSchema), TournamentMatchController.assignCourt ); // Iniciar partido (solo admins) router.put( '/matches/:matchId/start', authenticate, authorize(UserRole.ADMIN, UserRole.SUPERADMIN), validate(matchIdSchema), TournamentMatchController.startMatch ); // Cancelar partido (solo admins) router.put( '/matches/:matchId/cancel', authenticate, authorize(UserRole.ADMIN, UserRole.SUPERADMIN), validate(cancelMatchSchema), TournamentMatchController.cancelMatch ); // Registrar resultado (jugadores o admins) router.put( '/matches/:matchId/result', authenticate, validate(recordResultSchema), TournamentMatchController.recordResult ); // Confirmar resultado (jugadores) router.put( '/matches/:matchId/confirm', authenticate, validate(matchIdSchema), TournamentMatchController.confirmResult ); export default router;