# omar-elhadi/marsai architecture

> Architecture diagram of the GitHub repository omar-elhadi/marsai, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-09). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/omar-elhadi/marsai
- Repository: https://github.com/omar-elhadi/marsai

## Overview

#### Purpose and Entry Points
Marsai Festival is a TypeScript monorepo for AI-film submission, jury review/voting, festival administration, and public award/gallery presentation. The React SPA starts at `client/src/main.tsx` and composes routes/UI in `client/src/App.tsx`. The Express API starts through `server/src/index.ts`; Vercel serverless adaptation is at `server/api/index.ts`.

#### Frontend Application Shell
The Vite/React client separates public, admin, and jury experiences. Layout and route protection enforce authenticated access before privileged views; localization is initialized centrally. Key paths: `client/src/App.tsx`, `client/src/components/ProtectedRoute.tsx`, `client/src/contexts/AuthContext.tsx`.

#### Submission and Film Lifecycle
Public submitters create and track films, including YouTube-based film content. Administrators review entries, update statuses, request changes, select finalists, and manage film details. This lifecycle spans `client/src/pages/Submission/SubmissionForm.tsx`, `server/src/routes/film.routes.ts`, and `server/src/services/film.service.ts`.

#### Identity, Roles, and Authorization
JWT authentication uses argon2-backed credentials and role-based authorization for Admin, Moderator, and Jury workflows. The client restores/session-checks user identity and calls dedicated auth APIs; the server authenticates requests before protected handlers. Paths: `client/src/hooks/useAuth.ts`, `server/src/services/auth.service.ts`, `server/src/middlewares/auth.middleware.ts`.

#### Jury Evaluation and Awards
Jury members access assigned/reviewable films and submit ratings/comments. Votes feed administrative selection and award-category/winner management, with public palmarès output. Core boundaries are `client/src/pages/Jury/JuryDashboard.tsx`, `server/src/services/vote.service.ts`, and `server/src/services/award.service.ts`.

#### API Layer and Persistence
Express routes delegate through controllers to domain services, with centralized validation and error handling. Prisma owns the relational MySQL schema and migrations; shared Zod schemas provide a cross-workspace validation contract. Paths: `server/src/routes/vote.routes.ts`, `server/prisma/schema.prisma`, `packages/validators/src/index.ts`.

#### Public Content and Supporting Services
The public site exposes gallery, award results, events/resources, jury information, newsletter signup, and configurable site settings. Backend services include newsletter/mail handling and gallery/settings data; frontend hooks isolate API consumption. Paths: `client/src/pages/Gallery/Gallery.tsx`, `server/src/services/newsletter.service.ts`, `server/src/services/settings.service.ts`.

#### Runtime and Deployment Boundaries
Development runs a React/Vite client (5173) and Express API (5000), backed by MySQL 8.4. Docker Compose supports local/production container deployment; frontend and serverless API can deploy as separate Vercel projects. Mail transport is environment-configured. Paths: `docker-compose.yml`, `docker-compose.prod.yml`, `server/src/services/mail.service.ts`.

