Pool, competition & round pages overhaul: deep-link context, inline project management, AI filtering UX, email toggle
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m30s

- Pool page: auto-select program from edition context, URL params for roundId/competitionId deep-linking, unassigned toggle, round badges column
- Competition detail: rich round cards with project counts, dates, jury info, status badges replacing flat list
- Round detail: readiness checklist, embedded assignment dashboard, file requirements in config tab, notifyOnEntry toggle
- ProjectStatesTable: search input, project links, quick-add dialog, pool links with context params
- FilteringDashboard: expandable rows with AI reasoning inline, quick override buttons, search, clickable stats
- Backend: notifyOnEntry in round configJson triggers announcement emails on project assignment via existing email infra

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 08:23:40 +01:00
parent 7f334ed095
commit 845554fdb8
7 changed files with 1197 additions and 496 deletions

View File

@@ -42,15 +42,16 @@ export const programRouter = router({
: undefined,
})
// Return programs with rounds flattened
// Return programs with rounds flattened, preserving competitionId
return programs.map((p) => {
const allRounds = (p as any).competitions?.flatMap((c: any) => c.rounds || []) || []
const allRounds = (p as any).competitions?.flatMap((c: any) =>
(c.rounds || []).map((round: any) => ({ ...round, competitionId: c.id }))
) || []
return {
...p,
// Provide `stages` as alias for backward compatibility
stages: allRounds.map((round: any) => ({
...round,
// Backward-compatible _count shape
_count: {
projects: round._count?.projectRoundStates || 0,
assignments: round._count?.assignments || 0,
@@ -60,6 +61,7 @@ export const programRouter = router({
rounds: allRounds.map((round: any) => ({
id: round.id,
name: round.name,
competitionId: round.competitionId,
status: round.status,
votingEndAt: round.windowCloseAt,
_count: {
@@ -95,8 +97,10 @@ export const programRouter = router({
},
})
// Flatten rounds from all competitions
const allRounds = (program as any).competitions?.flatMap((c: any) => c.rounds || []) || []
// Flatten rounds from all competitions, preserving competitionId
const allRounds = (program as any).competitions?.flatMap((c: any) =>
(c.rounds || []).map((round: any) => ({ ...round, competitionId: c.id }))
) || []
const rounds = allRounds.map((round: any) => ({
...round,
_count: {