Redesign the rounds page from a card-per-competition layout to a flat
pipeline/timeline view. Rounds display as compact rows connected by a
vertical track with status dots (pulsing green for active). Special
awards branch off to the right from their linked evaluation round with
connector lines and tooltip details. Competition settings moved to a
dialog behind a gear icon. Filter pills replace the dropdown selector.
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>
- Add assignAllToRound mutation to project-pool router
- Rewrite pool page with round selector, bulk assignment, and better layout
- Add pool navigation link to admin projects page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename [id] → [competitionId] under /admin/competitions/ to fix
Next.js "different slug names for same dynamic path" error
- Update params.id → params.competitionId in competition detail page
- Fix seed import: use .js extension for tsx ESM module resolution
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>
Build and Push Docker Image / build (push) Failing after 9sDetails
- 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>
Build and Push Docker Image / build (push) Failing after 40sDetails
- 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>
Build and Push Docker Image / build (push) Failing after 9m17sDetails
Switch invite page from DB query (user.me) to JWT session for role checks,
avoiding failures when user ID is stale. Return friendly error from user.me
instead of throwing on missing user.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Has been cancelledDetails
- Refactor role selector to use computed availableRoles array instead of
conditional JSX fragments, fixing Radix Select not re-rendering admin
options when async user data loads
- Rewrite 38 generic expertise tags to 44 MOPC-specific tags across 8
categories aligned with OceanIssue enum: Pollution & Waste, Climate &
Carbon, Seafood & Aquaculture, Biodiversity & Habitat, Ocean Technology,
Shipping & Ports, Community & Education, Business & Investment
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 9m51sDetails
- 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>
Build and Push Docker Image / build (push) Successful in 9m31sDetails
- 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>
Build and Push Docker Image / build (push) Successful in 10m2sDetails
The DB configJson uses different field names than wizard types expect
(e.g., deterministic.rules vs rules, votingEnabled vs juryVotingEnabled).
The ?? operator only guards null/undefined, but configJson is {} (truthy),
so defaults never applied. This caused config.rules.map() to crash with
"Cannot read properties of undefined (reading 'map')".
Fix: spread defaults first then overlay DB values, and add defensive ??
fallbacks in all section components for potentially undefined properties.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 10m55sDetails
- Make pipeline cards clickable on list page (navigate to detail view)
- Fix broken nav link: applicant /messages → /mentor
- Fix broken nav link: mentor /messages → /projects
- Add isActive field locking to all 7 wizard sections (intake, main-track,
filtering, assignment, awards, live-finals, notifications)
- Add minLoad ≤ maxLoad cross-field validation in assignment section
- Add duplicate stage slug detection in main track section
- Add active pipeline warning banners in intake and main track sections
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 13m22sDetails
Move the "Required Reviews per Project" field from the Basic Information
card into the Evaluation Settings section of RoundTypeSettings, where it
contextually belongs. Add missing database migration for live voting
enhancements (criteria voting, audience voting, AudienceVoter table).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 10m30sDetails
- New projects (admin create, CSV import, public form) auto-assign to program's
first round (by sortOrder) when no round is specified
- Closing a FILTERING round auto-starts filtering job (configurable via
autoFilterOnClose setting, defaults to true)
- Add SUBMISSION_RECEIVED notification type for confirming submissions
- Replace separate List/Pipeline toggle with integrated pipeline view below
the sortable round list
- Add autoFilterOnClose toggle to filtering round type settings UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 11m20sDetails
- Add project-wide reporting table with scope selector (all rounds / per round)
- Fix horizontal overflow on mobile (body, admin sidebar, logo truncation)
- Make members header and reports tabs responsive with flex-wrap
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 10m25sDetails
- Jury dashboard: collapse zero-assignment state into single welcome card
with inline quick actions; merge completion bar into stats row; tighten spacing
- Manual assignment: replace tiny Dialog modal with inline collapsible section
featuring searchable juror combobox and multi-select project list with bulk assign
- Fix applicant invite URL path (/auth/accept-invite -> /accept-invite)
- Add APPLICANT role redirect to /my-submission from root page
- Add Applicant label to accept-invite role display
- Fix a/an grammar in invitation emails and accept-invite page
- Set-password page: use MOPC logo instead of lock icon
- Notification bell: remove filter tabs, always show all notifications
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 10m22sDetails
- Reports page now shows platform-wide stats even when no rounds exist
- Fix missing getCountryFlag import on projects page
- Clean up Docker entrypoint: remove hardcoded migrate resolve
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Has been cancelledDetails
- Add missing migration for FileRequirement table and ProjectFile.requirementId
column (existed in Prisma schema but had no migration, causing all queries
with `include: { files: true }` to fail with column not found)
- Make projectTags query resilient with try-catch in project.get
- Reset project status to SUBMITTED when round is deleted (prevents orphaned
ASSIGNED status after ON DELETE SET NULL nullifies roundId)
- Fix round creation/update to allow requiredReviews=0 for filtering rounds
- Parse Zod validation errors in round creation error display
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 15m32sDetails
- Extract observer dashboard to client component, add PDF export button
- Add PDF report generator with jsPDF for analytics reports
- Overhaul jury evaluation page with improved layout and UX
- Add new analytics endpoints for observer/admin reports
- Improve round creation/edit forms with better settings
- Fix filtering rules page, CSV export dialog, notification bell
- Update auth, prisma schema, and various type fixes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Round detail: add skeleton loading for filtering stats, inline results table
with expandable rows, pagination, override/reinstate, CSV export, and tooltip
on AI summaries button (removes need for separate results page)
- Projects: add select-all-across-pages with Gmail-style banner, show country
flags with tooltip instead of country codes (table + card views), add listAllIds
backend endpoint
- Settings: allow PROGRAM_ADMIN access to settings page, restrict infrastructure
tabs (AI, Email, Storage, Security, Webhooks) to SUPER_ADMIN only
- Members: add inline role change via dropdown submenu in user actions, enforce
role hierarchy (only super admins can modify admin/super-admin roles) in both
backend and UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 11m24sDetails
- Guard onboarding tRPC queries with session hydration check (fixes UNAUTHORIZED on first login)
- Defer expensive queries on awards page until UI elements are opened (dialog/tab)
- Fix perPage: 500 exceeding backend Zod max of 100 on awards eligibility query
- Add smooth open/close animation to project filters collapsible bar
- Fix seeded user status from ACTIVE to INVITED in seed-candidatures.ts
- Add router.refresh() cache invalidation across ~22 admin forms
- Fix geographic analytics query to use programId instead of round.programId
- Fix dashboard queries to scope by programId correctly
- Fix project.listPool and round queries for projects outside round context
- Add rounds page useEffect for state sync after mutations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 10m7sDetails
- Fix round deletion FK constraint: add onDelete Cascade on Evaluation.form and SetNull on ProjectFile.round
- Add configurable per-page selector (10/20/50/100) to Pagination component, wired in projects page with URL sync
- Add display_project_names_uppercase setting in admin defaults, applied to project titles across desktop/mobile views
- Redesign admin settings page: vertical sidebar nav on desktop with grouped sections, horizontal scrollable tabs on mobile
- Polish projects page: responsive header with total count, search clear button with result count, status stats bar, submission date column, country display, mobile card file count
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 10m11sDetails
Part A: File Requirements per Round
- New FileRequirement model with name, description, accepted MIME types, max size, required flag, sort order
- Added requirementId FK to ProjectFile for linking uploads to requirements
- Backend CRUD (create/update/delete/reorder) in file router with audit logging
- Mime type validation and team member upload authorization in applicant router
- Admin UI: FileRequirementsEditor component in round edit page
- Applicant UI: RequirementUploadSlot/List components in submission detail and team pages
- Viewer UI: RequirementChecklist with fulfillment status in file-viewer
Part B: Super Admin Promotion
- Added SUPER_ADMIN to role enums in user create/update/bulkCreate with guards
- Member detail page: SUPER_ADMIN dropdown option with AlertDialog confirmation
- Invite page: SUPER_ADMIN option visible only to super admins
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build and Push Docker Image / build (push) Failing after 3m29sDetails
- 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>
Build and Push Docker Image / build (push) Successful in 9m56sDetails
- 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>
Build and Push Docker Image / build (push) Has been cancelledDetails
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>
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>
Build and Push Docker Image / build (push) Successful in 9m43sDetails
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>