Files
MOPC-Portal/scripts/cleanup-test-pollution.ts

102 lines
4.8 KiB
TypeScript
Raw Permalink Normal View History

/**
* One-shot: remove leaked test data from dev DB.
*
* Test runs that crashed before reaching `afterAll` left orphan test users +
* programs. This mirrors `tests/helpers.ts#cleanupTestData` with the same
* reverse-dependency order, applied to all programs whose name matches the
* test patterns.
*
* Run: npx tsx scripts/cleanup-test-pollution.ts
*/
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
const TEST_PROGRAM_PATTERNS = [
'Test Program prog-%',
'getCandidates-%',
'bulk-%',
'source-flag-%',
'mentor-files-%',
'mentor-config-%',
]
async function main() {
const programs = await prisma.program.findMany({
where: {
OR: TEST_PROGRAM_PATTERNS.map((p) => ({ name: { startsWith: p.replace('%', '') } })),
},
select: { id: true, name: true },
})
console.log(`Found ${programs.length} test programs:`)
programs.forEach((p) => console.log(` - ${p.id} ${p.name}`))
for (const program of programs) {
const programId = program.id
console.log(`\nCleaning ${program.name}...`)
// MentorAssignment isn't in cleanupTestData — kill it first
const ma = await prisma.mentorAssignment.deleteMany({
where: { project: { programId } },
})
if (ma.count > 0) console.log(` ${ma.count} MentorAssignment`)
// Mirror tests/helpers.ts#cleanupTestData order
await prisma.cohortProject.deleteMany({ where: { cohort: { round: { competition: { programId } } } } })
await prisma.cohort.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.liveProgressCursor.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.filteringResult.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.filteringRule.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.filteringJob.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.assignmentJob.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.conflictOfInterest.deleteMany({ where: { assignment: { round: { competition: { programId } } } } })
await prisma.evaluation.deleteMany({ where: { assignment: { round: { competition: { programId } } } } })
await prisma.assignment.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.evaluationForm.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.fileRequirement.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.gracePeriod.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.reminderLog.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.evaluationSummary.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.evaluationDiscussion.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.projectRoundState.deleteMany({ where: { round: { competition: { programId } } } })
await prisma.awardEligibility.deleteMany({ where: { award: { program: { id: programId } } } })
await prisma.awardVote.deleteMany({ where: { award: { program: { id: programId } } } })
await prisma.awardJuror.deleteMany({ where: { award: { program: { id: programId } } } })
await prisma.specialAward.deleteMany({ where: { programId } })
await prisma.round.deleteMany({ where: { competition: { programId } } })
await prisma.competition.deleteMany({ where: { programId } })
await prisma.projectStatusHistory.deleteMany({ where: { project: { programId } } })
await prisma.projectFile.deleteMany({ where: { project: { programId } } })
await prisma.projectTag.deleteMany({ where: { project: { programId } } })
await prisma.project.deleteMany({ where: { programId } })
await prisma.program.deleteMany({ where: { id: programId } })
console.log(' cascade complete')
}
// Delete test users (@test.local). Catch any audit-log refs first.
const testUsers = await prisma.user.findMany({
where: { email: { endsWith: '@test.local' } },
select: { id: true },
})
const testUserIds = testUsers.map((u) => u.id)
console.log(`\nDeleting ${testUserIds.length} @test.local users...`)
if (testUserIds.length > 0) {
await prisma.decisionAuditLog.deleteMany({ where: { actorId: { in: testUserIds } } })
await prisma.auditLog.deleteMany({ where: { userId: { in: testUserIds } } })
// Any remaining MentorAssignments referencing these users (e.g., from other tests)
await prisma.mentorAssignment.deleteMany({ where: { mentorId: { in: testUserIds } } })
await prisma.user.deleteMany({ where: { id: { in: testUserIds } } })
}
console.log('\nDone.')
}
main()
.then(() => prisma.$disconnect())
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})