fix(mentor): restore Add Project on mentoring rounds + gate mentor assignment
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m15s
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m15s
Three related bugs around the mentoring-round Projects tab: 1. Add Project to Round was unreachable on MENTORING rounds — the table swap in the prior commit lost the button. Export AddProjectDialog from project-states-table and render it inside MentoringProjectsTable with an "Add" button in the filter row and a CTA in the empty state. 2. The "Assign Projects" quick action on the round overview linked to the global pool with an opaque filter; on MENTORING rounds it now switches to the Projects tab where the new Add Project button + auto-fill + per-team picker all live. Non-mentoring rounds keep the old behavior. 3. mentor.assign and mentor.bulkAssign now refuse projects that aren't enrolled in any MENTORING round (any status). The single-assign throws BAD_REQUEST with a guidance message; the bulk path filters them out and reports ineligibleProjectCount in the result so the UI can warn the admin instead of silently skipping. Tests: the multi-mentor-assignment suite now sets up a MENTORING round + ProjectRoundState for each project it tests against, matching the new gate.
This commit is contained in:
@@ -42,6 +42,37 @@ async function createUserWithRoles(
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* mentor.assign and mentor.bulkAssign now require the project to be enrolled
|
||||
* in some MENTORING round. This helper sets up the minimum: one competition
|
||||
* + one MENTORING round + one ProjectRoundState linking the project.
|
||||
*/
|
||||
async function attachToMentoringRound(programId: string, projectId: string) {
|
||||
const compSlug = `comp-${uid()}`
|
||||
const competition = await prisma.competition.create({
|
||||
data: {
|
||||
name: `Comp ${compSlug}`,
|
||||
slug: compSlug,
|
||||
programId,
|
||||
status: 'ACTIVE',
|
||||
},
|
||||
})
|
||||
const round = await prisma.round.create({
|
||||
data: {
|
||||
name: `Mentoring ${uid()}`,
|
||||
slug: `mentoring-${uid()}`,
|
||||
roundType: 'MENTORING',
|
||||
sortOrder: 1,
|
||||
status: 'ROUND_ACTIVE',
|
||||
competitionId: competition.id,
|
||||
},
|
||||
})
|
||||
await prisma.projectRoundState.create({
|
||||
data: { roundId: round.id, projectId },
|
||||
})
|
||||
return { competitionId: competition.id, roundId: round.id }
|
||||
}
|
||||
|
||||
describe('mentor.assign — stacking + per-team email idempotency', () => {
|
||||
const programIds: string[] = []
|
||||
const userIds: string[] = []
|
||||
@@ -62,6 +93,7 @@ describe('mentor.assign — stacking + per-team email idempotency', () => {
|
||||
const program = await createTestProgram({ name: `assign-stack-${uid()}` })
|
||||
programIds.push(program.id)
|
||||
const project = await createTestProject(program.id, { title: 'Stacking Project' })
|
||||
await attachToMentoringRound(program.id, project.id)
|
||||
|
||||
const m1 = await createUserWithRoles('MENTOR', ['MENTOR'], { name: 'M1' })
|
||||
const m2 = await createUserWithRoles('MENTOR', ['MENTOR'], { name: 'M2' })
|
||||
@@ -93,6 +125,7 @@ describe('mentor.assign — stacking + per-team email idempotency', () => {
|
||||
const program = await createTestProgram({ name: `assign-dup-${uid()}` })
|
||||
programIds.push(program.id)
|
||||
const project = await createTestProject(program.id, { title: 'Dup Project' })
|
||||
await attachToMentoringRound(program.id, project.id)
|
||||
const mentor = await createUserWithRoles('MENTOR', ['MENTOR'])
|
||||
userIds.push(mentor.id)
|
||||
|
||||
@@ -114,7 +147,9 @@ describe('mentor.assign — stacking + per-team email idempotency', () => {
|
||||
const program = await createTestProgram({ name: `assign-email-${uid()}` })
|
||||
programIds.push(program.id)
|
||||
const project1 = await createTestProject(program.id, { title: 'Project Alpha' })
|
||||
await attachToMentoringRound(program.id, project1.id)
|
||||
const project2 = await createTestProject(program.id, { title: 'Project Beta' })
|
||||
await attachToMentoringRound(program.id, project2.id)
|
||||
const mentor = await createUserWithRoles('MENTOR', ['MENTOR'])
|
||||
userIds.push(mentor.id)
|
||||
|
||||
@@ -144,6 +179,7 @@ describe('mentor.assign — stacking + per-team email idempotency', () => {
|
||||
const program = await createTestProgram({ name: `assign-comentor-${uid()}` })
|
||||
programIds.push(program.id)
|
||||
const project = await createTestProject(program.id, { title: 'Co-mentor Project' })
|
||||
await attachToMentoringRound(program.id, project.id)
|
||||
const m1 = await createUserWithRoles('MENTOR', ['MENTOR'], { name: 'Co-1' })
|
||||
const m2 = await createUserWithRoles('MENTOR', ['MENTOR'], { name: 'Co-2' })
|
||||
userIds.push(m1.id, m2.id)
|
||||
@@ -169,6 +205,7 @@ describe('mentor.assign — stacking + per-team email idempotency', () => {
|
||||
const program = await createTestProgram({ name: `assign-redrop-${uid()}` })
|
||||
programIds.push(program.id)
|
||||
const project = await createTestProject(program.id, { title: 'Re-assign Project' })
|
||||
await attachToMentoringRound(program.id, project.id)
|
||||
const mentor = await createUserWithRoles('MENTOR', ['MENTOR'])
|
||||
userIds.push(mentor.id)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user