Commit Graph

224 Commits

Author SHA1 Message Date
78334676d0 fix: avatar/logo display diagnostics and upload error handling
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m31s
Add error logging to silent catch blocks in avatar/logo URL generation,
show user avatar on admin member detail page, and surface specific error
messages for upload failures (CORS/network issues) instead of generic errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 02:11:16 +01:00
875c2e8f48 fix: security hardening — block self-registration, SSE auth, audit logging fixes
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
Security fixes:
- Block self-registration via magic link (PrismaAdapter createUser throws)
- Magic links only sent to existing ACTIVE users (prevents enumeration)
- signIn callback rejects non-existent users (defense-in-depth)
- Change schema default role from JURY_MEMBER to APPLICANT
- Add authentication to live-voting SSE stream endpoint
- Fix false FILE_OPENED/FILE_DOWNLOADED audit events on page load
  (remove purpose from eagerly pre-fetched URL queries)

Bug fixes:
- Fix impersonation skeleton screen on applicant dashboard
- Fix onboarding redirect loop in auth layout

Observer dashboard redesign (Steps 1-6):
- Clickable round pipeline with selected round highlighting
- Round-type-specific dashboard panels (intake, filtering, evaluation,
  submission, mentoring, live final, deliberation)
- Enhanced activity feed with server-side humanization
- Previous round comparison section
- New backend queries for round-specific analytics

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 20:18:50 +01:00
13f125af28 feat: error audit middleware, impersonation attribution, account lockout logging
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m13s
- Add withErrorAudit middleware tracking FORBIDDEN/UNAUTHORIZED/NOT_FOUND per user
- Fix impersonation attribution: log real admin ID, prefix IMPERSONATED_ on actions
- Add ACCOUNT_LOCKED audit events on login lockout (distinct from LOGIN_FAILED)
- Audit export of assignments and audit logs (meta-audit gap)
- Update audit page UI with new security event types and colors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:28:56 +01:00
c8c26beed2 feat: granular file access audit logging (viewed/opened/downloaded)
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
Replace single FILE_DOWNLOADED action with three granular actions:
- FILE_VIEWED: inline preview loaded in the UI
- FILE_OPENED: file opened in a new browser tab
- FILE_DOWNLOADED: explicit download button clicked

Add 'purpose' field to getDownloadUrl input (preview/open/download).
All client callers updated to pass the appropriate purpose.
Audit page updated with new filter options and color mappings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:18:28 +01:00
79ac60dc1e feat: automatic mutation audit logging for all non-super-admin users
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
Implement withMutationAudit middleware in tRPC that automatically logs
every successful mutation for non-SUPER_ADMIN users. Captures procedure
path, sanitized input (passwords/tokens redacted), user role, IP, and
user agent. Applied to all procedure types except superAdminProcedure.

- Input sanitization: strips sensitive fields, truncates long strings
  (500 chars), limits array size (20 items), caps nesting depth (4)
- Entity ID auto-extraction from common input patterns (id, userId,
  projectId, roundId, etc.)
- Action names derived from procedure path (e.g., evaluation.submit
  becomes EVALUATION_SUBMIT)
- Audit page updated with new action types and entity types for
  filtering auto-generated entries
- Failures silently caught — audit logging never breaks operations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:04:52 +01:00
6c52e519e5 feat: impersonation system, semi-finalist detail page, tRPC resilience
- Add super-admin impersonation: "Login As" from user list, red banner
  with "Return to Admin", audit logged start/end, nested impersonation
  blocked, onboarding gate skipped during impersonation
- Fix semi-finalist stats: check latest terminal state (not any PASSED),
  use passwordHash OR status=ACTIVE for activation check
- Add /admin/semi-finalists detail page with search, category/status filters
- Add account_reminder_days setting to notifications tab
- Add tRPC resilience: retry on 503/HTML responses, custom fetch detects
  nginx error pages, exponential backoff (2s/4s/8s)
