AI category-aware evaluation: per-round config, file parsing, shortlist, advance flow
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled

- Per-juror cap mode (HARD/SOFT/NONE) in add-member dialog and members table
- Jury invite flow: create user + add to group + send invitation from dialog
- Per-round config: notifyOnAdvance, aiParseFiles, startupAdvanceCount, conceptAdvanceCount
- Moved notify-on-advance from competition-level to per-round setting
- AI filtering: round-tagged files with newest-first sorting, optional file content extraction
- File content extractor service (pdf-parse for PDF, utf-8 for text files)
- AI shortlist runs independently per category (STARTUP / BUSINESS_CONCEPT)
- generateAIRecommendations tRPC endpoint with per-round config integration
- AI recommendations UI: trigger button, confirmation dialog, per-category results display
- Category-aware advance dialog: select/deselect projects by category with target caps
- STAGE_ACTIVE bug fix in assignment router

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 10:09:52 +01:00
parent 93f4ad4b31
commit 80c9e35971
21 changed files with 1886 additions and 1381 deletions

View File

@@ -1,6 +1,7 @@
'use client'
import Link from 'next/link'
import type { Route } from 'next'
import { trpc } from '@/lib/trpc/client'
import {
Card,
@@ -473,7 +474,7 @@ export function DashboardContent({ editionId, sessionName }: DashboardContentPro
</div>
<div>
<p className="text-sm font-medium">Rounds</p>
<p className="text-xs text-muted-foreground">Manage competition rounds</p>
<p className="text-xs text-muted-foreground">Manage rounds</p>
</div>
</Link>
<Link href="/admin/projects/new" className="group flex items-center gap-3 rounded-xl border border-border/60 p-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md hover:border-emerald-500/30 hover:bg-emerald-500/5">
@@ -513,7 +514,7 @@ export function DashboardContent({ editionId, sessionName }: DashboardContentPro
Rounds
</CardTitle>
<CardDescription>
Competition rounds in {edition.name}
Active rounds in {edition.name}
</CardDescription>
</div>
<Link
@@ -541,8 +542,9 @@ export function DashboardContent({ editionId, sessionName }: DashboardContentPro
) : (
<div className="space-y-3">
{roundsWithEvalStats.map((round: typeof roundsWithEvalStats[number]) => (
<div
<Link
key={round.id}
href={`/admin/rounds/${round.id}` as Route}
className="block"
>
<div className="rounded-lg border p-4 transition-all hover:bg-muted/50 hover:-translate-y-0.5 hover:shadow-md">
@@ -569,7 +571,7 @@ export function DashboardContent({ editionId, sessionName }: DashboardContentPro
<Progress value={round.evalPercent} className="mt-3 h-1.5" gradient />
)}
</div>
</div>
</Link>
))}
</div>
)}