Jury inline doc preview, download fix, category tags, admin eval reset
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m55s
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m55s
- Replace MultiWindowDocViewer with FileViewer for inline previews (PDF/image/video/Office) - Fix cross-origin download using fetch+blob instead of <a download> - Show Startup/Business Concept badge on jury project detail + evaluate pages - Add admin resetEvaluation procedure with audit logging - Add dropdown menu on admin assignment rows with Reset Evaluation + Delete - Make file action buttons responsive on mobile (separate row below file info) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -230,6 +230,67 @@ export const evaluationRouter = router({
|
||||
return updated
|
||||
}),
|
||||
|
||||
/**
|
||||
* Reset (erase) an evaluation so a juror can start over (admin only)
|
||||
* Deletes the evaluation record and resets the assignment's isCompleted flag.
|
||||
*/
|
||||
resetEvaluation: adminProcedure
|
||||
.input(
|
||||
z.object({
|
||||
assignmentId: z.string(),
|
||||
})
|
||||
)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const assignment = await ctx.prisma.assignment.findUniqueOrThrow({
|
||||
where: { id: input.assignmentId },
|
||||
include: {
|
||||
evaluation: true,
|
||||
user: { select: { id: true, name: true, email: true } },
|
||||
project: { select: { id: true, title: true } },
|
||||
},
|
||||
})
|
||||
|
||||
if (!assignment.evaluation) {
|
||||
throw new TRPCError({
|
||||
code: 'NOT_FOUND',
|
||||
message: 'No evaluation found for this assignment',
|
||||
})
|
||||
}
|
||||
|
||||
// Delete the evaluation and reset assignment completion in a transaction
|
||||
await ctx.prisma.$transaction([
|
||||
ctx.prisma.evaluation.delete({
|
||||
where: { id: assignment.evaluation.id },
|
||||
}),
|
||||
ctx.prisma.assignment.update({
|
||||
where: { id: input.assignmentId },
|
||||
data: { isCompleted: false },
|
||||
}),
|
||||
])
|
||||
|
||||
// Audit log
|
||||
await logAudit({
|
||||
prisma: ctx.prisma,
|
||||
userId: ctx.user.id,
|
||||
action: 'EVALUATION_RESET',
|
||||
entityType: 'Evaluation',
|
||||
entityId: assignment.evaluation.id,
|
||||
detailsJson: {
|
||||
assignmentId: input.assignmentId,
|
||||
jurorId: assignment.user.id,
|
||||
jurorName: assignment.user.name || assignment.user.email,
|
||||
projectId: assignment.project.id,
|
||||
projectTitle: assignment.project.title,
|
||||
previousStatus: assignment.evaluation.status,
|
||||
previousGlobalScore: assignment.evaluation.globalScore,
|
||||
},
|
||||
ipAddress: ctx.ip,
|
||||
userAgent: ctx.userAgent,
|
||||
})
|
||||
|
||||
return { success: true }
|
||||
}),
|
||||
|
||||
/**
|
||||
* Get aggregated stats for a project (admin only)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user