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

@@ -19,13 +19,13 @@ type WorkspaceResult = { success: boolean; errors?: string[] }
* Activate a mentor workspace for a given assignment.
*/
export async function activateWorkspace(
mentorAssignmentId: string,
workspaceId: string,
actorId: string,
prisma: PrismaClient | any,
prisma: PrismaClient,
): Promise<WorkspaceResult> {
try {
const assignment = await prisma.mentorAssignment.findUnique({
where: { id: mentorAssignmentId },
where: { id: workspaceId },
})
if (!assignment) {
@@ -36,9 +36,9 @@ export async function activateWorkspace(
return { success: false, errors: ['Workspace is already enabled'] }
}
await prisma.$transaction(async (tx: any) => {
await prisma.$transaction(async (tx: Prisma.TransactionClient) => {
await tx.mentorAssignment.update({
where: { id: mentorAssignmentId },
where: { id: workspaceId },
data: {
workspaceEnabled: true,
workspaceOpenAt: new Date(),
@@ -49,7 +49,7 @@ export async function activateWorkspace(
data: {
eventType: 'mentor_workspace.activated',
entityType: 'MentorAssignment',
entityId: mentorAssignmentId,
entityId: workspaceId,
actorId,
detailsJson: {
projectId: assignment.projectId,
@@ -64,7 +64,7 @@ export async function activateWorkspace(
userId: actorId,
action: 'WORKSPACE_ACTIVATE',
entityType: 'MentorAssignment',
entityId: mentorAssignmentId,
entityId: workspaceId,
detailsJson: { projectId: assignment.projectId },
})
})
@@ -86,15 +86,15 @@ export async function activateWorkspace(
*/
export async function sendMessage(
params: {
mentorAssignmentId: string
workspaceId: string
senderId: string
message: string
role: 'MENTOR_ROLE' | 'APPLICANT_ROLE' | 'ADMIN_ROLE'
},
prisma: PrismaClient | any,
prisma: PrismaClient,
) {
const assignment = await prisma.mentorAssignment.findUnique({
where: { id: params.mentorAssignmentId },
where: { id: params.workspaceId },
})
if (!assignment) {
@@ -107,11 +107,11 @@ export async function sendMessage(
return prisma.mentorMessage.create({
data: {
mentorAssignmentId: params.mentorAssignmentId,
workspaceId: params.workspaceId,
projectId: assignment.projectId,
senderId: params.senderId,
message: params.message,
role: params.role,
senderRole: params.role,
},
include: {
sender: { select: { id: true, name: true, email: true } },
@@ -123,11 +123,11 @@ export async function sendMessage(
* Get messages for a workspace.
*/
export async function getMessages(
mentorAssignmentId: string,
prisma: PrismaClient | any,
workspaceId: string,
prisma: PrismaClient,
) {
return prisma.mentorMessage.findMany({
where: { mentorAssignmentId },
where: { workspaceId },
include: {
sender: { select: { id: true, name: true, email: true, role: true } },
},
@@ -140,7 +140,7 @@ export async function getMessages(
*/
export async function markRead(
messageId: string,
prisma: PrismaClient | any,
prisma: PrismaClient,
): Promise<void> {
await prisma.mentorMessage.update({
where: { id: messageId },
@@ -155,7 +155,7 @@ export async function markRead(
*/
export async function uploadFile(
params: {
mentorAssignmentId: string
workspaceId: string
uploadedByUserId: string
fileName: string
mimeType: string
@@ -164,10 +164,10 @@ export async function uploadFile(
objectKey: string
description?: string
},
prisma: PrismaClient | any,
prisma: PrismaClient,
) {
const assignment = await prisma.mentorAssignment.findUnique({
where: { id: params.mentorAssignmentId },
where: { id: params.workspaceId },
})
if (!assignment) {
@@ -180,7 +180,7 @@ export async function uploadFile(
return prisma.mentorFile.create({
data: {
mentorAssignmentId: params.mentorAssignmentId,
mentorAssignmentId: params.workspaceId,
uploadedByUserId: params.uploadedByUserId,
fileName: params.fileName,
mimeType: params.mimeType,
@@ -205,7 +205,7 @@ export async function addFileComment(
content: string
parentCommentId?: string
},
prisma: PrismaClient | any,
prisma: PrismaClient,
) {
return prisma.mentorFileComment.create({
data: {
@@ -233,7 +233,7 @@ export async function promoteFile(
slotKey: string
promotedById: string
},
prisma: PrismaClient | any,
prisma: PrismaClient,
): Promise<{ success: boolean; errors?: string[] }> {
try {
const file = await prisma.mentorFile.findUnique({
@@ -251,7 +251,7 @@ export async function promoteFile(
return { success: false, errors: ['File is already promoted'] }
}
await prisma.$transaction(async (tx: any) => {
await prisma.$transaction(async (tx: Prisma.TransactionClient) => {
// Mark file as promoted
await tx.mentorFile.update({
where: { id: params.mentorFileId },