import { z } from 'zod' import { TRPCError } from '@trpc/server' import { router, adminProcedure, superAdminProcedure, protectedProcedure } from '../trpc' import { lockResults, unlockResults, isLocked, getLockHistory, } from '../services/result-lock' const categoryEnum = z.enum([ 'STARTUP', 'BUSINESS_CONCEPT', ]) export const resultLockRouter = router({ /** * Lock results for a competition/round/category (admin) */ lock: adminProcedure .input( z.object({ competitionId: z.string(), roundId: z.string(), category: categoryEnum, resultSnapshot: z.unknown(), }) ) .mutation(async ({ ctx, input }) => { const result = await lockResults( { competitionId: input.competitionId, roundId: input.roundId, category: input.category, lockedById: ctx.user.id, resultSnapshot: input.resultSnapshot, }, ctx.prisma, ) if (!result.success) { throw new TRPCError({ code: 'BAD_REQUEST', message: result.errors?.join('; ') ?? 'Failed to lock results', }) } return result }), /** * Unlock results (super-admin only) */ unlock: superAdminProcedure .input( z.object({ resultLockId: z.string(), reason: z.string().min(1).max(2000), }) ) .mutation(async ({ ctx, input }) => { const result = await unlockResults( { resultLockId: input.resultLockId, unlockedById: ctx.user.id, reason: input.reason, }, ctx.prisma, ) if (!result.success) { throw new TRPCError({ code: 'BAD_REQUEST', message: result.errors?.join('; ') ?? 'Failed to unlock results', }) } return result }), /** * Check if results are locked */ isLocked: protectedProcedure .input( z.object({ competitionId: z.string(), roundId: z.string(), category: categoryEnum, }) ) .query(async ({ ctx, input }) => { return isLocked(input.competitionId, input.roundId, input.category, ctx.prisma) }), /** * Get lock history for a competition */ history: adminProcedure .input(z.object({ competitionId: z.string() })) .query(async ({ ctx, input }) => { return getLockHistory(input.competitionId, ctx.prisma) }), })