# MOPC Platform - Architecture Overview ## System Overview The MOPC Platform is a secure jury voting system built as a modern full-stack TypeScript application for the **Monaco Ocean Protection Challenge**. It follows a layered architecture with clear separation of concerns. **Phase 1 Focus**: Jury selection rounds (130→60→6 projects) **Domain**: `monaco-opc.com` ## Finalized Decisions | Decision | Choice | |----------|--------| | **Domain** | `monaco-opc.com` | | **Evaluation Criteria** | Fully configurable per round (admin defines) | | **CSV Import** | Flexible column mapping (admin maps columns) | | **Max File Size** | 500MB (for videos) | | **Observer Role** | Included in Phase 1 | | **First Admin** | Database seed script | | **Past Evaluations** | Visible read-only after submit | | **Grace Period** | Admin-configurable per juror/project | | **Smart Assignment** | AI-powered (GPT) + Smart Algorithm fallback | | **AI Provider** | Admin-configurable (OpenAI GPT) | | **AI Data Privacy** | All data anonymized/encoded before sending to GPT | ## Tech Stack | Layer | Technology | Version | |-------|-----------|---------| | **Framework** | Next.js (App Router) | 15.x | | **Language** | TypeScript | 5.x | | **UI Components** | shadcn/ui | latest | | **Styling** | Tailwind CSS | 3.x | | **API Layer** | tRPC | 11.x | | **Database** | PostgreSQL | 16.x | | **ORM** | Prisma | 6.x | | **Authentication** | NextAuth.js (Auth.js) | 5.x | | **AI** | OpenAI GPT | 4.x SDK | | **File Storage** | MinIO (S3-compatible) | External | | **Email** | Nodemailer + Poste.io | External | | **Animation** | Motion (Framer Motion) | 11.x | | **Notifications** | Sonner | 1.x | | **Command Palette** | cmdk | 1.x | | **Containerization** | Docker Compose | 2.x | | **Reverse Proxy** | Nginx | External | ## Brand Identity ### Colors | Name | Hex | Usage | |------|-----|-------| | Primary Red | `#de0f1e` | Accents, CTAs, alerts | | Dark Blue | `#053d57` | Headers, sidebar, primary text | | White | `#fefefe` | Backgrounds | | Teal | `#557f8c` | Secondary elements, links | ### Typography - **Headings**: Montserrat (600/700 weight) - **Body**: Montserrat Light (300/400 weight) ## High-Level Architecture Diagram ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ PRESENTATION LAYER │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ │ │ Admin Views │ │ Jury Views │ │ Auth Views │ │ │ │ │ │ │ │ │ │ │ │ - Dashboard │ │ - Project List │ │ - Login │ │ │ │ - Rounds │ │ - Project View │ │ - Magic Link │ │ │ │ - Projects │ │ - Evaluation │ │ - Verify │ │ │ │ - Jury Mgmt │ │ - My Progress │ │ │ │ │ │ - Assignments │ │ │ │ │ │ │ │ - Reports │ │ │ │ │ │ │ └──────────────────┘ └──────────────────┘ └──────────────────┘ │ │ │ │ Built with: Next.js App Router + React Server Components + shadcn/ui │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ API LAYER │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │ │ tRPC Router │ │ │ │ │ │ │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │ │ │program │ │ round │ │project │ │ user │ │assign- │ │evalua- │ │ │ │ │ │Router │ │Router │ │Router │ │Router │ │ment │ │tion │ │ │ │ │ │ │ │ │ │ │ │ │ │Router │ │Router │ │ │ │ │ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │ │ │ └──────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ │ │ Auth Middleware │ │ RBAC Middleware │ │ Audit Logger │ │ │ │ (NextAuth.js) │ │ (role checks) │ │ (all actions) │ │ │ └──────────────────┘ └──────────────────┘ └──────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ SERVICE LAYER │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ Program │ │ Round │ │ Assignment │ │ Evaluation │ │ │ │ Service │ │ Service │ │ Service │ │ Service │ │ │ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ File │ │ Email │ │ Export │ │ Audit │ │ │ │ Service │ │ Service │ │ Service │ │ Service │ │ │ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ DATA LAYER │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │ │ Prisma ORM │ │ │ │ │ │ │ │ Type-safe database access, migrations, query building │ │ │ └──────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ PostgreSQL │ │ MinIO │ │ │ │ (Database) │ │ (File Store) │ │ │ │ │ │ │ │ │ │ - Users │ │ - PDFs │ │ │ │ - Programs │ │ - Videos │ │ │ │ - Rounds │ │ - Exports │ │ │ │ - Projects │ │ │ │ │ │ - Evaluations │ │ │ │ │ │ - Audit Logs │ │ │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` ## Component Responsibilities ### Presentation Layer | Component | Responsibility | |-----------|----------------| | **Admin Views** | Program/round management, project import, jury management, assignments, dashboards | | **Jury Views** | View assigned projects, evaluate projects, track progress | | **Auth Views** | Login, magic link verification, session management | | **Layouts** | Responsive navigation, sidebar, mobile adaptations | | **UI Components** | shadcn/ui based, reusable, accessible | ### API Layer | Component | Responsibility | |-----------|----------------| | **tRPC Routers** | Type-safe API endpoints grouped by domain | | **Auth Middleware** | Session validation via NextAuth.js | | **RBAC Middleware** | Role-based access control enforcement | | **Audit Logger** | Record all significant actions | | **Validators** | Zod schemas for input validation | ### Service Layer | Service | Responsibility | |---------|----------------| | **ProgramService** | CRUD for programs (e.g., "MOPC 2026") | | **RoundService** | Round lifecycle, voting windows, form versions | | **AssignmentService** | Jury-project assignments, load balancing | | **EvaluationService** | Form submission, autosave, scoring | | **FileService** | MinIO uploads, pre-signed URLs | | **EmailService** | Magic links, notifications via Nodemailer | | **ExportService** | CSV/Excel generation | | **AuditService** | Immutable event logging | ### Data Layer | Component | Responsibility | |-----------|----------------| | **Prisma Client** | Type-safe database queries | | **PostgreSQL** | Primary data store (relational) | | **MinIO** | S3-compatible file storage | | **Migrations** | Schema versioning and evolution | ## Data Flow Examples ### 1. Jury Login Flow ``` User Next.js NextAuth PostgreSQL │ │ │ │ │ 1. Enter email │ │ │ │───────────────────────>│ │ │ │ │ 2. Request magic link │ │ │ │───────────────────────>│ │ │ │ │ 3. Store token │ │ │ │───────────────────────>│ │ │ │<───────────────────────│ │ │ 4. Send email │ │ │ │<───────────────────────│ │ │ 5. Email with link │ │ │ │<───────────────────────│ │ │ │ │ │ │ │ 6. Click link │ │ │ │───────────────────────>│ │ │ │ │ 7. Verify token │ │ │ │───────────────────────>│ │ │ │ │ 8. Validate │ │ │ │───────────────────────>│ │ │ │<───────────────────────│ │ │ 9. Create session │ │ │ │<───────────────────────│ │ │ 10. Redirect to dash │ │ │ │<───────────────────────│ │ │ ``` ### 2. Jury Evaluation Flow ``` Jury Member Next.js/tRPC Service Layer PostgreSQL/MinIO │ │ │ │ │ 1. View project list │ │ │ │───────────────────────>│ 2. project.listAssigned() │ │ │───────────────────────>│ 3. Query assignments │ │ │ │───────────────────────>│ │ │ │<───────────────────────│ │ 4. Show assigned projects │ │ │<───────────────────────│ │ │ │ │ │ │ │ 5. Open project │ │ │ │───────────────────────>│ 6. project.getDetails() │ │ │───────────────────────>│ 7. Get project + files│ │ │ │───────────────────────>│ │ │ │ 8. Generate pre-signed URLs │ │ │<───────────────────────│ │ 9. Show project with file links │ │ │<───────────────────────│ │ │ │ │ │ │ │ 10. Fill evaluation │ │ │ │ (typing...) │ 11. evaluation.autosave() (debounced) │ │───────────────────────>│───────────────────────>│ 12. Save draft │ │ │ │───────────────────────>│ │ │ │<───────────────────────│ │ 13. Autosaved indicator │ │ │<───────────────────────│ │ │ │ │ │ │ │ 14. Submit final │ │ │ │───────────────────────>│ 15. evaluation.submit() │ │ │───────────────────────>│ 16. Validate window │ │ │ │ 17. Lock evaluation │ │ │ │ 18. Log audit event │ │ │ │───────────────────────>│ │ │ │<───────────────────────│ │ 19. Success, mark complete │ │ │<───────────────────────│ │ │ ``` ### 3. Admin Export Flow ``` Admin Next.js/tRPC Service Layer PostgreSQL/MinIO │ │ │ │ │ 1. Request CSV export │ │ │ │───────────────────────>│ 2. export.generateCSV() │ │ │───────────────────────>│ 3. Query all evals │ │ │ │───────────────────────>│ │ │ │<───────────────────────│ │ │ │ 4. Build CSV │ │ │ │ 5. Upload to MinIO │ │ │ │───────────────────────>│ │ │ │<───────────────────────│ │ │ │ 6. Log audit event │ │ │ │───────────────────────>│ │ │ 7. Return download URL│ │ │ │<───────────────────────│ │ │ 8. Download file │ │ │ │<───────────────────────│ │ │ ``` ## Security Architecture ### Authentication - **Method**: Email magic links (passwordless) - **Sessions**: JWT stored in HTTP-only cookies - **Provider**: NextAuth.js with custom email provider ### Authorization (RBAC) - **Enforcement**: tRPC middleware checks role before procedure - **Granularity**: Role + resource-level (jury sees only assigned projects) - **Storage**: User.role field in database ### Data Security - **File Access**: Pre-signed URLs with short TTL (15 min) - **SQL Injection**: Prevented by Prisma parameterized queries - **XSS**: React's built-in escaping + CSP headers - **CSRF**: NextAuth.js built-in protection ### Audit Trail - **Coverage**: All admin actions, all state changes - **Immutability**: Append-only audit_logs table - **Fields**: user, action, entity, details, timestamp, IP ## Scalability Considerations ### Current Design (Phase 1) - Single PostgreSQL instance (sufficient for ~200 concurrent users) - Single Next.js instance behind Nginx - MinIO for file storage (horizontally scalable) ### Future Scale Path 1. **Database**: Read replicas for dashboards, connection pooling (PgBouncer) 2. **Application**: Multiple Next.js instances behind load balancer 3. **Caching**: Redis for session storage and query caching 4. **CDN**: Static assets via CDN 5. **Background Jobs**: BullMQ for email queues, exports ## Smart Assignment System The platform includes two assignment modes: ### 1. AI-Powered Assignment (GPT) - Analyzes juror expertise and project tags - Optimizes for balanced workload - Respects organizational conflicts - **Privacy**: All data is anonymized before sending to GPT - Names → `JUROR_A`, `JUROR_B` - Projects → `PROJECT_1`, `PROJECT_2` - Organizations → `ORG_X`, `ORG_Y` - Emails and personal details are never sent ### 2. Smart Algorithm (Rule-Based Fallback) - Fully featured scoring algorithm - No external API required - Handles 200 projects × 50 jurors in < 1 second - Deterministic results **Scoring Formula**: ``` Score = (expertise_match × 40) + (load_balance × 25) + (specialty_match × 20) + (diversity × 10) - (conflict × 100) ``` ## Admin Settings Panel Centralized configuration for: - **AI Configuration**: Provider, API key, model, budget limits - **Platform Branding**: Logo, colors, name - **Email/SMTP**: Server, credentials, templates - **File Storage**: MinIO endpoint, bucket, limits - **Security**: Session duration, rate limits - **Defaults**: Timezone, pagination, autosave interval ## User Roles (RBAC) | Role | Permissions | |------|------------| | **SUPER_ADMIN** | Full system access, all programs, user management | | **PROGRAM_ADMIN** | Manage specific programs, rounds, projects, jury | | **JURY_MEMBER** | View assigned projects only, submit evaluations | | **OBSERVER** | Read-only access to dashboards | ## Related Documentation - [Database Design](./database.md) - Schema, relationships, indexes - [API Design](./api.md) - tRPC routers, endpoints, auth flow - [Infrastructure](./infrastructure.md) - Docker, Nginx, deployment - [UI/UX Patterns](./ui.md) - Components, responsive design