MOPC-App/CLAUDE.md

341 lines
13 KiB
Markdown

# MOPC Platform - Claude Code Context
## Project Overview
**MOPC (Monaco Ocean Protection Challenge)** is a secure jury online voting platform for managing project selection rounds. The platform enables jury members to evaluate submitted ocean conservation projects, with Phase 1 supporting two selection rounds:
- **Round 1**: ~130 projects → ~60 semi-finalists
- **Round 2**: ~60 projects → 6 finalists
**Domain**: `monaco-opc.com`
The platform is designed for future expansion into a comprehensive program management system including learning hub, communication workflows, and partner modules.
## Key Decisions
| Decision | Choice |
|----------|--------|
| 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 Data Privacy | All data anonymized before sending to GPT |
## Brand Identity
| Name | Hex | Usage |
|------|-----|-------|
| Primary Red | `#de0f1e` | CTAs, alerts |
| Dark Blue | `#053d57` | Headers, sidebar |
| White | `#fefefe` | Backgrounds |
| Teal | `#557f8c` | Links, secondary |
**Typography**: Montserrat (600/700 for headings, 300/400 for body)
## 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 |
| **Animation** | Motion (Framer Motion) | 11.x |
| **Notifications** | Sonner | 1.x |
| **Command Palette** | cmdk | 1.x |
| **File Storage** | MinIO (S3-compatible) | External |
| **Email** | Nodemailer + Poste.io | External |
| **Containerization** | Docker Compose | 2.x |
| **Reverse Proxy** | Nginx | External |
## Architecture Principles
1. **Type Safety First**: End-to-end TypeScript from database to UI via Prisma → tRPC → React
2. **Mobile-First Responsive**: All components designed for mobile, enhanced for desktop
3. **Full Control**: No black-box services; every component is understood and maintainable
4. **Extensible Data Model**: JSON fields for future attributes without schema migrations
5. **Security by Default**: RBAC, audit logging, secure file access with pre-signed URLs
## File Structure
```
mopc-platform/
├── CLAUDE.md # This file - project context
├── docs/
│ └── architecture/ # Architecture documentation
│ ├── README.md # System overview
│ ├── database.md # Database design
│ ├── api.md # API design
│ ├── infrastructure.md # Deployment docs
│ └── ui.md # UI/UX patterns
├── src/
│ ├── app/ # Next.js App Router pages
│ │ ├── (auth)/ # Public auth routes (login, verify)
│ │ ├── (admin)/ # Admin dashboard (protected)
│ │ ├── (jury)/ # Jury interface (protected)
│ │ ├── api/ # API routes
│ │ │ └── trpc/ # tRPC endpoint
│ │ ├── layout.tsx # Root layout
│ │ └── page.tsx # Home/landing
│ ├── components/
│ │ ├── ui/ # shadcn/ui components
│ │ ├── forms/ # Form components (evaluation, etc.)
│ │ ├── layouts/ # Layout components (sidebar, nav)
│ │ └── shared/ # Shared components
│ ├── lib/
│ │ ├── auth.ts # NextAuth configuration
│ │ ├── prisma.ts # Prisma client singleton
│ │ ├── trpc/ # tRPC client & server setup
│ │ ├── minio.ts # MinIO client
│ │ └── email.ts # Email utilities
│ ├── server/
│ │ ├── routers/ # tRPC routers by domain
│ │ │ ├── program.ts
│ │ │ ├── round.ts
│ │ │ ├── project.ts
│ │ │ ├── user.ts
│ │ │ ├── assignment.ts
│ │ │ ├── evaluation.ts
│ │ │ ├── audit.ts
│ │ │ ├── settings.ts
│ │ │ └── gracePeriod.ts
│ │ ├── services/ # Business logic services
│ │ └── middleware/ # RBAC & auth middleware
│ ├── hooks/ # React hooks
│ ├── types/ # Shared TypeScript types
│ └── utils/ # Utility functions
├── prisma/
│ ├── schema.prisma # Database schema
│ ├── migrations/ # Migration files
│ └── seed.ts # Seed data
├── public/ # Static assets
├── docker/
│ ├── Dockerfile # Production build
│ ├── docker-compose.yml # Production stack
│ └── docker-compose.dev.yml # Development stack
├── tests/
│ ├── unit/ # Unit tests
│ └── e2e/ # End-to-end tests
└── config files... # package.json, tsconfig, etc.
```
## Coding Standards
### TypeScript
- Strict mode enabled
- Explicit return types for functions
- Use `type` over `interface` for consistency (unless extending)
- Prefer `unknown` over `any`
### React/Next.js
- Use Server Components by default
- `'use client'` only when needed (interactivity, hooks)
- Collocate components with their routes when specific to that route
- Use React Query (via tRPC) for server state
### Naming Conventions
- **Files**: kebab-case (`user-profile.tsx`)
- **Components**: PascalCase (`UserProfile`)
- **Functions/Variables**: camelCase (`getUserById`)
- **Constants**: SCREAMING_SNAKE_CASE (`MAX_FILE_SIZE`)
- **Database Tables**: PascalCase in Prisma (`User`, `Project`)
- **Database Columns**: camelCase in Prisma (`createdAt`)
### Styling
- Tailwind CSS utility classes
- Mobile-first: base styles for mobile, `md:` for tablet, `lg:` for desktop
- Use shadcn/ui components as base, customize via CSS variables
- No inline styles; no separate CSS files unless absolutely necessary
### API Design (tRPC)
- Group by domain: `trpc.program.create()`, `trpc.round.list()`
- Use Zod for input validation
- Return consistent response shapes
- Throw `TRPCError` with appropriate codes
## Common Commands
```bash
# Development
npm run dev # Start Next.js dev server
npm run db:studio # Open Prisma Studio
npm run db:push # Push schema changes (dev only)
npm run db:migrate # Run migrations
npm run db:seed # Seed database
# Testing
npm run test # Run unit tests
npm run test:e2e # Run E2E tests
npm run test:coverage # Test with coverage
# Build & Deploy
npm run build # Production build
npm run start # Start production server
docker compose up -d # Start Docker stack
docker compose logs -f app # View app logs
# Code Quality
npm run lint # ESLint
npm run format # Prettier
npm run typecheck # TypeScript check
```
## Windows Development Notes
**IMPORTANT**: On Windows, all Docker commands must be run using PowerShell (`powershell -Command "..."`), not bash/cmd. This is required for proper Docker Desktop integration.
**IMPORTANT**: When invoking PowerShell from bash, always use `-ExecutionPolicy Bypass` to skip the user profile script which is blocked by execution policy:
```bash
powershell -ExecutionPolicy Bypass -Command "..."
```
```powershell
# Docker commands on Windows (use PowerShell)
docker compose -f docker/docker-compose.dev.yml up -d
docker compose -f docker/docker-compose.dev.yml build --no-cache app
docker compose -f docker/docker-compose.dev.yml logs -f app
docker compose -f docker/docker-compose.dev.yml down
```
## Environment Variables
```env
# Database
DATABASE_URL="postgresql://user:pass@localhost:5432/mopc"
# NextAuth
NEXTAUTH_URL="https://monaco-opc.com"
NEXTAUTH_SECRET="your-secret-key"
# MinIO (existing separate stack)
MINIO_ENDPOINT="http://localhost:9000"
MINIO_ACCESS_KEY="your-access-key"
MINIO_SECRET_KEY="your-secret-key"
MINIO_BUCKET="mopc-files"
# Email (Poste.io - existing)
SMTP_HOST="localhost"
SMTP_PORT="587"
SMTP_USER="noreply@monaco-opc.com"
SMTP_PASS="your-smtp-password"
EMAIL_FROM="MOPC Platform <noreply@monaco-opc.com>"
# OpenAI (for smart assignment)
OPENAI_API_KEY="your-openai-api-key"
```
## Key Architectural Decisions
### 1. Next.js App Router over Pages Router
**Rationale**: Server Components reduce client bundle, better data fetching patterns, layouts system
### 2. tRPC over REST
**Rationale**: End-to-end type safety without code generation, excellent DX with autocomplete
### 3. Prisma over raw SQL
**Rationale**: Type-safe queries, migration system, works seamlessly with TypeScript
### 4. NextAuth.js over custom auth
**Rationale**: Battle-tested, supports magic links, session management built-in
### 5. MinIO (external) over local file storage
**Rationale**: S3-compatible, pre-signed URLs for security, scalable, already deployed
### 6. JSON fields for extensibility
**Rationale**: `metadata_json`, `settings_json` allow adding attributes without migrations
### 7. Soft deletes with status fields
**Rationale**: Audit trail preservation, recovery capability, referential integrity
## 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 (optional) |
## Important Constraints
1. **Jury can only see assigned projects** - enforced at query level
2. **Voting windows are strict** - submissions blocked outside active window
3. **Evaluations are versioned** - edits create new versions
4. **All admin actions are audited** - immutable audit log
5. **Files accessed via pre-signed URLs** - no public bucket access
6. **Mobile responsiveness is mandatory** - every view must work on phones
7. **File downloads require project authorization** - jury/mentor must be assigned to the project
8. **Mentor endpoints require MENTOR role** - uses `mentorProcedure` middleware
## Security Notes
### CSRF Protection
tRPC mutations are protected against CSRF attacks because:
- tRPC uses `application/json` content type, which triggers CORS preflight on cross-origin requests
- Browsers block cross-origin JSON POSTs by default (Same-Origin Policy)
- NextAuth's own routes (`/api/auth/*`) have built-in CSRF token protection
- No custom CORS headers are configured to allow external origins
**Do NOT add permissive CORS headers** (e.g., `Access-Control-Allow-Origin: *`) without also implementing explicit CSRF token validation on all mutation endpoints.
### Rate Limiting
- tRPC API: 100 requests/minute per IP
- Auth endpoints: 10 POST requests/minute per IP
- Account lockout: 5 failed password attempts triggers 15-minute lockout
## External Services (Pre-existing)
These services are already running on the VPS in separate Docker Compose stacks:
- **MinIO**: `http://localhost:9000` - S3-compatible storage
- **Poste.io**: `localhost:587` - SMTP server for emails
- **Nginx**: Host-level reverse proxy with SSL (certbot)
The MOPC platform connects to these via environment variables.
## Phase 1 Scope
### In Scope
- Round management (create, configure, activate/close)
- Project import (CSV) and file uploads
- Jury invitation (magic link)
- Manual project assignment (single + bulk)
- Evaluation form (configurable criteria)
- Autosave + final submit
- Voting window enforcement
- Progress dashboards
- CSV export
- Audit logging
### Out of Scope (Phase 2+)
- Auto-assignment algorithm
- Typeform/Notion integrations
- WhatsApp notifications
- Learning hub
- Partner modules
- Public website
## Testing Strategy
- **Unit Tests**: Business logic, utilities, validators
- **Integration Tests**: tRPC routers with test database
- **E2E Tests**: Critical user flows (Playwright)
- **Manual Testing**: Responsive design on real devices
## Documentation Links
- [Architecture Overview](./docs/architecture/README.md)
- [Database Design](./docs/architecture/database.md)
- [API Design](./docs/architecture/api.md)
- [Infrastructure](./docs/architecture/infrastructure.md)
- [UI/UX Patterns](./docs/architecture/ui.md)