Fix AI filtering bugs, add special award shortlist integration
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m20s
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m20s
Part 1 - Bug Fixes: - Fix toProjectWithRelations() stripping file fields needed by AI (detectedLang, textContent, etc.) - Fix parseAIData() reading flat when aiScreeningJson is nested under rule ID - Fix getAIConfidenceScore() with same nesting issue (always returned 0) Part 2 - Special Award Track Integration: - Add shortlistSize to SpecialAward, qualityScore/shortlisted/confirmed fields to AwardEligibility - Add specialAwardId to Round for award-owned rounds - Update AI eligibility service to return qualityScore (0-100) for ranking - Update eligibility job with filteringRoundId scoping and auto-shortlist top N - Add 8 new specialAward router procedures (listForRound, runEligibilityForRound, listShortlist, toggleShortlisted, confirmShortlist, listRounds, createRound, deleteRound) - Create award-shortlist.tsx component with ranked table, shortlist checkboxes, confirm dialog - Add "Special Award Tracks" section to filtering dashboard Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
-- AlterTable: Add shortlistSize to SpecialAward
|
||||
ALTER TABLE "SpecialAward" ADD COLUMN IF NOT EXISTS "shortlistSize" INTEGER NOT NULL DEFAULT 10;
|
||||
|
||||
-- AlterTable: Add qualityScore, shortlisted, confirmedAt, confirmedBy to AwardEligibility
|
||||
ALTER TABLE "AwardEligibility" ADD COLUMN IF NOT EXISTS "qualityScore" DOUBLE PRECISION;
|
||||
ALTER TABLE "AwardEligibility" ADD COLUMN IF NOT EXISTS "shortlisted" BOOLEAN NOT NULL DEFAULT false;
|
||||
ALTER TABLE "AwardEligibility" ADD COLUMN IF NOT EXISTS "confirmedAt" TIMESTAMP(3);
|
||||
ALTER TABLE "AwardEligibility" ADD COLUMN IF NOT EXISTS "confirmedBy" TEXT;
|
||||
|
||||
-- AlterTable: Add specialAwardId to Round
|
||||
ALTER TABLE "Round" ADD COLUMN IF NOT EXISTS "specialAwardId" TEXT;
|
||||
|
||||
-- AddForeignKey: AwardEligibility.confirmedBy -> User.id
|
||||
ALTER TABLE "AwardEligibility" ADD CONSTRAINT "AwardEligibility_confirmedBy_fkey" FOREIGN KEY ("confirmedBy") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey: Round.specialAwardId -> SpecialAward.id
|
||||
ALTER TABLE "Round" ADD CONSTRAINT "Round_specialAwardId_fkey" FOREIGN KEY ("specialAwardId") REFERENCES "SpecialAward"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX IF NOT EXISTS "Round_specialAwardId_idx" ON "Round"("specialAwardId");
|
||||
@@ -378,8 +378,9 @@ model User {
|
||||
filteringOverrides FilteringResult[] @relation("FilteringOverriddenBy")
|
||||
|
||||
// Award overrides
|
||||
awardEligibilityOverrides AwardEligibility[] @relation("AwardEligibilityOverriddenBy")
|
||||
awardWinnerOverrides SpecialAward[] @relation("AwardOverriddenBy")
|
||||
awardEligibilityOverrides AwardEligibility[] @relation("AwardEligibilityOverriddenBy")
|
||||
awardEligibilityConfirms AwardEligibility[] @relation("AwardEligibilityConfirmer")
|
||||
awardWinnerOverrides SpecialAward[] @relation("AwardOverriddenBy")
|
||||
|
||||
// In-app notifications
|
||||
notifications InAppNotification[] @relation("UserNotifications")
|
||||
@@ -1507,6 +1508,7 @@ model SpecialAward {
|
||||
juryGroupId String?
|
||||
eligibilityMode AwardEligibilityMode @default(STAY_IN_MAIN)
|
||||
decisionMode String? // "JURY_VOTE" | "AWARD_MASTER_DECISION" | "ADMIN_DECISION"
|
||||
shortlistSize Int @default(10)
|
||||
|
||||
// Eligibility job tracking
|
||||
eligibilityJobStatus String? // PENDING, PROCESSING, COMPLETED, FAILED
|
||||
@@ -1530,6 +1532,7 @@ model SpecialAward {
|
||||
competition Competition? @relation(fields: [competitionId], references: [id], onDelete: SetNull)
|
||||
evaluationRound Round? @relation(fields: [evaluationRoundId], references: [id], onDelete: SetNull)
|
||||
awardJuryGroup JuryGroup? @relation(fields: [juryGroupId], references: [id], onDelete: SetNull)
|
||||
rounds Round[] @relation("AwardRounds")
|
||||
|
||||
@@index([programId])
|
||||
@@index([status])
|
||||
@@ -1545,11 +1548,17 @@ model AwardEligibility {
|
||||
method EligibilityMethod @default(AUTO)
|
||||
eligible Boolean @default(false)
|
||||
aiReasoningJson Json? @db.JsonB
|
||||
qualityScore Float?
|
||||
shortlisted Boolean @default(false)
|
||||
|
||||
// Admin override
|
||||
overriddenBy String?
|
||||
overriddenAt DateTime?
|
||||
|
||||
// Shortlist confirmation
|
||||
confirmedAt DateTime?
|
||||
confirmedBy String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@ -1557,6 +1566,7 @@ model AwardEligibility {
|
||||
award SpecialAward @relation(fields: [awardId], references: [id], onDelete: Cascade)
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
overriddenByUser User? @relation("AwardEligibilityOverriddenBy", fields: [overriddenBy], references: [id], onDelete: SetNull)
|
||||
confirmer User? @relation("AwardEligibilityConfirmer", fields: [confirmedBy], references: [id], onDelete: SetNull)
|
||||
|
||||
@@unique([awardId, projectId])
|
||||
@@index([awardId])
|
||||
@@ -2118,12 +2128,14 @@ model Round {
|
||||
// Links to other entities
|
||||
juryGroupId String?
|
||||
submissionWindowId String?
|
||||
specialAwardId String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
competition Competition @relation(fields: [competitionId], references: [id], onDelete: Cascade)
|
||||
specialAward SpecialAward? @relation("AwardRounds", fields: [specialAwardId], references: [id], onDelete: SetNull)
|
||||
juryGroup JuryGroup? @relation(fields: [juryGroupId], references: [id], onDelete: SetNull)
|
||||
submissionWindow SubmissionWindow? @relation(fields: [submissionWindowId], references: [id], onDelete: SetNull)
|
||||
projectRoundStates ProjectRoundState[]
|
||||
@@ -2157,6 +2169,7 @@ model Round {
|
||||
@@index([competitionId])
|
||||
@@index([roundType])
|
||||
@@index([status])
|
||||
@@index([specialAwardId])
|
||||
}
|
||||
|
||||
model ProjectRoundState {
|
||||
|
||||
Reference in New Issue
Block a user