# keiran101/mahjong-ledger architecture

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

## Overview

This is a local, browser-based Guangdong Mahjong ledger. Players create or join a room, enter a round by text or photo, review a score preview, then confirm or edit it; the room board, settlement transfers, and history are derived from the recorded events. Scoring is deterministic and separate from text and vision recognition. The README and sampled server excerpts support the main API flow; unsampled frontend and storage details are represented only where documented, so some internal links are omitted.

Main entry points: [`server.mjs`](https://github.com/keiran101/mahjong-ledger/blob/main/server.mjs) (API and static server), [`lib/vision.mjs`](https://github.com/keiran101/mahjong-ledger/blob/main/lib/vision.mjs) (Photo draft), [`lib/store.mjs`](https://github.com/keiran101/mahjong-ledger/blob/main/lib/store.mjs) (Event ledger and replay), [`lib/pattern.ts`](https://github.com/keiran101/mahjong-ledger/blob/main/lib/pattern.ts) (Hand pattern inference)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Player interface"]
  node_webapp["Room interface<br/>[app.js]"]
  node_results["Board and history<br/>[app.js]"]
end

subgraph group_http["HTTP service"]
  node_httpserver["API and static server<br/>[server.mjs]"]
  node_roomapi["Room and event API<br/>[server.mjs]"]
end

subgraph group_recognition["Round recognition"]
  node_roundparse["Text parser<br/>[parse.mjs]"]
  node_textllm["Text LLM client<br/>[llm.mjs]"]
  node_visiondraft["Photo draft<br/>[vision.mjs]"]
  node_vlmclient["Vision model client<br/>[vlm.mjs]"]
  node_patterninfer["Hand pattern inference<br/>[pattern.ts]"]
  node_tiletools["Tile utilities<br/>[tiles.ts]"]
end

subgraph group_scoring["Rules and scoring"]
  node_rules["Mahjong rules<br/>[rules.ts]"]
  node_scoreengine["Round scoring<br/>[score.ts]"]
end

subgraph group_ledger["Ledger and results"]
  node_ledgerstore[("Event ledger and replay<br/>[store.mjs]")]
  node_transfers["Minimum transfers<br/>[settle.ts]"]
end

node_player(("Player"))
node_modelservice["AI model services"]

node_player -->|"enters rounds"| node_webapp
node_webapp -->|"calls APIs"| node_httpserver
node_httpserver -->|"serves interface"| node_webapp
node_httpserver -->|"parses text"| node_roundparse
node_roundparse -->|"extracts fields"| node_textllm
node_textllm -->|"sends prompts"| node_modelservice
node_httpserver -->|"recognizes photo"| node_visiondraft
node_visiondraft -->|"requests vision"| node_vlmclient
node_vlmclient -->|"sends image"| node_modelservice
node_visiondraft -->|"suggests pattern"| node_patterninfer
node_visiondraft -->|"normalizes tiles"| node_tiletools
node_patterninfer -->|"uses tile encoding"| node_tiletools
node_patterninfer -->|"uses rule tiers"| node_rules
node_httpserver -->|"previews score"| node_scoreengine
node_scoreengine -->|"applies rules"| node_rules
node_httpserver -->|"appends events"| node_ledgerstore
node_ledgerstore -->|"computes settlement"| node_transfers
node_ledgerstore -->|"uses room rules"| node_rules
node_ledgerstore -->|"provides replayed state"| node_results
node_transfers -->|"supplies transfers"| node_results
node_player -->|"views room results"| node_results

click node_webapp "https://github.com/keiran101/mahjong-ledger/blob/main/public/app.js"
click node_httpserver "https://github.com/keiran101/mahjong-ledger/blob/main/server.mjs"
click node_roundparse "https://github.com/keiran101/mahjong-ledger/blob/main/lib/parse.mjs"
click node_textllm "https://github.com/keiran101/mahjong-ledger/blob/main/lib/llm.mjs"
click node_visiondraft "https://github.com/keiran101/mahjong-ledger/blob/main/lib/vision.mjs"
click node_vlmclient "https://github.com/keiran101/mahjong-ledger/blob/main/lib/vlm.mjs"
click node_patterninfer "https://github.com/keiran101/mahjong-ledger/blob/main/lib/pattern.ts"
click node_tiletools "https://github.com/keiran101/mahjong-ledger/blob/main/lib/tiles.ts"
click node_rules "https://github.com/keiran101/mahjong-ledger/blob/main/lib/rules.ts"
click node_scoreengine "https://github.com/keiran101/mahjong-ledger/blob/main/lib/score.ts"
click node_roomapi "https://github.com/keiran101/mahjong-ledger/blob/main/server.mjs"
click node_ledgerstore "https://github.com/keiran101/mahjong-ledger/blob/main/lib/store.mjs"
click node_transfers "https://github.com/keiran101/mahjong-ledger/blob/main/lib/settle.ts"
click node_results "https://github.com/keiran101/mahjong-ledger/blob/main/public/app.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_webapp,node_results toneBlue
class node_httpserver,node_roomapi toneAmber
class node_roundparse,node_textllm,node_visiondraft,node_vlmclient,node_patterninfer,node_tiletools toneMint
class node_rules,node_scoreengine toneRose
class node_ledgerstore,node_transfers,node_player,node_modelservice toneIndigo
```

## Components

### Player interface

- [Room interface](https://github.com/keiran101/mahjong-ledger/blob/main/public/app.js): `public/app.js`
- [Board and history](https://github.com/keiran101/mahjong-ledger/blob/main/public/app.js): `public/app.js`

### HTTP service

- [API and static server](https://github.com/keiran101/mahjong-ledger/blob/main/server.mjs): `server.mjs`
- [Room and event API](https://github.com/keiran101/mahjong-ledger/blob/main/server.mjs): `server.mjs`

### Round recognition

- [Text parser](https://github.com/keiran101/mahjong-ledger/blob/main/lib/parse.mjs): `lib/parse.mjs`
- [Text LLM client](https://github.com/keiran101/mahjong-ledger/blob/main/lib/llm.mjs): `lib/llm.mjs`
- [Photo draft](https://github.com/keiran101/mahjong-ledger/blob/main/lib/vision.mjs): `lib/vision.mjs`
- [Vision model client](https://github.com/keiran101/mahjong-ledger/blob/main/lib/vlm.mjs): `lib/vlm.mjs`
- [Hand pattern inference](https://github.com/keiran101/mahjong-ledger/blob/main/lib/pattern.ts): `lib/pattern.ts`
- [Tile utilities](https://github.com/keiran101/mahjong-ledger/blob/main/lib/tiles.ts): `lib/tiles.ts`

### Rules and scoring

- [Mahjong rules](https://github.com/keiran101/mahjong-ledger/blob/main/lib/rules.ts): `lib/rules.ts`
- [Round scoring](https://github.com/keiran101/mahjong-ledger/blob/main/lib/score.ts): `lib/score.ts`

### Ledger and results

- [Event ledger and replay](https://github.com/keiran101/mahjong-ledger/blob/main/lib/store.mjs): `lib/store.mjs`
- [Minimum transfers](https://github.com/keiran101/mahjong-ledger/blob/main/lib/settle.ts): `lib/settle.ts`

### Other components

- **Player**
- **AI model services**

## Connections

- Player → Room interface: enters rounds (evidence: `README.md`)
- Room interface → API and static server: calls APIs (evidence: `README.md`)
- API and static server → Room interface: serves interface (evidence: `README.md`)
- API and static server → Text parser: parses text (evidence: `server.mjs`)
- Text parser → Text LLM client: extracts fields (evidence: `lib/parse.mjs`)
- Text LLM client → AI model services: sends prompts (evidence: `lib/llm.mjs`)
- API and static server → Photo draft: recognizes photo (evidence: `server.mjs`)
- Photo draft → Vision model client: requests vision (evidence: `lib/vision.mjs`)
- Vision model client → AI model services: sends image (evidence: `lib/vlm.mjs`)
- Photo draft → Hand pattern inference: suggests pattern (evidence: `lib/vision.mjs`)
- Photo draft → Tile utilities: normalizes tiles (evidence: `lib/vision.mjs`)
- Hand pattern inference → Tile utilities: uses tile encoding (evidence: `lib/pattern.ts`)
- Hand pattern inference → Mahjong rules: uses rule tiers (evidence: `lib/pattern.ts`)
- API and static server → Round scoring: previews score (evidence: `server.mjs`)
- Round scoring → Mahjong rules: applies rules (evidence: `lib/score.ts`)
- API and static server → Event ledger and replay: appends events (evidence: `server.mjs`)
- Event ledger and replay → Minimum transfers: computes settlement (evidence: `lib/store.mjs`)
- Event ledger and replay → Mahjong rules: uses room rules (evidence: `lib/store.mjs`)
- Event ledger and replay → Board and history: provides replayed state (evidence: `README.md`)
- Minimum transfers → Board and history: supplies transfers (evidence: `README.md`)
- Player → Board and history: views room results (evidence: `README.md`)
