refactor: tech debt batch 3 — type safety + assignment router split
All checks were successful
Build and Push Docker Image / build (push) Successful in 13m4s

#5 — Replaced 55x PrismaClient | any with proper Prisma types across 8 files
- Service files: PrismaClient | any → PrismaClient, tx: any → Prisma.TransactionClient
- Fixed 4 real bugs uncovered by typing:
  - mentor-workspace.ts: wrong FK fields (mentorAssignmentId → workspaceId, role → senderRole)
  - ai-shortlist.ts: untyped string passed to CompetitionCategory enum filter
  - result-lock.ts: unknown passed where Prisma.InputJsonValue required

#9 — Split assignment.ts (2,775 lines) into 6 focused files:
  - shared.ts (93 lines) — MOVABLE_EVAL_STATUSES, buildBatchNotifications, getCandidateJurors
  - assignment-crud.ts (473 lines) — 8 core CRUD procedures
  - assignment-suggestions.ts (880 lines) — AI suggestions + job runner
  - assignment-notifications.ts (138 lines) — 2 notification procedures
  - assignment-redistribution.ts (1,162 lines) — 8 reassign/transfer procedures
  - index.ts (15 lines) — barrel export with router merge, zero frontend changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 12:47:06 +01:00
parent 1c78ecf21d
commit 6b40fe7726
16 changed files with 2836 additions and 2851 deletions

View File

@@ -34,7 +34,7 @@ export type SubmissionValidationResult = {
export async function openWindow(
windowId: string,
actorId: string,
prisma: PrismaClient | any,
prisma: PrismaClient,
): Promise<WindowLifecycleResult> {
try {
const window = await prisma.submissionWindow.findUnique({ where: { id: windowId } })
@@ -47,7 +47,7 @@ export async function openWindow(
return { success: false, errors: ['Cannot open a locked window'] }
}
await prisma.$transaction(async (tx: any) => {
await prisma.$transaction(async (tx: Prisma.TransactionClient) => {
await tx.submissionWindow.update({
where: { id: windowId },
data: {
@@ -93,7 +93,7 @@ export async function openWindow(
export async function closeWindow(
windowId: string,
actorId: string,
prisma: PrismaClient | any,
prisma: PrismaClient,
): Promise<WindowLifecycleResult> {
try {
const window = await prisma.submissionWindow.findUnique({ where: { id: windowId } })
@@ -102,7 +102,7 @@ export async function closeWindow(
return { success: false, errors: [`Submission window ${windowId} not found`] }
}
await prisma.$transaction(async (tx: any) => {
await prisma.$transaction(async (tx: Prisma.TransactionClient) => {
const data: Record<string, unknown> = {
windowCloseAt: new Date(),
}
@@ -155,7 +155,7 @@ export async function closeWindow(
export async function lockWindow(
windowId: string,
actorId: string,
prisma: PrismaClient | any,
prisma: PrismaClient,
): Promise<WindowLifecycleResult> {
try {
const window = await prisma.submissionWindow.findUnique({ where: { id: windowId } })
@@ -168,7 +168,7 @@ export async function lockWindow(
return { success: false, errors: ['Window is already locked'] }
}
await prisma.$transaction(async (tx: any) => {
await prisma.$transaction(async (tx: Prisma.TransactionClient) => {
await tx.submissionWindow.update({
where: { id: windowId },
data: { isLocked: true },
@@ -212,7 +212,7 @@ export async function lockWindow(
*/
export async function checkDeadlinePolicy(
windowId: string,
prisma: PrismaClient | any,
prisma: PrismaClient,
): Promise<DeadlineStatus> {
const window = await prisma.submissionWindow.findUnique({ where: { id: windowId } })
@@ -273,7 +273,7 @@ export async function validateSubmission(
projectId: string,
windowId: string,
files: Array<{ mimeType: string; size: number; requirementId?: string }>,
prisma: PrismaClient | any,
prisma: PrismaClient,
): Promise<SubmissionValidationResult> {
const errors: string[] = []
@@ -327,7 +327,7 @@ export async function validateSubmission(
*/
export async function isWindowReadOnly(
windowId: string,
prisma: PrismaClient | any,
prisma: PrismaClient,
): Promise<boolean> {
const status = await checkDeadlinePolicy(windowId, prisma)
return status.status === 'LOCKED' || status.status === 'CLOSED'
@@ -340,7 +340,7 @@ export async function isWindowReadOnly(
*/
export async function getVisibleWindows(
roundId: string,
prisma: PrismaClient | any,
prisma: PrismaClient,
) {
const visibility = await prisma.roundSubmissionVisibility.findMany({
where: { roundId, canView: true },