refactor: tech debt batch 2 — drop dead models, stale columns, schema cleanup
Schema: - Drop 4 dead models: OverrideAction, NotificationPolicy, AssignmentException, AdvancementRule - Drop 2 dead enums: OverrideReasonCode, AdvancementRuleType - Drop 3 stale columns: Project.roundId, ConflictOfInterest.roundId, Evaluation.version - Remove 3 back-relation fields from User, Assignment, Round Code: - Fix 6 COI queries in assignment.ts + 1 in juror-reassignment.ts (roundId filter → assignment.roundId after column drop) - Remove orphaned Project.roundId write in project.ts createProject - Remove advancementRules include from round.ts getById - Remove AdvancementRule from RoundWithRelations type - Clean up seed.ts (remove advancement rule seeding) - Clean up tests/helpers.ts (remove dead model cleanup) - Add TODO comments on user delete mutations (FK violation risk) Migration: 20260308000000_drop_dead_models_and_stale_columns Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "AdvancementRule" DROP CONSTRAINT "AdvancementRule_roundId_fkey";
|
||||||
|
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "AssignmentException" DROP CONSTRAINT "AssignmentException_approvedById_fkey";
|
||||||
|
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "AssignmentException" DROP CONSTRAINT "AssignmentException_assignmentId_fkey";
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "ConflictOfInterest" DROP COLUMN "roundId";
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Evaluation" DROP COLUMN "version";
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Project" DROP COLUMN "roundId";
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "AdvancementRule";
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "AssignmentException";
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "NotificationPolicy";
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "OverrideAction";
|
||||||
|
|
||||||
|
-- DropEnum
|
||||||
|
DROP TYPE "AdvancementRuleType";
|
||||||
|
|
||||||
|
-- DropEnum
|
||||||
|
DROP TYPE "OverrideReasonCode";
|
||||||
@@ -134,13 +134,6 @@ enum PartnerType {
|
|||||||
OTHER
|
OTHER
|
||||||
}
|
}
|
||||||
|
|
||||||
enum OverrideReasonCode {
|
|
||||||
DATA_CORRECTION
|
|
||||||
POLICY_EXCEPTION
|
|
||||||
JURY_CONFLICT
|
|
||||||
SPONSOR_DECISION
|
|
||||||
ADMIN_DISCRETION
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// COMPETITION / ROUND ENGINE ENUMS
|
// COMPETITION / ROUND ENGINE ENUMS
|
||||||
@@ -179,13 +172,6 @@ enum ProjectRoundStateValue {
|
|||||||
WITHDRAWN
|
WITHDRAWN
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AdvancementRuleType {
|
|
||||||
AUTO_ADVANCE
|
|
||||||
SCORE_THRESHOLD
|
|
||||||
TOP_N
|
|
||||||
ADMIN_SELECTION
|
|
||||||
AI_RECOMMENDED
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CapMode {
|
enum CapMode {
|
||||||
HARD
|
HARD
|
||||||
@@ -431,7 +417,6 @@ model User {
|
|||||||
mentorFileComments MentorFileComment[] @relation("MentorFileCommentAuthor")
|
mentorFileComments MentorFileComment[] @relation("MentorFileCommentAuthor")
|
||||||
resultLocksCreated ResultLock[] @relation("ResultLockCreator")
|
resultLocksCreated ResultLock[] @relation("ResultLockCreator")
|
||||||
resultUnlockEvents ResultUnlockEvent[] @relation("ResultUnlocker")
|
resultUnlockEvents ResultUnlockEvent[] @relation("ResultUnlocker")
|
||||||
assignmentExceptionsApproved AssignmentException[] @relation("AssignmentExceptionApprover")
|
|
||||||
submissionPromotions SubmissionPromotionEvent[] @relation("SubmissionPromoter")
|
submissionPromotions SubmissionPromotionEvent[] @relation("SubmissionPromoter")
|
||||||
deliberationReplacements DeliberationParticipant[] @relation("DeliberationReplacement")
|
deliberationReplacements DeliberationParticipant[] @relation("DeliberationReplacement")
|
||||||
|
|
||||||
@@ -563,7 +548,6 @@ model EvaluationForm {
|
|||||||
model Project {
|
model Project {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
programId String
|
programId String
|
||||||
roundId String?
|
|
||||||
status ProjectStatus @default(SUBMITTED)
|
status ProjectStatus @default(SUBMITTED)
|
||||||
|
|
||||||
// Core fields
|
// Core fields
|
||||||
@@ -763,7 +747,6 @@ model Assignment {
|
|||||||
juryGroup JuryGroup? @relation(fields: [juryGroupId], references: [id], onDelete: SetNull)
|
juryGroup JuryGroup? @relation(fields: [juryGroupId], references: [id], onDelete: SetNull)
|
||||||
evaluation Evaluation?
|
evaluation Evaluation?
|
||||||
conflictOfInterest ConflictOfInterest?
|
conflictOfInterest ConflictOfInterest?
|
||||||
exceptions AssignmentException[]
|
|
||||||
|
|
||||||
@@unique([userId, projectId, roundId])
|
@@unique([userId, projectId, roundId])
|
||||||
@@index([roundId])
|
@@index([roundId])
|
||||||
@@ -790,11 +773,6 @@ model Evaluation {
|
|||||||
binaryDecision Boolean? // Yes/No for semi-finalist
|
binaryDecision Boolean? // Yes/No for semi-finalist
|
||||||
feedbackText String? @db.Text
|
feedbackText String? @db.Text
|
||||||
|
|
||||||
// Versioning (currently unused - evaluations are updated in-place.
|
|
||||||
// TODO: Implement proper versioning by creating new rows on re-submission
|
|
||||||
// if version history is needed for audit purposes)
|
|
||||||
version Int @default(1)
|
|
||||||
|
|
||||||
// Timestamps
|
// Timestamps
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
@@ -1729,7 +1707,6 @@ model ConflictOfInterest {
|
|||||||
assignmentId String @unique
|
assignmentId String @unique
|
||||||
userId String
|
userId String
|
||||||
projectId String
|
projectId String
|
||||||
roundId String? // Legacy — kept for historical data
|
|
||||||
hasConflict Boolean @default(false)
|
hasConflict Boolean @default(false)
|
||||||
conflictType String? // "financial", "personal", "organizational", "other"
|
conflictType String? // "financial", "personal", "organizational", "other"
|
||||||
description String? @db.Text
|
description String? @db.Text
|
||||||
@@ -2111,24 +2088,6 @@ model LiveProgressCursor {
|
|||||||
@@index([sessionId])
|
@@index([sessionId])
|
||||||
}
|
}
|
||||||
|
|
||||||
model OverrideAction {
|
|
||||||
id String @id @default(cuid())
|
|
||||||
entityType String // ProjectRoundState, FilteringResult, AwardEligibility, etc.
|
|
||||||
entityId String
|
|
||||||
previousValue Json? @db.JsonB
|
|
||||||
newValueJson Json @db.JsonB
|
|
||||||
reasonCode OverrideReasonCode
|
|
||||||
reasonText String? @db.Text
|
|
||||||
actorId String
|
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
|
|
||||||
@@index([entityType, entityId])
|
|
||||||
@@index([actorId])
|
|
||||||
@@index([reasonCode])
|
|
||||||
@@index([createdAt])
|
|
||||||
}
|
|
||||||
|
|
||||||
model DecisionAuditLog {
|
model DecisionAuditLog {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
eventType String // stage.transitioned, routing.executed, filtering.completed, etc.
|
eventType String // stage.transitioned, routing.executed, filtering.completed, etc.
|
||||||
@@ -2146,21 +2105,6 @@ model DecisionAuditLog {
|
|||||||
@@index([createdAt])
|
@@index([createdAt])
|
||||||
}
|
}
|
||||||
|
|
||||||
model NotificationPolicy {
|
|
||||||
id String @id @default(cuid())
|
|
||||||
eventType String @unique // stage.transitioned, filtering.completed, etc.
|
|
||||||
channel String @default("EMAIL") // EMAIL, IN_APP, BOTH, NONE
|
|
||||||
templateId String? // Optional reference to MessageTemplate
|
|
||||||
isActive Boolean @default(true)
|
|
||||||
configJson Json? @db.JsonB // Additional config (delay, batch, etc.)
|
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @updatedAt
|
|
||||||
|
|
||||||
@@index([eventType])
|
|
||||||
@@index([isActive])
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// COMPETITION / ROUND ENGINE MODELS (NEW — coexists with Pipeline/Track/Stage)
|
// COMPETITION / ROUND ENGINE MODELS (NEW — coexists with Pipeline/Track/Stage)
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -2236,7 +2180,6 @@ model Round {
|
|||||||
juryGroup JuryGroup? @relation(fields: [juryGroupId], references: [id], onDelete: SetNull)
|
juryGroup JuryGroup? @relation(fields: [juryGroupId], references: [id], onDelete: SetNull)
|
||||||
submissionWindow SubmissionWindow? @relation(fields: [submissionWindowId], references: [id], onDelete: SetNull)
|
submissionWindow SubmissionWindow? @relation(fields: [submissionWindowId], references: [id], onDelete: SetNull)
|
||||||
projectRoundStates ProjectRoundState[]
|
projectRoundStates ProjectRoundState[]
|
||||||
advancementRules AdvancementRule[]
|
|
||||||
visibleSubmissionWindows RoundSubmissionVisibility[]
|
visibleSubmissionWindows RoundSubmissionVisibility[]
|
||||||
assignmentIntents AssignmentIntent[]
|
assignmentIntents AssignmentIntent[]
|
||||||
deliberationSessions DeliberationSession[]
|
deliberationSessions DeliberationSession[]
|
||||||
@@ -2295,24 +2238,6 @@ model ProjectRoundState {
|
|||||||
@@index([roundId, state])
|
@@index([roundId, state])
|
||||||
}
|
}
|
||||||
|
|
||||||
model AdvancementRule {
|
|
||||||
id String @id @default(cuid())
|
|
||||||
roundId String
|
|
||||||
targetRoundId String?
|
|
||||||
ruleType AdvancementRuleType
|
|
||||||
configJson Json @db.JsonB
|
|
||||||
isDefault Boolean @default(true)
|
|
||||||
sortOrder Int @default(0)
|
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
|
|
||||||
// Relations
|
|
||||||
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
||||||
|
|
||||||
@@unique([roundId, sortOrder])
|
|
||||||
@@index([roundId])
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// JURY GROUP MODELS (NEW)
|
// JURY GROUP MODELS (NEW)
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -2489,22 +2414,6 @@ model AssignmentIntent {
|
|||||||
@@index([status])
|
@@index([status])
|
||||||
}
|
}
|
||||||
|
|
||||||
model AssignmentException {
|
|
||||||
id String @id @default(cuid())
|
|
||||||
assignmentId String
|
|
||||||
reason String @db.Text
|
|
||||||
overCapBy Int
|
|
||||||
approvedById String
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
|
|
||||||
// Relations
|
|
||||||
assignment Assignment @relation(fields: [assignmentId], references: [id], onDelete: Cascade)
|
|
||||||
approvedBy User @relation("AssignmentExceptionApprover", fields: [approvedById], references: [id])
|
|
||||||
|
|
||||||
@@index([assignmentId])
|
|
||||||
@@index([approvedById])
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// MENTORING WORKSPACE MODELS (NEW)
|
// MENTORING WORKSPACE MODELS (NEW)
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import {
|
|||||||
RoundStatus,
|
RoundStatus,
|
||||||
CapMode,
|
CapMode,
|
||||||
JuryGroupMemberRole,
|
JuryGroupMemberRole,
|
||||||
AdvancementRuleType,
|
|
||||||
} from '@prisma/client'
|
} from '@prisma/client'
|
||||||
import bcrypt from 'bcryptjs'
|
import bcrypt from 'bcryptjs'
|
||||||
// Inline default configs so seed has ZERO dependency on src/ (not available in Docker prod image)
|
// Inline default configs so seed has ZERO dependency on src/ (not available in Docker prod image)
|
||||||
@@ -858,24 +857,6 @@ async function main() {
|
|||||||
}
|
}
|
||||||
console.log(` ✓ ${rounds.length} rounds created (R1-R8)`)
|
console.log(` ✓ ${rounds.length} rounds created (R1-R8)`)
|
||||||
|
|
||||||
// --- Advancement Rules (auto-advance between rounds) ---
|
|
||||||
for (let i = 0; i < rounds.length - 1; i++) {
|
|
||||||
await prisma.advancementRule.upsert({
|
|
||||||
where: {
|
|
||||||
roundId_sortOrder: { roundId: rounds[i].id, sortOrder: 0 },
|
|
||||||
},
|
|
||||||
update: {},
|
|
||||||
create: {
|
|
||||||
roundId: rounds[i].id,
|
|
||||||
ruleType: AdvancementRuleType.AUTO_ADVANCE,
|
|
||||||
sortOrder: 0,
|
|
||||||
targetRoundId: rounds[i + 1].id,
|
|
||||||
configJson: {},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
console.log(` ✓ ${rounds.length - 1} advancement rules created`)
|
|
||||||
|
|
||||||
// --- Assign all projects to intake round (COMPLETED, since intake is closed) ---
|
// --- Assign all projects to intake round (COMPLETED, since intake is closed) ---
|
||||||
const intakeRound = rounds[0]
|
const intakeRound = rounds[0]
|
||||||
const allProjects = await prisma.project.findMany({
|
const allProjects = await prisma.project.findMany({
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ async function runAIAssignmentJob(jobId: string, roundId: string, userId: string
|
|||||||
// Query COI records for this round to exclude conflicted juror-project pairs
|
// Query COI records for this round to exclude conflicted juror-project pairs
|
||||||
const coiRecords = await prisma.conflictOfInterest.findMany({
|
const coiRecords = await prisma.conflictOfInterest.findMany({
|
||||||
where: {
|
where: {
|
||||||
roundId,
|
assignment: { roundId },
|
||||||
hasConflict: true,
|
hasConflict: true,
|
||||||
},
|
},
|
||||||
select: { userId: true, projectId: true },
|
select: { userId: true, projectId: true },
|
||||||
@@ -1665,7 +1665,7 @@ export const assignmentRouter = router({
|
|||||||
for (const a of existingAssignments) currentLoads.set(a.userId, (currentLoads.get(a.userId) ?? 0) + 1)
|
for (const a of existingAssignments) currentLoads.set(a.userId, (currentLoads.get(a.userId) ?? 0) + 1)
|
||||||
|
|
||||||
const coiRecords = await ctx.prisma.conflictOfInterest.findMany({
|
const coiRecords = await ctx.prisma.conflictOfInterest.findMany({
|
||||||
where: { roundId: input.roundId, hasConflict: true, userId: { in: candidateIds } },
|
where: { assignment: { roundId: input.roundId }, hasConflict: true, userId: { in: candidateIds } },
|
||||||
select: { userId: true, projectId: true },
|
select: { userId: true, projectId: true },
|
||||||
})
|
})
|
||||||
const coiPairs = new Set(coiRecords.map((c) => `${c.userId}:${c.projectId}`))
|
const coiPairs = new Set(coiRecords.map((c) => `${c.userId}:${c.projectId}`))
|
||||||
@@ -1911,7 +1911,7 @@ export const assignmentRouter = router({
|
|||||||
|
|
||||||
const coiRecords = await ctx.prisma.conflictOfInterest.findMany({
|
const coiRecords = await ctx.prisma.conflictOfInterest.findMany({
|
||||||
where: {
|
where: {
|
||||||
roundId: input.roundId,
|
assignment: { roundId: input.roundId },
|
||||||
hasConflict: true,
|
hasConflict: true,
|
||||||
userId: { in: candidateIds },
|
userId: { in: candidateIds },
|
||||||
},
|
},
|
||||||
@@ -2026,7 +2026,7 @@ export const assignmentRouter = router({
|
|||||||
|
|
||||||
const coiRecords = await ctx.prisma.conflictOfInterest.findMany({
|
const coiRecords = await ctx.prisma.conflictOfInterest.findMany({
|
||||||
where: {
|
where: {
|
||||||
roundId: input.roundId,
|
assignment: { roundId: input.roundId },
|
||||||
hasConflict: true,
|
hasConflict: true,
|
||||||
userId: { in: destinationIds },
|
userId: { in: destinationIds },
|
||||||
},
|
},
|
||||||
@@ -2367,7 +2367,7 @@ export const assignmentRouter = router({
|
|||||||
|
|
||||||
const coiRecords = await ctx.prisma.conflictOfInterest.findMany({
|
const coiRecords = await ctx.prisma.conflictOfInterest.findMany({
|
||||||
where: {
|
where: {
|
||||||
roundId: input.roundId,
|
assignment: { roundId: input.roundId },
|
||||||
hasConflict: true,
|
hasConflict: true,
|
||||||
userId: { in: candidateIds },
|
userId: { in: candidateIds },
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -638,10 +638,6 @@ export const projectRouter = router({
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (input.roundId) {
|
if (input.roundId) {
|
||||||
await tx.project.update({
|
|
||||||
where: { id: created.id },
|
|
||||||
data: { roundId: input.roundId },
|
|
||||||
})
|
|
||||||
await tx.projectRoundState.create({
|
await tx.projectRoundState.create({
|
||||||
data: {
|
data: {
|
||||||
projectId: created.id,
|
projectId: created.id,
|
||||||
|
|||||||
@@ -120,7 +120,6 @@ export const roundRouter = router({
|
|||||||
submissionWindow: {
|
submissionWindow: {
|
||||||
include: { fileRequirements: true },
|
include: { fileRequirements: true },
|
||||||
},
|
},
|
||||||
advancementRules: { orderBy: { sortOrder: 'asc' } },
|
|
||||||
visibleSubmissionWindows: {
|
visibleSubmissionWindows: {
|
||||||
include: { submissionWindow: true },
|
include: { submissionWindow: true },
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -206,7 +206,10 @@ export const userRouter = router({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete user
|
// TODO: This delete will fail with a FK violation for any user with activity
|
||||||
|
// (COI declarations, mentor assignments, messages, evaluations, etc.).
|
||||||
|
// A proper purge flow with pre-deletion cleanup or soft-delete is needed
|
||||||
|
// before hard-delete can work reliably for active users.
|
||||||
await ctx.prisma.user.delete({
|
await ctx.prisma.user.delete({
|
||||||
where: { id: ctx.user.id },
|
where: { id: ctx.user.id },
|
||||||
})
|
})
|
||||||
@@ -657,6 +660,10 @@ export const userRouter = router({
|
|||||||
select: { email: true },
|
select: { email: true },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// TODO: This delete will fail with a FK violation for any user with activity
|
||||||
|
// (COI declarations, mentor assignments, messages, evaluations, etc.).
|
||||||
|
// A proper purge flow with pre-deletion cleanup or soft-delete is needed
|
||||||
|
// before hard-delete can work reliably for active users.
|
||||||
const user = await ctx.prisma.user.delete({
|
const user = await ctx.prisma.user.delete({
|
||||||
where: { id: input.id },
|
where: { id: input.id },
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -357,7 +357,7 @@ export async function reassignDroppedJurorAssignments(params: {
|
|||||||
|
|
||||||
const coiRecords = await prisma.conflictOfInterest.findMany({
|
const coiRecords = await prisma.conflictOfInterest.findMany({
|
||||||
where: {
|
where: {
|
||||||
roundId: params.roundId,
|
assignment: { roundId: params.roundId },
|
||||||
hasConflict: true,
|
hasConflict: true,
|
||||||
userId: { in: candidateIds },
|
userId: { in: candidateIds },
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import type {
|
|||||||
JuryGroupMember,
|
JuryGroupMember,
|
||||||
SubmissionWindow,
|
SubmissionWindow,
|
||||||
SubmissionFileRequirement,
|
SubmissionFileRequirement,
|
||||||
AdvancementRule,
|
|
||||||
RoundSubmissionVisibility,
|
RoundSubmissionVisibility,
|
||||||
ProjectRoundState,
|
ProjectRoundState,
|
||||||
DeliberationSession,
|
DeliberationSession,
|
||||||
@@ -36,7 +35,6 @@ export type RoundSummary = Pick<
|
|||||||
export type RoundWithRelations = Round & {
|
export type RoundWithRelations = Round & {
|
||||||
juryGroup: (JuryGroup & { members: JuryGroupMember[] }) | null
|
juryGroup: (JuryGroup & { members: JuryGroupMember[] }) | null
|
||||||
submissionWindow: (SubmissionWindow & { fileRequirements: SubmissionFileRequirement[] }) | null
|
submissionWindow: (SubmissionWindow & { fileRequirements: SubmissionFileRequirement[] }) | null
|
||||||
advancementRules: AdvancementRule[]
|
|
||||||
visibleSubmissionWindows: (RoundSubmissionVisibility & { submissionWindow: SubmissionWindow })[]
|
visibleSubmissionWindows: (RoundSubmissionVisibility & { submissionWindow: SubmissionWindow })[]
|
||||||
_count?: { projectRoundStates: number; assignments: number }
|
_count?: { projectRoundStates: number; assignments: number }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -329,7 +329,6 @@ export async function cleanupTestData(programId: string, userIds: string[] = [])
|
|||||||
// Delete in reverse dependency order — scoped by programId or userIds
|
// Delete in reverse dependency order — scoped by programId or userIds
|
||||||
if (userIds.length > 0) {
|
if (userIds.length > 0) {
|
||||||
await prisma.decisionAuditLog.deleteMany({ where: { actorId: { in: userIds } } })
|
await prisma.decisionAuditLog.deleteMany({ where: { actorId: { in: userIds } } })
|
||||||
await prisma.overrideAction.deleteMany({ where: { actorId: { in: userIds } } })
|
|
||||||
await prisma.auditLog.deleteMany({ where: { userId: { in: userIds } } })
|
await prisma.auditLog.deleteMany({ where: { userId: { in: userIds } } })
|
||||||
}
|
}
|
||||||
// Competition/Round cascade cleanup
|
// Competition/Round cascade cleanup
|
||||||
@@ -350,7 +349,6 @@ export async function cleanupTestData(programId: string, userIds: string[] = [])
|
|||||||
await prisma.evaluationSummary.deleteMany({ where: { round: { competition: { programId } } } })
|
await prisma.evaluationSummary.deleteMany({ where: { round: { competition: { programId } } } })
|
||||||
await prisma.evaluationDiscussion.deleteMany({ where: { round: { competition: { programId } } } })
|
await prisma.evaluationDiscussion.deleteMany({ where: { round: { competition: { programId } } } })
|
||||||
await prisma.projectRoundState.deleteMany({ where: { round: { competition: { programId } } } })
|
await prisma.projectRoundState.deleteMany({ where: { round: { competition: { programId } } } })
|
||||||
await prisma.advancementRule.deleteMany({ where: { round: { competition: { programId } } } })
|
|
||||||
await prisma.awardEligibility.deleteMany({ where: { award: { program: { id: programId } } } })
|
await prisma.awardEligibility.deleteMany({ where: { award: { program: { id: programId } } } })
|
||||||
await prisma.awardVote.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.awardJuror.deleteMany({ where: { award: { program: { id: programId } } } })
|
||||||
|
|||||||
Reference in New Issue
Block a user