refactor(schema-cascade): rename Project.mentorAssignment → mentorAssignments

Schema dropped @unique on MentorAssignment.projectId in PR8 Task 1 →
back-relation becomes a list. Mechanical rename of Prisma queries and
consumer accessors. Legacy single-mentor callers use [0] with a TODO for
PR8 Task 8 to surface the full list. mentor-workspace.ts is left as Task 5.

- routers (mentor, project, applicant, finalist, round) and smart-assignment
  service: include/where/select keys renamed; `mentorAssignment: null` →
  `mentorAssignments: { none: {} }`; `{ isNot: null }` → `{ some: {} }`.
- UI consumers (mentor + applicant pages): `project.mentorAssignment` →
  `project.mentorAssignments[0]` with TODO markers.
- Tests: `findUnique({ projectId })` → `findFirst({ projectId })` since the
  composite key now requires both projectId+mentorId. MentorFile.create gains
  the new required projectId.
- Workspace endpoints in mentor.ts now guard null mentorAssignmentId until
  Task 5 re-scopes them to project.
- finalist.unconfirm now cascades to ALL active mentor assignments.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt
2026-05-22 16:37:37 +02:00
parent 9152ebb399
commit 66110598a0
11 changed files with 127 additions and 71 deletions

View File

@@ -772,7 +772,8 @@ export const finalistRouter = router({
select: {
id: true,
title: true,
mentorAssignment: {
mentorAssignments: {
where: { droppedAt: null, completionStatus: { not: 'completed' } },
select: {
id: true,
completionStatus: true,
@@ -796,10 +797,12 @@ export const finalistRouter = router({
data: { status: 'SUPERSEDED' },
})
// Cascade: drop active mentor assignment (skip if completed or already dropped)
const ma = confirmation.project.mentorAssignment
// Cascade: drop ALL active mentor assignments (skip dropped/completed
// those were filtered out by the include `where` above). With multi-mentor
// (PR8) we propagate the cascade to every active assignment.
const activeAssignments = confirmation.project.mentorAssignments
let cascadedMentorAssignment = false
if (ma && !ma.droppedAt && ma.completionStatus !== 'completed') {
for (const ma of activeAssignments) {
await ctx.prisma.mentorAssignment.update({
where: { id: ma.id },
data: {
@@ -833,6 +836,7 @@ export const finalistRouter = router({
reason: input.reason,
projectId: confirmation.projectId,
cascadedMentorAssignment,
cascadedAssignmentCount: activeAssignments.length,
},
})
return { ok: true, cascadedMentorAssignment }