- Reduce dashboard polling intervals (60s stats, 30s activity, 120s semi)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:55:44 +01:00
b1a994a9d6 fix: enforce onboarding gate for applicants and observers
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m37s
Applicants could bypass onboarding and land directly on the dashboard.
Added onboardingCompletedAt check + redirect to /onboarding in both
the applicant and observer layouts (jury/mentor already had this gate).
Also removed premature status ACTIVE on magic-link first login — now
only completeOnboarding sets ACTIVE.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:00:19 +01:00
43e21c6c6e feat: semi-finalist tracker dashboard, account reminders, search + UX fixes
- Add getSemiFinalistStats query with per-category/per-award breakdown
- Add sendAccountReminders mutation with invite token generation and dedup
- Add SemiFinalistTracker dashboard widget with progress bars and remind buttons
- Add ACCOUNT_REMINDER email template
- Extend project search to match team member name/email (7 locations)
- Fix Passed count deduplication: count distinct projects, not round-state rows
- Fix role switcher: visible pills above user section, auto-refresh session on mount

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 15:41:03 +01:00
267d26581d feat: resolve project logo URLs server-side, show logos in admin + observer
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m30s
Add attachProjectLogoUrls utility mirroring avatar URL pattern. Pipe
project.list and analytics.getAllProjects through logo URL resolver so
ProjectLogo components receive presigned URLs. Add logos to observer
projects table and mobile cards.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 13:29:54 +01:00
a39e27f6ff fix: applicant portal — document uploads, round filtering, auth hardening
Fix round-specific document uploads (submittedAt no longer blocks uploads),
add view/download buttons for existing files, enforce active-round-only for
uploads/deletes. Harden auth layout and set-password page. Filter applicant
portal rounds by award track membership.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 13:29:39 +01:00
1103d42439 feat: admin UX improvements — notify buttons, eval config, round finalization
Custom body support for advancement/rejection notification emails, evaluation
config toggle fix, user actions improvements, round finalization with reorder
support, project detail page enhancements, award pool duplicate prevention.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 13:29:22 +01:00
84d90e1978 fix: soften award notification email tone from "selected" to "under consideration"
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m32s
The email was implying projects had won the award. Updated banner, subject,
and body copy to clarify they are being considered, not awarded.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:04:28 +01:00
daf50831f1 feat: award round reordering, assign-to-first-round, and applicant timeline for award tracks
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m22s
- Add drag-and-drop round reordering on award detail Rounds tab (dnd-kit)
- Replace "Open Voting" with "Assign to First Round" for SEPARATE_POOL awards
- Add reorderAwardRounds mutation (two-phase transaction for unique constraint)
- Add assignToFirstRound mutation (re-runnable, moves/creates ProjectRoundState)
- Extend applicant timeline to show award-specific rounds for SEPARATE_POOL projects
- Hide irrelevant main competition rounds when project is in award track
- Prefix award round labels with award name in timeline

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 23:42:21 +01:00
924f8071e1 feat: add email preview to award notification and finalization tab
- Award "Notify Pool" dialog now uses EmailPreviewDialog with live preview
- Button shows eligible project count: "Notify Pool (38)"
- Finalization tab email section has "Preview" buttons for both
  advancement and rejection messages
- EmailPreviewDialog supports previewOnly mode (close button, no send)
- Backend: previewAwardSelectionEmail, previewFinalizationAdvancementEmail,
  previewFinalizationRejectionEmail queries

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 22:57:52 +01:00
f79a6d1341 fix: project edit status dropdown empty for projects with blank status
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m35s
Use || instead of ?? so empty string '' falls back to 'SUBMITTED'.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 22:30:49 +01:00
050836d522 feat: finalization tab respects ranking overrides, grouped by category
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m2s
- processRoundClose now applies reordersJson drag-reorder overrides
  when building the evaluation pass set (was ignoring admin reorders)
- Finalization tab groups proposed outcomes by category (Startup/Concept)
  with per-group pass/reject/total counts
- Added category filter dropdown alongside the existing outcome filter
- Removed legacy "Advance Top N" button and dialog from ranking page
  (replaced by the finalization workflow)
- Fix project edit status defaultValue showing empty placeholder

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 22:10:04 +01:00
cfee3bc8a9 feat: round finalization with ranking-based outcomes + award pool notifications
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m0s
- processRoundClose EVALUATION uses ranking scores + advanceMode config
  (threshold vs count) to auto-set proposedOutcome instead of defaulting all to PASSED
- Advancement emails generate invite tokens for passwordless users with
  "Create Your Account" CTA; rejection emails have no link
