Commit Graph

34 Commits

Author SHA1 Message Date
Matt
3a6a9a2b45 feat: add inline file viewer and project logos to award voting
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m24s
- Replace custom download-only file list with full FileViewer component
  that supports inline preview (PDF, video, images, Office docs),
  open in new tab, and download
- Add project logos next to project names in award voting cards
- Backend now returns full file metadata (mimeType, size, pageCount,
  language detection) and project logo URLs
- Award jurors can access files for eligible projects (access control
  already added in prior commit)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 12:49:28 -04:00
Matt
0987d49817 feat: show awards on jury dashboard and add project details to award voting
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m27s
- Jury dashboard now shows active award voting banners with project
  count, deadline countdown, and direct link to vote
- Award voting page shows full project details: description, team
  members, tags, and downloadable files in expandable cards
- Award jurors can now download files for eligible projects (added
  awardJuror access check to file.getDownloadUrl)
- Backend query enhanced to include files and team members

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 12:28:53 -04:00
Matt
29502a2b88 feat: add Decision Mode dropdown to award edit page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 20:13:51 -04:00
Matt
fbc8b5165a feat: add award master tRPC procedures — enhanced detail, vote with justification, confirm winner, set chair
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 16:42:21 -04:00
b85a9b9a7b fix: security hardening + performance refactoring (code review batch 1)
- IDOR fix: deliberation vote now verifies juryMemberId === ctx.user.id
- Rate limiting: tRPC middleware (100/min), AI endpoints (5/hr), auth IP-based (10/15min)
- 6 compound indexes added to Prisma schema
- N+1 eliminated in processRoundClose (batch updateMany/createMany)
- N+1 eliminated in batchCheckRequirementsAndTransition (3 batch queries)
- Service extraction: juror-reassignment.ts (578 lines)
- Dead code removed: award.ts, cohort.ts, decision.ts (680 lines)
- 35 bare catch blocks replaced across 16 files
- Fire-and-forget async calls fixed
- Notification false positive bug fixed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 16:18:24 +01:00
c6d0f90038 fix: presigned URL signatures, bucket consolidation, login & invite status
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m44s
- MinIO: use separate public client for presigned URLs so AWS V4 signature
  matches the browser's Host header (fixes SignatureDoesNotMatch on all uploads)
- Consolidate applicant/partner uploads to mopc-files bucket (removes
  non-existent mopc-submissions and mopc-partners buckets)
- Auth: allow magic links for any non-SUSPENDED user (was ACTIVE-only,
  blocking first-time CSV-seeded applicants)
- Auth: accept invite tokens for any non-SUSPENDED user (was INVITED-only)
- Ensure all 14 invite token locations set status to INVITED

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 13:06:17 +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
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
5854aa37a9 feat: prevent duplicate award pool notifications
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m1s
Add notifiedAt field to AwardEligibility. notifyEligibleProjects now
skips already-notified entries and stamps notifiedAt after sending,
so re-clicking "Notify Pool" only emails newly added projects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:32:14 +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
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
Matt
51e18870b6 Admin UI audit round 2: fix 28 display bugs across 23 files
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m51s
HIGH fixes (broken features / wrong data):
- H1: Fix roundAssignments → projectRoundStates in project router (7 occurrences)
- H2: Fix deliberation results panel blank table (wrong field names)
- H3: Fix deliberation participant names blank (wrong data path)
- H4: Fix awards "Evaluated" stat duplicating "Eligible" count
- H5: Fix cross-round comparison enabled at 1 round (backend requires 2)
- H6: Fix setState during render anti-pattern (6 occurrences)
- H7: Fix round detail jury member count always showing 0
- H8: Remove 4 invalid status values from observer dashboard filter
- H9: Fix filtering progress bar always showing 100%

MEDIUM fixes (misleading display):
- M1: Filter special-award rounds from competition timeline
- M2: Exclude special-award rounds from distinct project count
- M3: Fix MENTORING pipeline node hardcoded "0 mentored"
- M4: Fix DELIB_LOCKED badge using red for success state
- M5: Add status label maps to deliberation session detail
- M6: Humanize deliberation category + tie-break method displays
- M8: Rename setStageId → setRoundId, "Select Stage" → "Select Round"
- M9: Add missing INVITED/ACTIVE/SUSPENDED to members status labels
- M10: Add ROUND_DRAFT/ACTIVE/CLOSED/ARCHIVED to StatusBadge
- M11: Fix unsent messages showing "Scheduled" instead of "Draft"
- M12: Rename misleading totalEvaluations → totalAssignments
- M13: Rename "Stage" column to "Program" in projects page

