# jasperxxl/y-kopie architecture

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

- Interactive diagram: https://gitdiagram.com/jasperxxl/y-kopie
- Repository: https://github.com/jasperxxl/y-kopie

## Overview

Yanlaa is a web-based interactive quiz platform. Teachers create and manage quizzes, optionally generate them from uploaded PDFs, then host live games or share self-paced quizzes; players join, answer questions, and view results and rankings. The React client also provides quiz discovery and school-management experiences, backed by Django APIs, WebSockets, persistent models, and background tasks. The README documents the major product modes; source-index references and sampled files support selected internal relationships, while unsampled wiring is left unasserted.

Main entry points: [`server/quiz/quiz_generator/tasks.py`](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/quiz_generator/tasks.py) (Document generation tasks), [`client/src/App.tsx`](https://github.com/jasperxxl/y-kopie/blob/main/client/src/App.tsx) (App routes), [`server/quiz/models.py`](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/models.py) (Quiz and session data), [`server/quiz/gameplay/services/sessions.py`](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/gameplay/services/sessions.py) (Session and answer services)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["React client"]
  node_client_app["App routes<br/>[App.tsx]"]
  node_dashboard["Quiz dashboard<br/>[background.tsx]"]
  node_host_ui["Live host UI<br/>[HostLivePlay.tsx]"]
  node_player_ui["Live player UI<br/>[PlayerLivePlay.tsx]"]
  node_async_ui["Self-paced play<br/>[useAsyncQuiz.tsx]"]
  node_library_ui["Quiz library<br/>[Library.tsx]"]
  node_generator_ui["PDF quiz workflow"]
  node_school_ui["School management"]
  node_host_hooks["Host session hooks"]
  node_player_hooks["Player session hooks<br/>[useJoinSession.tsx]"]
end

subgraph group_gameplay["Quiz gameplay"]
  node_game_registry["Game registry<br/>[gameRegistry.ts]"]
  node_game_session["Session and answer services<br/>[sessions.py]"]
  node_realtime["Realtime services<br/>[realtime.py]"]
  node_ws_consumers["WebSocket consumers<br/>[consumers.py]"]
  node_async_api["Async quiz API<br/>[async_api.py]"]
  node_game_tasks["Gameplay tasks<br/>[tasks.py]"]
end

subgraph group_content["Quiz content"]
  node_quiz_models[("Quiz and session data<br/>[models.py]")]
  node_library_api["Library API<br/>[api.py]"]
  node_library_search["Library search<br/>[search.py]"]
  node_generator_tasks["Document generation tasks<br/>[tasks.py]"]
  node_generator_models[("Generation records<br/>[models.py]")]
end

subgraph group_platform["Accounts and schools"]
  node_account_api["Account API<br/>[api.py]"]
  node_quotas["Account quotas<br/>[quotas.py]"]
  node_school_api["School API<br/>[api.py]"]
end

subgraph group_runtime["Backend runtime"]
  node_database[("PostgreSQL")]
  node_redis[("Redis / Valkey")]
  node_celery["Celery worker"]
end

node_teacher(("Teacher"))
node_player(("Player"))

node_teacher -->|"uses"| node_client_app
node_player -->|"uses"| node_client_app
node_client_app -->|"routes to"| node_dashboard
node_client_app -->|"routes to"| node_library_ui
node_client_app -->|"routes to"| node_generator_ui
node_teacher -.->|"creates quizzes"| node_dashboard
node_teacher -->|"hosts games"| node_host_ui
node_player -->|"joins games"| node_player_ui
node_host_ui -->|"uses"| node_host_hooks
node_player_ui -.->|"uses"| node_player_hooks
node_host_hooks -->|"connects by WebSocket"| node_ws_consumers
node_player_hooks -->|"connects by WebSocket"| node_ws_consumers
node_ws_consumers -->|"uses realtime services"| node_realtime
node_game_tasks -->|"updates game state"| node_realtime
node_game_tasks -->|"reads sessions"| node_quiz_models
node_async_ui -.->|"requests async play"| node_async_api
node_async_api -.->|"uses session services"| node_game_session
node_dashboard -.->|"manages quiz content"| node_quiz_models
node_library_ui -.->|"browses quizzes"| node_library_api
node_library_api -.->|"searches library"| node_library_search
node_generator_ui -.->|"requests generation"| node_generator_tasks
node_generator_tasks -->|"updates jobs and documents"| node_generator_models
node_generator_tasks -->|"runs asynchronously"| node_celery
node_generator_tasks -->|"checks quotas"| node_quotas
node_generator_tasks -.->|"creates quiz"| node_quiz_models
node_account_api -.->|"checks account limits"| node_quotas
node_school_ui -.->|"manages school"| node_school_api
node_game_session -->|"reads and writes"| node_quiz_models
node_game_session -->|"stores session state"| node_redis
node_realtime -->|"uses state store"| node_redis
node_quiz_models -->|"persists records"| node_database
node_school_api -.->|"persists school data"| node_database
node_library_api -.->|"reads library data"| node_database

click node_client_app "https://github.com/jasperxxl/y-kopie/blob/main/client/src/App.tsx"
click node_dashboard "https://github.com/jasperxxl/y-kopie/blob/main/client/src/dashboard/background.tsx"
click node_host_ui "https://github.com/jasperxxl/y-kopie/blob/main/client/src/host/HostLivePlay.tsx"
click node_player_ui "https://github.com/jasperxxl/y-kopie/blob/main/client/src/host/PlayerLivePlay.tsx"
click node_async_ui "https://github.com/jasperxxl/y-kopie/blob/main/client/src/modules/async/hooks/useAsyncQuiz.tsx"
click node_library_ui "https://github.com/jasperxxl/y-kopie/blob/main/client/src/library/Library.tsx"
click node_generator_ui "https://github.com/jasperxxl/y-kopie/blob/main/client/src/library/GeneratorDocumentPage.tsx"
click node_school_ui "https://github.com/jasperxxl/y-kopie/blob/main/client/src/school/SchoolDashboard.tsx"
click node_host_hooks "https://github.com/jasperxxl/y-kopie/blob/main/client/src/modules/host/hooks/useHostWebSocket.tsx"
click node_player_hooks "https://github.com/jasperxxl/y-kopie/blob/main/client/src/modules/player/hooks/useJoinSession.tsx"
click node_game_registry "https://github.com/jasperxxl/y-kopie/blob/main/client/src/modules/games/gameRegistry.ts"
click node_game_session "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/gameplay/services/sessions.py"
click node_realtime "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/gameplay/services/realtime.py"
click node_ws_consumers "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/gameplay/consumers.py"
click node_async_api "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/gameplay/async_api.py"
click node_game_tasks "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/gameplay/tasks.py"
click node_quiz_models "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/models.py"
click node_library_api "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/library/api.py"
click node_library_search "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/library/services/search.py"
click node_generator_tasks "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/quiz_generator/tasks.py"
click node_generator_models "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/quiz_generator/models.py"
click node_account_api "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/accounts/api.py"
click node_quotas "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/accounts/services/quotas.py"
click node_school_api "https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/schools/api.py"

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_app,node_dashboard,node_host_ui,node_player_ui,node_async_ui,node_library_ui,node_generator_ui,node_school_ui,node_host_hooks,node_player_hooks toneBlue
class node_game_registry,node_game_session,node_realtime,node_ws_consumers,node_async_api,node_game_tasks toneAmber
class node_quiz_models,node_library_api,node_library_search,node_generator_tasks,node_generator_models toneMint
class node_account_api,node_quotas,node_school_api toneRose
class node_database,node_redis,node_celery,node_teacher,node_player toneIndigo
```

## Components

### React client

- [App routes](https://github.com/jasperxxl/y-kopie/blob/main/client/src/App.tsx): `client/src/App.tsx`
- [Quiz dashboard](https://github.com/jasperxxl/y-kopie/blob/main/client/src/dashboard/background.tsx): `client/src/dashboard/background.tsx`
- [Live host UI](https://github.com/jasperxxl/y-kopie/blob/main/client/src/host/HostLivePlay.tsx): `client/src/host/HostLivePlay.tsx`
- [Live player UI](https://github.com/jasperxxl/y-kopie/blob/main/client/src/host/PlayerLivePlay.tsx): `client/src/host/PlayerLivePlay.tsx`
- [Self-paced play](https://github.com/jasperxxl/y-kopie/blob/main/client/src/modules/async/hooks/useAsyncQuiz.tsx): `client/src/modules/async/hooks/useAsyncQuiz.tsx`
- [Quiz library](https://github.com/jasperxxl/y-kopie/blob/main/client/src/library/Library.tsx): `client/src/library/Library.tsx`
- [PDF quiz workflow](https://github.com/jasperxxl/y-kopie/blob/main/client/src/library/GeneratorDocumentPage.tsx): `client/src/library/GeneratorDocumentPage.tsx`
- [School management](https://github.com/jasperxxl/y-kopie/blob/main/client/src/school/SchoolDashboard.tsx): `client/src/school/SchoolDashboard.tsx`
- [Host session hooks](https://github.com/jasperxxl/y-kopie/blob/main/client/src/modules/host/hooks/useHostWebSocket.tsx): `client/src/modules/host/hooks/useHostWebSocket.tsx`
- [Player session hooks](https://github.com/jasperxxl/y-kopie/blob/main/client/src/modules/player/hooks/useJoinSession.tsx): `client/src/modules/player/hooks/useJoinSession.tsx`

### Quiz gameplay

- [Game registry](https://github.com/jasperxxl/y-kopie/blob/main/client/src/modules/games/gameRegistry.ts): `client/src/modules/games/gameRegistry.ts`
- [Session and answer services](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/gameplay/services/sessions.py): `server/quiz/gameplay/services/sessions.py`
- [Realtime services](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/gameplay/services/realtime.py): `server/quiz/gameplay/services/realtime.py`
- [WebSocket consumers](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/gameplay/consumers.py): `server/quiz/gameplay/consumers.py`
- [Async quiz API](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/gameplay/async_api.py): `server/quiz/gameplay/async_api.py`
- [Gameplay tasks](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/gameplay/tasks.py): `server/quiz/gameplay/tasks.py`

### Quiz content

- [Quiz and session data](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/models.py): `server/quiz/models.py`
- [Library API](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/library/api.py): `server/quiz/library/api.py`
- [Library search](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/library/services/search.py): `server/quiz/library/services/search.py`
- [Document generation tasks](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/quiz_generator/tasks.py): `server/quiz/quiz_generator/tasks.py`
- [Generation records](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/quiz_generator/models.py): `server/quiz/quiz_generator/models.py`

### Accounts and schools

- [Account API](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/accounts/api.py): `server/quiz/accounts/api.py`
- [Account quotas](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/accounts/services/quotas.py): `server/quiz/accounts/services/quotas.py`
- [School API](https://github.com/jasperxxl/y-kopie/blob/main/server/quiz/schools/api.py): `server/quiz/schools/api.py`

### Backend runtime

- **PostgreSQL**
- **Redis / Valkey**
- **Celery worker**

### Other components

- **Teacher**
- **Player**

## Connections

- Teacher → App routes: uses (evidence: `README.md`)
- Player → App routes: uses (evidence: `README.md`)
- App routes → Quiz dashboard: routes to (evidence: `client/src/App.tsx`)
- App routes → Quiz library: routes to (evidence: `client/src/App.tsx`)
- App routes → PDF quiz workflow: routes to (evidence: `client/src/App.tsx`)
- Teacher → Quiz dashboard: creates quizzes
- Teacher → Live host UI: hosts games (evidence: `README.md`)
- Player → Live player UI: joins games (evidence: `README.md`)
- Live host UI → Host session hooks: uses (evidence: `client/src/host/HostLivePlay.tsx`)
- Live player UI → Player session hooks: uses
- Host session hooks → WebSocket consumers: connects by WebSocket (evidence: `README.md`)
- Player session hooks → WebSocket consumers: connects by WebSocket (evidence: `README.md`)
- WebSocket consumers → Realtime services: uses realtime services
- Gameplay tasks → Realtime services: updates game state (evidence: `server/quiz/gameplay/tasks.py`)
- Gameplay tasks → Quiz and session data: reads sessions (evidence: `server/quiz/gameplay/tasks.py`)
- Self-paced play → Async quiz API: requests async play
- Async quiz API → Session and answer services: uses session services
- Quiz dashboard → Quiz and session data: manages quiz content
- Quiz library → Library API: browses quizzes
- Library API → Library search: searches library
- PDF quiz workflow → Document generation tasks: requests generation
- Document generation tasks → Generation records: updates jobs and documents (evidence: `server/quiz/quiz_generator/tasks.py`)
- Document generation tasks → Celery worker: runs asynchronously (evidence: `server/quiz/quiz_generator/tasks.py`)
- Document generation tasks → Account quotas: checks quotas (evidence: `server/quiz/quiz_generator/tasks.py`)
- Document generation tasks → Quiz and session data: creates quiz
- Account API → Account quotas: checks account limits
- School management → School API: manages school
- Session and answer services → Quiz and session data: reads and writes (evidence: `server/quiz/gameplay/services/sessions.py`)
- Session and answer services → Redis / Valkey: stores session state (evidence: `server/quiz/gameplay/services/sessions.py`)
- Realtime services → Redis / Valkey: uses state store (evidence: `server/quiz/gameplay/services/realtime.py`)
- Quiz and session data → PostgreSQL: persists records (evidence: `README.md`)
- School API → PostgreSQL: persists school data
- Library API → PostgreSQL: reads library data
