# leozh0u/blundernet architecture

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

- Interactive diagram: https://gitdiagram.com/leozh0u/blundernet
- Repository: https://github.com/leozh0u/blundernet

## Overview

BlunderNet is a chess-training web application centered on searchable, rated puzzle practice, with game play, classrooms, and post-game review as major companion workflows. The browser talks to a Go HTTP/WebSocket API; queued work moves engine replies and reviews off request paths. Redis holds live game state and cross-process messages, while PostgreSQL backs durable records and puzzle data. The README documents capabilities whose detailed handlers were not sampled, so those branches use tree-supported paths and omit uncertain internal wiring.

Main entry points: [`internal/httpapi/server.go`](https://github.com/leozh0u/blundernet/blob/main/internal/httpapi/server.go) (HTTP and WebSocket API), [`internal/worker/worker.go`](https://github.com/leozh0u/blundernet/blob/main/internal/worker/worker.go) (Background worker), [`web/src/App.jsx`](https://github.com/leozh0u/blundernet/blob/main/web/src/App.jsx) (Web application), [`internal/store/puzzles.go`](https://github.com/leozh0u/blundernet/blob/main/internal/store/puzzles.go) (Puzzle corpus)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Web experience"]
  node_webapp["Web application<br/>[App.jsx]"]
  node_puzzleui["Puzzle practice<br/>[Puzzles.jsx]"]
  node_rankedui["Ranked puzzles<br/>[Ranked.jsx]"]
  node_classui["Classroom UI<br/>[Classrooms.jsx]"]
  node_analysisui["Game analysis<br/>[Analyse.jsx]"]
  node_accountui["Account<br/>[Account.jsx]"]
end

subgraph group_api["API workflows"]
  node_api["HTTP and WebSocket API<br/>[server.go]"]
  node_puzzleapi["Puzzle endpoints<br/>[puzzles.go]"]
  node_classapi["Classroom endpoints<br/>[classrooms.go]"]
  node_importapi["Game import endpoints<br/>[imports.go]"]
end

subgraph group_domain["Chess domains"]
  node_game["Game rules and state<br/>[game.go]"]
  node_puzzledomain["Puzzle selection and explanation<br/>[derive.go]"]
  node_reviewdomain["Move-by-move review<br/>[review.go]"]
  node_rating["Player and puzzle ratings<br/>[glicko2.go]"]
  node_importer["Puzzle data loader<br/>[main.go]"]
end

subgraph group_async["Queued processing"]
  node_queue["Job queue<br/>[queue.go]"]
  node_worker["Background worker<br/>[worker.go]"]
  node_engine["Bot and analysis engines<br/>[engine.go]"]
end

subgraph group_state["Persistence"]
  node_redis[("Redis live state<br/>[redis.go]")]
  node_postgres[("PostgreSQL archive<br/>[postgres.go]")]
  node_puzzlestore[("Puzzle corpus<br/>[puzzles.go]")]
  node_classstore[("Classroom records<br/>[classrooms.go]")]
end

node_player(("Player or coach"))
node_lichess(("Lichess puzzle dump"))

node_player -->|"uses"| node_webapp
node_webapp -->|"opens"| node_puzzleui
node_webapp -->|"opens"| node_rankedui
node_webapp -->|"opens"| node_classui
node_webapp -->|"opens"| node_analysisui
node_webapp -->|"opens"| node_accountui
node_puzzleui -->|"requests puzzles"| node_api
node_rankedui -->|"requests ranked play"| node_api
node_classui -->|"sends room actions"| node_api
node_analysisui -->|"requests review"| node_api
node_accountui -->|"sends account actions"| node_api
node_api -->|"dispatches"| node_puzzleapi
node_api -->|"dispatches"| node_classapi
node_api -->|"dispatches"| node_importapi
node_api -->|"updates games"| node_game
node_api -->|"selects puzzles"| node_puzzledomain
node_api -->|"enqueues work"| node_queue
node_api -->|"reads and writes"| node_redis
node_api -->|"reads and writes"| node_postgres
node_puzzleapi -->|"queries corpus"| node_puzzlestore
node_classapi -->|"stores classroom data"| node_classstore
node_importapi -->|"enqueues review"| node_queue
node_worker -->|"receives jobs"| node_queue
node_worker -->|"loads and publishes games"| node_redis
node_worker -->|"applies moves"| node_game
node_worker -->|"requests moves"| node_engine
node_worker -->|"judges games"| node_reviewdomain
node_worker -->|"saves reviews"| node_postgres
node_worker -.->|"updates ratings"| node_rating
node_lichess -.->|"provides puzzles"| node_importer
node_importer -->|"loads corpus"| node_puzzlestore
node_puzzlestore -->|"stored in"| node_postgres

click node_webapp "https://github.com/leozh0u/blundernet/blob/main/web/src/App.jsx"
click node_puzzleui "https://github.com/leozh0u/blundernet/blob/main/web/src/features/puzzles/Puzzles.jsx"
click node_rankedui "https://github.com/leozh0u/blundernet/blob/main/web/src/features/puzzles/Ranked.jsx"
click node_classui "https://github.com/leozh0u/blundernet/blob/main/web/src/features/classrooms/Classrooms.jsx"
click node_analysisui "https://github.com/leozh0u/blundernet/blob/main/web/src/features/analysis/Analyse.jsx"
click node_accountui "https://github.com/leozh0u/blundernet/blob/main/web/src/features/account/Account.jsx"
click node_api "https://github.com/leozh0u/blundernet/blob/main/internal/httpapi/server.go"
click node_puzzleapi "https://github.com/leozh0u/blundernet/blob/main/internal/httpapi/puzzles.go"
click node_classapi "https://github.com/leozh0u/blundernet/blob/main/internal/httpapi/classrooms.go"
click node_importapi "https://github.com/leozh0u/blundernet/blob/main/internal/httpapi/imports.go"
click node_game "https://github.com/leozh0u/blundernet/blob/main/internal/game/game.go"
click node_puzzledomain "https://github.com/leozh0u/blundernet/blob/main/internal/puzzle/derive.go"
click node_reviewdomain "https://github.com/leozh0u/blundernet/blob/main/internal/review/review.go"
click node_rating "https://github.com/leozh0u/blundernet/blob/main/internal/rating/glicko2.go"
click node_queue "https://github.com/leozh0u/blundernet/blob/main/internal/queue/queue.go"
click node_worker "https://github.com/leozh0u/blundernet/blob/main/internal/worker/worker.go"
click node_engine "https://github.com/leozh0u/blundernet/blob/main/internal/engine/engine.go"
click node_redis "https://github.com/leozh0u/blundernet/blob/main/internal/store/redis.go"
click node_postgres "https://github.com/leozh0u/blundernet/blob/main/internal/store/postgres.go"
click node_puzzlestore "https://github.com/leozh0u/blundernet/blob/main/internal/store/puzzles.go"
click node_classstore "https://github.com/leozh0u/blundernet/blob/main/internal/store/classrooms.go"
click node_importer "https://github.com/leozh0u/blundernet/blob/main/cmd/puzzleload/main.go"

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_webapp,node_puzzleui,node_rankedui,node_classui,node_analysisui,node_accountui toneBlue
class node_api,node_puzzleapi,node_classapi,node_importapi toneAmber
class node_game,node_puzzledomain,node_reviewdomain,node_rating,node_importer toneMint
class node_queue,node_worker,node_engine toneRose
class node_redis,node_postgres,node_puzzlestore,node_classstore,node_player,node_lichess toneIndigo
```

## Components

### Web experience

- [Web application](https://github.com/leozh0u/blundernet/blob/main/web/src/App.jsx): `web/src/App.jsx`
- [Puzzle practice](https://github.com/leozh0u/blundernet/blob/main/web/src/features/puzzles/Puzzles.jsx): `web/src/features/puzzles/Puzzles.jsx`
- [Ranked puzzles](https://github.com/leozh0u/blundernet/blob/main/web/src/features/puzzles/Ranked.jsx): `web/src/features/puzzles/Ranked.jsx`
- [Classroom UI](https://github.com/leozh0u/blundernet/blob/main/web/src/features/classrooms/Classrooms.jsx): `web/src/features/classrooms/Classrooms.jsx`
- [Game analysis](https://github.com/leozh0u/blundernet/blob/main/web/src/features/analysis/Analyse.jsx): `web/src/features/analysis/Analyse.jsx`
- [Account](https://github.com/leozh0u/blundernet/blob/main/web/src/features/account/Account.jsx): `web/src/features/account/Account.jsx`

### API workflows

- [HTTP and WebSocket API](https://github.com/leozh0u/blundernet/blob/main/internal/httpapi/server.go): `internal/httpapi/server.go`
- [Puzzle endpoints](https://github.com/leozh0u/blundernet/blob/main/internal/httpapi/puzzles.go): `internal/httpapi/puzzles.go`
- [Classroom endpoints](https://github.com/leozh0u/blundernet/blob/main/internal/httpapi/classrooms.go): `internal/httpapi/classrooms.go`
- [Game import endpoints](https://github.com/leozh0u/blundernet/blob/main/internal/httpapi/imports.go): `internal/httpapi/imports.go`

### Chess domains

- [Game rules and state](https://github.com/leozh0u/blundernet/blob/main/internal/game/game.go): `internal/game/game.go`
- [Puzzle selection and explanation](https://github.com/leozh0u/blundernet/blob/main/internal/puzzle/derive.go): `internal/puzzle/derive.go`
- [Move-by-move review](https://github.com/leozh0u/blundernet/blob/main/internal/review/review.go): `internal/review/review.go`
- [Player and puzzle ratings](https://github.com/leozh0u/blundernet/blob/main/internal/rating/glicko2.go): `internal/rating/glicko2.go`
- [Puzzle data loader](https://github.com/leozh0u/blundernet/blob/main/cmd/puzzleload/main.go): `cmd/puzzleload/main.go`

### Queued processing

- [Job queue](https://github.com/leozh0u/blundernet/blob/main/internal/queue/queue.go): `internal/queue/queue.go`
- [Background worker](https://github.com/leozh0u/blundernet/blob/main/internal/worker/worker.go): `internal/worker/worker.go`
- [Bot and analysis engines](https://github.com/leozh0u/blundernet/blob/main/internal/engine/engine.go): `internal/engine/engine.go`

### Persistence

- [Redis live state](https://github.com/leozh0u/blundernet/blob/main/internal/store/redis.go): `internal/store/redis.go`
- [PostgreSQL archive](https://github.com/leozh0u/blundernet/blob/main/internal/store/postgres.go): `internal/store/postgres.go`
- [Puzzle corpus](https://github.com/leozh0u/blundernet/blob/main/internal/store/puzzles.go): `internal/store/puzzles.go`
- [Classroom records](https://github.com/leozh0u/blundernet/blob/main/internal/store/classrooms.go): `internal/store/classrooms.go`

### Other components

- **Player or coach**
- **Lichess puzzle dump**

## Connections

- Player or coach → Web application: uses
- Web application → Puzzle practice: opens
- Web application → Ranked puzzles: opens
- Web application → Classroom UI: opens
- Web application → Game analysis: opens
- Web application → Account: opens
- Puzzle practice → HTTP and WebSocket API: requests puzzles
- Ranked puzzles → HTTP and WebSocket API: requests ranked play
- Classroom UI → HTTP and WebSocket API: sends room actions
- Game analysis → HTTP and WebSocket API: requests review
- Account → HTTP and WebSocket API: sends account actions
- HTTP and WebSocket API → Puzzle endpoints: dispatches
- HTTP and WebSocket API → Classroom endpoints: dispatches
- HTTP and WebSocket API → Game import endpoints: dispatches
- HTTP and WebSocket API → Game rules and state: updates games
- HTTP and WebSocket API → Puzzle selection and explanation: selects puzzles
- HTTP and WebSocket API → Job queue: enqueues work
- HTTP and WebSocket API → Redis live state: reads and writes
- HTTP and WebSocket API → PostgreSQL archive: reads and writes
- Puzzle endpoints → Puzzle corpus: queries corpus
- Classroom endpoints → Classroom records: stores classroom data
- Game import endpoints → Job queue: enqueues review
- Background worker → Job queue: receives jobs
- Background worker → Redis live state: loads and publishes games
- Background worker → Game rules and state: applies moves
- Background worker → Bot and analysis engines: requests moves
- Background worker → Move-by-move review: judges games
- Background worker → PostgreSQL archive: saves reviews
- Background worker → Player and puzzle ratings: updates ratings
- Lichess puzzle dump → Puzzle data loader: provides puzzles
- Puzzle data loader → Puzzle corpus: loads corpus
- Puzzle corpus → PostgreSQL archive: stored in
