Commit Graph

101 Commits

Author SHA1 Message Date
Matt e0e4cb2a32 Reconcile schema with migrations and fix failed migration
Build and Push Docker Image / build (push) Successful in 17m39s Details
- Align schema.prisma with add_15_features migration (15 discrepancies):
  nullability, column names, PKs, missing/extra columns, onDelete behavior
- Make universal_apply_programid migration idempotent for safe re-execution
- Add reconciliation migration for missing FKs and indexes
- Fix message.ts and mentor.ts to match corrected schema field names

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 14:37:32 +01:00
Matt 04d0deced1 Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
Build and Push Docker Image / build (push) Successful in 11m24s Details
Schema: Add 11 new models (RoundTemplate, MentorNote, MentorMilestone,
MentorMilestoneCompletion, EvaluationDiscussion, DiscussionComment,
Message, MessageRecipient, MessageTemplate, Webhook, WebhookDelivery,
DigestLog) and missing fields on existing models (Project.isDraft,
ProjectFile.version, LiveVotingSession.allowAudienceVotes, User.digestFrequency,
AuditLog.sessionId, MentorAssignment.completionStatus, etc).
Add AUDIT_CONFIG/LOCALIZATION/DIGEST/ANALYTICS enum values.

Code: Fix implicit any types, route type casts, enum casts, null safety,
composite key handling, and relation field names across 11 source files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 14:04:02 +01:00
Matt 24fdd2f6be Fix build error: remove non-existent version property from ProjectFile mapping
Build and Push Docker Image / build (push) Failing after 3m17s Details
ProjectFile model does not have a version field; FileViewer accepts it as optional.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:41:53 +01:00
Matt e7c86a7b1b Add dynamic apply wizard customization with admin settings UI
Build and Push Docker Image / build (push) Failing after 3m29s Details
- Create wizard config types, utilities, and defaults (wizard-config.ts)
- Add admin apply settings page with drag-and-drop step ordering, dropdown
  option management, feature toggles, welcome message customization, and
  custom field builder with select/multiselect options editor
- Build dynamic apply wizard component with animated step transitions,
  mobile-first responsive design, and config-driven form validation
- Update step components to accept dynamic config (categories, ocean issues,
  field visibility, feature flags)
- Replace hardcoded enum validation with string-based validation for
  admin-configurable dropdown values, with safe enum casting at storage layer
- Add wizard template system (model, router, admin UI) with built-in
  MOPC Classic preset
- Add program wizard config CRUD procedures to program router
- Update application router getConfig to return wizardConfig, submit handler
  to store custom field data in metadataJson
- Add edition-based apply page, project pool page, and supporting routers
- Fix CSS (invalid sm:fixed-none), Enter key handler (skip textarea),
  safe area insets for notched phones, buildStepsArray field visibility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:21:26 +01:00
Matt 98fe658c33 UI polish: grouped dropdowns, analytics readability, invite tag picker
Build and Push Docker Image / build (push) Successful in 9m56s Details
- Messages: group users by role in recipient dropdown (SelectGroup)
- Analytics: full country names via Intl.DisplayNames, format SNAKE_CASE
  labels to Title Case, custom tooltips, increased font sizes
- Invite: replace free-text tag input with grouped dropdown from DB tags
  using Command/Popover, showing tags organized by category with colors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:06:47 +01:00
