# blchen10203/chrichu architecture

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

- Interactive diagram: https://gitdiagram.com/blchen10203/chrichu
- Repository: https://github.com/blchen10203/chrichu

## Overview

Reachdle is a UFC-fighter stats guessing game with a Python data pipeline and a Next.js web app. The pipeline fetches UFCStats CSVs, parses and derives fighter metrics, then emits data consumed by the site. The app exposes Daily, Infinite, and Survival routes, but the sampled Infinite and How-to-Play pages are placeholders; the other game routes were not sampled, so their internals are not inferred. The graph preserves documented routes and pipeline stages while omitting unverified runtime wiring among engine, display, and storage modules.

Main entry points: [`pipeline/build.py`](https://github.com/blchen10203/chrichu/blob/main/pipeline/build.py) (Data builder), [`web/app/page.tsx`](https://github.com/blchen10203/chrichu/blob/main/web/app/page.tsx) (Home navigation), [`pipeline/draft_roster.py`](https://github.com/blchen10203/chrichu/blob/main/pipeline/draft_roster.py) (Roster drafting), [`pipeline/derive.py`](https://github.com/blchen10203/chrichu/blob/main/pipeline/derive.py) (Fight metrics)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_pipeline["Data pipeline"]
  node_build["Data builder<br/>[build.py]"]
  node_parse["Field parsing<br/>[parse.py]"]
  node_derive["Fight metrics<br/>[derive.py]"]
  node_metrics["Metric definitions<br/>[metrics.py]"]
  node_draft["Roster drafting<br/>[draft_roster.py]"]
  node_fighterdata["Fighter data<br/>[fighters.json]"]
  node_metricdata["Metric data<br/>[metrics.json]"]
end

subgraph group_web["Web experience"]
  node_home["Home navigation<br/>[page.tsx]"]
  node_daily["Daily mode route<br/>[page.tsx]"]
  node_infinite["Infinite mode route<br/>[page.tsx]"]
  node_survival["Survival mode route<br/>[page.tsx]"]
  node_howto["How-to-play page<br/>[page.tsx]"]
  node_faq["FAQ page<br/>[page.tsx]"]
end

subgraph group_engine["Game engine"]
  node_rounds["Round generation<br/>[rounds.ts]"]
  node_rng["Seeded randomness<br/>[rng.ts]"]
  node_scoring["Guess scoring<br/>[scoring.ts]"]
  node_scale["Metric scaling<br/>[scale.ts]"]
  node_share["Result sharing<br/>[share.ts]"]
  node_storage["Game state<br/>[index.ts]"]
end

subgraph group_presentation["Game presentation"]
  node_stages["Round displays<br/>[RoundShell.tsx]"]
  node_barstage["Bar stage<br/>[BarStage.tsx]"]
  node_silhouette["Silhouette stage"]
  node_results["Results display<br/>[Results.tsx]"]
  node_reveal["Answer reveal<br/>[Reveal.tsx]"]
  node_timer["Round timer<br/>[Timer.tsx]"]
  node_hpbar["Health bar<br/>[HpBar.tsx]"]
  node_sharebutton["Share control<br/>[ShareButton.tsx]"]
end

node_player(("Player"))
node_ufcstats["UFCStats CSV source"]
node_localstorage[("Browser storage")]

node_player -->|"opens"| node_home
node_home -->|"links to"| node_daily
node_home -->|"links to"| node_infinite
node_home -->|"links to"| node_survival
node_home -->|"links to"| node_howto
node_home -->|"links to"| node_faq
node_ufcstats -->|"provides CSVs"| node_build
node_build -->|"parses fields"| node_parse
node_build -->|"derives metrics"| node_derive
node_build -->|"summarizes metrics"| node_metrics
node_derive -->|"uses parsers"| node_parse
node_build -->|"writes"| node_fighterdata
node_build -->|"writes"| node_metricdata
node_draft -->|"loads source data"| node_build
node_draft -->|"ranks fights"| node_derive
node_draft -->|"extracts IDs"| node_parse
node_rounds -->|"uses"| node_rng
node_storage -->|"reads and writes"| node_localstorage

click node_build "https://github.com/blchen10203/chrichu/blob/main/pipeline/build.py"
click node_parse "https://github.com/blchen10203/chrichu/blob/main/pipeline/parse.py"
click node_derive "https://github.com/blchen10203/chrichu/blob/main/pipeline/derive.py"
click node_metrics "https://github.com/blchen10203/chrichu/blob/main/pipeline/metrics.py"
click node_draft "https://github.com/blchen10203/chrichu/blob/main/pipeline/draft_roster.py"
click node_fighterdata "https://github.com/blchen10203/chrichu/blob/main/web/data/fighters.json"
click node_metricdata "https://github.com/blchen10203/chrichu/blob/main/web/data/metrics.json"
click node_home "https://github.com/blchen10203/chrichu/blob/main/web/app/page.tsx"
click node_daily "https://github.com/blchen10203/chrichu/blob/main/web/app/daily/page.tsx"
click node_infinite "https://github.com/blchen10203/chrichu/blob/main/web/app/infinite/page.tsx"
click node_survival "https://github.com/blchen10203/chrichu/blob/main/web/app/survival/page.tsx"
click node_howto "https://github.com/blchen10203/chrichu/blob/main/web/app/how-to-play/page.tsx"
click node_faq "https://github.com/blchen10203/chrichu/blob/main/web/app/faq/page.tsx"
click node_rounds "https://github.com/blchen10203/chrichu/blob/main/web/lib/engine/rounds.ts"
click node_rng "https://github.com/blchen10203/chrichu/blob/main/web/lib/engine/rng.ts"
click node_scoring "https://github.com/blchen10203/chrichu/blob/main/web/lib/engine/scoring.ts"
click node_scale "https://github.com/blchen10203/chrichu/blob/main/web/lib/engine/scale.ts"
click node_share "https://github.com/blchen10203/chrichu/blob/main/web/lib/engine/share.ts"
click node_storage "https://github.com/blchen10203/chrichu/blob/main/web/lib/storage/index.ts"
click node_stages "https://github.com/blchen10203/chrichu/blob/main/web/components/RoundShell.tsx"
click node_barstage "https://github.com/blchen10203/chrichu/blob/main/web/components/BarStage.tsx"
click node_silhouette "https://github.com/blchen10203/chrichu/blob/main/web/components/SilhouetteStage.tsx"
click node_results "https://github.com/blchen10203/chrichu/blob/main/web/components/Results.tsx"
click node_reveal "https://github.com/blchen10203/chrichu/blob/main/web/components/Reveal.tsx"
click node_timer "https://github.com/blchen10203/chrichu/blob/main/web/components/Timer.tsx"
click node_hpbar "https://github.com/blchen10203/chrichu/blob/main/web/components/HpBar.tsx"
click node_sharebutton "https://github.com/blchen10203/chrichu/blob/main/web/components/ShareButton.tsx"

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_build,node_parse,node_derive,node_metrics,node_draft,node_fighterdata,node_metricdata toneBlue
class node_home,node_daily,node_infinite,node_survival,node_howto,node_faq,node_localstorage toneAmber
class node_rounds,node_rng,node_scoring,node_scale,node_share,node_storage toneMint
class node_stages,node_barstage,node_silhouette,node_results,node_reveal,node_timer,node_hpbar,node_sharebutton toneRose
class node_player,node_ufcstats toneIndigo
```

## Components

### Data pipeline

- [Data builder](https://github.com/blchen10203/chrichu/blob/main/pipeline/build.py): `pipeline/build.py`
- [Field parsing](https://github.com/blchen10203/chrichu/blob/main/pipeline/parse.py): `pipeline/parse.py`
- [Fight metrics](https://github.com/blchen10203/chrichu/blob/main/pipeline/derive.py): `pipeline/derive.py`
- [Metric definitions](https://github.com/blchen10203/chrichu/blob/main/pipeline/metrics.py): `pipeline/metrics.py`
- [Roster drafting](https://github.com/blchen10203/chrichu/blob/main/pipeline/draft_roster.py): `pipeline/draft_roster.py`
- [Fighter data](https://github.com/blchen10203/chrichu/blob/main/web/data/fighters.json): `web/data/fighters.json`
- [Metric data](https://github.com/blchen10203/chrichu/blob/main/web/data/metrics.json): `web/data/metrics.json`

### Web experience

- [Home navigation](https://github.com/blchen10203/chrichu/blob/main/web/app/page.tsx): `web/app/page.tsx`
- [Daily mode route](https://github.com/blchen10203/chrichu/blob/main/web/app/daily/page.tsx): `web/app/daily/page.tsx`
- [Infinite mode route](https://github.com/blchen10203/chrichu/blob/main/web/app/infinite/page.tsx): `web/app/infinite/page.tsx`
- [Survival mode route](https://github.com/blchen10203/chrichu/blob/main/web/app/survival/page.tsx): `web/app/survival/page.tsx`
- [How-to-play page](https://github.com/blchen10203/chrichu/blob/main/web/app/how-to-play/page.tsx): `web/app/how-to-play/page.tsx`
- [FAQ page](https://github.com/blchen10203/chrichu/blob/main/web/app/faq/page.tsx): `web/app/faq/page.tsx`

### Game engine

- [Round generation](https://github.com/blchen10203/chrichu/blob/main/web/lib/engine/rounds.ts): `web/lib/engine/rounds.ts`
- [Seeded randomness](https://github.com/blchen10203/chrichu/blob/main/web/lib/engine/rng.ts): `web/lib/engine/rng.ts`
- [Guess scoring](https://github.com/blchen10203/chrichu/blob/main/web/lib/engine/scoring.ts): `web/lib/engine/scoring.ts`
- [Metric scaling](https://github.com/blchen10203/chrichu/blob/main/web/lib/engine/scale.ts): `web/lib/engine/scale.ts`
- [Result sharing](https://github.com/blchen10203/chrichu/blob/main/web/lib/engine/share.ts): `web/lib/engine/share.ts`
- [Game state](https://github.com/blchen10203/chrichu/blob/main/web/lib/storage/index.ts): `web/lib/storage/index.ts`

### Game presentation

- [Round displays](https://github.com/blchen10203/chrichu/blob/main/web/components/RoundShell.tsx): `web/components/RoundShell.tsx`
- [Bar stage](https://github.com/blchen10203/chrichu/blob/main/web/components/BarStage.tsx): `web/components/BarStage.tsx`
- [Silhouette stage](https://github.com/blchen10203/chrichu/blob/main/web/components/SilhouetteStage.tsx): `web/components/SilhouetteStage.tsx`
- [Results display](https://github.com/blchen10203/chrichu/blob/main/web/components/Results.tsx): `web/components/Results.tsx`
- [Answer reveal](https://github.com/blchen10203/chrichu/blob/main/web/components/Reveal.tsx): `web/components/Reveal.tsx`
- [Round timer](https://github.com/blchen10203/chrichu/blob/main/web/components/Timer.tsx): `web/components/Timer.tsx`
- [Health bar](https://github.com/blchen10203/chrichu/blob/main/web/components/HpBar.tsx): `web/components/HpBar.tsx`
- [Share control](https://github.com/blchen10203/chrichu/blob/main/web/components/ShareButton.tsx): `web/components/ShareButton.tsx`

### Other components

- **Player**
- **UFCStats CSV source**
- **Browser storage**

## Connections

- Player → Home navigation: opens (evidence: `web/app/page.tsx`)
- Home navigation → Daily mode route: links to (evidence: `web/app/page.tsx`)
- Home navigation → Infinite mode route: links to (evidence: `web/app/page.tsx`)
- Home navigation → Survival mode route: links to (evidence: `web/app/page.tsx`)
- Home navigation → How-to-play page: links to (evidence: `web/app/page.tsx`)
- Home navigation → FAQ page: links to (evidence: `web/app/page.tsx`)
- UFCStats CSV source → Data builder: provides CSVs (evidence: `pipeline/build.py`)
- Data builder → Field parsing: parses fields (evidence: `pipeline/build.py`)
- Data builder → Fight metrics: derives metrics (evidence: `pipeline/build.py`)
- Data builder → Metric definitions: summarizes metrics (evidence: `pipeline/build.py`)
- Fight metrics → Field parsing: uses parsers (evidence: `pipeline/derive.py`)
- Data builder → Fighter data: writes (evidence: `pipeline/build.py`)
- Data builder → Metric data: writes (evidence: `pipeline/build.py`)
- Roster drafting → Data builder: loads source data (evidence: `pipeline/draft_roster.py`)
- Roster drafting → Fight metrics: ranks fights (evidence: `pipeline/draft_roster.py`)
- Roster drafting → Field parsing: extracts IDs (evidence: `pipeline/draft_roster.py`)
- Round generation → Seeded randomness: uses (evidence: `web/lib/engine/rounds.ts`)
- Game state → Browser storage: reads and writes (evidence: `web/lib/storage/index.ts`)
