- Fix bug: AI assignment router read non-existent `(m as any).maxAssignments`
instead of the actual schema field `m.maxAssignmentsOverride`
- Wire `jurorLimits` record into AI assignment constraints so per-juror
caps are respected during both AI scoring and algorithmic assignment
- Add inline editable cap in jury members table (click to edit, blur/enter
to save, empty = no cap / use group default)
- Add inline editable cap badges on round page member list so admins can
set caps right from the assignment workflow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rewrite AIRecommendationsDisplay: show project titles, per-project
checkboxes, Apply and Mark as Passed button with batch transition
- Show AI jury assignment reasoning directly in rows (not tooltip)
- Fix unassigned projects badge using requiredReviews instead of hardcoded 3
- Add aiParseFiles to EvaluationConfigSchema
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Server: presigned GET URLs now include Content-Disposition: attachment header
when forDownload=true, triggering native browser downloads on all platforms
- Download button uses window.location.href with attachment URL (works on iOS Safari)
- Bulk download uses hidden iframes instead of fetch+blob
- Fix COI gate: getCOIStatus returns null (not undefined) when undeclared,
so `!== undefined` was always true — changed to `!= null`
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Integrate COI declaration dialog into jury evaluate page (blocks evaluation until declared)
- Add COI review section to admin round page with clear/reassign/note actions
- Fix mobile: remove inline preview (viewport too small), add labeled buttons
- Fix iOS: open-in-new-tab uses synchronous window.open to avoid popup blocker
- Fix iOS: download falls back to direct link if fetch+blob fails (CORS/Safari)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace MultiWindowDocViewer with FileViewer for inline previews (PDF/image/video/Office)
- Fix cross-origin download using fetch+blob instead of <a download>
- Show Startup/Business Concept badge on jury project detail + evaluate pages
- Add admin resetEvaluation procedure with audit logging
- Add dropdown menu on admin assignment rows with Reset Evaluation + Delete
- Make file action buttons responsive on mobile (separate row below file info)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix project documents not displaying on jury project page (rewrote MultiWindowDocViewer to use file.listByProject)
- Add working download/preview for project files via presigned URLs
- Display project tags on jury project detail page
- Add autosave for evaluation drafts (debounced 3s + save on unmount/beforeunload)
- Support mixed criterion types: numeric scores, yes/no booleans, text responses, section headers
- Replace inline criteria editor with rich EvaluationFormBuilder on admin round page
- Remove COI dialog from evaluation page
- Update AI summary service to handle boolean/text criteria (yes/no counts, text synthesis)
- Update EvaluationSummaryCard to show boolean criteria bars and text responses
- Add evaluation detail sheet on admin project page (click juror row to view full scores + feedback)
- Add Recent Evaluations dashboard widget showing latest jury reviews
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- finalizeResults now queries confirmed SEPARATE_POOL shortlist and
excludes those projects from the main pool ELIGIBLE set
- Finalize confirmation dialog shows breakdown: main pool vs award-routed
- Finalize toast includes award-routed count
- Audit log records routedToAwards count
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Stats cards show new 'Award Track' card with count of confirmed
SEPARATE_POOL shortlisted projects
- Passed card shows breakdown (main + award) when awards are routed
- Results table shows award badge on projects routed to award tracks
- getResults query includes confirmed award eligibility data per project
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Auth layout verifies user exists in DB before redirecting to dashboard,
breaking infinite loop for deleted accounts with stale sessions
- Jury/Mentor layouts handle null user (deleted) by redirecting to login
- Filtering stats cards and result list now use effective outcome
(finalOutcome ?? outcome) instead of raw AI outcome
- Award eligibility evaluation includes admin-overridden PASSED projects
- Award shortlist reasoning column shows full text instead of truncating
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reduced badge size (text-[11px], h-5, tighter padding/gaps) and capped
the selected tags container to max-h-20 with overflow scroll so they
no longer push the rest of the form off-screen on mobile.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Single AI call now evaluates both screening criteria AND award eligibility.
Awards with useAiEligibility + criteriaText are appended to the system prompt,
AI returns award_matches per project, results auto-populate AwardEligibility
and auto-shortlist top-N. Re-running filtering clears and re-evaluates awards.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
- Add missing fields to FilteringConfigSchema (aiParseFiles, startupAdvanceCount,
conceptAdvanceCount, notifyOnEntry, notifyOnAdvance) — Zod was silently
stripping them on save
- Restore auto-save with 800ms debounce on config changes
- Add staggered animations for filtering results (stream in one-by-one)
- Improve AI screening prompt: file type label mappings, soft cap handling,
missing documents = fail, better user prompt structure
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removes duplicate: the setting was in Config tab (General Settings) AND
inside Advanced Settings in the Filtering tab. Now it lives only in the
Filtering tab as a prominent standalone toggle, since it's directly
related to AI filtering behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace auto-save with manual floating save bar that appears when config
has unsaved changes (Discard / Save Changes buttons). Fixes race condition
where server sync overwrote local state after toggling switches.
- Show file requirement name (e.g. "Pitch Deck", "Presentation") above each
document in the All Uploaded Files section on project detail page
- Pass requirement relation data through to FileViewer component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add filtering results summary card on round Overview tab with pass/fail/flag
counts and color-coded progress bar (polls every 5s)
- Auto-delete previous filtering results when re-running so new ones stream in
- Rename BUSINESS_CONCEPT to "Concept" in filtering results to prevent overflow
- Fix config save race condition where toggling switches (aiParseFiles, advance
counts) would revert: pendingSaveRef cleared before refetch completed
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
- Add aiPreview mutation with full project/juror data (bios, descriptions,
documents, categories, ocean issues, countries, team sizes)
- Increase AI description limit from 300 to 2000 chars for richer context
- Update GPT system prompt to use all available data fields
- Add mode toggle (AI default / Algorithm fallback) in assignment preview
- Lift AI mutation to parent page for background generation persistence
- Show visual indicator on page while AI generates (spinner + progress card)
- Toast notification with "Review" action when AI completes
- Staggered reveal animation for assignment results (streaming feel)
- Fix assignment balance with dynamic penalty (25pts per existing assignment)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace bare summary stats with full interactive assignment preview:
- Assignments grouped by juror with collapsible cards
- Per-assignment detail: match score, tags, reasoning, policy warnings
- Remove individual assignments with hover X button
- Inline add projects per juror + global juror/project picker
- No cap enforcement on manual adds (admin override)
- Track manual additions and removals with badge indicators
- Include user details in round.getById jury group members query
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Voting check now uses round.status === ROUND_ACTIVE instead of requiring
windowOpenAt/windowCloseAt date range, fixing manual open/reopen scenarios.
Added requireDocumentUpload toggle (default off) to evaluation round config
so rounds reusing prior-round documents don't need file requirements.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add AutoRefresh client component that calls router.refresh() on an
interval. Pauses when tab is hidden and refreshes immediately when
tab becomes visible again. Jury dashboard now reflects round
activations within seconds.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix assignments page header overflow on mobile (flex-wrap)
- Hide 'Back to Dashboard' button on mobile (logo tap navigates home)
- Make logo/brand text clickable to navigate to role dashboard
- Snap windowOpenAt to now when manually activating a round early
- Gate Compare Projects cards behind jury_compare_enabled setting (defaults off)
- Expose jury_compare_enabled in getFeatureFlags tRPC procedure
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix criteria not showing for jurors: fetch active form independently via
getStageForm query instead of relying on existing evaluation record
- Fix scoringMode default from 'global' to 'criteria' (matching schema)
- Parse scale string format ("1-10") into minScore/maxScore for criteria display
- Fix COI dialog dismissal: prevent outside click on evaluate page Dialog
- Fix requiredReviews hardcoded to 3: read from round configJson in 4 locations
- Add jury preferences banner for unconfirmed caps on jury dashboard
- Add updateJuryPreferences tRPC procedure for self-service cap/ratio
- Simplify onboarding: always show jury step, allow cap up to 50
- Add role/ratio/availability fields to jury member invite dialog
- Simplify jury group settings (keep only defaultMaxAssignments)
- Enforce deliberation showCollectiveRankings flag for non-admin users
- Redesign dashboard stat cards: editorial data strip on mobile,
clean grid layout on desktop (no more generic card pattern)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix onboarding card overflow (overflow-hidden → overflow-x-hidden) so
expertise step can scroll to submit button
- Reduce expertise category list height (max-h-64 → max-h-48)
- Add color dots to expertise tag options matching admin display
- Single-column layout for expertise tags (no truncation)
- Ocean background on onboarding (matches email template)
- Rewrite jury competitions page as assignment-centric grouped by round
- Conditionally show Awards nav item only when juror has award assignments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace blue gradient with ocean.png background (matches email templates)
- Display expertise tags one per line with full names (no truncation)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Complete rewrite of the admin dashboard replacing the 1056-line monolith with
modular components. Key improvements:
- Competition pipeline: horizontal visualization of all rounds in pipeline order
(by sortOrder, not creation date) with type-specific icons and metrics
- Round-specific stats: stat cards dynamically change based on active round type
(INTAKE shows submissions/docs, FILTERING shows pass/fail/flagged, EVALUATION
shows assignments/completion, fallback shows generic project/jury stats)
- Smart actions: context-aware "Action Required" panel that only flags the next
draft round (not all), only flags unassigned projects for EVALUATION rounds,
includes deadline warnings with severity levels (critical/warning/info)
- Active round panel: detailed view with project state bar, type-specific content,
and deadline countdown
- Extracted components: project list, activity feed, category breakdown, skeleton
Backend enriched with 17 parallel queries building rich PipelineRound data
including per-round project states, eval stats, filtering stats, live session
status, and deliberation counts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces a document analyzer service that extracts page count (via pdf-parse),
text preview, and detected language (via franc) from uploaded files. Analysis runs
automatically on upload (configurable via SystemSettings) and can be triggered
retroactively for existing files. Results are displayed as badges in the FileViewer
and fed to AI screening for language-based filtering criteria.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add utils.user.list.invalidate() after mutations that change user
status to ensure member lists refresh without manual page reload:
- Member detail page: after update and send invitation
- User mobile actions: after send invitation
- Add member dialog: after send invitation in jury group flow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Assignment dialog overhaul: replace raw UUID inputs with searchable
juror Combobox (shows name, email, capacity) and multi-select project
checklist with bulk assignment support
2. Query invalidation sweep: fix missing invalidations in
assignment-preview-sheet (roundAssignment.execute) and
filtering-dashboard (filtering.finalizeResults) so data refreshes
without page reload
3. Rename Submissions tab to Document Windows with descriptive
header explaining upload window configuration
4. Connect 6 disconnected settings: storage_provider, local_storage_path,
avatar_max_size_mb, allowed_image_types, whatsapp_enabled,
whatsapp_provider - all now accessible in Settings UI
5. Admin dashboard redesign: branded Editorial Command Center with
Dark Blue gradient header, colored border-l-4 stat cards, staggered
animations, 2-column layout, action-required panel, activity timeline
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add ai_provider setting: 'openai' (API key) or 'litellm' (ChatGPT subscription proxy)
- Auto-strip max_tokens/max_completion_tokens for chatgpt/ prefix models
(ChatGPT subscription backend rejects token limit fields)
- LiteLLM mode: dummy API key when none configured, base URL required
- isOpenAIConfigured() checks base URL instead of API key for LiteLLM
- listAvailableModels() returns manualEntry flag for LiteLLM (no models.list)
- Settings UI: conditional fields, info banner, manual model input with
chatgpt/ prefix examples when LiteLLM selected
- All 7 AI services work transparently via buildCompletionParams()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change AI tagging to use AI_MODELS.QUICK (gpt-4o-mini) instead of gpt-4o for
10-15x cost reduction on classification tasks
- Add openai_base_url system setting for OpenAI-compatible providers
(OpenRouter, Groq, Together AI, local models)
- Reset OpenAI client singleton when API key, base URL, or model changes
- Add base URL field to AI settings form with provider examples
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added Jury tab to round detail page with full jury management inline
- Create new jury groups (auto-assigns to current round)
- Delete jury groups with confirmation dialog
- Add/remove members with inline member list
- Assign/switch jury groups via dropdown selector
- Added delete endpoint to juryGroup router (unlinks rounds, deletes members)
- Removed CHAIR/OBSERVER role selectors from add-member dialog (all members)
- Removed role column from jury-members-table
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add reopenRound() to round engine (CLOSED → ACTIVE) with auto-pause of subsequent active rounds
- Add reopen endpoint to roundEngine router and UI button on round detail page
- Replace free-text MIME type input with toggle-only badge buttons in file requirements editor
- Enable refetchOnWindowFocus and shorter polling intervals for readiness checklist queries
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Per-juror cap mode (HARD/SOFT/NONE) in add-member dialog and members table
- Jury invite flow: create user + add to group + send invitation from dialog
- Per-round config: notifyOnAdvance, aiParseFiles, startupAdvanceCount, conceptAdvanceCount
- Moved notify-on-advance from competition-level to per-round setting
- AI filtering: round-tagged files with newest-first sorting, optional file content extraction
- File content extractor service (pdf-parse for PDF, utf-8 for text files)
- AI shortlist runs independently per category (STARTUP / BUSINESS_CONCEPT)
- generateAIRecommendations tRPC endpoint with per-round config integration
- AI recommendations UI: trigger button, confirmation dialog, per-category results display
- Category-aware advance dialog: select/deselect projects by category with target caps
- STAGE_ACTIVE bug fix in assignment router
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Round detail page: 15s for live data (projects, assignments, scores, workload), 30s for config, 60s for static data
- Filtering dashboard: 15s for results/stats, 30s for rules (job status already 2s)
- Project states table: 15s polling
- Coverage report: 15s polling
- Jury round page: 30s for assignments and round data
- Deliberation session: 10s polling for live vote updates
- Admin dashboard: 30s for stats
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
Replace Pipeline/Stage system with Competition/Round architecture.
New schema: Competition, Round (7 types), JuryGroup, AssignmentPolicy,
ProjectRoundState, DeliberationSession, ResultLock, SubmissionWindow.
New services: round-engine, round-assignment, deliberation, result-lock,
submission-manager, competition-context, ai-prompt-guard.
Full admin/jury/applicant/mentor UI rewrite. AI prompt hardening with
structured prompts, retry logic, and injection detection. All legacy
pipeline/stage code removed. 4 new migrations + seed aligned.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove RoutingRule model and routing engine (replaced by direct award assignment)
- Simplify RoutingMode enum: PARALLEL/POST_MAIN → SHARED, keep EXCLUSIVE
- Remove routing router, routing-rules-editor, and related tests
- Update pipeline, award, and notification code to remove routing references
- Seed: include all CSV entries (no filtering/dedup), AI screening handles duplicates
- Seed: fix non-breaking space (U+00A0) bug in category/issue mapping
- Stage filtering: add duplicate detection that flags projects for admin review
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Simplify pipeline list cards: whole card is clickable, remove clutter
- Add wizard edit page for existing pipelines with full state pre-population
- Extract toWizardTrackConfig to shared utility for reuse
- Rewrite predicate builder with 3 modes: Simple (sentence-style), AI (NLP), Advanced (JSON)
- Fix routing operators to match backend (eq/neq/in/contains/gt/lt)
- Rewrite routing rules editor with collapsible cards and natural language summaries
- Add parseNaturalLanguageRule AI procedure for routing rules
- Add per-category quotas to SelectionConfig and EvaluationConfig
- Add category quota UI toggles to selection and assignment sections
- Add category breakdown display to selection panel
- Add category-aware scoring to smart assignment (penalty/bonus)
- Add category-aware filtering targets with excess demotion
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously checkboxes only appeared for users with status NONE (Not Invited),
hiding them for INVITED/ACTIVE members and making "Select all" confusing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Sheet UI component and StageDetailSheet with config/activity tabs
- Stage config opens in right-side sheet (always-editable, no collapsed summary)
- Replace JSON textarea in routing rules with structured PredicateBuilder form
- Remove StageTransitionsEditor from UI (transitions auto-managed)
- Promote Stage Management section to immediately after flowchart
- Conditionally hide Routing Rules (single track) and Award Governance (no awards)
- Add section headers with descriptions and increase spacing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix critical crash when clicking Edit on INTAKE stage configs: normalize
DB fileRequirements shape (type/required → acceptedMimeTypes/isRequired),
add null guard in getActiveCategoriesFromMimeTypes
- Fix config summary display for all stage types to handle seed data key
mismatches (votingEnabled→juryVotingEnabled, minAssignmentsPerJuror→
minLoadPerJuror, deterministic.rules→rules, etc.)
- Add AWARD_MASTER role to invite page dropdown and user router validations
- Restructure settings sidebar: Tags and Webhooks as direct links instead
of nested tabs, remove redundant Quick Links section
- Seed 38 expertise tags across 7 categories (Marine Science, Technology,
Policy, Conservation, Business, Education, Engineering)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Detail page header: stack on mobile, icon-only Advanced button on small screens
- InlineEditableText: show pencil icon on mobile (not hover-only)
- EditableCard: show Edit button on mobile (not hover-only)
- PipelineFlowchart: add right-edge fade gradient as scroll hint on mobile
- Summary cards: always 3-col grid (compact on mobile)
- Track switcher: add overflow-x-auto for horizontal scroll
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>