Matt 4830c0638c Add database migration for 15 platform features
Build and Push Docker Image / build (push) Successful in 14m6s Details
Creates tables: DigestLog, RoundTemplate, MentorNote, MentorMilestone,
MentorMilestoneCompletion, Message, MessageTemplate, MessageRecipient,
Webhook, WebhookDelivery, EvaluationDiscussion, DiscussionComment,
ReminderLog, ConflictOfInterest, EvaluationSummary, ProjectStatusHistory,
MentorMessage. Adds columns to User, AuditLog, LiveVotingSession, LiveVote,
MentorAssignment, Project, ProjectFile. Adds SettingCategory enum values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 23:32:25 +01:00
Matt 59436ed67a Implement 15 platform features: digest, availability, templates, comparison, live voting SSE, file versioning, mentorship, messaging, analytics, drafts, webhooks, peer review, audit enhancements, i18n
Build and Push Docker Image / build (push) Has been cancelled Details
Features implemented:
- F1: Email digest notifications with cron endpoint and per-user frequency
- F2: Jury availability windows and workload preferences in smart assignment
- F3: Round templates with save-from-round and CRUD management
- F4: Side-by-side project comparison view for jury members
- F5: Real-time voting dashboard with Server-Sent Events (SSE)
- F6: Live voting UX: QR codes, audience voting, tie-breaking, score animations
- F7: File versioning, inline preview, bulk download with presigned URLs
- F8: Mentor dashboard: milestones, private notes, activity tracking
- F9: Communication hub with broadcasts, templates, and recipient targeting
- F10: Advanced analytics: cross-round comparison, juror consistency, diversity metrics, PDF export
- F11: Applicant draft saving with magic link resume and cron cleanup
- F12: Webhook integration layer with HMAC signing, retry, and delivery logs
- F13: Peer review discussions with anonymized scores and threaded comments
- F14: Audit log enhancements: before/after diffs, session grouping, anomaly detection, retention
- F15: i18n foundation with next-intl (EN/FR), cookie-based locale, language switcher

Schema: 12 new models, field additions to User, Project, ProjectFile, LiveVotingSession, LiveVote, MentorAssignment, AuditLog, Program
New routers: roundTemplate, message, webhook (registered in _app.ts)
New services: email-digest, webhook-dispatcher
New cron endpoints: /api/cron/digest, /api/cron/draft-cleanup, /api/cron/audit-cleanup
New API routes: /api/live-voting/stream (SSE), /api/files/bulk-download

All features are admin-configurable via SystemSettings or per-model settingsJson fields.
Docker build verified successfully.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 23:31:41 +01:00
Matt f038c95777 Fix Docker build failure: lazy-initialize MinIO client
Build and Push Docker Image / build (push) Successful in 13m48s Details
The production env var check in createMinioClient() was throwing during
`next build` page data collection because MINIO_ACCESS_KEY/SECRET_KEY
aren't available at Docker build time. Changed from eager module-level
initialization to a lazy Proxy pattern that defers client creation to
first actual use, while maintaining backward compatibility with all
existing `minio.method()` call sites.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 22:16:29 +01:00
Matt 699248e40b Implement 10 platform features: evaluation UX, admin tools, AI summaries, applicant portal
Build and Push Docker Image / build (push) Failing after 5m5s Details
Batch 1 - Quick Wins:
- F1: Evaluation progress indicator with touch tracking in sticky status bar
- F2: Export filtering results as CSV with dynamic AI column flattening
- F3: Observer access to analytics dashboards (8 procedures changed to observerProcedure)

Batch 2 - Jury Experience:
- F4: Countdown timer component with urgency colors + email reminder service with cron endpoint
- F5: Conflict of interest declaration system (dialog, admin management, review workflow)

Batch 3 - Admin & AI Enhancements:
- F6: Bulk status update UI with selection checkboxes, floating toolbar, status history recording
- F7: AI-powered evaluation summary with anonymized data, OpenAI integration, scoring patterns
- F8: Smart assignment improvements (geo diversity penalty, round familiarity bonus, COI blocking)

Batch 4 - Form Flexibility & Applicant Portal:
- F9: Evaluation form flexibility (text, boolean, section_header types, conditional visibility)
- F10: Applicant portal (status timeline, per-round documents, mentor messaging)

Schema: 5 new models (ReminderLog, ConflictOfInterest, EvaluationSummary, ProjectStatusHistory, MentorMessage), ProjectFile extended with roundId + isLate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 21:58:27 +01:00
Matt 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
Matt 8d0979e649 Comprehensive platform review: security fixes, query optimization, UI improvements, and code cleanup
Security (Critical/High):
- Fix path traversal bypass in local storage provider (path.resolve + prefix check)
- Fix timing-unsafe HMAC comparison (crypto.timingSafeEqual)
- Add auth + ownership checks to email API routes (verify-credentials, change-password)
- Remove hardcoded secret key fallback in local storage provider
- Add production credential check for MinIO (fail loudly if not set)
- Remove DB error details from health check response
- Add stricter rate limiting on application submissions (5/hour)
- Add rate limiting on email availability check (anti-enumeration)
- Change getAIAssignmentJobStatus to adminProcedure
- Block dangerous file extensions on upload
- Reduce project list max perPage from 5000 to 200