LOW fixes (cosmetic / edge-case):
- L1: Use unfiltered rounds array for active round detection
- L2: Use all rounds length for new round sort order
- L3: Filter special-award rounds from header count
- L4: Fix single-underscore replace in award status badges
- L5: Fix score bucket boundary gaps (4.99 dropped between buckets)
- L6: Title-case LIVE_FINAL pipeline metric status
- L7: Fix roundType.replace only replacing first underscore
- L8: Remove duplicate severity sort in smart-actions component

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 11:11:00 +01:00
Matt
ae1685179c Comprehensive admin UI stats audit: fix 16 display bugs
HIGH fixes:
- H1: Competition detail project count no longer double-counts across rounds
- H2: Rounds page header stats use unfiltered round set
- H3: Rounds page "eval" label corrected to "asgn" (assignment count)
- H4: Observer reports project count uses distinct analytics count
- H5: Awards eligibility count filters to only eligible=true (backend)
- H6: Round detail projectCount derived from projectStates for consistency
- H7: Deliberation hasVoted derived from votes array (was always undefined)

MEDIUM fixes:
- M1: Reports page round status badges use correct ROUND_ACTIVE/ROUND_CLOSED enums
- M2: Observer reports badges use ROUND_ prefix instead of stale STAGE_ prefix
- M3: Deliberation list status badges use correct VOTING/TALLYING/RUNOFF enums
- M4: Competition list/detail round count excludes special-award rounds (backend)
- M5: Messages page shows actual recipient count instead of hardcoded "1 user"

LOW fixes:
- L2: Observer analytics jurorCount scoped to round when roundId provided
- L3: Analytics round-scoped project count uses ProjectRoundState not assignments
- L4: JuryGroup delete audit log reports member count (not assignment count)
- L5: Project rankings include unevaluated projects at bottom instead of hiding

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 09:56:09 +01:00
1308c3ba87 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
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>
2026-02-19 08:20:13 +01:00
aa1bf564ee Fix award eligibility FK constraint + add country column to round projects
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m13s
- specialAward.setEligibility: add ensureUserExists() guard and use Prisma
  connect syntax to prevent FK violation on stale session user IDs
- specialAward.confirmShortlist: same ensureUserExists() guard for confirmedBy
- Round projects table: add Country column showing project origin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 22:47:20 +01:00
d02b0b91b9 Award shortlist UX improvements + configurable invite link expiry
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m30s
Award shortlist:
- Expandable reasoning text (click to toggle, hover hint)
- Bulk select/deselect all checkbox in header
- Top N projects highlighted with amber background
- New bulkToggleShortlisted backend mutation

Invite link expiry:
- New "Invitation Link Expiry (hours)" field in Security Settings
- Reads from systemSettings `invite_link_expiry_hours` (default 72h / 3 days)
- Email template dynamically shows "X hours" or "X days" based on setting
- All 3 invite paths (bulk create, single invite, bulk resend) use setting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 22:05:58 +01:00
70d24036f9 Fix award source round dropdown — auto-resolve competitionId from program
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m19s
Awards created from /admin/awards/new only sent programId, leaving
competitionId null. The edit page's source round dropdown was empty
because it depended on competitionId to fetch competition rounds.

- create mutation: auto-resolve competitionId from program's latest competition
- update mutation: backfill competitionId on save if missing
- get query: backfill competitionId on read for legacy awards
- edit page: use award.competition.rounds directly instead of separate query

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 21:00:20 +01:00
1fe6667400 Special awards: Rounds tab UI, auto-filter threshold, remove auto-tag rules
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m23s
- Add Rounds tab to award detail page with create/list/delete functionality
- Add "Entry point" badge on first award round (confirmShortlist routes here)
- Fix round detail back-link to navigate to parent award when specialAwardId set
- Filter award rounds out of competition round list
- Add specialAwardId to competition getById round select
- Warn on confirmShortlist when no award rounds exist (SEPARATE_POOL mode)
- Remove auto-tag rules from award config, edit page, router, and AI service
- Fix competitionId not passed when creating awards from competition context
- Add AUTO_FILTER quality threshold to AI filtering dashboard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:53:20 +01:00
Matt
a02ed59158 Fix AI filtering bugs, add special award shortlist integration
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m20s
Part 1 - Bug Fixes:
- Fix toProjectWithRelations() stripping file fields needed by AI (detectedLang, textContent, etc.)
- Fix parseAIData() reading flat when aiScreeningJson is nested under rule ID
- Fix getAIConfidenceScore() with same nesting issue (always returned 0)

Part 2 - Special Award Track Integration:
- Add shortlistSize to SpecialAward, qualityScore/shortlisted/confirmed fields to AwardEligibility
- Add specialAwardId to Round for award-owned rounds
- Update AI eligibility service to return qualityScore (0-100) for ranking
- Update eligibility job with filteringRoundId scoping and auto-shortlist top N
- Add 8 new specialAward router procedures (listForRound, runEligibilityForRound,
  listShortlist, toggleShortlisted, confirmShortlist, listRounds, createRound, deleteRound)
