feat(01-01): add RankingSnapshot model + enums to schema.prisma
- Add RankingTriggerType enum (MANUAL, AUTO, RETROACTIVE, QUICK) - Add RankingMode enum (PREVIEW, CONFIRMED, QUICK) - Add RankingSnapshotStatus enum (PENDING, RUNNING, COMPLETED, FAILED) - Add RankingSnapshot model with roundId/triggeredById FKs, criteria/results JSON fields, AI metadata - Add Round.rankingSnapshots back-relation (RoundRankingSnapshots) - Add User.rankingSnapshots back-relation (TriggeredRankingSnapshots) - Create migration 20260227000000_add_ranking_snapshot - Regenerate Prisma client (prisma.rankingSnapshot accessible)
This commit is contained in:
@@ -0,0 +1,45 @@
|
|||||||
|
-- CreateEnum
|
||||||
|
CREATE TYPE "RankingTriggerType" AS ENUM ('MANUAL', 'AUTO', 'RETROACTIVE', 'QUICK');
|
||||||
|
|
||||||
|
-- CreateEnum
|
||||||
|
CREATE TYPE "RankingMode" AS ENUM ('PREVIEW', 'CONFIRMED', 'QUICK');
|
||||||
|
|
||||||
|
-- CreateEnum
|
||||||
|
CREATE TYPE "RankingSnapshotStatus" AS ENUM ('PENDING', 'RUNNING', 'COMPLETED', 'FAILED');
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "RankingSnapshot" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"roundId" TEXT NOT NULL,
|
||||||
|
"triggeredById" TEXT,
|
||||||
|
"triggerType" "RankingTriggerType" NOT NULL DEFAULT 'MANUAL',
|
||||||
|
"criteriaText" TEXT NOT NULL,
|
||||||
|
"parsedRulesJson" JSONB NOT NULL,
|
||||||
|
"startupRankingJson" JSONB,
|
||||||
|
"conceptRankingJson" JSONB,
|
||||||
|
"evaluationDataJson" JSONB,
|
||||||
|
"mode" "RankingMode" NOT NULL DEFAULT 'PREVIEW',
|
||||||
|
"status" "RankingSnapshotStatus" NOT NULL DEFAULT 'COMPLETED',
|
||||||
|
"reordersJson" JSONB,
|
||||||
|
"model" TEXT,
|
||||||
|
"tokensUsed" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "RankingSnapshot_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "RankingSnapshot_roundId_idx" ON "RankingSnapshot"("roundId");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "RankingSnapshot_triggeredById_idx" ON "RankingSnapshot"("triggeredById");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "RankingSnapshot_createdAt_idx" ON "RankingSnapshot"("createdAt");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "RankingSnapshot" ADD CONSTRAINT "RankingSnapshot_roundId_fkey" FOREIGN KEY ("roundId") REFERENCES "Round"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "RankingSnapshot" ADD CONSTRAINT "RankingSnapshot_triggeredById_fkey" FOREIGN KEY ("triggeredById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
@@ -425,6 +425,9 @@ model User {
|
|||||||
submissionPromotions SubmissionPromotionEvent[] @relation("SubmissionPromoter")
|
submissionPromotions SubmissionPromotionEvent[] @relation("SubmissionPromoter")
|
||||||
deliberationReplacements DeliberationParticipant[] @relation("DeliberationReplacement")
|
deliberationReplacements DeliberationParticipant[] @relation("DeliberationReplacement")
|
||||||
|
|
||||||
|
// AI Ranking
|
||||||
|
rankingSnapshots RankingSnapshot[] @relation("TriggeredRankingSnapshots")
|
||||||
|
|
||||||
@@index([role])
|
@@index([role])
|
||||||
@@index([status])
|
@@index([status])
|
||||||
}
|
}
|
||||||
@@ -1405,6 +1408,74 @@ enum AssignmentJobStatus {
|
|||||||
FAILED
|
FAILED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// AI RANKING MODELS
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
enum RankingTriggerType {
|
||||||
|
MANUAL // Admin clicked "Run ranking"
|
||||||
|
AUTO // Auto-triggered by assignment completion
|
||||||
|
RETROACTIVE // Retroactive scan on deployment
|
||||||
|
QUICK // Quick-rank mode (no preview)
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RankingMode {
|
||||||
|
PREVIEW // Parsed rules shown to admin (not yet applied)
|
||||||
|
CONFIRMED // Admin confirmed rules, ranking applied
|
||||||
|
QUICK // Quick-rank: parse + apply without preview
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RankingSnapshotStatus {
|
||||||
|
PENDING
|
||||||
|
RUNNING
|
||||||
|
COMPLETED
|
||||||
|
FAILED
|
||||||
|
}
|
||||||
|
|
||||||
|
// Captures a point-in-time AI ranking run for a round
|
||||||
|
model RankingSnapshot {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
|
||||||
|
roundId String
|
||||||
|
|
||||||
|
// Trigger metadata
|
||||||
|
triggeredById String? // null = auto-triggered
|
||||||
|
triggerType RankingTriggerType @default(MANUAL)
|
||||||
|
|
||||||
|
// Criteria used
|
||||||
|
criteriaText String @db.Text
|
||||||
|
parsedRulesJson Json @db.JsonB
|
||||||
|
|
||||||
|
// Results per category (either can be null/empty if no projects in that category)
|
||||||
|
startupRankingJson Json? @db.JsonB
|
||||||
|
conceptRankingJson Json? @db.JsonB
|
||||||
|
|
||||||
|
// Evaluation data freeze (raw scores at time of ranking)
|
||||||
|
evaluationDataJson Json? @db.JsonB
|
||||||
|
|
||||||
|
// Mode and status
|
||||||
|
mode RankingMode @default(PREVIEW)
|
||||||
|
status RankingSnapshotStatus @default(COMPLETED)
|
||||||
|
|
||||||
|
// Post-drag-and-drop reorders (Phase 2 will populate this)
|
||||||
|
reordersJson Json? @db.JsonB
|
||||||
|
|
||||||
|
// AI metadata
|
||||||
|
model String?
|
||||||
|
tokensUsed Int @default(0)
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
// Relations
|
||||||
|
round Round @relation("RoundRankingSnapshots", fields: [roundId], references: [id], onDelete: Cascade)
|
||||||
|
triggeredBy User? @relation("TriggeredRankingSnapshots", fields: [triggeredById], references: [id], onDelete: SetNull)
|
||||||
|
|
||||||
|
@@index([roundId])
|
||||||
|
@@index([triggeredById])
|
||||||
|
@@index([createdAt])
|
||||||
|
}
|
||||||
|
|
||||||
// Tracks progress of long-running AI tagging jobs
|
// Tracks progress of long-running AI tagging jobs
|
||||||
model TaggingJob {
|
model TaggingJob {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
@@ -2146,6 +2217,7 @@ model Round {
|
|||||||
filteringResults FilteringResult[]
|
filteringResults FilteringResult[]
|
||||||
filteringJobs FilteringJob[]
|
filteringJobs FilteringJob[]
|
||||||
assignmentJobs AssignmentJob[]
|
assignmentJobs AssignmentJob[]
|
||||||
|
rankingSnapshots RankingSnapshot[] @relation("RoundRankingSnapshots")
|
||||||
reminderLogs ReminderLog[]
|
reminderLogs ReminderLog[]
|
||||||
evaluationSummaries EvaluationSummary[]
|
evaluationSummaries EvaluationSummary[]
|
||||||
evaluationDiscussions EvaluationDiscussion[]
|
evaluationDiscussions EvaluationDiscussion[]
|
||||||
|
|||||||
Reference in New Issue
Block a user