Query Optimization:
- Optimize analytics getProjectRankings with select instead of full includes
- Fix N+1 in mentor.getSuggestions (batch findMany instead of loop)
- Use _count for files instead of fetching full file records in project list
- Switch to bulk notifications in assignment and user bulk operations
- Batch filtering upserts (25 per transaction instead of all at once)

UI/UX:
- Replace Inter font with Montserrat in public layout (brand consistency)
- Use Logo component in public layout instead of placeholder
- Create branded 404 and error pages
- Make admin rounds table responsive with mobile card layout
- Fix notification bell paths to be role-aware
- Replace hardcoded slate colors with semantic tokens in admin sidebar
- Force light mode (dark mode untested)
- Adjust CardTitle default size
- Improve muted-foreground contrast for accessibility (A11Y)
- Move profile form state initialization to useEffect

Code Quality:
- Extract shared toProjectWithRelations to anonymization.ts (removed 3 duplicates)
- Remove dead code: getObjectInfo, isValidImageSize, unused batch tag functions, debug logs
- Remove unused twilio dependency
- Remove redundant email index from schema
- Add actual storage object deletion when file records are deleted
- Wrap evaluation submit + assignment update in
- Add comprehensive platform review document

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 20:31:08 +01:00
Matt a1f32597a0 Fix evaluation submission redirect to assignments page
Build and Push Docker Image / build (push) Successful in 9m25s Details
The previous code incorrectly tried to extract a project ID from the
assignment ID by splitting on '-', which doesn't work with CUIDs.

Now redirects to /jury/assignments with a success toast message
after submitting an evaluation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 17:13:31 +01:00
Matt 049ac9257f Fix voting start time race condition
Build and Push Docker Image / build (push) Has been cancelled Details
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
Matt d6386be678 Add reopen button for closed rounds
Build and Push Docker Image / build (push) Successful in 9m43s Details
Allows admins to reopen a closed round. When reopened, the voting start
date will automatically update to now (if it was in the future).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 16:51:02 +01:00
Matt 13de30775e Add special awards management features and fix voting/assignment issues
Build and Push Docker Image / build (push) Successful in 10m4s Details
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
Matt e01d741f01 Fix GPT-5 nano empty response issue with token limits
Build and Push Docker Image / build (push) Successful in 9m36s Details
GPT-5 nano (and other GPT-5 models) use reasoning that consumes
the output token budget. When max_tokens is too low, all tokens
get used by internal reasoning, leaving nothing for the response.

- Add needsHigherTokenLimit() to detect models needing more tokens
- Add getMinTokenLimit() to ensure minimum 16k tokens for GPT-5
- Update buildCompletionParams to apply minimum token limits
- This fixes the No response from AI error with gpt-5-nano

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 15:02:22 +01:00
Matt bf187e4b9a Improve AI assignment error messages for invalid models
Build and Push Docker Image / build (push) Has been cancelled Details
- Add try-catch around OpenAI API call to catch model errors
- Provide clearer error messages when model name is invalid
- Handle empty response cases with helpful feedback
- Suggest checking AI Configuration settings when model fails

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 14:56:21 +01:00
Matt c82406abcf Hide All projects covered message while AI job is running
Build and Push Docker Image / build (push) Has been cancelled Details
The empty state message was incorrectly showing during AI processing.
Now it only shows when job is complete and there are no suggestions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 14:53:45 +01:00
Matt 3abfccb22a Fix AI suggestions not displaying after job completion
Build and Push Docker Image / build (push) Successful in 9m26s Details
BREAKING CHANGE: AI assignment job now stores suggestions in database

- Add suggestionsJson column to AssignmentJob table
- Store enriched suggestions when job completes
- Update getAISuggestions to retrieve stored suggestions instead of regenerating
- Filter out already-assigned pairs from stored suggestions

