# gyrese/lthhoot architecture

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

- Interactive diagram: https://gitdiagram.com/gyrese/lthhoot
- Repository: https://github.com/gyrese/lthhoot

## Overview

LTNHoot is a self-hosted, Kahoot-inspired quiz platform. A manager authenticates, selects or edits a quiz, launches a room, and shares its join code; players join, answer live rounds, and see rankings and a podium. The repository separates the web client, Socket.IO handlers and game services, with shared quiz/game types. Major documented capabilities include solo play, AI quiz generation, media search and uploads, folders, guest accounts, remote control, and multilingual UI. Some subsystem links are inferred from names and README descriptions because their implementation was not sampled.

Main entry points: [`packages/web/src/features/game/contexts/socket-context.tsx`](https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/game/contexts/socket-context.tsx) (Socket context), [`packages/socket/src/index.ts`](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/index.ts) (Socket server), [`packages/web/src/features/manager/components/ManagerDashboard/index.tsx`](https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/manager/components/ManagerDashboard/index.tsx) (Manager dashboard), [`packages/socket/src/services/game/round-manager.ts`](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/game/round-manager.ts) (Round manager)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web experience"]
  node_manager["Manager dashboard<br/>[index.tsx]"]
  node_solo["Solo quiz<br/>[$quizzId.tsx]"]
  node_live["Live game screens<br/>[GameWrapper.tsx]"]
  node_remote["Remote control<br/>[RemoteControl.tsx]"]
  node_client_socket["Socket context<br/>[socket-context.tsx]"]
  node_manager_store["Manager state<br/>[manager.tsx]"]
end

subgraph group_authoring["Quiz authoring"]
  node_editor["Quiz editor"]
  node_ai["AI generator<br/>[index.tsx]"]
end

subgraph group_realtime["Realtime backend"]
  node_socket_entry["Socket server<br/>[index.ts]"]
  node_manager_handler["Manager handlers<br/>[manager.ts]"]
  node_game_handler["Game handlers<br/>[game.ts]"]
  node_quiz_handler["Quiz handlers<br/>[quizz.ts]"]
  node_results_handler["Results handlers<br/>[results.ts]"]
  node_game_service["Game coordinator<br/>[index.ts]"]
  node_player_manager["Player manager<br/>[player-manager.ts]"]
  node_round_manager["Round manager<br/>[round-manager.ts]"]
  node_powerups["Power-up manager<br/>[powerup-manager.ts]"]
  node_config[("Quiz and config<br/>[config.ts]")]
  node_persistence["Game persistence<br/>[persistence.ts]"]
end

subgraph group_shared["Shared domain"]
  node_common_types["Shared game types<br/>[index.ts]"]
end

subgraph group_integrations["External services"]
  node_ai_service["AI service<br/>[ai.ts]"]
  node_image_search["Image search<br/>[unsplash.ts]"]
end

node_manager_actor(("Quiz host"))
node_player_actor(("Player"))
node_ai_provider(("AI provider"))
node_image_provider(("Image provider"))

node_manager_actor -->|"manages quizzes"| node_manager
node_manager -->|"sends commands"| node_client_socket
node_client_socket -->|"Socket.IO events"| node_socket_entry
node_socket_entry -->|"dispatches"| node_manager_handler
node_manager_handler -->|"authenticates and reads"| node_config
node_manager_handler -->|"returns config"| node_manager_store
node_manager -->|"opens editor"| node_editor
node_editor -->|"quiz operations"| node_client_socket
node_socket_entry -->|"dispatches"| node_quiz_handler
node_quiz_handler -->|"reads and writes quizzes"| node_config
node_ai -.->|"requests generation"| node_client_socket
node_socket_entry -.->|"dispatches AI requests"| node_ai_service
node_ai_service -.->|"generates content"| node_ai_provider
node_editor -.->|"searches media"| node_image_search
node_image_search -.->|"searches images"| node_image_provider
node_manager_actor -->|"launches game"| node_live
node_player_actor -->|"joins and answers"| node_live
node_live -->|"sends game events"| node_client_socket
node_remote -->|"sends control events"| node_client_socket
node_socket_entry -->|"dispatches"| node_game_handler
node_game_handler -->|"routes game actions"| node_game_service
node_game_service -->|"manages players"| node_player_manager
node_game_service -->|"coordinates rounds"| node_round_manager
node_round_manager -->|"applies power-ups"| node_powerups
node_round_manager -->|"uses game contracts"| node_common_types
node_player_manager -->|"uses player contracts"| node_common_types
node_manager -->|"requests results"| node_results_handler
node_socket_entry -->|"dispatches"| node_results_handler
node_results_handler -->|"reads results"| node_persistence
node_round_manager -->|"saves game state"| node_persistence
node_solo -->|"plays quiz"| node_client_socket