Main entry points: [`server/src/routes/vote.routes.ts`](https://github.com/omar-elhadi/marsai/blob/main/server/src/routes/vote.routes.ts) (Routes, controllers & validation), [`server/src/index.ts`](https://github.com/omar-elhadi/marsai/blob/main/server/src/index.ts) (API entry), [`client/src/App.tsx`](https://github.com/omar-elhadi/marsai/blob/main/client/src/App.tsx) (App shell & routes), [`server/prisma/schema.prisma`](https://github.com/omar-elhadi/marsai/blob/main/server/prisma/schema.prisma) (Prisma schema & migrations)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["React client"]
  node_client_entry["Vite entry<br/>React bootstrap<br/>[main.tsx]"]
  node_app_shell["App shell &amp; routes<br/>React routing<br/>[App.tsx]"]
  node_auth_context["Auth session<br/>client identity<br/>[AuthContext.tsx]"]
  node_protected_routes["Protected routes<br/>route guard<br/>[ProtectedRoute.tsx]"]
  node_submission_ui["Film submission<br/>public workflow<br/>[SubmissionForm.tsx]"]
  node_jury_ui["Jury dashboard<br/>jury workflow<br/>[JuryDashboard.tsx]"]
  node_gallery_ui["Public gallery<br/>public presentation<br/>[Gallery.tsx]"]
end

subgraph group_api["Express API"]
  node_api_entry["API entry<br/>Express bootstrap<br/>[index.ts]"]
  node_api_pipeline["Routes, controllers &amp; validation<br/>HTTP layer<br/>[vote.routes.ts]"]
  node_auth_security["Authentication &amp; RBAC<br/>security layer<br/>[auth.middleware.ts]"]
  node_auth_service["Credential service<br/>auth domain service<br/>[auth.service.ts]"]
  node_film_service["Film lifecycle service<br/>film domain service<br/>[film.service.ts]"]
  node_vote_service["Voting service<br/>jury domain service<br/>[vote.service.ts]"]
  node_award_service["Awards service<br/>award domain service<br/>[award.service.ts]"]
  node_content_services["Content services"]
  node_mail_service["Mail transport<br/>outbound mail<br/>[mail.service.ts]"]
end

subgraph group_data["Data contracts"]
  node_validators["Shared Zod schemas<br/>validation contract<br/>[index.ts]"]
  node_prisma["Prisma schema &amp; migrations<br/>persistence layer<br/>[schema.prisma]"]
  node_mysql[("MySQL 8.4<br/>relational database")]
end

subgraph group_runtime["Runtime &amp; deployment"]
  node_vercel_api["Vercel API adapter<br/>serverless entry<br/>[index.ts]"]
  node_containers["Docker Compose<br/>container deployment<br/>[docker-compose.yml]"]
end

node_client_entry -->|"mounts"| node_app_shell
node_app_shell -->|"uses"| node_auth_context
node_app_shell -->|"guards views with"| node_protected_routes
node_app_shell -->|"routes to"| node_submission_ui
node_app_shell -->|"routes to"| node_jury_ui
node_app_shell -->|"routes to"| node_gallery_ui
node_auth_context -->|"checks session"| node_api_entry
node_submission_ui -->|"submits and tracks films"| node_api_entry
node_jury_ui -->|"loads films and votes"| node_api_entry
node_gallery_ui -->|"loads public content"| node_api_entry
node_api_entry -->|"dispatches requests"| node_api_pipeline
node_api_pipeline -->|"validates with"| node_validators
node_api_pipeline -->|"protects handlers"| node_auth_security
node_auth_security -->|"authenticates via"| node_auth_service
node_api_pipeline -->|"film endpoints"| node_film_service
node_api_pipeline -->|"vote endpoints"| node_vote_service
node_api_pipeline -->|"award endpoints"| node_award_service
node_api_pipeline -->|"content endpoints"| node_content_services
node_content_services -->|"sends newsletters"| node_mail_service
node_auth_service -->|"persists users"| node_prisma
node_film_service -->|"persists films"| node_prisma
node_vote_service -->|"persists votes"| node_prisma
node_award_service -->|"persists awards"| node_prisma
node_content_services -->|"persists site content"| node_prisma
node_prisma -->|"maps to"| node_mysql
node_vercel_api -->|"adapts"| node_api_entry
node_containers -.->|"runs client"| node_client_entry
node_containers -.->|"runs API"| node_api_entry
node_containers -.->|"runs database"| node_mysql

click node_client_entry "https://github.com/omar-elhadi/marsai/blob/main/client/src/main.tsx"
click node_app_shell "https://github.com/omar-elhadi/marsai/blob/main/client/src/App.tsx"
click node_auth_context "https://github.com/omar-elhadi/marsai/blob/main/client/src/contexts/AuthContext.tsx"
click node_protected_routes "https://github.com/omar-elhadi/marsai/blob/main/client/src/components/ProtectedRoute.tsx"
click node_submission_ui "https://github.com/omar-elhadi/marsai/blob/main/client/src/pages/Submission/SubmissionForm.tsx"
click node_jury_ui "https://github.com/omar-elhadi/marsai/blob/main/client/src/pages/Jury/JuryDashboard.tsx"
click node_gallery_ui "https://github.com/omar-elhadi/marsai/blob/main/client/src/pages/Gallery/Gallery.tsx"
click node_api_entry "https://github.com/omar-elhadi/marsai/blob/main/server/src/index.ts"
click node_api_pipeline "https://github.com/omar-elhadi/marsai/blob/main/server/src/routes/vote.routes.ts"
click node_auth_security "https://github.com/omar-elhadi/marsai/blob/main/server/src/middlewares/auth.middleware.ts"
click node_auth_service "https://github.com/omar-elhadi/marsai/blob/main/server/src/services/auth.service.ts"
click node_film_service "https://github.com/omar-elhadi/marsai/blob/main/server/src/services/film.service.ts"
click node_vote_service "https://github.com/omar-elhadi/marsai/blob/main/server/src/services/vote.service.ts"
click node_award_service "https://github.com/omar-elhadi/marsai/blob/main/server/src/services/award.service.ts"
click node_content_services "https://github.com/omar-elhadi/marsai/blob/main/server/src/services/settings.service.ts"
click node_mail_service "https://github.com/omar-elhadi/marsai/blob/main/server/src/services/mail.service.ts"
click node_validators "https://github.com/omar-elhadi/marsai/blob/main/packages/validators/src/index.ts"
click node_prisma "https://github.com/omar-elhadi/marsai/blob/main/server/prisma/schema.prisma"
click node_vercel_api "https://github.com/omar-elhadi/marsai/blob/main/server/api/index.ts"
click node_containers "https://github.com/omar-elhadi/marsai/blob/main/docker-compose.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_client_entry,node_app_shell,node_auth_context,node_protected_routes,node_submission_ui,node_jury_ui,node_gallery_ui toneBlue
class node_api_entry,node_api_pipeline,node_auth_security,node_auth_service,node_film_service,node_vote_service,node_award_service,node_content_services,node_mail_service toneAmber
class node_validators,node_prisma,node_mysql toneMint
class node_vercel_api,node_containers toneRose
```

## Components

### React client

Public, admin, and jury SPA.

- [Vite entry](https://github.com/omar-elhadi/marsai/blob/main/client/src/main.tsx): React bootstrap · `client/src/main.tsx`
- [App shell & routes](https://github.com/omar-elhadi/marsai/blob/main/client/src/App.tsx): React routing · Composes public, admin, and jury experiences. · `client/src/App.tsx`
- [Auth session](https://github.com/omar-elhadi/marsai/blob/main/client/src/contexts/AuthContext.tsx): client identity · Restores and exposes the current user. · `client/src/contexts/AuthContext.tsx`
- [Protected routes](https://github.com/omar-elhadi/marsai/blob/main/client/src/components/ProtectedRoute.tsx): route guard · Restricts privileged views by authentication and role. · `client/src/components/ProtectedRoute.tsx`
- [Film submission](https://github.com/omar-elhadi/marsai/blob/main/client/src/pages/Submission/SubmissionForm.tsx): public workflow · `client/src/pages/Submission/SubmissionForm.tsx`
- [Jury dashboard](https://github.com/omar-elhadi/marsai/blob/main/client/src/pages/Jury/JuryDashboard.tsx): jury workflow · `client/src/pages/Jury/JuryDashboard.tsx`
- [Public gallery](https://github.com/omar-elhadi/marsai/blob/main/client/src/pages/Gallery/Gallery.tsx): public presentation · `client/src/pages/Gallery/Gallery.tsx`

### Express API

HTTP API and domain services.

- [API entry](https://github.com/omar-elhadi/marsai/blob/main/server/src/index.ts): Express bootstrap · `server/src/index.ts`
- [Routes, controllers & validation](https://github.com/omar-elhadi/marsai/blob/main/server/src/routes/vote.routes.ts): HTTP layer · Routes delegate requests through controllers with centralized validation and errors. · `server/src/routes/vote.routes.ts`
- [Authentication & RBAC](https://github.com/omar-elhadi/marsai/blob/main/server/src/middlewares/auth.middleware.ts): security layer · JWT authentication and role authorization for protected handlers. · `server/src/middlewares/auth.middleware.ts`
- [Credential service](https://github.com/omar-elhadi/marsai/blob/main/server/src/services/auth.service.ts): auth domain service · Uses argon2-backed credentials and issues identity access. · `server/src/services/auth.service.ts`
- [Film lifecycle service](https://github.com/omar-elhadi/marsai/blob/main/server/src/services/film.service.ts): film domain service · Manages submissions, review status, change requests, and finalists. · `server/src/services/film.service.ts`
- [Voting service](https://github.com/omar-elhadi/marsai/blob/main/server/src/services/vote.service.ts): jury domain service · Records jury ratings and comments. · `server/src/services/vote.service.ts`
- [Awards service](https://github.com/omar-elhadi/marsai/blob/main/server/src/services/award.service.ts): award domain service · Manages categories, winners, and palmarès output. · `server/src/services/award.service.ts`
- [Content services](https://github.com/omar-elhadi/marsai/blob/main/server/src/services/settings.service.ts): site content services · Provides newsletter, settings, gallery, event, and resource data. · `server/src/services/settings.service.ts`
- [Mail transport](https://github.com/omar-elhadi/marsai/blob/main/server/src/services/mail.service.ts): outbound mail · Environment-configured mail delivery. · `server/src/services/mail.service.ts`

### Data contracts

- [Shared Zod schemas](https://github.com/omar-elhadi/marsai/blob/main/packages/validators/src/index.ts): validation contract · Cross-workspace request and data validation. · `packages/validators/src/index.ts`
- [Prisma schema & migrations](https://github.com/omar-elhadi/marsai/blob/main/server/prisma/schema.prisma): persistence layer · Owns relational schema and migrations. · `server/prisma/schema.prisma`
- **MySQL 8.4**: relational database

### Runtime & deployment

- [Vercel API adapter](https://github.com/omar-elhadi/marsai/blob/main/server/api/index.ts): serverless entry · Adapts the API for serverless deployment. · `server/api/index.ts`
- [Docker Compose](https://github.com/omar-elhadi/marsai/blob/main/docker-compose.yml): container deployment · Runs client, API, and MySQL locally or in production. · `docker-compose.yml`

## Connections

- Vite entry → App shell & routes: mounts
- App shell & routes → Auth session: uses
- App shell & routes → Protected routes: guards views with
- App shell & routes → Film submission: routes to
- App shell & routes → Jury dashboard: routes to
- App shell & routes → Public gallery: routes to
- Auth session → API entry: checks session
- Film submission → API entry: submits and tracks films
- Jury dashboard → API entry: loads films and votes
- Public gallery → API entry: loads public content
- API entry → Routes, controllers & validation: dispatches requests
- Routes, controllers & validation → Shared Zod schemas: validates with
- Routes, controllers & validation → Authentication & RBAC: protects handlers
- Authentication & RBAC → Credential service: authenticates via
- Routes, controllers & validation → Film lifecycle service: film endpoints
- Routes, controllers & validation → Voting service: vote endpoints
- Routes, controllers & validation → Awards service: award endpoints
- Routes, controllers & validation → Content services: content endpoints
- Content services → Mail transport: sends newsletters
- Credential service → Prisma schema & migrations: persists users
- Film lifecycle service → Prisma schema & migrations: persists films
- Voting service → Prisma schema & migrations: persists votes
- Awards service → Prisma schema & migrations: persists awards
- Content services → Prisma schema & migrations: persists site content
- Prisma schema & migrations → MySQL 8.4: maps to
- Vercel API adapter → API entry: adapts
- Docker Compose → Vite entry: runs client
- Docker Compose → API entry: runs API
- Docker Compose → MySQL 8.4: runs database