Previously, the background job generated suggestions but discarded them,
and getAISuggestions tried to regenerate from scratch (causing infinite loading).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 14:38:43 +01:00
Matt e3e3fa9da4 Fix AI assignment errors and tag matching
Build and Push Docker Image / build (push) Successful in 9m7s Details
- Add missing updatedAt column to AssignmentJob table
- Fix algorithmic assignment to use AI-assigned projectTags instead of raw CSV tags
- Add case-insensitive tag matching for better expertise matching
- Scores should now properly reflect tag matches between judges and projects

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 14:14:19 +01:00
Matt fbb1173ea9 Add migration for User.country column
Build and Push Docker Image / build (push) Successful in 9m5s Details
The country field was in the schema but missing its migration.
This was causing user.get and user.me queries to fail.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 13:58:11 +01:00
Matt d7f0118940 Add user tag editing and improve member error display
Build and Push Docker Image / build (push) Successful in 9m4s Details
- Display actual error message in member detail page instead of generic Member not found
- Add debug logging to user.get query to help diagnose issues
- Add expertise tags editing for users in profile settings page
- Update user.updateProfile mutation to accept expertiseTags

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 13:45:34 +01:00
Matt f59cfd393b Display AI-assigned expertise tags on project detail page
Build and Push Docker Image / build (push) Successful in 8m56s Details
- Add projectTags relation to project.get query
- Show expertise tags with confidence percentages
- Tags displayed with their assigned colors

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 13:18:45 +01:00
Matt 4d8823e8e9 Show all errors in scrollable list instead of just first one
Build and Push Docker Image / build (push) Has been cancelled Details
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 13:13:25 +01:00
Matt 1b2311b4a3 Convert AI tagging to background job with progress tracking
Build and Push Docker Image / build (push) Successful in 9m40s Details
- Add TaggingJob model for tracking tagging progress
- Convert batch tagging to background job processing (prevents timeouts)
- Add real-time progress polling in UI with percentage/count display
- Add admin notifications when tagging job completes or fails
- Export getTaggingSettings and getAvailableTags functions

After deployment, run: npx prisma migrate deploy

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 11:48:57 +01:00
Matt 0b86dc6477 Add detailed logging for AI tagging progress
Build and Push Docker Image / build (push) Successful in 9m41s Details
- Log each project being processed with timing
- Log progress every 10 projects with time estimates
- Log final completion stats

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 11:34:32 +01:00
Matt e37154d812 Make migrations idempotent and add missing tables
Build and Push Docker Image / build (push) Successful in 9m41s Details
- Make all pending migrations idempotent (safe to re-run)
- Disable decouple_projects_from_rounds migration (schema not changed)
- Add ProjectTag table for AI tagging
- Add AssignmentJob table for AI assignment progress