- Create award-shortlist.tsx component with ranked table, shortlist checkboxes, confirm dialog
- Add "Special Award Tracks" section to filtering dashboard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 15:38:31 +01:00
7f334ed095 Round detail overhaul, file requirements, project management, audit log fix
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m32s
- Redesign round detail page with 6 tabs (overview, projects, filtering, assignments, config, documents)
- Add jury group assignment selector in round stats bar
- Add FileRequirementsEditor component replacing SubmissionWindowManager
- Add FilteringDashboard component for AI-powered project screening
- Add project removal from rounds (single + bulk) with cascading to subsequent rounds
- Add project add/remove UI in ProjectStatesTable with confirmation dialogs
- Fix logAudit inside $transaction pattern across all 12 router files
  (PostgreSQL aborted-transaction state caused silent operation failures)
- Fix special awards creation, deletion, status update, and winner assignment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 07:49:39 +01:00
f572336781 Rounds overhaul: full CRUD submission windows, scheduling UI, analytics, design refresh
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m40s
- Fix special award FK crash: replace 4x raw auditLog.create with logAudit() helper
- Add updateSubmissionWindow + deleteSubmissionWindow mutations to round router
- Add per-round analytics (_count, juryGroup) to competition.getById
- Remove redundant acceptedCategories from intake config
- Rewrite submission window manager with full CRUD, all fields, date pickers
- Add round scheduling card (open/close dates) to round detail page
- Add project count, assignment count, jury group to round list cards
- Visual redesign: pipeline view, brand colors, progress bars, enhanced cards

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 07:07:09 +01:00
4c0efb232c Admin system overhaul: full round config UI, flattened navigation, juries, awards integration, evaluation rewrite
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m23s
- Phase 1: 7 round config sub-components covering all ~65 Zod schema fields across INTAKE, FILTERING, EVALUATION, SUBMISSION, MENTORING, LIVE_FINAL, DELIBERATION
- Phase 2: Replace Competitions nav with Rounds + add Juries; new /admin/rounds and /admin/rounds/[roundId] pages with tabbed detail (Config, Projects, Windows, Documents, Awards)
- Phase 3: Top-level /admin/juries with list + detail pages (members table, settings panel, self-service review)
- Phase 4: File requirements editor in round config; project detail per-requirement upload slots replacing generic drop zone
- Phase 5: Awards edit page with source round dropdown, eligibility mode, auto-tag rules builder; round detail Awards tab; specialAward router enhanced with evaluationRoundId/eligibilityMode fields
- Phase 6: Evaluation page rewrite supporting all 3 scoring modes (criteria/global/binary) with config-driven behavior; live voting UI polish
- Phase 7: UI design polish across admin pages — consistent headers, cards, hover transitions, empty states, brand colors
- Bulk upload page for admin project imports
- File router enhanced with admin upload and submission window procedures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 01:16:55 +01:00
Matt
b5425e705e Apply full refactor updates plus pipeline/email UX confirmations
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m33s
2026-02-14 15:26:42 +01:00
ce4069bf92 Platform-wide visual overhaul, team invites, analytics improvements, and deployment hardening
UI overhaul applying jury dashboard design patterns across all pages:
- Stat cards with border-l-4 accent + icon pills on admin, observer, mentor, applicant dashboards and reports
- Card section headers with color-coded icon pills throughout
- Hover lift effects (translate-y + shadow) on cards and list items
- Gradient progress bars (brand-teal to brand-blue) platform-wide
- AnimatedCard stagger animations on all dashboard sections
- Auth pages with gradient accent strip and polished icon containers
- EmptyState component upgraded with rounded icon pill containers
- Replaced AI-looking icons (Brain/Sparkles/Bot/Wand2/Cpu) with descriptive alternatives across 12 files
- Removed gradient overlay from jury dashboard header
- Quick actions restyled as card links with group hover effects

Backend improvements:
- Team member invite emails with account setup flow and notification logging
- Analytics routers accept edition-wide queries (programId) in addition to roundId
- Round detail endpoint returns inline progress data (eliminates extra getProgress call)
- Award voting endpoints parallelized with Promise.all
- Bulk invite supports optional sendInvitation flag
- AwardVote composite index migration for query performance

Infrastructure:
- Docker entrypoint with migration retry loop (configurable retries/delay)
- docker-compose pull_policy: always for automatic image refresh
- Simplified deploy/update scripts using docker compose up -d --pull always
- Updated deployment documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 13:20:52 +01:00
e73a676412 Comprehensive platform audit: security, UX, performance, and visual polish
Phase 1: Security - status transition validation, Zod tightening, DB indexes, transactions