- Finalization UI shows account stats (invite vs dashboard link counts)
- Fixed getFinalizationSummary ranking query (was using non-existent rankingsJson)
- New award pool notification system: getAwardSelectionNotificationTemplate email,
  notifyEligibleProjects mutation with invite token generation,
  "Notify Pool" button on award detail page with custom message dialog

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 19:14:41 +01:00
7735f3ecdf fix: hide Advancement Targets for non-scoring round types
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m24s
Submission, Intake, and Mentoring rounds don't use score-based
advancement (Fixed Count / Score Threshold). The section is now
only shown for Evaluation and Filtering rounds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 09:47:20 +01:00
0285622fe1 fix: tooltip no longer covers status dropdown menu items
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
The outer Tooltip on the status badge was overlaying the DropdownMenu
content, hiding "Reopen Round". Now the tooltip is forced closed
whenever the dropdown is open.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 09:43:28 +01:00
2df9c54de2 fix: backfill binaryDecision, fix boolean criterion lookup, add assign buttons
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m9s
- Backfilled 166 evaluations' binaryDecision from criterionScoresJson on production DB
- Fixed roundEvaluationScores and ai-ranking to look in EvaluationForm.criteriaJson
  instead of round.configJson for the boolean "Move to the Next Stage?" criterion
- Added advanceMode (count/threshold) toggle to round config Advancement Targets
- Added "Assign to Jurors" button on Unassigned Projects section and Projects tab bulk bar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 12:48:08 +01:00
c6ebd169dd feat: admin evaluation editing, ranking improvements, status transition fix
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m26s
- Add adminEditEvaluation mutation and getJurorEvaluations query
- Create shared EvaluationEditSheet component with inline feedback editing
- Add Evaluations tab to member detail page (grouped by round)
- Make jury group member names clickable (link to member detail)
- Replace inline EvaluationDetailSheet on project page with shared component
- Fix project status transition validation (skip when status unchanged)
- Fix frontend to not send status when unchanged on project edit
- Ranking dashboard improvements and boolean decision converter fixes
- Backfill script updates for binary decisions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 10:46:52 +01:00
49e706f2cf feat: applicant onboarding, bulk invite, team management enhancements
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m50s
- Add nationality/institution fields to User model with migration
- Applicant onboarding wizard (name, photo, nationality, country, institution, bio, project logo, preferences)
- Project logo upload from applicant context with team membership verification
- APPLICANT redirects in set-password, onboarding, and auth layout
- Mask evaluation round names as "Evaluation Round 1/2/..." for applicants
- Extend inviteTeamMember with nationality/country/institution/sendInvite fields
- Admin getApplicants query with search/filter/pagination
- Admin bulkInviteApplicants mutation with token generation and emails
- Applicants tab on Members page with bulk select and floating invite bar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 10:11:11 +01:00
68aa393559 feat: show submission round file requirements on project edit page
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m40s
Adds a new tRPC procedure `round.getSubmissionRoundForProgram` that
fetches the most recent SUBMISSION round for a given program, then
displays any `requiredDocuments` from its configJson as labeled info
cards above the general file upload section on the project edit page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:47:42 +01:00
dd004baf79 feat: add View Project links to admin tables, conditionally show Awards tab
- IndividualAssignmentsTable: add View Project (new tab) as first dropdown item
- AwardShortlist: make project title a clickable link opening in new tab
- ProjectStatesTable: change View Project from same-tab Link to new-tab anchor
- Round page: Awards tab now only shown when roundAwards.length > 0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:37:45 +01:00
36560a1837 fix: assign project to round on creation (create ProjectRoundState)
- Add optional roundId field to project.create mutation input schema
- After project creation, update project.roundId FK and create a
  ProjectRoundState record (state: PENDING) when roundId is supplied