On server deployment, run: npx prisma migrate deploy

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 11:09:37 +01:00
Matt 05862f1e55 Redesign AI Tagging dialog and add edition-wide tagging
Build and Push Docker Image / build (push) Successful in 9m22s Details
- Redesign AI Tagging dialog with scope selection (Round vs Edition)
- Add visual progress indicator during AI processing
- Display result stats (tagged/skipped/failed) after completion
- Add batchTagProgramProjects endpoint for edition-wide tagging
- Fix getFilterOptions to include program.id for filtering
- Improve error handling with toast notifications

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 10:27:52 +01:00
Matt 7f95f681d6 Fix AI tagging issues and improve error messages
Build and Push Docker Image / build (push) Successful in 9m33s Details
- Fall back to ai_enabled setting if ai_tagging_enabled not set
- Check both tags array and projectTags relationship for untagged projects
- Add detailed logging for debugging
- Show errors in toast instead of just counts
- Handle "no projects to tag" case with appropriate message
- Add early checks for OpenAI config and available tags

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 09:24:44 +01:00
Matt 6f6d5ef501 Add visual progress indicator for AI assignment batches
Build and Push Docker Image / build (push) Successful in 9m13s Details
- Add AssignmentJob model to track AI assignment progress
- Create startAIAssignmentJob mutation for background processing
- Add getAIAssignmentJobStatus query for polling progress
- Update AI assignment service with progress callback support
- Add progress bar UI showing batch/project processing status
- Add toast notifications for job completion/failure
- Add AI_SUGGESTIONS_READY notification type

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:40:26 +01:00
Matt 148925cb95 Fix AI suggestions query running twice
Build and Push Docker Image / build (push) Successful in 9m8s Details
Disable automatic refetching for expensive AI assignment query:
- Set staleTime to Infinity (never auto-refetch)
- Disable refetchOnWindowFocus, refetchOnReconnect, refetchOnMount
- Only manual refresh via button will trigger new request

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:19:20 +01:00
Matt c45a428d8b Add AI Assignment toggle and Tags tab to settings
Build and Push Docker Image / build (push) Successful in 9m25s Details
- Add "Use AI" button to assignments page to switch between algorithmic and GPT-powered suggestions
- Normalize AI suggestions format to match algorithmic format for consistent UI
- Add Tags tab to Settings page with link to expertise tags management
- AI assignment mode shows GPT-analyzed suggestions with confidence scores

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 16:56:07 +01:00
Matt c0f318a867 Add country mapping support for imports and geographic map
Build and Push Docker Image / build (push) Successful in 9m7s Details
- Add normalizeCountryToCode utility to convert country names to ISO-2 codes
- Support English, French and common alternate spellings
- Update Typeform import to support country field mapping
- Update Notion import to support country field mapping
- Allow project.update to set/update country with automatic normalization
- Fix geographic distribution map showing empty when country data exists

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 16:13:40 +01:00
Matt 6d2537ec04 Add per-round assignment constraints (min/max per judge)
Build and Push Docker Image / build (push) Successful in 9m41s Details
- Add minAssignmentsPerJuror and maxAssignmentsPerJuror fields to Round model
- Update assignment router:
  - Calculate effective max from user override or round default
  - Add forceOverride parameter for manual assignment beyond limits
  - Update getSuggestions to use round constraints with min target bonus
  - Update getAISuggestions to pass constraints to AI service
- Update AI assignment service:
  - Add minAssignmentsPerJuror to constraints interface
  - Update fallback algorithm with under-min bonus scoring
  - New score weights: 50% expertise, 30% load, 20% under-min bonus
- Update round router:
  - Add new constraint fields to create/update schemas
  - Add validation for min <= max constraint
- Update admin UI:
  - Add min/max constraint fields to round edit page
  - Remove hardcoded maxPerJuror from assignments page
- Add migration files for production deployment:
  - User.bio field for judge/mentor profiles
  - Round assignment constraint fields

Constraint hierarchy:
1. User.maxAssignments (if set) overrides round default
2. Round.maxAssignmentsPerJuror is the default cap
3. Admin can force-override any limit with confirmation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 16:01:18 +01:00
Matt ff26769ce1 Add bio field and enhance smart assignment with bio matching
Build and Push Docker Image / build (push) Successful in 9m13s Details
- Add bio field to User model for judge/mentor profile descriptions
- Add bio step to onboarding wizard (optional step with 500 char limit)
- Enhance smart assignment to match judge bio against project description
  - Uses keyword extraction and Jaccard-like similarity scoring
  - Only applies if judge has a bio (no penalty for empty bio)
  - Max 15 points for bio match on top of existing scoring
- Fix geographic distribution query to use round relation for programId
- Update score breakdown: tags (40), bio (15), workload (25), country (15)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 15:27:28 +01:00
Matt 3a7177c652 Rename Assignments to Judge Assignments for clarity
Build and Push Docker Image / build (push) Successful in 9m21s Details
Updates labels in admin round pages:
- "Assignments" → "Judge Assignments"
- "Manage Assignments" → "Manage Judge Assignments"
- "Current Assignments" → "Current Judge Assignments"
- Updated descriptions to reference judges instead of jury members

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 15:15:10 +01:00
Matt 5cbcad28ad Add AI Tags button to admin projects page
Build and Push Docker Image / build (push) Has been cancelled Details
Adds a new "AI Tags" button that opens a dialog to batch-generate
expertise tags using AI for all untagged projects in a selected round.

