feat: per-category evaluation criteria (startup vs business concept)
Add ability to define completely different evaluation criteria for each competition category. Admins toggle "Separate Criteria per Category" in round config, then configure criteria independently via tabbed editor. - Schema: add nullable `category` to EvaluationForm with updated constraints - Config: add `perCategoryCriteria` boolean to EvaluationConfigSchema - Helper: new `findActiveForm()` with category-aware resolution + fallback - Backend: getForm, upsertForm, getStageForm, startStage all category-aware - AI services: use project category for form lookup in summaries + ranking - Export/ranking: merge criteria from all active forms for cross-category reports - Admin UI: toggle switch + tabbed criteria editor with per-category builders - Jury UI: auto-selects correct form based on project category (invisible to juror) - Fully backwards compatible: toggle defaults OFF, existing forms unchanged Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
-- AlterTable: add nullable category column to EvaluationForm
|
||||
ALTER TABLE "EvaluationForm" ADD COLUMN "category" "CompetitionCategory";
|
||||
|
||||
-- Drop old unique constraint
|
||||
ALTER TABLE "EvaluationForm" DROP CONSTRAINT "EvaluationForm_roundId_version_key";
|
||||
|
||||
-- Add new unique constraint including category
|
||||
ALTER TABLE "EvaluationForm" ADD CONSTRAINT "EvaluationForm_roundId_version_category_key" UNIQUE ("roundId", "version", "category");
|
||||
|
||||
-- Partial unique index: prevent duplicate shared forms at the same version
|
||||
-- (PostgreSQL treats NULLs as distinct in unique constraints, so we need this)
|
||||
CREATE UNIQUE INDEX "EvaluationForm_roundId_version_null_category"
|
||||
ON "EvaluationForm" ("roundId", "version") WHERE "category" IS NULL;
|
||||
|
||||
-- Compound index for category-aware active form lookups
|
||||
CREATE INDEX "EvaluationForm_roundId_isActive_category_idx"
|
||||
ON "EvaluationForm" ("roundId", "isActive", "category");
|
||||
@@ -519,9 +519,10 @@ model WizardTemplate {
|
||||
// =============================================================================
|
||||
|
||||
model EvaluationForm {
|
||||
id String @id @default(cuid())
|
||||
roundId String
|
||||
version Int @default(1)
|
||||
id String @id @default(cuid())
|
||||
roundId String
|
||||
version Int @default(1)
|
||||
category CompetitionCategory? // null=shared form, STARTUP or BUSINESS_CONCEPT=category-specific
|
||||
|
||||
// Form configuration
|
||||
// criteriaJson: Array of { id, label, description, scale, weight, required }
|
||||
@@ -537,8 +538,9 @@ model EvaluationForm {
|
||||
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
||||
evaluations Evaluation[]
|
||||
|
||||
@@unique([roundId, version])
|
||||
@@unique([roundId, version, category])
|
||||
@@index([roundId, isActive])
|
||||
@@index([roundId, isActive, category])
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user