- Pass selectedRoundId from the new-project form to createProject.mutate()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:31:08 +01:00
25e06e11e4 feat: add all missing fields to project update mutation and edit form
Adds competitionCategory, oceanIssue, institution, geographicZone,
wantsMentorship, and foundedAt to the tRPC update mutation input schema
and the admin project edit form UI (with CountrySelect + Switch).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:28:26 +01:00
8f71527353 feat(02-01): register Ranking tab in round detail page + create component stub
- Create src/components/admin/round/ranking-dashboard.tsx (stub with placeholder text)
- Import RankingDashboard in round detail page.tsx
- Add Ranking tab entry guarded by isEvaluation (uses existing BarChart3 icon)
- Add TabsContent block rendering RankingDashboard with competitionId + roundId props
2026-02-27 09:41:59 +01:00
c96f1b67a5 feat: add admin advancement summary card and advance column in assignments table
- Update listByStage query to include evaluation form criteriaJson and criterionScoresJson
- Add Advance column to individual assignments table showing YES/NO badge per submitted evaluation
- Create AdvancementSummaryCard component showing yes/no/pending vote counts with stacked bar
- Wire AdvancementSummaryCard into the EVALUATION round overview tab

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 15:19:30 +01:00
79bd4dbae7 feat: add juror progress dashboard with evaluation.getMyProgress query
- Add getMyProgress juryProcedure query to evaluationRouter: fetches all
  assignments for the current juror in a round, tallies completed/total,
  advance yes/no counts, per-project numeric scores and averages
- Create JurorProgressDashboard client component with progress bar, advance
  badge summary, and collapsible per-submission score table
- Wire dashboard into jury round page, gated by configJson.showJurorProgressDashboard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 15:15:08 +01:00
a327962f04 feat: render advance criterion on juror evaluation page and fix related renderers
- Jury evaluate page: add prominent advance criterion block (h-14, brand-blue border) before boolean block, fix type cast to include 'advance', add advance to required-field validation
- evaluation-form.tsx: add 'advance' to CriterionType, schema, default values, progress tracking, rendering via new AdvanceCriterionField component with prominent styling
- Admin project detail: treat advance same as boolean in EvaluationDetailSheet criterion score display
- Observer project detail: treat advance same as boolean in evaluation criterion score display

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 15:11:24 +01:00
0a96960ae2 Fix race condition: deduplicate startMutation calls between autosave and submit
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m5s
Use a shared startPromiseRef so autosave and handleSubmit reuse the same
in-flight "create evaluation" promise instead of firing duplicate requests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:49:35 +01:00
f3fd9eebee Multi-role members, round detail UI overhaul, dashboard jury progress, and submit bug fix
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
- Add roles UserRole[] to User model with migration + backfill from existing role column
- Update auth JWT/session to propagate roles array with [role] fallback for stale tokens
- Update tRPC hasRole() middleware and add userHasRole() helper for inline role checks
- Update ~15 router inline checks and ~13 DB queries to use roles array
- Add updateRoles admin mutation with SUPER_ADMIN guard and priority-based primary role
- Add role switcher UI in admin sidebar and role-nav for multi-role users
- Remove redundant stats cards from round detail, add window dates to header banner
- Merge Members section into JuryProgressTable with inline cap editor and remove buttons
- Reorder round detail assignments tab: Progress > Score Dist > Assignments > Coverage > Jury Group
- Make score distribution fill full vertical height, reassignment history always open
- Add per-juror progress bars to admin dashboard ActiveRoundPanel for EVALUATION rounds
- Fix evaluation submit bug: use isSubmitting state instead of startMutation.isPending

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:44:55 +01:00
230347005c Show 100% progress for closed/archived rounds in Round Pipeline
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m23s
Closed and archived rounds now always display a full progress bar instead
of relying on the computed completionRate which is 0 for non-evaluation rounds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 21:07:18 +01:00
5ece50268b Improve reports page: active round defaults, compact project summary, status labels
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m34s
- Default round selectors to ROUND_ACTIVE instead of first round (StageAnalytics, JurorConsistency, Diversity, PDF export)
- Reimagine Project Reports as compact dashboard: summary stats, status chips, top-10 table
- Map ELIGIBLE status to "Special Award" display label

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 20:18:14 +01:00
61c4d0eb75 Fix evaluation double-click submit: autosave was blocking the submit button
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m35s
Root cause: submit button was disabled when autosaveMutation.isPending was true.
If the 3-second autosave timer fired while the user clicked Submit, the click
was silently swallowed. User had to wait for autosave to finish, then click again.

