2026-01-30 13:41:32 +01:00
|
|
|
// =============================================================================
|
|
|
|
|
// MOPC Platform - Prisma Schema
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// This schema defines the database structure for the Monaco Ocean Protection
|
|
|
|
|
// Challenge jury voting platform.
|
|
|
|
|
|
|
|
|
|
generator client {
|
|
|
|
|
provider = "prisma-client-js"
|
|
|
|
|
binaryTargets = ["native", "windows", "linux-musl-openssl-3.0.x"]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
datasource db {
|
|
|
|
|
provider = "postgresql"
|
|
|
|
|
url = env("DATABASE_URL")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// ENUMS
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
enum UserRole {
|
|
|
|
|
SUPER_ADMIN
|
|
|
|
|
PROGRAM_ADMIN
|
|
|
|
|
JURY_MEMBER
|
|
|
|
|
MENTOR
|
|
|
|
|
OBSERVER
|
|
|
|
|
APPLICANT
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum UserStatus {
|
2026-02-10 23:08:00 +01:00
|
|
|
NONE
|
2026-01-30 13:41:32 +01:00
|
|
|
INVITED
|
|
|
|
|
ACTIVE
|
|
|
|
|
SUSPENDED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum ProgramStatus {
|
|
|
|
|
DRAFT
|
|
|
|
|
ACTIVE
|
|
|
|
|
ARCHIVED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum RoundStatus {
|
|
|
|
|
DRAFT
|
|
|
|
|
ACTIVE
|
|
|
|
|
CLOSED
|
|
|
|
|
ARCHIVED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum ProjectStatus {
|
|
|
|
|
SUBMITTED
|
|
|
|
|
ELIGIBLE
|
|
|
|
|
ASSIGNED
|
|
|
|
|
SEMIFINALIST
|
|
|
|
|
FINALIST
|
|
|
|
|
REJECTED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum EvaluationStatus {
|
|
|
|
|
NOT_STARTED
|
|
|
|
|
DRAFT
|
|
|
|
|
SUBMITTED
|
|
|
|
|
LOCKED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum AssignmentMethod {
|
|
|
|
|
MANUAL
|
|
|
|
|
BULK
|
|
|
|
|
AI_SUGGESTED
|
|
|
|
|
AI_AUTO
|
|
|
|
|
ALGORITHM
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum FileType {
|
|
|
|
|
EXEC_SUMMARY
|
|
|
|
|
PRESENTATION
|
|
|
|
|
VIDEO
|
|
|
|
|
OTHER
|
|
|
|
|
BUSINESS_PLAN
|
|
|
|
|
VIDEO_PITCH
|
|
|
|
|
SUPPORTING_DOC
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum SubmissionSource {
|
|
|
|
|
MANUAL
|
|
|
|
|
CSV
|
|
|
|
|
NOTION
|
|
|
|
|
TYPEFORM
|
|
|
|
|
PUBLIC_FORM
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum RoundType {
|
|
|
|
|
FILTERING
|
|
|
|
|
EVALUATION
|
|
|
|
|
LIVE_EVENT
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum SettingType {
|
|
|
|
|
STRING
|
|
|
|
|
NUMBER
|
|
|
|
|
BOOLEAN
|
|
|
|
|
JSON
|
|
|
|
|
SECRET
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum SettingCategory {
|
|
|
|
|
AI
|
|
|
|
|
BRANDING
|
|
|
|
|
EMAIL
|
|
|
|
|
STORAGE
|
|
|
|
|
SECURITY
|
|
|
|
|
DEFAULTS
|
|
|
|
|
WHATSAPP
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
AUDIT_CONFIG
|
|
|
|
|
LOCALIZATION
|
|
|
|
|
DIGEST
|
|
|
|
|
ANALYTICS
|
2026-02-08 14:37:32 +01:00
|
|
|
INTEGRATIONS
|
|
|
|
|
COMMUNICATION
|
2026-01-30 13:41:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum NotificationChannel {
|
|
|
|
|
EMAIL
|
|
|
|
|
WHATSAPP
|
|
|
|
|
BOTH
|
|
|
|
|
NONE
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum ResourceType {
|
|
|
|
|
PDF
|
|
|
|
|
VIDEO
|
|
|
|
|
DOCUMENT
|
|
|
|
|
LINK
|
|
|
|
|
OTHER
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum CohortLevel {
|
|
|
|
|
ALL
|
|
|
|
|
SEMIFINALIST
|
|
|
|
|
FINALIST
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum PartnerVisibility {
|
|
|
|
|
ADMIN_ONLY
|
|
|
|
|
JURY_VISIBLE
|
|
|
|
|
PUBLIC
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum PartnerType {
|
|
|
|
|
SPONSOR
|
|
|
|
|
PARTNER
|
|
|
|
|
SUPPORTER
|
|
|
|
|
MEDIA
|
|
|
|
|
OTHER
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// APPLICANT SYSTEM ENUMS
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
enum CompetitionCategory {
|
|
|
|
|
STARTUP // Existing companies
|
|
|
|
|
BUSINESS_CONCEPT // Students/graduates
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum OceanIssue {
|
|
|
|
|
POLLUTION_REDUCTION
|
|
|
|
|
CLIMATE_MITIGATION
|
|
|
|
|
TECHNOLOGY_INNOVATION
|
|
|
|
|
SUSTAINABLE_SHIPPING
|
|
|
|
|
BLUE_CARBON
|
|
|
|
|
HABITAT_RESTORATION
|
|
|
|
|
COMMUNITY_CAPACITY
|
|
|
|
|
SUSTAINABLE_FISHING
|
|
|
|
|
CONSUMER_AWARENESS
|
|
|
|
|
OCEAN_ACIDIFICATION
|
|
|
|
|
OTHER
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum TeamMemberRole {
|
|
|
|
|
LEAD // Primary contact / team lead
|
|
|
|
|
MEMBER // Regular team member
|
|
|
|
|
ADVISOR // Advisor/mentor from team side
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum MentorAssignmentMethod {
|
|
|
|
|
MANUAL
|
|
|
|
|
AI_SUGGESTED
|
|
|
|
|
AI_AUTO
|
|
|
|
|
ALGORITHM
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// USERS & AUTHENTICATION
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model User {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
email String @unique
|
|
|
|
|
name String?
|
|
|
|
|
emailVerified DateTime? // Required by NextAuth Prisma adapter
|
|
|
|
|
role UserRole @default(JURY_MEMBER)
|
|
|
|
|
status UserStatus @default(INVITED)
|
|
|
|
|
expertiseTags String[] @default([])
|
|
|
|
|
maxAssignments Int? // Per-round limit
|
2026-02-04 14:15:06 +01:00
|
|
|
country String? // User's home country (for mentor matching)
|
2026-01-30 13:41:32 +01:00
|
|
|
metadataJson Json? @db.JsonB
|
|
|
|
|
|
2026-02-04 15:27:28 +01:00
|
|
|
// Profile
|
|
|
|
|
bio String? // User bio for matching with project descriptions
|
2026-01-30 13:41:32 +01:00
|
|
|
profileImageKey String? // Storage key (e.g., "avatars/user123/1234567890.jpg")
|
|
|
|
|
profileImageProvider String? // Storage provider used: 's3' or 'local'
|
|
|
|
|
|
|
|
|
|
// Phone and notification preferences (Phase 2)
|
|
|
|
|
phoneNumber String?
|
|
|
|
|
phoneNumberVerified Boolean @default(false)
|
|
|
|
|
notificationPreference NotificationChannel @default(EMAIL)
|
|
|
|
|
whatsappOptIn Boolean @default(false)
|
|
|
|
|
|
|
|
|
|
// Onboarding (Phase 2B)
|
|
|
|
|
onboardingCompletedAt DateTime?
|
|
|
|
|
|
|
|
|
|
// Password authentication (hybrid auth)
|
|
|
|
|
passwordHash String? // bcrypt hashed password
|
|
|
|
|
passwordSetAt DateTime? // When password was set
|
|
|
|
|
mustSetPassword Boolean @default(true) // Force setup on first login
|
|
|
|
|
|
2026-01-31 14:13:16 +01:00
|
|
|
// Invitation token for one-click invite acceptance
|
|
|
|
|
inviteToken String? @unique
|
|
|
|
|
inviteTokenExpiresAt DateTime?
|
|
|
|
|
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
// Digest & availability preferences
|
2026-02-08 14:37:32 +01:00
|
|
|
digestFrequency String @default("none") // 'none' | 'daily' | 'weekly'
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
preferredWorkload Int?
|
|
|
|
|
availabilityJson Json? @db.JsonB // { startDate?: string, endDate?: string }
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
lastLoginAt DateTime?
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
assignments Assignment[]
|
|
|
|
|
auditLogs AuditLog[]
|
|
|
|
|
gracePeriods GracePeriod[]
|
|
|
|
|
grantedGracePeriods GracePeriod[] @relation("GrantedBy")
|
|
|
|
|
notificationLogs NotificationLog[]
|
|
|
|
|
createdResources LearningResource[] @relation("ResourceCreatedBy")
|
|
|
|
|
resourceAccess ResourceAccess[]
|
|
|
|
|
submittedProjects Project[] @relation("ProjectSubmittedBy")
|
|
|
|
|
liveVotes LiveVote[]
|
|
|
|
|
|
|
|
|
|
// Team membership & mentorship
|
|
|
|
|
teamMemberships TeamMember[]
|
|
|
|
|
mentorAssignments MentorAssignment[] @relation("MentorAssignments")
|
|
|
|
|
|
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
|
|
|
// Awards
|
|
|
|
|
awardJurorships AwardJuror[]
|
|
|
|
|
awardVotes AwardVote[]
|
|
|
|
|
|
|
|
|
|
// Filtering overrides
|
|
|
|
|
filteringOverrides FilteringResult[] @relation("FilteringOverriddenBy")
|
|
|
|
|
|
|
|
|
|
// Award overrides
|
|
|
|
|
awardEligibilityOverrides AwardEligibility[] @relation("AwardEligibilityOverriddenBy")
|
2026-02-05 21:09:06 +01:00
|
|
|
awardWinnerOverrides SpecialAward[] @relation("AwardOverriddenBy")
|
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
|
|
|
|
2026-02-03 21:30:25 +01:00
|
|
|
// In-app notifications
|
|
|
|
|
notifications InAppNotification[] @relation("UserNotifications")
|
|
|
|
|
notificationSettingsUpdated NotificationEmailSetting[] @relation("NotificationSettingUpdater")
|
|
|
|
|
|
Implement 10 platform features: evaluation UX, admin tools, AI summaries, applicant portal
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
|
|
|
// Reminder logs
|
|
|
|
|
reminderLogs ReminderLog[]
|
|
|
|
|
|
|
|
|
|
// Conflict of interest
|
|
|
|
|
conflictsOfInterest ConflictOfInterest[]
|
|
|
|
|
coiReviews ConflictOfInterest[] @relation("COIReviewedBy")
|
|
|
|
|
|
|
|
|
|
// Evaluation summaries
|
|
|
|
|
generatedSummaries EvaluationSummary[] @relation("EvaluationSummaryGeneratedBy")
|
|
|
|
|
|
|
|
|
|
// Mentor messages
|
|
|
|
|
mentorMessages MentorMessage[] @relation("MentorMessageSender")
|
|
|
|
|
|
Add dynamic apply wizard customization with admin settings UI
- 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:18:20 +01:00
|
|
|
// Wizard templates
|
|
|
|
|
wizardTemplates WizardTemplate[] @relation("WizardTemplateCreatedBy")
|
Implement 15 platform features: digest, availability, templates, comparison, live voting SSE, file versioning, mentorship, messaging, analytics, drafts, webhooks, peer review, audit enhancements, i18n
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
|
|
|
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
// Round templates
|
|
|
|
|
roundTemplates RoundTemplate[] @relation("RoundTemplateCreatedBy")
|
|
|
|
|
|
|
|
|
|
// Mentor notes
|
|
|
|
|
mentorNotes MentorNote[] @relation("MentorNoteAuthor")
|
|
|
|
|
|
|
|
|
|
// Milestone completions
|
|
|
|
|
milestoneCompletions MentorMilestoneCompletion[] @relation("MilestoneCompletedBy")
|
|
|
|
|
|
|
|
|
|
// Evaluation discussions
|
|
|
|
|
closedDiscussions EvaluationDiscussion[] @relation("DiscussionClosedBy")
|
|
|
|
|
discussionComments DiscussionComment[] @relation("DiscussionCommentAuthor")
|
|
|
|
|
|
|
|
|
|
// Messaging
|
|
|
|
|
sentMessages Message[] @relation("MessageSender")
|
|
|
|
|
receivedMessages MessageRecipient[] @relation("MessageRecipient")
|
|
|
|
|
messageTemplates MessageTemplate[] @relation("MessageTemplateCreator")
|
|
|
|
|
|
|
|
|
|
// Webhooks
|
|
|
|
|
webhooks Webhook[] @relation("WebhookCreator")
|
|
|
|
|
|
|
|
|
|
// Digest logs
|
|
|
|
|
digestLogs DigestLog[] @relation("DigestLog")
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
// NextAuth relations
|
|
|
|
|
accounts Account[]
|
|
|
|
|
sessions Session[]
|
|
|
|
|
|
|
|
|
|
@@index([role])
|
|
|
|
|
@@index([status])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NextAuth.js required models
|
|
|
|
|
model Account {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
type String
|
|
|
|
|
provider String
|
|
|
|
|
providerAccountId String
|
|
|
|
|
refresh_token String? @db.Text
|
|
|
|
|
access_token String? @db.Text
|
|
|
|
|
expires_at Int?
|
|
|
|
|
token_type String?
|
|
|
|
|
scope String?
|
|
|
|
|
id_token String? @db.Text
|
|
|
|
|
session_state String?
|
|
|
|
|
|
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@unique([provider, providerAccountId])
|
|
|
|
|
@@index([userId])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model Session {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
sessionToken String @unique
|
|
|
|
|
userId String
|
|
|
|
|
expires DateTime
|
|
|
|
|
|
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@index([userId])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model VerificationToken {
|
|
|
|
|
identifier String
|
|
|
|
|
token String @unique
|
|
|
|
|
expires DateTime
|
|
|
|
|
|
|
|
|
|
@@unique([identifier, token])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// PROGRAMS & ROUNDS
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model Program {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
name String // e.g., "Monaco Ocean Protection Challenge"
|
Add dynamic apply wizard customization with admin settings UI
- 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:18:20 +01:00
|
|
|
slug String? @unique // URL-friendly identifier for edition-wide applications
|
2026-01-30 13:41:32 +01:00
|
|
|
year Int // e.g., 2026
|
|
|
|
|
status ProgramStatus @default(DRAFT)
|
|
|
|
|
description String?
|
|
|
|
|
settingsJson Json? @db.JsonB
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
Add dynamic apply wizard customization with admin settings UI
- 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:18:20 +01:00
|
|
|
projects Project[]
|
2026-01-30 13:41:32 +01:00
|
|
|
rounds Round[]
|
|
|
|
|
learningResources LearningResource[]
|
|
|
|
|
partners Partner[]
|
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
|
|
|
specialAwards SpecialAward[]
|
2026-02-05 11:48:57 +01:00
|
|
|
taggingJobs TaggingJob[]
|
Add dynamic apply wizard customization with admin settings UI
- 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:18:20 +01:00
|
|
|
wizardTemplates WizardTemplate[]
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
roundTemplates RoundTemplate[]
|
|
|
|
|
mentorMilestones MentorMilestone[]
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
@@unique([name, year])
|
|
|
|
|
@@index([status])
|
|
|
|
|
}
|
|
|
|
|
|
Add dynamic apply wizard customization with admin settings UI
- 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:18:20 +01:00
|
|
|
model WizardTemplate {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
name String
|
|
|
|
|
description String?
|
|
|
|
|
config Json @db.JsonB
|
|
|
|
|
isGlobal Boolean @default(false)
|
|
|
|
|
programId String?
|
|
|
|
|
program Program? @relation(fields: [programId], references: [id], onDelete: Cascade)
|
|
|
|
|
createdBy String
|
|
|
|
|
creator User @relation("WizardTemplateCreatedBy", fields: [createdBy], references: [id])
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
@@index([programId])
|
|
|
|
|
@@index([isGlobal])
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
model Round {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
programId String
|
|
|
|
|
name String // e.g., "Round 1 - Semi-Finalists"
|
|
|
|
|
slug String? @unique // URL-friendly identifier for public submissions
|
|
|
|
|
status RoundStatus @default(DRAFT)
|
|
|
|
|
roundType RoundType @default(EVALUATION)
|
2026-02-04 14:15:06 +01:00
|
|
|
sortOrder Int @default(0) // Display order within program
|
|
|
|
|
|
|
|
|
|
// Entry notification settings
|
|
|
|
|
entryNotificationType String? // Type of notification to send when project enters round
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
// Submission window (for applicant portal)
|
|
|
|
|
submissionDeadline DateTime? // Deadline for project submissions
|
|
|
|
|
submissionStartDate DateTime? // When submissions open
|
|
|
|
|
submissionEndDate DateTime? // When submissions close (replaces submissionDeadline if set)
|
|
|
|
|
lateSubmissionGrace Int? // Hours of grace period after deadline
|
|
|
|
|
|
|
|
|
|
// Phase-specific deadlines
|
|
|
|
|
phase1Deadline DateTime?
|
|
|
|
|
phase2Deadline DateTime?
|
|
|
|
|
|
|
|
|
|
// Voting window
|
|
|
|
|
votingStartAt DateTime?
|
|
|
|
|
votingEndAt DateTime?
|
|
|
|
|
|
|
|
|
|
// Configuration
|
2026-02-04 16:01:18 +01:00
|
|
|
requiredReviews Int @default(3) // Min evaluations per project
|
|
|
|
|
minAssignmentsPerJuror Int @default(5) // Target minimum projects per judge
|
|
|
|
|
maxAssignmentsPerJuror Int @default(20) // Max projects per judge in this round
|
|
|
|
|
settingsJson Json? @db.JsonB // Grace periods, visibility rules, etc.
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
2026-02-03 19:48:41 +01:00
|
|
|
program Program @relation(fields: [programId], references: [id], onDelete: Cascade)
|
2026-02-04 14:15:06 +01:00
|
|
|
projects Project[]
|
2026-02-03 19:48:41 +01:00
|
|
|
assignments Assignment[]
|
|
|
|
|
evaluationForms EvaluationForm[]
|
|
|
|
|
gracePeriods GracePeriod[]
|
2026-01-30 13:41:32 +01:00
|
|
|
liveVotingSession LiveVotingSession?
|
2026-02-03 19:48:41 +01:00
|
|
|
filteringRules FilteringRule[]
|
|
|
|
|
filteringResults FilteringResult[]
|
|
|
|
|
filteringJobs FilteringJob[]
|
2026-02-04 17:40:26 +01:00
|
|
|
assignmentJobs AssignmentJob[]
|
2026-02-05 11:48:57 +01:00
|
|
|
taggingJobs TaggingJob[]
|
Implement 10 platform features: evaluation UX, admin tools, AI summaries, applicant portal
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
|
|
|
reminderLogs ReminderLog[]
|
|
|
|
|
projectFiles ProjectFile[]
|
2026-02-08 23:01:33 +01:00
|
|
|
fileRequirements FileRequirement[]
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
evaluationDiscussions EvaluationDiscussion[]
|
|
|
|
|
messages Message[]
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
@@index([programId])
|
|
|
|
|
@@index([status])
|
|
|
|
|
@@index([roundType])
|
|
|
|
|
@@index([votingStartAt, votingEndAt])
|
|
|
|
|
@@index([submissionStartDate, submissionEndDate])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model EvaluationForm {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
roundId String
|
|
|
|
|
version Int @default(1)
|
|
|
|
|
|
|
|
|
|
// Form configuration
|
|
|
|
|
// criteriaJson: Array of { id, label, description, scale, weight, required }
|
|
|
|
|
criteriaJson Json @db.JsonB
|
|
|
|
|
// scalesJson: { "1-5": { min, max, labels }, "1-10": { min, max, labels } }
|
|
|
|
|
scalesJson Json? @db.JsonB
|
|
|
|
|
isActive Boolean @default(false)
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
|
|
|
evaluations Evaluation[]
|
|
|
|
|
|
|
|
|
|
@@unique([roundId, version])
|
|
|
|
|
@@index([roundId, isActive])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// PROJECTS
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model Project {
|
|
|
|
|
id String @id @default(cuid())
|
Add dynamic apply wizard customization with admin settings UI
- 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:18:20 +01:00
|
|
|
programId String
|
|
|
|
|
roundId String?
|
2026-02-04 14:15:06 +01:00
|
|
|
status ProjectStatus @default(SUBMITTED)
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
// Core fields
|
|
|
|
|
title String
|
|
|
|
|
teamName String?
|
|
|
|
|
description String? @db.Text
|
|
|
|
|
|
|
|
|
|
// Competition category
|
|
|
|
|
competitionCategory CompetitionCategory?
|
|
|
|
|
oceanIssue OceanIssue?
|
|
|
|
|
|
|
|
|
|
// Location
|
|
|
|
|
country String?
|
|
|
|
|
geographicZone String? // "Europe, France"
|
|
|
|
|
|
|
|
|
|
// Institution (for students/Business Concepts)
|
|
|
|
|
institution String?
|
|
|
|
|
|
|
|
|
|
// Mentorship
|
|
|
|
|
wantsMentorship Boolean @default(false)
|
|
|
|
|
|
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
|
|
|
// Founding date
|
|
|
|
|
foundedAt DateTime? // When the project/company was founded
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
// Submission links (external, from CSV)
|
|
|
|
|
phase1SubmissionUrl String?
|
|
|
|
|
phase2SubmissionUrl String?
|
|
|
|
|
|
|
|
|
|
// Referral tracking
|
|
|
|
|
referralSource String?
|
|
|
|
|
|
|
|
|
|
// Internal admin fields
|
|
|
|
|
internalComments String? @db.Text
|
|
|
|
|
applicationStatus String? // "Received", etc.
|
|
|
|
|
|
|
|
|
|
// Submission tracking
|
|
|
|
|
submissionSource SubmissionSource @default(MANUAL)
|
|
|
|
|
submittedByEmail String?
|
|
|
|
|
submittedAt DateTime?
|
|
|
|
|
submittedByUserId String?
|
|
|
|
|
|
|
|
|
|
// Project branding
|
|
|
|
|
logoKey String? // Storage key (e.g., "logos/project456/1234567890.png")
|
|
|
|
|
logoProvider String? // Storage provider used: 's3' or 'local'
|
|
|
|
|
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
// Draft support
|
|
|
|
|
isDraft Boolean @default(false)
|
|
|
|
|
draftDataJson Json? @db.JsonB // Form data for drafts
|
|
|
|
|
draftExpiresAt DateTime?
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
// Flexible fields
|
|
|
|
|
tags String[] @default([]) // "Ocean Conservation", "Tech", etc.
|
|
|
|
|
metadataJson Json? @db.JsonB // Custom fields from Typeform, etc.
|
|
|
|
|
externalIdsJson Json? @db.JsonB // Typeform ID, Notion ID, etc.
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
Add dynamic apply wizard customization with admin settings UI
- 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:18:20 +01:00
|
|
|
program Program @relation(fields: [programId], references: [id], onDelete: Cascade)
|
|
|
|
|
round Round? @relation(fields: [roundId], references: [id], onDelete: SetNull)
|
2026-01-30 13:41:32 +01:00
|
|
|
files ProjectFile[]
|
|
|
|
|
assignments Assignment[]
|
|
|
|
|
submittedBy User? @relation("ProjectSubmittedBy", fields: [submittedByUserId], references: [id], onDelete: SetNull)
|
|
|
|
|
teamMembers TeamMember[]
|
|
|
|
|
mentorAssignment MentorAssignment?
|
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
|
|
|
filteringResults FilteringResult[]
|
|
|
|
|
awardEligibilities AwardEligibility[]
|
|
|
|
|
awardVotes AwardVote[]
|
|
|
|
|
wonAwards SpecialAward[] @relation("AwardWinner")
|
2026-02-04 14:15:06 +01:00
|
|
|
projectTags ProjectTag[]
|
Implement 10 platform features: evaluation UX, admin tools, AI summaries, applicant portal
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
|
|
|
statusHistory ProjectStatusHistory[]
|
|
|
|
|
mentorMessages MentorMessage[]
|
|
|
|
|
evaluationSummaries EvaluationSummary[]
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
evaluationDiscussions EvaluationDiscussion[]
|
2026-01-30 13:41:32 +01:00
|
|
|
|
Add dynamic apply wizard customization with admin settings UI
- 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:18:20 +01:00
|
|
|
@@index([programId])
|
2026-02-04 14:15:06 +01:00
|
|
|
@@index([roundId])
|
Add dynamic apply wizard customization with admin settings UI
- 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:18:20 +01:00
|
|
|
@@index([programId, roundId])
|
2026-02-04 14:15:06 +01:00
|
|
|
@@index([status])
|
2026-01-30 13:41:32 +01:00
|
|
|
@@index([tags])
|
|
|
|
|
@@index([submissionSource])
|
|
|
|
|
@@index([submittedByUserId])
|
|
|
|
|
@@index([competitionCategory])
|
|
|
|
|
@@index([oceanIssue])
|
|
|
|
|
@@index([country])
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-08 23:01:33 +01:00
|
|
|
model FileRequirement {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
roundId String
|
|
|
|
|
name String
|
|
|
|
|
description String?
|
|
|
|
|
acceptedMimeTypes String[] // e.g. ["application/pdf", "video/*"]
|
|
|
|
|
maxSizeMB Int? // Max file size in MB
|
|
|
|
|
isRequired Boolean @default(true)
|
|
|
|
|
sortOrder Int @default(0)
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
|
|
|
files ProjectFile[]
|
|
|
|
|
|
|
|
|
|
@@index([roundId])
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
model ProjectFile {
|
2026-02-08 23:01:33 +01:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
projectId String
|
|
|
|
|
roundId String? // Which round this file was submitted for
|
|
|
|
|
requirementId String? // FK to FileRequirement (if uploaded against a requirement)
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
// File info
|
|
|
|
|
fileType FileType
|
|
|
|
|
fileName String
|
|
|
|
|
mimeType String
|
|
|
|
|
size Int // bytes
|
|
|
|
|
|
|
|
|
|
// MinIO location
|
|
|
|
|
bucket String
|
|
|
|
|
objectKey String
|
|
|
|
|
|
Implement 10 platform features: evaluation UX, admin tools, AI summaries, applicant portal
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
|
|
|
isLate Boolean @default(false) // Uploaded after round deadline
|
|
|
|
|
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
// Versioning
|
|
|
|
|
version Int @default(1)
|
|
|
|
|
replacedById String? // FK to the newer file that replaced this one
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
2026-02-08 23:01:33 +01:00
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
Improve projects UX, settings layout, uppercase names, per-page selector, and fix round deletion
- 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>
2026-02-10 20:13:47 +01:00
|
|
|
round Round? @relation(fields: [roundId], references: [id], onDelete: SetNull)
|
2026-02-08 23:01:33 +01:00
|
|
|
requirement FileRequirement? @relation(fields: [requirementId], references: [id], onDelete: SetNull)
|
|
|
|
|
replacedBy ProjectFile? @relation("FileVersions", fields: [replacedById], references: [id], onDelete: SetNull)
|
|
|
|
|
replacements ProjectFile[] @relation("FileVersions")
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
@@unique([bucket, objectKey])
|
|
|
|
|
@@index([projectId])
|
Implement 10 platform features: evaluation UX, admin tools, AI summaries, applicant portal
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
|
|
|
@@index([roundId])
|
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
|
|
|
@@index([projectId, roundId])
|
2026-01-30 13:41:32 +01:00
|
|
|
@@index([fileType])
|
2026-02-08 23:01:33 +01:00
|
|
|
@@index([requirementId])
|
2026-01-30 13:41:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// ASSIGNMENTS & EVALUATIONS
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model Assignment {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
projectId String
|
|
|
|
|
roundId String
|
|
|
|
|
|
|
|
|
|
// Assignment info
|
|
|
|
|
method AssignmentMethod @default(MANUAL)
|
|
|
|
|
isRequired Boolean @default(true)
|
|
|
|
|
isCompleted Boolean @default(false)
|
|
|
|
|
|
|
|
|
|
// AI assignment metadata
|
|
|
|
|
aiConfidenceScore Float? // 0-1 confidence from AI
|
|
|
|
|
expertiseMatchScore Float? // 0-1 match score
|
|
|
|
|
aiReasoning String? @db.Text
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
createdBy String? // Admin who created the assignment
|
|
|
|
|
|
|
|
|
|
// Relations
|
Implement 10 platform features: evaluation UX, admin tools, AI summaries, applicant portal
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
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
|
|
|
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
|
|
|
evaluation Evaluation?
|
|
|
|
|
conflictOfInterest ConflictOfInterest?
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
@@unique([userId, projectId, roundId])
|
|
|
|
|
@@index([userId])
|
|
|
|
|
@@index([projectId])
|
|
|
|
|
@@index([roundId])
|
|
|
|
|
@@index([isCompleted])
|
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
|
|
|
@@index([projectId, userId])
|
2026-01-30 13:41:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model Evaluation {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
assignmentId String @unique
|
|
|
|
|
formId String
|
|
|
|
|
|
|
|
|
|
// Status
|
|
|
|
|
status EvaluationStatus @default(NOT_STARTED)
|
|
|
|
|
|
|
|
|
|
// Scores
|
|
|
|
|
// criterionScoresJson: { "criterion_id": score, ... }
|
|
|
|
|
criterionScoresJson Json? @db.JsonB
|
|
|
|
|
globalScore Int? // 1-10
|
|
|
|
|
binaryDecision Boolean? // Yes/No for semi-finalist
|
|
|
|
|
feedbackText String? @db.Text
|
|
|
|
|
|
2026-02-05 21:09:06 +01:00
|
|
|
// Versioning (currently unused - evaluations are updated in-place.
|
|
|
|
|
// TODO: Implement proper versioning by creating new rows on re-submission
|
|
|
|
|
// if version history is needed for audit purposes)
|
2026-01-30 13:41:32 +01:00
|
|
|
version Int @default(1)
|
|
|
|
|
|
|
|
|
|
// Timestamps
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
submittedAt DateTime?
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
assignment Assignment @relation(fields: [assignmentId], references: [id], onDelete: Cascade)
|
Improve projects UX, settings layout, uppercase names, per-page selector, and fix round deletion
- 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>
2026-02-10 20:13:47 +01:00
|
|
|
form EvaluationForm @relation(fields: [formId], references: [id], onDelete: Cascade)
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
@@index([status])
|
|
|
|
|
@@index([submittedAt])
|
|
|
|
|
@@index([formId])
|
2026-02-05 21:09:06 +01:00
|
|
|
@@index([status, formId])
|
2026-01-30 13:41:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// GRACE PERIODS
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model GracePeriod {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
roundId String
|
|
|
|
|
userId String
|
|
|
|
|
projectId String? // Optional: specific project or all projects in round
|
|
|
|
|
|
|
|
|
|
extendedUntil DateTime
|
|
|
|
|
reason String? @db.Text
|
|
|
|
|
grantedById String
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
grantedBy User @relation("GrantedBy", fields: [grantedById], references: [id])
|
|
|
|
|
|
|
|
|
|
@@index([roundId])
|
|
|
|
|
@@index([userId])
|
|
|
|
|
@@index([extendedUntil])
|
|
|
|
|
@@index([grantedById])
|
|
|
|
|
@@index([projectId])
|
2026-02-05 21:09:06 +01:00
|
|
|
@@index([roundId, userId, extendedUntil])
|
2026-01-30 13:41:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// SYSTEM SETTINGS
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model SystemSettings {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
key String @unique
|
|
|
|
|
value String @db.Text
|
|
|
|
|
type SettingType @default(STRING)
|
|
|
|
|
category SettingCategory
|
|
|
|
|
|
|
|
|
|
description String?
|
|
|
|
|
isSecret Boolean @default(false) // If true, value is encrypted
|
|
|
|
|
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
updatedBy String?
|
|
|
|
|
|
|
|
|
|
@@index([category])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// AUDIT LOGGING
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model AuditLog {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String?
|
|
|
|
|
|
|
|
|
|
// Event info
|
|
|
|
|
action String // "CREATE", "UPDATE", "DELETE", "LOGIN", "EXPORT", etc.
|
|
|
|
|
entityType String // "Round", "Project", "Evaluation", etc.
|
|
|
|
|
entityId String?
|
|
|
|
|
|
|
|
|
|
// Details
|
2026-02-08 14:37:32 +01:00
|
|
|
detailsJson Json? @db.JsonB // Before/after values, additional context
|
|
|
|
|
previousDataJson Json? @db.JsonB // Previous state for tracking changes
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
// Request info
|
|
|
|
|
ipAddress String?
|
|
|
|
|
userAgent String?
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
sessionId String?
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
timestamp DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
|
|
|
|
|
|
|
|
|
@@index([userId])
|
|
|
|
|
@@index([action])
|
|
|
|
|
@@index([entityType, entityId])
|
|
|
|
|
@@index([timestamp])
|
2026-02-05 21:09:06 +01:00
|
|
|
@@index([entityType, entityId, timestamp])
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
@@index([sessionId])
|
2026-01-30 13:41:32 +01:00
|
|
|
}
|
|
|
|
|
|
2026-02-03 11:58:12 +01:00
|
|
|
// =============================================================================
|
|
|
|
|
// AI USAGE TRACKING
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model AIUsageLog {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Who/what triggered it
|
|
|
|
|
userId String?
|
|
|
|
|
action String // ASSIGNMENT, FILTERING, AWARD_ELIGIBILITY, MENTOR_MATCHING
|
|
|
|
|
entityType String? // Round, Project, Award
|
|
|
|
|
entityId String?
|
|
|
|
|
|
|
|
|
|
// What was used
|
|
|
|
|
model String // gpt-4o, gpt-4o-mini, o1, etc.
|
|
|
|
|
promptTokens Int
|
|
|
|
|
completionTokens Int
|
|
|
|
|
totalTokens Int
|
|
|
|
|
|
|
|
|
|
// Cost tracking
|
|
|
|
|
estimatedCostUsd Decimal? @db.Decimal(10, 6)
|
|
|
|
|
|
|
|
|
|
// Request context
|
|
|
|
|
batchSize Int?
|
|
|
|
|
itemsProcessed Int?
|
|
|
|
|
|
|
|
|
|
// Status
|
|
|
|
|
status String // SUCCESS, PARTIAL, ERROR
|
|
|
|
|
errorMessage String?
|
|
|
|
|
|
|
|
|
|
// Detailed data (optional)
|
|
|
|
|
detailsJson Json? @db.JsonB
|
|
|
|
|
|
|
|
|
|
@@index([userId])
|
|
|
|
|
@@index([action])
|
|
|
|
|
@@index([createdAt])
|
|
|
|
|
@@index([model])
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
// =============================================================================
|
|
|
|
|
// NOTIFICATION LOG (Phase 2)
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model NotificationLog {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
channel NotificationChannel
|
|
|
|
|
provider String? // META, TWILIO, SMTP
|
|
|
|
|
type String // MAGIC_LINK, REMINDER, ANNOUNCEMENT, JURY_INVITATION
|
|
|
|
|
status String // PENDING, SENT, DELIVERED, FAILED
|
|
|
|
|
externalId String? // Message ID from provider
|
|
|
|
|
errorMsg String? @db.Text
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@index([userId])
|
|
|
|
|
@@index([status])
|
|
|
|
|
@@index([createdAt])
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-03 21:30:25 +01:00
|
|
|
// =============================================================================
|
|
|
|
|
// IN-APP NOTIFICATIONS
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model InAppNotification {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
type String // FILTERING_COMPLETE, NEW_APPLICATION, ASSIGNED_TO_PROJECT, etc.
|
|
|
|
|
priority String @default("normal") // low, normal, high, urgent
|
|
|
|
|
icon String? // lucide icon name
|
|
|
|
|
title String
|
|
|
|
|
message String @db.Text
|
|
|
|
|
linkUrl String? // Where to navigate when clicked
|
|
|
|
|
linkLabel String? // CTA text
|
|
|
|
|
metadata Json? @db.JsonB // Extra context (projectId, roundId, etc.)
|
|
|
|
|
groupKey String? // For batching similar notifications
|
|
|
|
|
|
|
|
|
|
isRead Boolean @default(false)
|
|
|
|
|
readAt DateTime?
|
|
|
|
|
expiresAt DateTime? // Auto-dismiss after date
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
user User @relation("UserNotifications", fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@index([userId, isRead])
|
|
|
|
|
@@index([userId, createdAt])
|
|
|
|
|
@@index([groupKey])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model NotificationEmailSetting {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
notificationType String @unique // e.g., "ADVANCED_TO_ROUND", "ASSIGNED_TO_PROJECT"
|
|
|
|
|
category String // "team", "jury", "mentor", "admin"
|
|
|
|
|
label String // Human-readable label for admin UI
|
|
|
|
|
description String? // Help text
|
|
|
|
|
sendEmail Boolean @default(true)
|
|
|
|
|
emailSubject String? // Custom subject template (optional)
|
|
|
|
|
emailTemplate String? @db.Text // Custom body template (optional)
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
updatedById String?
|
|
|
|
|
updatedBy User? @relation("NotificationSettingUpdater", fields: [updatedById], references: [id])
|
|
|
|
|
|
|
|
|
|
@@index([category])
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
// =============================================================================
|
|
|
|
|
// LEARNING HUB (Phase 2)
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model LearningResource {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
programId String? // null = global resource
|
|
|
|
|
title String
|
|
|
|
|
description String? @db.Text
|
|
|
|
|
contentJson Json? @db.JsonB // BlockNote document structure
|
|
|
|
|
resourceType ResourceType
|
|
|
|
|
cohortLevel CohortLevel @default(ALL)
|
|
|
|
|
|
|
|
|
|
// File storage (for uploaded resources)
|
|
|
|
|
fileName String?
|
|
|
|
|
mimeType String?
|
|
|
|
|
size Int?
|
|
|
|
|
bucket String?
|
|
|
|
|
objectKey String?
|
|
|
|
|
|
|
|
|
|
// External link
|
|
|
|
|
externalUrl String?
|
|
|
|
|
|
|
|
|
|
sortOrder Int @default(0)
|
|
|
|
|
isPublished Boolean @default(false)
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
createdById String
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
program Program? @relation(fields: [programId], references: [id], onDelete: SetNull)
|
|
|
|
|
createdBy User @relation("ResourceCreatedBy", fields: [createdById], references: [id])
|
|
|
|
|
accessLogs ResourceAccess[]
|
|
|
|
|
|
|
|
|
|
@@index([programId])
|
|
|
|
|
@@index([cohortLevel])
|
|
|
|
|
@@index([isPublished])
|
|
|
|
|
@@index([sortOrder])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model ResourceAccess {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
resourceId String
|
|
|
|
|
userId String
|
|
|
|
|
accessedAt DateTime @default(now())
|
|
|
|
|
ipAddress String?
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
resource LearningResource @relation(fields: [resourceId], references: [id], onDelete: Cascade)
|
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@index([resourceId])
|
|
|
|
|
@@index([userId])
|
|
|
|
|
@@index([accessedAt])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// PARTNER MANAGEMENT (Phase 2)
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model Partner {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
programId String? // null = global partner
|
|
|
|
|
name String
|
|
|
|
|
description String? @db.Text
|
|
|
|
|
website String?
|
|
|
|
|
partnerType PartnerType @default(PARTNER)
|
|
|
|
|
visibility PartnerVisibility @default(ADMIN_ONLY)
|
|
|
|
|
|
|
|
|
|
// Logo file
|
|
|
|
|
logoFileName String?
|
|
|
|
|
logoBucket String?
|
|
|
|
|
logoObjectKey String?
|
|
|
|
|
|
|
|
|
|
sortOrder Int @default(0)
|
|
|
|
|
isActive Boolean @default(true)
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
program Program? @relation(fields: [programId], references: [id], onDelete: SetNull)
|
|
|
|
|
|
|
|
|
|
@@index([programId])
|
|
|
|
|
@@index([partnerType])
|
|
|
|
|
@@index([visibility])
|
|
|
|
|
@@index([isActive])
|
|
|
|
|
@@index([sortOrder])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// EXPERTISE TAGS (Phase 2B)
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model ExpertiseTag {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
name String @unique
|
|
|
|
|
description String?
|
|
|
|
|
category String? // "Marine Science", "Technology", "Policy"
|
|
|
|
|
color String? // Hex for badge
|
|
|
|
|
isActive Boolean @default(true)
|
|
|
|
|
sortOrder Int @default(0)
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
2026-02-04 14:15:06 +01:00
|
|
|
// Relations
|
|
|
|
|
projectTags ProjectTag[]
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
@@index([category])
|
|
|
|
|
@@index([isActive])
|
|
|
|
|
@@index([sortOrder])
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-04 14:15:06 +01:00
|
|
|
// Project-Tag relationship for AI tagging
|
|
|
|
|
model ProjectTag {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
projectId String
|
|
|
|
|
tagId String
|
|
|
|
|
confidence Float @default(1.0) // AI confidence score 0-1
|
|
|
|
|
source String @default("AI") // "AI" or "MANUAL"
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
|
|
|
tag ExpertiseTag @relation(fields: [tagId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@unique([projectId, tagId])
|
|
|
|
|
@@index([projectId])
|
|
|
|
|
@@index([tagId])
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
// =============================================================================
|
|
|
|
|
// LIVE VOTING (Phase 2B)
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model LiveVotingSession {
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
id String @id @default(cuid())
|
|
|
|
|
roundId String @unique
|
|
|
|
|
status String @default("NOT_STARTED") // NOT_STARTED, IN_PROGRESS, PAUSED, COMPLETED
|
|
|
|
|
currentProjectIndex Int @default(0)
|
|
|
|
|
currentProjectId String?
|
|
|
|
|
votingStartedAt DateTime?
|
|
|
|
|
votingEndsAt DateTime?
|
|
|
|
|
projectOrderJson Json? @db.JsonB // Array of project IDs in presentation order
|
|
|
|
|
|
Round system redesign: criteria voting, audience voting, pipeline view, and admin UX improvements
- Schema: Extend LiveVotingSession with votingMode, criteriaJson, audience fields;
add AudienceVoter model; make LiveVote.userId nullable for audience voters
- Backend: Criteria-based voting with weighted scores, audience registration/voting
with token-based dedup, configurable jury/audience weight in results
- Jury UI: Criteria scoring with per-criterion sliders alongside simple 1-10 mode
- Public audience voting page at /vote/[sessionId] with mobile-first design
- Admin live voting: Tabbed layout (Session/Config/Results), criteria config,
audience settings, weight-adjustable results with tie detection
- Round type settings: Visual card selector replacing dropdown, feature tags
- Round detail page: Live event status section, type-specific stats and actions
- Round pipeline view: Horizontal visualization with bottleneck detection,
List/Pipeline toggle on rounds page
- SSE: Separate jury/audience vote events, audience vote tracking
- Field visibility: Hide irrelevant fields per round type in create/edit forms
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:27:49 +01:00
|
|
|
// Criteria-based voting
|
|
|
|
|
votingMode String @default("simple") // "simple" (1-10) | "criteria" (per-criterion scores)
|
|
|
|
|
criteriaJson Json? @db.JsonB // Array of { id, label, description, scale, weight }
|
|
|
|
|
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
// Audience & presentation settings
|
|
|
|
|
allowAudienceVotes Boolean @default(false)
|
2026-02-08 14:37:32 +01:00
|
|
|
audienceVoteWeight Float @default(0) // 0.0 to 1.0
|
|
|
|
|
tieBreakerMethod String @default("admin_decides") // 'admin_decides' | 'highest_individual' | 'revote'
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
presentationSettingsJson Json? @db.JsonB
|
|
|
|
|
|
Round system redesign: criteria voting, audience voting, pipeline view, and admin UX improvements
- Schema: Extend LiveVotingSession with votingMode, criteriaJson, audience fields;
add AudienceVoter model; make LiveVote.userId nullable for audience voters
- Backend: Criteria-based voting with weighted scores, audience registration/voting
with token-based dedup, configurable jury/audience weight in results
- Jury UI: Criteria scoring with per-criterion sliders alongside simple 1-10 mode
- Public audience voting page at /vote/[sessionId] with mobile-first design
- Admin live voting: Tabbed layout (Session/Config/Results), criteria config,
audience settings, weight-adjustable results with tie detection
- Round type settings: Visual card selector replacing dropdown, feature tags
- Round detail page: Live event status section, type-specific stats and actions
- Round pipeline view: Horizontal visualization with bottleneck detection,
List/Pipeline toggle on rounds page
- SSE: Separate jury/audience vote events, audience vote tracking
- Field visibility: Hide irrelevant fields per round type in create/edit forms
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:27:49 +01:00
|
|
|
// Audience voting configuration
|
|
|
|
|
audienceVotingMode String @default("disabled") // "disabled" | "per_project" | "per_category" | "favorites"
|
|
|
|
|
audienceMaxFavorites Int @default(3) // For "favorites" mode
|
|
|
|
|
audienceRequireId Boolean @default(false) // Require email/phone for audience
|
|
|
|
|
audienceVotingDuration Int? // Minutes (null = same as jury)
|
|
|
|
|
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
// Relations
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
|
|
|
votes LiveVote[]
|
Round system redesign: criteria voting, audience voting, pipeline view, and admin UX improvements
- Schema: Extend LiveVotingSession with votingMode, criteriaJson, audience fields;
add AudienceVoter model; make LiveVote.userId nullable for audience voters
- Backend: Criteria-based voting with weighted scores, audience registration/voting
with token-based dedup, configurable jury/audience weight in results
- Jury UI: Criteria scoring with per-criterion sliders alongside simple 1-10 mode
- Public audience voting page at /vote/[sessionId] with mobile-first design
- Admin live voting: Tabbed layout (Session/Config/Results), criteria config,
audience settings, weight-adjustable results with tie detection
- Round type settings: Visual card selector replacing dropdown, feature tags
- Round detail page: Live event status section, type-specific stats and actions
- Round pipeline view: Horizontal visualization with bottleneck detection,
List/Pipeline toggle on rounds page
- SSE: Separate jury/audience vote events, audience vote tracking
- Field visibility: Hide irrelevant fields per round type in create/edit forms
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:27:49 +01:00
|
|
|
audienceVoters AudienceVoter[]
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
@@index([status])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model LiveVote {
|
Round system redesign: criteria voting, audience voting, pipeline view, and admin UX improvements
- Schema: Extend LiveVotingSession with votingMode, criteriaJson, audience fields;
add AudienceVoter model; make LiveVote.userId nullable for audience voters
- Backend: Criteria-based voting with weighted scores, audience registration/voting
with token-based dedup, configurable jury/audience weight in results
- Jury UI: Criteria scoring with per-criterion sliders alongside simple 1-10 mode
- Public audience voting page at /vote/[sessionId] with mobile-first design
- Admin live voting: Tabbed layout (Session/Config/Results), criteria config,
audience settings, weight-adjustable results with tie detection
- Round type settings: Visual card selector replacing dropdown, feature tags
- Round detail page: Live event status section, type-specific stats and actions
- Round pipeline view: Horizontal visualization with bottleneck detection,
List/Pipeline toggle on rounds page
- SSE: Separate jury/audience vote events, audience vote tracking
- Field visibility: Hide irrelevant fields per round type in create/edit forms
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:27:49 +01:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
sessionId String
|
|
|
|
|
projectId String
|
|
|
|
|
userId String? // Nullable for audience voters without accounts
|
|
|
|
|
score Int // 1-10 (or weighted score for criteria mode)
|
|
|
|
|
isAudienceVote Boolean @default(false)
|
|
|
|
|
votedAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Criteria scores (used when votingMode="criteria")
|
|
|
|
|
criterionScoresJson Json? @db.JsonB // { [criterionId]: score } - null for simple mode
|
|
|
|
|
|
|
|
|
|
// Audience voter link
|
|
|
|
|
audienceVoterId String?
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
// Relations
|
Round system redesign: criteria voting, audience voting, pipeline view, and admin UX improvements
- Schema: Extend LiveVotingSession with votingMode, criteriaJson, audience fields;
add AudienceVoter model; make LiveVote.userId nullable for audience voters
- Backend: Criteria-based voting with weighted scores, audience registration/voting
with token-based dedup, configurable jury/audience weight in results
- Jury UI: Criteria scoring with per-criterion sliders alongside simple 1-10 mode
- Public audience voting page at /vote/[sessionId] with mobile-first design
- Admin live voting: Tabbed layout (Session/Config/Results), criteria config,
audience settings, weight-adjustable results with tie detection
- Round type settings: Visual card selector replacing dropdown, feature tags
- Round detail page: Live event status section, type-specific stats and actions
- Round pipeline view: Horizontal visualization with bottleneck detection,
List/Pipeline toggle on rounds page
- SSE: Separate jury/audience vote events, audience vote tracking
- Field visibility: Hide irrelevant fields per round type in create/edit forms
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:27:49 +01:00
|
|
|
session LiveVotingSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
|
|
|
|
|
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
audienceVoter AudienceVoter? @relation(fields: [audienceVoterId], references: [id], onDelete: Cascade)
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
@@unique([sessionId, projectId, userId])
|
Round system redesign: criteria voting, audience voting, pipeline view, and admin UX improvements
- Schema: Extend LiveVotingSession with votingMode, criteriaJson, audience fields;
add AudienceVoter model; make LiveVote.userId nullable for audience voters
- Backend: Criteria-based voting with weighted scores, audience registration/voting
with token-based dedup, configurable jury/audience weight in results
- Jury UI: Criteria scoring with per-criterion sliders alongside simple 1-10 mode
- Public audience voting page at /vote/[sessionId] with mobile-first design
- Admin live voting: Tabbed layout (Session/Config/Results), criteria config,
audience settings, weight-adjustable results with tie detection
- Round type settings: Visual card selector replacing dropdown, feature tags
- Round detail page: Live event status section, type-specific stats and actions
- Round pipeline view: Horizontal visualization with bottleneck detection,
List/Pipeline toggle on rounds page
- SSE: Separate jury/audience vote events, audience vote tracking
- Field visibility: Hide irrelevant fields per round type in create/edit forms
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:27:49 +01:00
|
|
|
@@unique([sessionId, projectId, audienceVoterId])
|
2026-01-30 13:41:32 +01:00
|
|
|
@@index([sessionId])
|
|
|
|
|
@@index([projectId])
|
|
|
|
|
@@index([userId])
|
Round system redesign: criteria voting, audience voting, pipeline view, and admin UX improvements
- Schema: Extend LiveVotingSession with votingMode, criteriaJson, audience fields;
add AudienceVoter model; make LiveVote.userId nullable for audience voters
- Backend: Criteria-based voting with weighted scores, audience registration/voting
with token-based dedup, configurable jury/audience weight in results
- Jury UI: Criteria scoring with per-criterion sliders alongside simple 1-10 mode
- Public audience voting page at /vote/[sessionId] with mobile-first design
- Admin live voting: Tabbed layout (Session/Config/Results), criteria config,
audience settings, weight-adjustable results with tie detection
- Round type settings: Visual card selector replacing dropdown, feature tags
- Round detail page: Live event status section, type-specific stats and actions
- Round pipeline view: Horizontal visualization with bottleneck detection,
List/Pipeline toggle on rounds page
- SSE: Separate jury/audience vote events, audience vote tracking
- Field visibility: Hide irrelevant fields per round type in create/edit forms
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:27:49 +01:00
|
|
|
@@index([audienceVoterId])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model AudienceVoter {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
sessionId String
|
|
|
|
|
token String @unique // Unique voting token (UUID)
|
|
|
|
|
identifier String? // Optional: email, phone, or name
|
|
|
|
|
identifierType String? // "email" | "phone" | "name" | "anonymous"
|
|
|
|
|
ipAddress String?
|
|
|
|
|
userAgent String?
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
session LiveVotingSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
|
|
|
|
|
votes LiveVote[]
|
|
|
|
|
|
|
|
|
|
@@index([sessionId])
|
|
|
|
|
@@index([token])
|
2026-01-30 13:41:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// TEAM MEMBERSHIP
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model TeamMember {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
projectId String
|
|
|
|
|
userId String
|
|
|
|
|
role TeamMemberRole @default(MEMBER)
|
|
|
|
|
title String? // "CEO", "CTO", etc.
|
|
|
|
|
joinedAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@unique([projectId, userId])
|
|
|
|
|
@@index([projectId])
|
|
|
|
|
@@index([userId])
|
|
|
|
|
@@index([role])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// MENTOR ASSIGNMENT
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model MentorAssignment {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
projectId String @unique // One mentor per project
|
|
|
|
|
mentorId String // User with MENTOR role or expertise
|
|
|
|
|
|
|
|
|
|
// Assignment tracking
|
|
|
|
|
method MentorAssignmentMethod @default(MANUAL)
|
|
|
|
|
assignedAt DateTime @default(now())
|
|
|
|
|
assignedBy String? // Admin who assigned
|
|
|
|
|
|
|
|
|
|
// AI assignment metadata
|
|
|
|
|
aiConfidenceScore Float?
|
|
|
|
|
expertiseMatchScore Float?
|
|
|
|
|
aiReasoning String? @db.Text
|
|
|
|
|
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
// Tracking
|
|
|
|
|
completionStatus String @default("in_progress") // 'in_progress' | 'completed' | 'paused'
|
|
|
|
|
lastViewedAt DateTime?
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
// Relations
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
|
|
|
mentor User @relation("MentorAssignments", fields: [mentorId], references: [id])
|
|
|
|
|
notes MentorNote[]
|
|
|
|
|
milestoneCompletions MentorMilestoneCompletion[]
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
@@index([mentorId])
|
|
|
|
|
@@index([method])
|
|
|
|
|
}
|
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
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// FILTERING ROUND SYSTEM
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
enum FilteringOutcome {
|
|
|
|
|
PASSED
|
|
|
|
|
FILTERED_OUT
|
|
|
|
|
FLAGGED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum FilteringRuleType {
|
|
|
|
|
FIELD_BASED
|
|
|
|
|
DOCUMENT_CHECK
|
|
|
|
|
AI_SCREENING
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model FilteringRule {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
roundId String
|
|
|
|
|
name String
|
|
|
|
|
ruleType FilteringRuleType
|
|
|
|
|
configJson Json @db.JsonB // Conditions, logic, action per rule type
|
|
|
|
|
priority Int @default(0)
|
|
|
|
|
isActive Boolean @default(true)
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@index([roundId])
|
|
|
|
|
@@index([priority])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model FilteringResult {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
roundId String
|
|
|
|
|
projectId String
|
|
|
|
|
outcome FilteringOutcome
|
|
|
|
|
ruleResultsJson Json? @db.JsonB // Per-rule results
|
|
|
|
|
aiScreeningJson Json? @db.JsonB // AI screening details
|
|
|
|
|
|
|
|
|
|
// Admin override
|
|
|
|
|
overriddenBy String?
|
|
|
|
|
overriddenAt DateTime?
|
|
|
|
|
overrideReason String? @db.Text
|
|
|
|
|
finalOutcome FilteringOutcome?
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
|
|
|
overriddenByUser User? @relation("FilteringOverriddenBy", fields: [overriddenBy], references: [id], onDelete: SetNull)
|
|
|
|
|
|
|
|
|
|
@@unique([roundId, projectId])
|
|
|
|
|
@@index([roundId])
|
|
|
|
|
@@index([projectId])
|
|
|
|
|
@@index([outcome])
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-03 19:48:41 +01:00
|
|
|
// Tracks progress of long-running filtering jobs
|
|
|
|
|
model FilteringJob {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
roundId String
|
|
|
|
|
status FilteringJobStatus @default(PENDING)
|
|
|
|
|
totalProjects Int @default(0)
|
|
|
|
|
totalBatches Int @default(0)
|
|
|
|
|
currentBatch Int @default(0)
|
|
|
|
|
processedCount Int @default(0)
|
|
|
|
|
passedCount Int @default(0)
|
|
|
|
|
filteredCount Int @default(0)
|
|
|
|
|
flaggedCount Int @default(0)
|
|
|
|
|
errorMessage String? @db.Text
|
|
|
|
|
startedAt DateTime?
|
|
|
|
|
completedAt DateTime?
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@index([roundId])
|
|
|
|
|
@@index([status])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum FilteringJobStatus {
|
|
|
|
|
PENDING
|
|
|
|
|
RUNNING
|
|
|
|
|
COMPLETED
|
|
|
|
|
FAILED
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-04 17:40:26 +01:00
|
|
|
// Tracks progress of long-running AI assignment jobs
|
|
|
|
|
model AssignmentJob {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
roundId String
|
|
|
|
|
status AssignmentJobStatus @default(PENDING)
|
|
|
|
|
totalProjects Int @default(0)
|
|
|
|
|
totalBatches Int @default(0)
|
|
|
|
|
currentBatch Int @default(0)
|
|
|
|
|
processedCount Int @default(0)
|
|
|
|
|
suggestionsCount Int @default(0)
|
2026-02-05 14:38:43 +01:00
|
|
|
suggestionsJson Json? @db.JsonB // Stores the AI-generated suggestions
|
2026-02-04 17:40:26 +01:00
|
|
|
errorMessage String? @db.Text
|
|
|
|
|
startedAt DateTime?
|
|
|
|
|
completedAt DateTime?
|
|
|
|
|
fallbackUsed Boolean @default(false)
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@index([roundId])
|
|
|
|
|
@@index([status])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum AssignmentJobStatus {
|
|
|
|
|
PENDING
|
|
|
|
|
RUNNING
|
|
|
|
|
COMPLETED
|
|
|
|
|
FAILED
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-05 11:48:57 +01:00
|
|
|
// Tracks progress of long-running AI tagging jobs
|
|
|
|
|
model TaggingJob {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
programId String? // If tagging entire program
|
|
|
|
|
roundId String? // If tagging single round
|
|
|
|
|
status TaggingJobStatus @default(PENDING)
|
|
|
|
|
totalProjects Int @default(0)
|
|
|
|
|
processedCount Int @default(0)
|
|
|
|
|
taggedCount Int @default(0)
|
|
|
|
|
skippedCount Int @default(0)
|
|
|
|
|
failedCount Int @default(0)
|
|
|
|
|
errorMessage String? @db.Text
|
|
|
|
|
errorsJson Json? @db.JsonB // Array of error messages
|
|
|
|
|
startedAt DateTime?
|
|
|
|
|
completedAt DateTime?
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations (optional - can tag by program or round)
|
|
|
|
|
program Program? @relation(fields: [programId], references: [id], onDelete: Cascade)
|
|
|
|
|
round Round? @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@index([programId])
|
|
|
|
|
@@index([roundId])
|
|
|
|
|
@@index([status])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum TaggingJobStatus {
|
|
|
|
|
PENDING
|
|
|
|
|
RUNNING
|
|
|
|
|
COMPLETED
|
|
|
|
|
FAILED
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
// =============================================================================
|
|
|
|
|
// SPECIAL AWARDS SYSTEM
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
enum AwardScoringMode {
|
|
|
|
|
PICK_WINNER
|
|
|
|
|
RANKED
|
|
|
|
|
SCORED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum AwardStatus {
|
|
|
|
|
DRAFT
|
|
|
|
|
NOMINATIONS_OPEN
|
|
|
|
|
VOTING_OPEN
|
|
|
|
|
CLOSED
|
|
|
|
|
ARCHIVED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum EligibilityMethod {
|
|
|
|
|
AUTO
|
|
|
|
|
MANUAL
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model SpecialAward {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
programId String
|
|
|
|
|
name String
|
|
|
|
|
description String? @db.Text
|
|
|
|
|
status AwardStatus @default(DRAFT)
|
|
|
|
|
|
|
|
|
|
// Criteria
|
2026-02-02 20:02:58 +01:00
|
|
|
criteriaText String? @db.Text // Plain-language criteria for AI
|
|
|
|
|
autoTagRulesJson Json? @db.JsonB // Deterministic eligibility rules
|
|
|
|
|
useAiEligibility Boolean @default(true) // Whether AI evaluates eligibility
|
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
|
|
|
|
|
|
|
|
// Scoring
|
|
|
|
|
scoringMode AwardScoringMode @default(PICK_WINNER)
|
|
|
|
|
maxRankedPicks Int? // For RANKED mode
|
|
|
|
|
|
|
|
|
|
// Voting window
|
|
|
|
|
votingStartAt DateTime?
|
|
|
|
|
votingEndAt DateTime?
|
|
|
|
|
|
|
|
|
|
// Evaluation form (for SCORED mode)
|
|
|
|
|
evaluationFormId String?
|
|
|
|
|
|
|
|
|
|
// Winner
|
|
|
|
|
winnerProjectId String?
|
|
|
|
|
winnerOverridden Boolean @default(false)
|
2026-02-05 21:09:06 +01:00
|
|
|
winnerOverriddenBy String? // FK to User who overrode the winner
|
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
|
|
|
|
|
|
|
|
sortOrder Int @default(0)
|
|
|
|
|
|
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
|
|
|
// Eligibility job tracking
|
|
|
|
|
eligibilityJobStatus String? // PENDING, PROCESSING, COMPLETED, FAILED
|
|
|
|
|
eligibilityJobTotal Int? // total projects to process
|
|
|
|
|
eligibilityJobDone Int? // completed so far
|
|
|
|
|
eligibilityJobError String? @db.Text // error message if failed
|
|
|
|
|
eligibilityJobStarted DateTime? // when job started
|
|
|
|
|
|
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
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
program Program @relation(fields: [programId], references: [id], onDelete: Cascade)
|
|
|
|
|
winnerProject Project? @relation("AwardWinner", fields: [winnerProjectId], references: [id], onDelete: SetNull)
|
2026-02-05 21:09:06 +01:00
|
|
|
overriddenByUser User? @relation("AwardOverriddenBy", fields: [winnerOverriddenBy], references: [id], onDelete: SetNull)
|
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
|
|
|
eligibilities AwardEligibility[]
|
|
|
|
|
jurors AwardJuror[]
|
|
|
|
|
votes AwardVote[]
|
|
|
|
|
|
|
|
|
|
@@index([programId])
|
|
|
|
|
@@index([status])
|
|
|
|
|
@@index([sortOrder])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model AwardEligibility {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
awardId String
|
|
|
|
|
projectId String
|
|
|
|
|
method EligibilityMethod @default(AUTO)
|
|
|
|
|
eligible Boolean @default(false)
|
|
|
|
|
aiReasoningJson Json? @db.JsonB
|
|
|
|
|
|
|
|
|
|
// Admin override
|
|
|
|
|
overriddenBy String?
|
|
|
|
|
overriddenAt DateTime?
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
award SpecialAward @relation(fields: [awardId], references: [id], onDelete: Cascade)
|
|
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
|
|
|
overriddenByUser User? @relation("AwardEligibilityOverriddenBy", fields: [overriddenBy], references: [id], onDelete: SetNull)
|
|
|
|
|
|
|
|
|
|
@@unique([awardId, projectId])
|
|
|
|
|
@@index([awardId])
|
|
|
|
|
@@index([projectId])
|
|
|
|
|
@@index([eligible])
|
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
|
|
|
@@index([awardId, eligible])
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model AwardJuror {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
awardId String
|
|
|
|
|
userId String
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
award SpecialAward @relation(fields: [awardId], references: [id], onDelete: Cascade)
|
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@unique([awardId, userId])
|
|
|
|
|
@@index([awardId])
|
|
|
|
|
@@index([userId])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model AwardVote {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
awardId String
|
|
|
|
|
userId String
|
|
|
|
|
projectId String
|
|
|
|
|
rank Int? // For RANKED mode
|
|
|
|
|
votedAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
award SpecialAward @relation(fields: [awardId], references: [id], onDelete: Cascade)
|
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@unique([awardId, userId, projectId])
|
|
|
|
|
@@index([awardId])
|
|
|
|
|
@@index([userId])
|
|
|
|
|
@@index([projectId])
|
2026-02-11 13:20:52 +01:00
|
|
|
@@index([awardId, userId])
|
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
|
|
|
}
|
Implement 10 platform features: evaluation UX, admin tools, AI summaries, applicant portal
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
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// REMINDER LOG (Evaluation Deadline Reminders)
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model ReminderLog {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
roundId String
|
|
|
|
|
userId String
|
|
|
|
|
type String // "3_DAYS", "24H", "1H"
|
|
|
|
|
sentAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@unique([roundId, userId, type])
|
|
|
|
|
@@index([roundId])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// CONFLICT OF INTEREST
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model ConflictOfInterest {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
assignmentId String @unique
|
|
|
|
|
userId String
|
|
|
|
|
projectId String
|
|
|
|
|
roundId String
|
|
|
|
|
hasConflict Boolean @default(false)
|
|
|
|
|
conflictType String? // "financial", "personal", "organizational", "other"
|
|
|
|
|
description String? @db.Text
|
|
|
|
|
declaredAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Admin review
|
|
|
|
|
reviewedById String?
|
|
|
|
|
reviewedAt DateTime?
|
|
|
|
|
reviewAction String? // "cleared", "reassigned", "noted"
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
assignment Assignment @relation(fields: [assignmentId], references: [id], onDelete: Cascade)
|
|
|
|
|
user User @relation(fields: [userId], references: [id])
|
|
|
|
|
reviewedBy User? @relation("COIReviewedBy", fields: [reviewedById], references: [id])
|
|
|
|
|
|
|
|
|
|
@@index([userId])
|
|
|
|
|
@@index([roundId, hasConflict])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// AI EVALUATION SUMMARY
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model EvaluationSummary {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
projectId String
|
|
|
|
|
roundId String
|
|
|
|
|
summaryJson Json @db.JsonB
|
|
|
|
|
generatedAt DateTime @default(now())
|
|
|
|
|
generatedById String
|
|
|
|
|
model String
|
|
|
|
|
tokensUsed Int
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
|
|
|
generatedBy User @relation("EvaluationSummaryGeneratedBy", fields: [generatedById], references: [id])
|
|
|
|
|
|
|
|
|
|
@@unique([projectId, roundId])
|
|
|
|
|
@@index([roundId])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// PROJECT STATUS HISTORY
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model ProjectStatusHistory {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
projectId String
|
|
|
|
|
status ProjectStatus
|
|
|
|
|
changedAt DateTime @default(now())
|
|
|
|
|
changedBy String?
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@index([projectId, changedAt])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// MENTOR MESSAGES
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model MentorMessage {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
projectId String
|
|
|
|
|
senderId String
|
|
|
|
|
message String @db.Text
|
|
|
|
|
isRead Boolean @default(false)
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
|
|
|
sender User @relation("MentorMessageSender", fields: [senderId], references: [id])
|
|
|
|
|
|
|
|
|
|
@@index([projectId, createdAt])
|
|
|
|
|
}
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// ROUND TEMPLATES
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model RoundTemplate {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
name String
|
|
|
|
|
description String?
|
|
|
|
|
programId String?
|
|
|
|
|
roundType RoundType @default(EVALUATION)
|
|
|
|
|
criteriaJson Json @db.JsonB
|
|
|
|
|
settingsJson Json? @db.JsonB
|
|
|
|
|
assignmentConfig Json? @db.JsonB
|
|
|
|
|
createdBy String
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
program Program? @relation(fields: [programId], references: [id], onDelete: Cascade)
|
|
|
|
|
creator User @relation("RoundTemplateCreatedBy", fields: [createdBy], references: [id])
|
|
|
|
|
|
|
|
|
|
@@index([programId])
|
|
|
|
|
@@index([roundType])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// MENTOR NOTES & MILESTONES
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model MentorNote {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
mentorAssignmentId String
|
|
|
|
|
authorId String
|
|
|
|
|
content String @db.Text
|
|
|
|
|
isVisibleToAdmin Boolean @default(true)
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
mentorAssignment MentorAssignment @relation(fields: [mentorAssignmentId], references: [id], onDelete: Cascade)
|
|
|
|
|
author User @relation("MentorNoteAuthor", fields: [authorId], references: [id])
|
|
|
|
|
|
|
|
|
|
@@index([mentorAssignmentId])
|
|
|
|
|
@@index([authorId])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model MentorMilestone {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
programId String
|
|
|
|
|
name String
|
|
|
|
|
description String? @db.Text
|
|
|
|
|
isRequired Boolean @default(false)
|
|
|
|
|
deadlineOffsetDays Int?
|
|
|
|
|
sortOrder Int @default(0)
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
program Program @relation(fields: [programId], references: [id], onDelete: Cascade)
|
|
|
|
|
completions MentorMilestoneCompletion[]
|
|
|
|
|
|
|
|
|
|
@@index([programId])
|
|
|
|
|
@@index([sortOrder])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model MentorMilestoneCompletion {
|
2026-02-08 14:37:32 +01:00
|
|
|
id String @id @default(cuid())
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
milestoneId String
|
|
|
|
|
mentorAssignmentId String
|
|
|
|
|
completedById String
|
|
|
|
|
completedAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
milestone MentorMilestone @relation(fields: [milestoneId], references: [id], onDelete: Cascade)
|
|
|
|
|
mentorAssignment MentorAssignment @relation(fields: [mentorAssignmentId], references: [id], onDelete: Cascade)
|
|
|
|
|
completedBy User @relation("MilestoneCompletedBy", fields: [completedById], references: [id])
|
|
|
|
|
|
2026-02-08 14:37:32 +01:00
|
|
|
@@unique([milestoneId, mentorAssignmentId])
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
@@index([mentorAssignmentId])
|
|
|
|
|
@@index([completedById])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// EVALUATION DISCUSSIONS
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model EvaluationDiscussion {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
projectId String
|
|
|
|
|
roundId String
|
|
|
|
|
status String @default("open") // 'open' | 'closed'
|
2026-02-08 14:37:32 +01:00
|
|
|
createdAt DateTime @default(now())
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
closedAt DateTime?
|
|
|
|
|
closedById String?
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
|
|
|
round Round @relation(fields: [roundId], references: [id], onDelete: Cascade)
|
|
|
|
|
closedBy User? @relation("DiscussionClosedBy", fields: [closedById], references: [id], onDelete: SetNull)
|
|
|
|
|
comments DiscussionComment[]
|
|
|
|
|
|
|
|
|
|
@@unique([projectId, roundId])
|
|
|
|
|
@@index([roundId])
|
|
|
|
|
@@index([closedById])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model DiscussionComment {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
discussionId String
|
|
|
|
|
userId String
|
|
|
|
|
content String @db.Text
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
discussion EvaluationDiscussion @relation(fields: [discussionId], references: [id], onDelete: Cascade)
|
|
|
|
|
user User @relation("DiscussionCommentAuthor", fields: [userId], references: [id])
|
|
|
|
|
|
|
|
|
|
@@index([discussionId])
|
|
|
|
|
@@index([userId])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// MESSAGING SYSTEM
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model Message {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
senderId String
|
|
|
|
|
recipientType String // 'USER', 'ROLE', 'ROUND_JURY', 'PROGRAM_TEAM', 'ALL'
|
|
|
|
|
recipientFilter Json? @db.JsonB
|
|
|
|
|
roundId String?
|
|
|
|
|
templateId String?
|
|
|
|
|
subject String
|
|
|
|
|
body String @db.Text
|
|
|
|
|
deliveryChannels String[]
|
|
|
|
|
|
|
|
|
|
scheduledAt DateTime?
|
|
|
|
|
sentAt DateTime?
|
2026-02-08 14:37:32 +01:00
|
|
|
metadata Json? @db.JsonB
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
2026-02-08 14:37:32 +01:00
|
|
|
sender User @relation("MessageSender", fields: [senderId], references: [id])
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
round Round? @relation(fields: [roundId], references: [id], onDelete: SetNull)
|
|
|
|
|
template MessageTemplate? @relation(fields: [templateId], references: [id], onDelete: SetNull)
|
|
|
|
|
recipients MessageRecipient[]
|
|
|
|
|
|
|
|
|
|
@@index([senderId])
|
|
|
|
|
@@index([roundId])
|
|
|
|
|
@@index([sentAt])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model MessageRecipient {
|
2026-02-08 14:37:32 +01:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
messageId String
|
|
|
|
|
userId String
|
|
|
|
|
channel String // 'EMAIL', 'IN_APP', etc.
|
|
|
|
|
isRead Boolean @default(false)
|
|
|
|
|
readAt DateTime?
|
|
|
|
|
deliveredAt DateTime?
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
message Message @relation(fields: [messageId], references: [id], onDelete: Cascade)
|
|
|
|
|
user User @relation("MessageRecipient", fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@unique([messageId, userId, channel])
|
|
|
|
|
@@index([userId])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model MessageTemplate {
|
2026-02-08 14:37:32 +01:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
name String
|
|
|
|
|
category String // 'SYSTEM', 'EVALUATION', 'ASSIGNMENT'
|
|
|
|
|
subject String
|
|
|
|
|
body String @db.Text
|
|
|
|
|
variables Json? @db.JsonB
|
|
|
|
|
isActive Boolean @default(true)
|
|
|
|
|
createdBy String
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
2026-02-08 14:37:32 +01:00
|
|
|
creator User @relation("MessageTemplateCreator", fields: [createdBy], references: [id])
|
|
|
|
|
messages Message[]
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
|
|
|
|
|
@@index([category])
|
|
|
|
|
@@index([isActive])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// WEBHOOKS
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model Webhook {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
name String
|
|
|
|
|
url String
|
|
|
|
|
secret String
|
|
|
|
|
events String[]
|
|
|
|
|
headers Json? @db.JsonB
|
|
|
|
|
maxRetries Int @default(3)
|
|
|
|
|
isActive Boolean @default(true)
|
|
|
|
|
createdById String
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
updatedAt DateTime @updatedAt
|
|
|
|
|
|
|
|
|
|
// Relations
|
2026-02-08 14:37:32 +01:00
|
|
|
createdBy User @relation("WebhookCreator", fields: [createdById], references: [id])
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
deliveries WebhookDelivery[]
|
|
|
|
|
|
|
|
|
|
@@index([isActive])
|
|
|
|
|
@@index([createdById])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model WebhookDelivery {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
webhookId String
|
|
|
|
|
event String
|
|
|
|
|
payload Json @db.JsonB
|
|
|
|
|
status String @default("PENDING") // 'PENDING', 'DELIVERED', 'FAILED'
|
|
|
|
|
responseStatus Int?
|
|
|
|
|
responseBody String? @db.Text
|
|
|
|
|
attempts Int @default(0)
|
|
|
|
|
lastAttemptAt DateTime?
|
|
|
|
|
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
webhook Webhook @relation(fields: [webhookId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
|
|
|
|
@@index([webhookId])
|
|
|
|
|
@@index([status])
|
|
|
|
|
@@index([event])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
// DIGEST LOGS
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
model DigestLog {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
digestType String // 'daily' | 'weekly'
|
|
|
|
|
contentJson Json @db.JsonB
|
|
|
|
|
sentAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
// Relations
|
|
|
|
|
user User @relation("DigestLog", fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
|
|
2026-02-08 14:37:32 +01:00
|
|
|
@@index([userId])
|
|
|
|
|
@@index([sentAt])
|
Fix build errors: add missing Prisma models/fields and resolve TypeScript type errors
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
|
|
|
}
|