The feature uses the existing tag.batchTagProjects endpoint which:
- Only processes projects without existing tags
- Preserves any manually added tags
- Logs AI usage for cost tracking

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 15:08:46 +01:00
Matt d1f7f0361d Add migration for Round.sortOrder field
Build and Push Docker Image / build (push) Successful in 9m22s Details
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 14:32:52 +01:00
Matt 29827268b2 Remove dynamic form builder and complete RoundProject→roundId migration
Build and Push Docker Image / build (push) Successful in 14m3s Details
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
Matt 7bcd2ce6ca Remove red focus ring from command input
Build and Push Docker Image / build (push) Successful in 8m55s Details
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 09:54:37 +01:00
Matt 20db3e1e3a Add visual indicator for eliminated projects
Build and Push Docker Image / build (push) Has been cancelled Details
- Shows "Eliminated" badge next to round name for REJECTED projects
- Rows for eliminated projects have reduced opacity and red tint
- Works in both table and mobile card views

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 09:49:31 +01:00
Matt 68c0ed00e4 Add manual assignment feature to assignments page
- Added "Manual Assignment" button with dialog
- Select jury member and project from dropdowns
- Shows current assignment counts and prevents duplicates
- Disables full-capacity jurors and already-assigned combinations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 09:45:32 +01:00
Matt 1b12aa8ccd Fix smart assignment suggestions to display juror/project names
Build and Push Docker Image / build (push) Successful in 8m57s Details
The suggestions table was showing truncated IDs instead of actual names.
Updated getSuggestions to include jurorName and projectTitle in response.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 09:36:33 +01:00
Matt 8cdf6c9e5e Add unified expertise tag system and round entry notifications
Build and Push Docker Image / build (push) Successful in 9m14s Details
- ExpertiseSelect now fetches tags from database with category grouping
- Tags set by admin during invitation are locked and cannot be removed
- Onboarding merges user-selected tags with admin-preset tags
- MENTOR role now goes through onboarding flow
- Added migration for Round.entryNotificationType column
- Added seed script with ~90 comprehensive expertise tags

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:15:21 +01:00
Matt 41a36f72b3 Add WhatsApp feature flag and improve onboarding
Build and Push Docker Image / build (push) Failing after 2m59s Details
- Add getFeatureFlags endpoint to check if WhatsApp is enabled
- Skip phone step in onboarding when WhatsApp is disabled
- Hide WhatsApp notification options when disabled
- Add ExpertiseSelect component with predefined ocean conservation tags
- Fix onboarding layout to fill viewport on desktop

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 00:58:22 +01:00
Matt 4f0531d2ee Add ExpertiseSelect component for onboarding
Replace database-backed TagInput with a cleaner ExpertiseSelect
component that has predefined ocean conservation expertise areas.
Features a checkbox grid UI that's more user-friendly for onboarding.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 00:56:03 +01:00
Matt 39f7bc207b Use PhoneInput component with country dropdown in onboarding
Replace plain text input with the existing PhoneInput component that
includes country code dropdown with flags and auto-formatting.
Default country is set to Monaco (MC).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 00:54:57 +01:00
Matt a3cc73e49d Fix redirect loop for users who need to set password
Build and Push Docker Image / build (push) Successful in 8m19s Details
The auth layout was redirecting logged-in users to their dashboard even
when they still needed to set their password. This caused a redirect
loop: auth layout redirects to /jury, middleware redirects back to
/set-password, repeat until crash.

Now the auth layout checks mustSetPassword before redirecting, allowing
users to complete the password setup flow.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 00:41:32 +01:00
Matt 0f956cf23f Fix invitation flow by allowing unauthenticated tRPC requests
Build and Push Docker Image / build (push) Successful in 8m28s Details
The middleware was blocking /api/trpc requests for unauthenticated users,
which prevented the accept-invite page from calling the public
validateInviteToken procedure. tRPC handles its own authentication
via procedure middleware, so the NextAuth middleware should allow
all tRPC requests through.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 00:26:05 +01:00
Matt b0189cad92 Add styled notification emails and round-attached notifications
Build and Push Docker Image / build (push) Successful in 8m18s Details
- Add 15+ styled email templates matching existing invite email design
- Wire up notification triggers in all routers (assignment, round, project, mentor, application, onboarding)
- Add test email button for each notification type in admin settings
- Add round-attached notifications: admins can configure which notification to send when projects enter a round
- Fall back to status-based notifications when round has no configured notification

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 00:10:51 +01:00