Admin platform audit: fix bugs, harden backend, add auto-refresh, clean dead code
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m23s
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m23s
Phase 1 — Critical bugs: - Fix deliberation participant selection (wire jury group query) - Fix reports "By Round" tab (inline content instead of 404 route) - Fix messages "Sent History" (add message.sent procedure, wire tab) - Add missing fields to competition award form (criteriaText, maxRankedPicks) - Wire LiveControlPanel buttons (cursor, voting, scores) - Fix ResultLockControls empty snapshot (fetch actual data before lock) - Fix SubmissionWindowManager losing fields on edit Phase 2 — Backend fixes: - Remove write-in-query from specialAward.get - Fix award eligibility job overwriting manual shortlist overrides - Fix filtering startJob deleting all prior results (defer cleanup to post-success) - Tighten access control: protectedProcedure → adminProcedure on 8 procedures - Add audit logging to deliberation mutations - Add FINALIST/SEMIFINALIST delete guard on project.delete/bulkDelete Phase 3 — Auto-refresh: - Add refetchInterval to 15+ admin pages/components (10s–30s) - Fix AI job polling: derive speed from job status for all viewers Phase 4 — Dead code cleanup: - Delete unused command-palette, pdf-report, admin-page-transition - Remove dead subItems sidebar code, unused GripVertical import - Replace redundant isGenerating state with mutation.isPending - Add Role column to jury members table - Remove misleading manual mentor assignment stub Phase 5 — UX improvements: - Fix rounds page single-competition assumption (add selector) - Remove raw UUID fallback in deliberation config - Fix programs page "Stage" → "Round" terminology Phase 6 — Backend hardening: - Complete logAudit calls (add prisma, ipAddress, userAgent) - Batch analytics queries (fix N+1 in getCrossRoundComparison, getYearOverYear) - Batch user.bulkCreate writes (assignments, jury memberships, intents) - Remove any casts from deliberation service (typed PrismaClient + TransactionClient) - Fix stale DeliberationStatus enum values blocking build 40 files changed, 1010 insertions(+), 612 deletions(-) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -122,18 +122,19 @@ export default function RoundsPage() {
|
||||
const [competitionEdits, setCompetitionEdits] = useState<Record<string, unknown>>({})
|
||||
const [editingCompId, setEditingCompId] = useState<string | null>(null)
|
||||
const [filterType, setFilterType] = useState<string>('all')
|
||||
const [selectedCompId, setSelectedCompId] = useState<string | null>(null)
|
||||
|
||||
const { data: competitions, isLoading } = trpc.competition.list.useQuery(
|
||||
{ programId: programId! },
|
||||
{ enabled: !!programId }
|
||||
{ enabled: !!programId, refetchInterval: 30_000 }
|
||||
)
|
||||
|
||||
// Use the first (and usually only) competition
|
||||
const comp = competitions?.[0]
|
||||
// Auto-select first competition, or use the user's selection
|
||||
const comp = competitions?.find((c: any) => c.id === selectedCompId) ?? competitions?.[0]
|
||||
|
||||
const { data: compDetail, isLoading: isLoadingDetail } = trpc.competition.getById.useQuery(
|
||||
{ id: comp?.id! },
|
||||
{ enabled: !!comp?.id }
|
||||
{ enabled: !!comp?.id, refetchInterval: 30_000 }
|
||||
)
|
||||
|
||||
const { data: awards } = trpc.specialAward.list.useQuery(
|
||||
@@ -289,6 +290,22 @@ export default function RoundsPage() {
|
||||
return (
|
||||
<TooltipProvider delayDuration={200}>
|
||||
<div className="space-y-5">
|
||||
{/* Competition selector (when multiple exist) */}
|
||||
{competitions && competitions.length > 1 && (
|
||||
<Select value={comp.id} onValueChange={setSelectedCompId}>
|
||||
<SelectTrigger className="w-[280px] mb-4">
|
||||
<SelectValue placeholder="Select competition" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{competitions.map((c: any) => (
|
||||
<SelectItem key={c.id} value={c.id}>
|
||||
{c.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
|
||||
{/* ── Header Bar ──────────────────────────────────────────────── */}
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div className="min-w-0">
|
||||
|
||||
Reference in New Issue
Block a user