# vgebrev/leagr architecture

> Architecture diagram of the GitHub repository vgebrev/leagr, 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/vgebrev/leagr
- Repository: https://github.com/vgebrev/leagr

## Overview

Leagr is a multi-league web app for organizing social five-a-side football. Organisers and players use league pages to manage signups, draw teams, schedule and record matches, then view standings, rankings, awards, and recaps; Fantasy League adds a stats-scored weekly squad game. The graph follows the documented UI/API/domain split and sampled server calls. The README describes JSON-file storage and optional Mailgun/OpenAI integrations; unsampled routes and feature internals are represented only at their existing enclosing directories.

Main entry points: [`src/routes`](https://github.com/vgebrev/leagr/tree/main/src/routes) (League pages), [`src/lib/server/data.js`](https://github.com/vgebrev/leagr/blob/main/src/lib/server/data.js) (League JSON data), [`src/lib/server/playerManager.js`](https://github.com/vgebrev/leagr/blob/main/src/lib/server/playerManager.js) (Player management), [`src/lib/server/rankings.js`](https://github.com/vgebrev/leagr/blob/main/src/lib/server/rankings.js) (Rankings and ELO)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_experience["League experience"]
  node_web_ui["League pages"]
  node_shared_ui["Reusable UI"]
  node_client_services["Client services"]
end

subgraph group_api["API boundary"]
  node_api_routes["Feature API routes"]
  node_player_api["Player API<br/>[+server.js]"]
  node_team_api["Team API<br/>[+server.js]"]
  node_games_api["Games API<br/>[+server.js]"]
  node_discipline_api["Discipline API<br/>[+server.js]"]
end

subgraph group_league_ops["League operations"]
  node_player_manager["Player management<br/>[playerManager.js]"]
  node_team_generator["Team generation<br/>[teamGenerator.js]"]
  node_discipline["Discipline rules<br/>[discipline.js]"]
  node_game_scheduler["Match scheduling<br/>[gameScheduler.js]"]
  node_knockout["Knockout tournaments<br/>[knockoutManager.js]"]
end

subgraph group_insights["Competition insights"]
  node_rankings["Rankings and ELO<br/>[rankings.js]"]
  node_standings["League standings<br/>[standings.js]"]
  node_fantasy["Fantasy League<br/>[fantasyManager.js]"]
  node_news_momentum["News and momentum<br/>[newsFeed.js]"]
  node_year_recap["Year recap"]
end

subgraph group_infrastructure["State and integrations"]
  node_json_data[("League JSON data<br/>[data.js]")]
  node_league_access["League access<br/>[league.js]"]
  node_email["Recovery email<br/>[email.js]"]
  node_openai_images["OpenAI image service"]
end

node_organiser(("Organiser or player"))

node_organiser -->|"uses"| node_web_ui
node_web_ui -->|"renders"| node_shared_ui
node_web_ui -->|"requests data"| node_client_services
node_client_services -->|"calls"| node_api_routes
node_api_routes -->|"validates league"| node_league_access
node_player_api -->|"manages players"| node_player_manager
node_player_api -->|"evaluates signup"| node_discipline
node_team_api -->|"loads players"| node_player_manager
node_team_api -->|"generates teams"| node_team_generator
node_team_api -.->|"requests logos"| node_openai_images
node_games_api -->|"builds schedule"| node_game_scheduler
node_discipline_api -->|"reads records"| node_discipline
node_player_manager -->|"loads state"| node_json_data
node_player_manager -->|"loads rankings"| node_rankings
node_discipline -->|"reads and writes"| node_json_data
node_game_scheduler -->|"reads and writes"| node_json_data
node_rankings -->|"loads history"| node_json_data
node_standings -->|"reads results"| node_json_data
node_fantasy -->|"reads session data"| node_json_data
node_news_momentum -->|"loads standings"| node_standings
node_news_momentum -->|"loads rankings"| node_rankings
node_year_recap -->|"loads season data"| node_json_data
node_league_access -.->|"sends recovery"| node_email
node_web_ui -->|"features bracket"| node_knockout
node_web_ui -->|"features fantasy"| node_fantasy
node_web_ui -->|"shows rankings"| node_rankings
node_web_ui -->|"shows table"| node_standings
node_web_ui -->|"shows feed"| node_news_momentum
node_web_ui -->|"shows recap"| node_year_recap

click node_web_ui "https://github.com/vgebrev/leagr/tree/main/src/routes"
click node_shared_ui "https://github.com/vgebrev/leagr/tree/main/src/components"
click node_client_services "https://github.com/vgebrev/leagr/tree/main/src/lib/client/services"
click node_api_routes "https://github.com/vgebrev/leagr/tree/main/src/routes/api"
click node_player_api "https://github.com/vgebrev/leagr/blob/main/src/routes/api/players/%2Bserver.js"
click node_team_api "https://github.com/vgebrev/leagr/blob/main/src/routes/api/teams/%2Bserver.js"
click node_games_api "https://github.com/vgebrev/leagr/blob/main/src/routes/api/games/%2Bserver.js"
click node_discipline_api "https://github.com/vgebrev/leagr/blob/main/src/routes/api/discipline/%2Bserver.js"
click node_player_manager "https://github.com/vgebrev/leagr/blob/main/src/lib/server/playerManager.js"
click node_team_generator "https://github.com/vgebrev/leagr/blob/main/src/lib/server/teamGenerator.js"
click node_discipline "https://github.com/vgebrev/leagr/blob/main/src/lib/server/discipline.js"
click node_game_scheduler "https://github.com/vgebrev/leagr/blob/main/src/lib/server/gameScheduler.js"
click node_knockout "https://github.com/vgebrev/leagr/blob/main/src/lib/server/knockoutManager.js"
click node_rankings "https://github.com/vgebrev/leagr/blob/main/src/lib/server/rankings.js"
click node_standings "https://github.com/vgebrev/leagr/blob/main/src/lib/server/standings.js"
click node_fantasy "https://github.com/vgebrev/leagr/blob/main/src/lib/server/fantasyManager.js"
click node_news_momentum "https://github.com/vgebrev/leagr/blob/main/src/lib/server/newsFeed.js"
click node_year_recap "https://github.com/vgebrev/leagr/blob/main/src/lib/server/yearRecapManager.js"
click node_json_data "https://github.com/vgebrev/leagr/blob/main/src/lib/server/data.js"
click node_league_access "https://github.com/vgebrev/leagr/blob/main/src/lib/server/league.js"
click node_email "https://github.com/vgebrev/leagr/blob/main/src/lib/server/email.js"
click node_openai_images "https://github.com/vgebrev/leagr/blob/main/src/lib/server/openaiImageClient.js"

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_web_ui,node_shared_ui,node_client_services toneBlue
class node_api_routes,node_player_api,node_team_api,node_games_api,node_discipline_api toneAmber
class node_player_manager,node_team_generator,node_discipline,node_game_scheduler,node_knockout toneMint
class node_rankings,node_standings,node_fantasy,node_news_momentum,node_year_recap toneRose
class node_json_data,node_league_access,node_email,node_openai_images,node_organiser toneIndigo
```

## Components

### League experience

- [League pages](https://github.com/vgebrev/leagr/tree/main/src/routes): `src/routes`
- [Reusable UI](https://github.com/vgebrev/leagr/tree/main/src/components): `src/components`
- [Client services](https://github.com/vgebrev/leagr/tree/main/src/lib/client/services): `src/lib/client/services`

### API boundary

- [Feature API routes](https://github.com/vgebrev/leagr/tree/main/src/routes/api): `src/routes/api`
- [Player API](https://github.com/vgebrev/leagr/blob/main/src/routes/api/players/%2Bserver.js): `src/routes/api/players/+server.js`
- [Team API](https://github.com/vgebrev/leagr/blob/main/src/routes/api/teams/%2Bserver.js): `src/routes/api/teams/+server.js`
- [Games API](https://github.com/vgebrev/leagr/blob/main/src/routes/api/games/%2Bserver.js): `src/routes/api/games/+server.js`
- [Discipline API](https://github.com/vgebrev/leagr/blob/main/src/routes/api/discipline/%2Bserver.js): `src/routes/api/discipline/+server.js`

### League operations

- [Player management](https://github.com/vgebrev/leagr/blob/main/src/lib/server/playerManager.js): `src/lib/server/playerManager.js`
- [Team generation](https://github.com/vgebrev/leagr/blob/main/src/lib/server/teamGenerator.js): `src/lib/server/teamGenerator.js`
- [Discipline rules](https://github.com/vgebrev/leagr/blob/main/src/lib/server/discipline.js): `src/lib/server/discipline.js`
- [Match scheduling](https://github.com/vgebrev/leagr/blob/main/src/lib/server/gameScheduler.js): `src/lib/server/gameScheduler.js`
- [Knockout tournaments](https://github.com/vgebrev/leagr/blob/main/src/lib/server/knockoutManager.js): `src/lib/server/knockoutManager.js`

### Competition insights

- [Rankings and ELO](https://github.com/vgebrev/leagr/blob/main/src/lib/server/rankings.js): `src/lib/server/rankings.js`
- [League standings](https://github.com/vgebrev/leagr/blob/main/src/lib/server/standings.js): `src/lib/server/standings.js`
- [Fantasy League](https://github.com/vgebrev/leagr/blob/main/src/lib/server/fantasyManager.js): `src/lib/server/fantasyManager.js`
- [News and momentum](https://github.com/vgebrev/leagr/blob/main/src/lib/server/newsFeed.js): `src/lib/server/newsFeed.js`
- [Year recap](https://github.com/vgebrev/leagr/blob/main/src/lib/server/yearRecapManager.js): `src/lib/server/yearRecapManager.js`

### State and integrations

- [League JSON data](https://github.com/vgebrev/leagr/blob/main/src/lib/server/data.js): `src/lib/server/data.js`
- [League access](https://github.com/vgebrev/leagr/blob/main/src/lib/server/league.js): `src/lib/server/league.js`
- [Recovery email](https://github.com/vgebrev/leagr/blob/main/src/lib/server/email.js): `src/lib/server/email.js`
- [OpenAI image service](https://github.com/vgebrev/leagr/blob/main/src/lib/server/openaiImageClient.js): `src/lib/server/openaiImageClient.js`

### Other components

- **Organiser or player**

## Connections

- Organiser or player → League pages: uses
- League pages → Reusable UI: renders
- League pages → Client services: requests data
- Client services → Feature API routes: calls
- Feature API routes → League access: validates league
- Player API → Player management: manages players
- Player API → Discipline rules: evaluates signup
- Team API → Player management: loads players
- Team API → Team generation: generates teams
- Team API → OpenAI image service: requests logos
- Games API → Match scheduling: builds schedule
- Discipline API → Discipline rules: reads records
- Player management → League JSON data: loads state
- Player management → Rankings and ELO: loads rankings
- Discipline rules → League JSON data: reads and writes
- Match scheduling → League JSON data: reads and writes
- Rankings and ELO → League JSON data: loads history
- League standings → League JSON data: reads results
- Fantasy League → League JSON data: reads session data
- News and momentum → League standings: loads standings
- News and momentum → Rankings and ELO: loads rankings
- Year recap → League JSON data: loads season data
- League access → Recovery email: sends recovery
- League pages → Knockout tournaments: features bracket
- League pages → Fantasy League: features fantasy
- League pages → Rankings and ELO: shows rankings
- League pages → League standings: shows table
- League pages → News and momentum: shows feed
- League pages → Year recap: shows recap