Fixes:
- Remove autosaveMutation.isPending from submit button disabled state
- Cancel pending autosave timer when submit starts (prevents race condition)
- Add isSubmittingRef guard to prevent autosave from firing during submit
- Reset submitting flag on validation failure or submit error

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:14:37 +01:00
3bc6552f47 Fix multi-click submit bug and add draft submit indicator on juror dashboard
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m24s
- Initialize slider values to midpoint so visual matches stored value
  (root cause: sliders appeared filled but criteriaValues was undefined)
- Use mutateAsync for submit to properly await and prevent double-clicks
- Add startMutation.isPending to submit button disabled state
- Add error toast in evaluation-form.tsx catch block (was silent)
- Show "Ready to submit" badge and "Review & Submit" button for drafts
  on juror dashboard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:29:13 +01:00
ab2c73bad2 Add 5-second auto-refresh for dashboard Activity feed
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m0s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:15:42 +01:00
95d51e7de3 Add juror quick actions to Members section, redistribute button, dropout emails, and transfer duplicate detection
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
- Add mail/transfer/reshuffle/redistribute icons to each juror row in Members card
- New redistributeJurorAssignments procedure: reassign all pending projects without dropping juror from group
- New DROPOUT_REASSIGNED email template with project names, deadline, and dropped juror context
- Update reassignDroppedJuror to send per-juror DROPOUT_REASSIGNED emails instead of generic BATCH_ASSIGNED
- Transfer dialog now shows all candidates with "Already assigned" / "At cap" labels instead of hiding them
- SQL script for prod DB insertion of new notification setting without seeding

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 16:08:46 +01:00
f26ee3f076 Admin dashboard & round management UX overhaul
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m43s
- Extract round detail monolith (2900→600 lines) into 13 standalone components
- Add shared round/status config (round-config.ts) replacing 4 local copies
- Delete 12 legacy competition-scoped pages, merge project pool into projects page
- Add round-type-specific dashboard stat panels (submission, mentoring, live final, deliberation, summary)
- Add contextual header quick actions based on active round type
- Improve pipeline visualization: progress bars, checkmarks, chevron connectors, overflow fix
- Add config tab completion dots (green/amber/red) and inline validation warnings
- Enhance juries page with round assignments, member avatars, and cap mode badges
- Add context-aware project list (recent submissions vs active evaluations)
- Move competition settings into Manage Editions page

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 17:14:00 +01:00
09cc49d920 Fix score distribution chart and add auto-assign for transfer dialog
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m30s
- Fix bar chart CSS: percentage heights now resolve correctly with flex-1
  and absolute bottom-anchored bars
- Add Auto-assign button to transfer assignments dialog that distributes
  projects across eligible jurors balanced by load, preferring jurors who
  haven't completed all evaluations and are under their cap

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 20:16:15 +01:00
351d8144d9 Fix score distribution chart bars not rendering in admin round page
CSS percentage heights require parent with resolved height. Changed layout
to use flex-1 with absolute bottom-anchored bars instead of percentage-height containers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 19:58:13 +01:00
5a609457c2 Overhaul applicant portal: timeline, evaluations, nav, resources
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m6s
- Fix programId/competitionId bug in competition timeline
- Add applicantVisibility config to EvaluationConfigSchema (JSONB)
- Add admin UI card for controlling applicant feedback visibility
- Add 6 new tRPC procedures: getNavFlags, getMyCompetitionTimeline,
  getMyEvaluations, getUpcomingDeadlines, getDocumentCompleteness,
  and extend getMyDashboard with hasPassedIntake
- Rewrite competition timeline to show only EVALUATION + Grand Finale,
  synthesize FILTERING rejections, handle manually-created projects
- Dynamic ApplicantNav with conditional Evaluations/Mentoring/Resources
- Dashboard: conditional timeline, jury feedback card, deadlines,
  document completeness, conditional mentor tile
- New /applicant/evaluations page with anonymous jury feedback
- New /applicant/resources pages (clone of jury learning hub)
- Rename /applicant/competitions → /applicant/competition
- Remove broken /applicant/competitions/[windowId] page
- Add permission info banner to team invite dialog

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 19:51:17 +01:00
ee2f10e080 Add jury assignment transfer, cap redistribution, and learning hub overhaul
All checks were successful
Build and Push Docker Image / build (push) Successful in 12m19s
- Add getTransferCandidates/transferAssignments procedures for targeted
  assignment moves between jurors with TOCTOU guards and audit logging