click node_manager "https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/manager/components/ManagerDashboard/index.tsx"
click node_editor "https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/quizz/components/EditorWorkspace.tsx"
click node_ai "https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/quizz/components/AIGeneratorModal/index.tsx"
click node_solo "https://github.com/gyrese/lthhoot/blob/main/packages/web/src/pages/solo/%24quizzId.tsx"
click node_live "https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/game/components/GameWrapper.tsx"
click node_remote "https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/game/components/remote/RemoteControl.tsx"
click node_client_socket "https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/game/contexts/socket-context.tsx"
click node_manager_store "https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/game/stores/manager.tsx"
click node_socket_entry "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/index.ts"
click node_manager_handler "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/handlers/manager.ts"
click node_game_handler "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/handlers/game.ts"
click node_quiz_handler "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/handlers/quizz.ts"
click node_results_handler "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/handlers/results.ts"
click node_game_service "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/game/index.ts"
click node_player_manager "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/game/player-manager.ts"
click node_round_manager "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/game/round-manager.ts"
click node_powerups "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/game/powerup-manager.ts"
click node_config "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/config.ts"
click node_persistence "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/persistence.ts"
click node_common_types "https://github.com/gyrese/lthhoot/blob/main/packages/common/src/types/game/index.ts"
click node_ai_service "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/ai.ts"
click node_image_search "https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/unsplash.ts"

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_manager,node_solo,node_live,node_remote,node_client_socket,node_manager_store toneBlue
class node_editor,node_ai toneAmber
class node_socket_entry,node_manager_handler,node_game_handler,node_quiz_handler,node_results_handler,node_game_service,node_player_manager,node_round_manager,node_powerups,node_config,node_persistence toneMint
class node_common_types toneRose
class node_ai_service,node_image_search,node_manager_actor,node_player_actor,node_ai_provider,node_image_provider toneIndigo
```

## Components

### Web experience

- [Manager dashboard](https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/manager/components/ManagerDashboard/index.tsx): `packages/web/src/features/manager/components/ManagerDashboard/index.tsx`
- [Solo quiz](https://github.com/gyrese/lthhoot/blob/main/packages/web/src/pages/solo/%24quizzId.tsx): `packages/web/src/pages/solo/$quizzId.tsx`
- [Live game screens](https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/game/components/GameWrapper.tsx): `packages/web/src/features/game/components/GameWrapper.tsx`
- [Remote control](https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/game/components/remote/RemoteControl.tsx): `packages/web/src/features/game/components/remote/RemoteControl.tsx`
- [Socket context](https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/game/contexts/socket-context.tsx): `packages/web/src/features/game/contexts/socket-context.tsx`
- [Manager state](https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/game/stores/manager.tsx): `packages/web/src/features/game/stores/manager.tsx`

### Quiz authoring

- [Quiz editor](https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/quizz/components/EditorWorkspace.tsx): `packages/web/src/features/quizz/components/EditorWorkspace.tsx`
- [AI generator](https://github.com/gyrese/lthhoot/blob/main/packages/web/src/features/quizz/components/AIGeneratorModal/index.tsx): `packages/web/src/features/quizz/components/AIGeneratorModal/index.tsx`

### Realtime backend

- [Socket server](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/index.ts): `packages/socket/src/index.ts`
- [Manager handlers](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/handlers/manager.ts): `packages/socket/src/handlers/manager.ts`
- [Game handlers](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/handlers/game.ts): `packages/socket/src/handlers/game.ts`
- [Quiz handlers](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/handlers/quizz.ts): `packages/socket/src/handlers/quizz.ts`
- [Results handlers](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/handlers/results.ts): `packages/socket/src/handlers/results.ts`
- [Game coordinator](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/game/index.ts): `packages/socket/src/services/game/index.ts`
- [Player manager](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/game/player-manager.ts): `packages/socket/src/services/game/player-manager.ts`
- [Round manager](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/game/round-manager.ts): `packages/socket/src/services/game/round-manager.ts`
- [Power-up manager](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/game/powerup-manager.ts): `packages/socket/src/services/game/powerup-manager.ts`
- [Quiz and config](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/config.ts): `packages/socket/src/services/config.ts`
- [Game persistence](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/persistence.ts): `packages/socket/src/services/persistence.ts`

### Shared domain

- [Shared game types](https://github.com/gyrese/lthhoot/blob/main/packages/common/src/types/game/index.ts): `packages/common/src/types/game/index.ts`

### External services

- [AI service](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/ai.ts): `packages/socket/src/services/ai.ts`
- [Image search](https://github.com/gyrese/lthhoot/blob/main/packages/socket/src/services/unsplash.ts): `packages/socket/src/services/unsplash.ts`

### Other components

- **Quiz host**
- **Player**
- **AI provider**
- **Image provider**

## Connections

- Quiz host → Manager dashboard: manages quizzes
- Manager dashboard → Socket context: sends commands
- Socket context → Socket server: Socket.IO events
- Socket server → Manager handlers: dispatches
- Manager handlers → Quiz and config: authenticates and reads
- Manager handlers → Manager state: returns config
- Manager dashboard → Quiz editor: opens editor
- Quiz editor → Socket context: quiz operations
- Socket server → Quiz handlers: dispatches
- Quiz handlers → Quiz and config: reads and writes quizzes
- AI generator → Socket context: requests generation
- Socket server → AI service: dispatches AI requests
- AI service → AI provider: generates content
- Quiz editor → Image search: searches media
- Image search → Image provider: searches images
- Quiz host → Live game screens: launches game
- Player → Live game screens: joins and answers
- Live game screens → Socket context: sends game events
- Remote control → Socket context: sends control events
- Socket server → Game handlers: dispatches
- Game handlers → Game coordinator: routes game actions
- Game coordinator → Player manager: manages players
- Game coordinator → Round manager: coordinates rounds
- Round manager → Power-up manager: applies power-ups
- Round manager → Shared game types: uses game contracts
- Player manager → Shared game types: uses player contracts
- Manager dashboard → Results handlers: requests results
- Socket server → Results handlers: dispatches
- Results handlers → Game persistence: reads results
- Round manager → Game persistence: saves game state
- Solo quiz → Socket context: plays quiz