Phase 2: Admin UX - search/filter for awards, learning, partners pages

Phase 3: Dashboard - Recent Activity feed, Pending Actions card, quick actions

Phase 4: Jury - assignments progress/urgency, autosave indicator, divergence highlighting

Phase 5: Portals - observer charts, mentor search, login/onboarding polish

Phase 6: Messages preview dialog, CsvExportDialog with column selection

Phase 7: Performance - query optimizations, loading skeletons, useDebounce hook

Phase 8: Visual - AnimatedCard, hover effects, StatusBadge, empty state CTAs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 22:05:01 +01:00
002a9dbfc3 Platform review round 2: audit logging migration, nav unification, DB indexes, and UI polish
- Migrate ~41 inline audit log calls to shared logAudit() utility across all routers
- Add transaction-aware prisma parameter to logAudit() for atomic operations
- Unify jury/mentor/observer navigation into shared RoleNav component
- Add composite DB indexes (Evaluation, GracePeriod, AuditLog) for query performance
- Fix profile page: consolidate dual save buttons, proper useEffect initialization
- Enhance auth error page with MOPC branding and navigation
- Improve observer dashboard with prominent read-only badge
- Fix DI-3: fetch projects before bulk status update for accurate notifications
- Remove unused aiBoost field from smart-assignment scoring
- Add shared image-upload utility and structured logger module

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 21:09:06 +01:00
049ac9257f Fix voting start time race condition
Set votingStartAt to 1 minute in the past when opening/reopening rounds
or awards. This ensures voting is immediately available without the
"opens in less than a minute" message appearing due to timing differences
between when the date is set and when the page renders.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 17:08:09 +01:00
13de30775e Add special awards management features and fix voting/assignment issues
Special Awards:
- Add delete button with confirmation dialog to award detail page
- Add voting window dates (start/end) to award edit page
- Add manual project eligibility management (add/remove projects)
- Show eligibility method (Auto/Manual) in eligibility table
- Auto-set votingStartAt when opening voting if date is in future

Assignment Suggestions:
- Replace toggle with proper tabs UI (Algorithm vs AI Powered)
- Persist AI suggestions when navigating away (stored in database)
- Show suggestion counts on tab badges
- Independent refresh/start buttons per tab

Round Voting:
- Auto-update votingStartAt to now when activating round if date is in future
- Fixes issue where round was opened but voting dates were in future

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 16:29:36 +01:00
29827268b2 Remove dynamic form builder and complete RoundProject→roundId migration
Major cleanup and schema migration:
- Remove unused dynamic form builder system (ApplicationForm, ApplicationFormField, etc.)
- Complete migration from RoundProject junction table to direct Project.roundId
- Add sortOrder and entryNotificationType fields to Round model
- Add country field to User model for mentor matching
- Enhance onboarding with profile photo and country selection steps
- Fix all TypeScript errors related to roundProjects references
- Remove unused libraries (@radix-ui/react-toast, embla-carousel-react, vaul)

Files removed:
- admin/forms/* pages and related components
- admin/onboarding/* pages
- applicationForm.ts and onboarding.ts routers
- Dynamic form builder Prisma models and enums

Schema changes:
- Removed ApplicationForm, ApplicationFormField, OnboardingStep, ApplicationFormSubmission, SubmissionFile models
- Removed FormFieldType and SpecialFieldType enums
- Added Round.sortOrder, Round.entryNotificationType
- Added User.country

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 14:15:06 +01:00
fd5e5222da Decouple projects from rounds with RoundProject join table
Projects now exist at the program level instead of being locked to a
single round. A new RoundProject join table enables many-to-many
relationships with per-round status tracking. Rounds have sortOrder
for configurable progression paths.

- Add RoundProject model, programId on Project, sortOrder on Round
- Migration preserves existing data (roundId -> RoundProject entries)
- Update all routers to query through RoundProject join
- Add assign/remove/advance/reorder round endpoints
- Add Assign, Advance, Remove Projects dialogs on round detail page
- Add round reorder controls (up/down arrows) on rounds list
- Show all rounds on project detail page

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 22:33:55 +01:00
8931da98ba Add AI eligibility toggle and include-submitted filter for awards
- Add useAiEligibility boolean to SpecialAward schema (default true)
- Toggle on creation form lets admins disable AI for feeling-based awards
- Detail page shows "Load All Projects" when AI is off vs "Run AI Eligibility"
- Include Submitted toggle lets admins include SUBMITTED-status projects
- Fix perPage: 200 → 100 to match user.list validation max
- Fix edition display on award detail page
- Add migration for new column

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 20:02:58 +01:00
90e3adfab2 Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00