- Add getOverCapPreview/redistributeOverCap for auto-redistributing
  assignments when a juror's cap is lowered below their current load
- Add TransferAssignmentsDialog (2-step: select projects, pick destinations)
- Extend InlineMemberCap with over-cap detection and redistribute banner
- Extend getReassignmentHistory to show ASSIGNMENT_TRANSFER and CAP_REDISTRIBUTE events
- Learning hub: replace ResourceType/CohortLevel enums with accessJson JSONB,
  add coverImageKey, resource detail pages for jury/mentor, shared renderer
- Migration: 20260221200000_learning_hub_overhaul

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 18:50:29 +01:00
161cd1684a Fix observer reports: charts, filtering, project preview, dashboard stats
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m32s
- Rewrite diversity metrics: horizontal bar charts for ocean issues and
  geographic distribution (replaces unreadable vertical/donut charts)
- Rewrite juror score heatmap: expandable table with score distribution
- Rewrite juror consistency: horizontal bar visual with juror names
- Merge filtering tabs into single screening view with per-project
  AI reasoning and expandable rows
- Add project preview dialog for juror performance table
- Fix status breakdown for evaluation rounds (Fully/Partially/Not Reviewed)
- Show active round name instead of count on observer dashboard
- Move Global tab to last position, default to first round-specific tab
- Add 4-card stats layout for evaluation with reviews/project ratio
- Fix oceanIssue field (singular) and remove non-existent aiSummary

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 10:12:21 +01:00
2e4b95f29c Add round-type-specific observer reports with dynamic tabs
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m44s
Refactor the observer reports page from a static 3-tab layout to a
dynamic tab system that adapts to each round type (INTAKE, FILTERING,
EVALUATION, SUBMISSION, MENTORING, LIVE_FINAL, DELIBERATION). Adds a
persistent Global tab for edition-wide analytics, juror score heatmap,
expandable juror assignment rows, filtering screening bar, and
deliberation results with tie detection.

- Add 5 observer proxy procedures to analytics router
- Create JurorScoreHeatmap, ExpandableJurorTable, FilteringScreeningBar
- Create 8 round-type tab components + GlobalAnalyticsTab
- Reduce reports page from 914 to ~190 lines (thin dispatcher)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 09:29:26 +01:00
ee3bfec8b0 Add Tremor design tokens for Tailwind v4 compatibility
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m27s
Tremor v3 expects its TW3 plugin to register tremor-* design tokens
(tremor-content, tremor-background, tremor-border, etc.). Since TW4
has no v3 plugin support, define these tokens manually in @theme and
safelist the utility classes via @source inline().

This fixes chart axis labels, grid lines, and tooltips rendering
without proper colors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 01:43:11 +01:00
8e607478d5 Fix Tremor chart colors: safelist dynamic utility classes for Tailwind v4
Tremor constructs class names via template literals (e.g. fill-${color}-${shade})
which Tailwind v4's scanner cannot detect statically. Added @source inline()
directives to explicitly safelist all color×shade×property combinations needed
by Tremor chart components.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 01:39:24 +01:00
6d4ee93ab3 Fix round completion rate: use evaluations/assignments, closed rounds=100%
The round breakdown was showing 200% for active rounds (assignments/projects)
and 0% for closed rounds. Now correctly computes evaluations/assignments for
active rounds and shows 100% for closed/archived rounds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 01:34:42 +01:00
350e9b96e8 Fix Tremor chart colors: add @source for Tailwind v4 to scan Tremor classes
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m22s
Tremor generates Tailwind utility classes dynamically (fill-blue-500,
bg-emerald-500, etc). Tailwind v4 auto-content detection doesn't scan
node_modules, so these classes were missing from CSS output, causing
all charts to render in black.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 01:14:59 +01:00
4f73ba5a0e Fix reports: status breakdown uses round states, filter boolean criteria, replace insight tiles with country chart
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m47s
- getStatusBreakdown now uses ProjectRoundState when a specific round is selected
  (fixes donut showing all "Eligible")
- Filter out boolean/section_header criteria from getCriteriaScores
  (removes "Move to the Next Stage?" from bar chart)
- Replace 6 insight tiles with Top Countries horizontal bar chart
- Add round-level state labels/colors to chart-theme

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 00:00:55 +01:00