updating documentation

This commit is contained in:
lila 2026-05-16 01:59:43 +02:00
parent 1ba57c7e9d
commit 7e0311683f
25 changed files with 2660 additions and 226 deletions

231
README.md
View file

@ -1,170 +1,107 @@
# lila
# Lila
**Learn words. Beat friends.**
lila is a vocabulary trainer built around a Duolingo-style quiz loop: a word appears in one language, you pick the correct translation from four choices. It supports singleplayer and real-time multiplayer, and is designed to work across multiple language pairs without schema changes.
Lila is a vocabulary trainer that turns the media you love into language practice. Learn vocabulary from a Shakira song, the first chapter of _Harry Potter_, or an episode of _Breaking Bad_ — then challenge your friends in real-time multiplayer quizzes.
Live at [lilastudy.com](https://lilastudy.com).
---
## Quickstart
```bash
# 1. Clone and install
git clone git@git.lilastudy.com:forgejo-lila/lila.git
cd lila
pnpm install
# 2. Environment
cp .env.example .env
# 3. Start local services (PostgreSQL, Valkey)
docker compose up -d
# 4. Build shared packages
pnpm --filter @lila/shared build
pnpm --filter @lila/db build
# 5. Run migrations and seed data
pnpm --filter @lila/db migrate
pnpm --filter @lila/db seed
# 6. Start dev servers
pnpm dev
```
API: `http://localhost:3000` · Web: `http://localhost:5173`
See [DEPLOYMENT.md](DEPLOYMENT.md) for production infrastructure details.
---
## Documentation Index
| Document | What you'll find there |
| -------------------------------------------- | ----------------------------------------------------------------------- |
| [STATUS.md](STATUS.md) | Current state — what's working, what's blocked, what we're building now |
| [BACKLOG.md](BACKLOG.md) | Prioritized task list: now / next / later / changelog |
| [ARCHITECTURE.md](ARCHITECTURE.md) | Monorepo structure, layered architecture, data flow |
| [DECISIONS.md](DECISIONS.md) | Why we chose X over Y — tool choices, schema design, trade-offs |
| [DATA_PIPELINE.md](DATA_PIPELINE.md) | Kaikki → CEFR enrichment → production PostgreSQL |
| [MODEL_STRATEGY.md](MODEL_STRATEGY.md) | LLM voter architecture for sense-disambiguated CEFR assignment |
| [LLM_SETUP.md](LLM_SETUP.md) | Local and cloud LLM provider configuration |
| [DEPLOYMENT.md](DEPLOYMENT.md) | Hetzner VPS, Caddy, Docker Compose, CI/CD, backups |
| [design/GAME_MODES.md](design/GAME_MODES.md) | Planned multiplayer and singleplayer game modes |
---
## Stack
| Layer | Technology |
| ------------ | ---------------------------------- |
| Monorepo | pnpm workspaces |
| Frontend | React 18, Vite, TypeScript |
| Routing | TanStack Router |
| Server state | TanStack Query |
| Styling | Tailwind CSS |
| Backend | Node.js, Express, TypeScript |
| Database | PostgreSQL + Drizzle ORM |
| Validation | Zod (shared schemas) |
| Auth | Better Auth (Google + GitHub) |
| Realtime | WebSockets (`ws` library) |
| Testing | Vitest, supertest |
| Deployment | Docker Compose, Caddy, Hetzner VPS |
| CI/CD | Forgejo Actions |
| Layer | Technology |
| ---------- | ------------------------------------------------------------- |
| Monorepo | pnpm workspaces |
| Frontend | React 18, Vite, TanStack Router, TanStack Query, Tailwind CSS |
| Backend | Node.js, Express, TypeScript, WebSockets (`ws`) |
| Database | PostgreSQL + Drizzle ORM |
| Auth | Better Auth (Google + GitHub) |
| Validation | Zod (shared between frontend and backend) |
| Testing | Vitest, supertest |
| Deployment | Docker Compose, Caddy, Hetzner VPS |
| CI/CD | Forgejo Actions |
---
## Current Status
- ✅ Singleplayer quiz (5 language pairs: en↔it/de/es/fr)
- ✅ Multiplayer lobby + real-time game (24 players, simultaneous answers, 15s timer)
- ✅ Auth (Google + GitHub)
- ✅ Live deployment with CI/CD
- 🔄 Migrating vocabulary data from OpenWordNet to **Kaikki** (sense-disambiguated translations)
- 🔄 Phase 7 hardening (rate limiting, error boundaries, monitoring)
See [STATUS.md](STATUS.md) for the full picture.
---
## Repository Structure
```tree
```
lila/
├── apps/
│ ├── api/ — Express backend
│ └── web/ — React frontend
│ ├── api/ — Express backend
│ └── web/ — React frontend
├── packages/
│ ├── shared/ — Zod schemas and types shared between frontend and backend
│ └── db/ — Drizzle schema, migrations, models, seeding scripts
├── scripts/ — Python scripts for vocabulary data extraction
└── documentation/ — Project docs
```
`packages/shared` is the contract between frontend and backend. All request/response shapes are defined there as Zod schemas and never duplicated.
---
## Architecture
Requests flow through a strict layered architecture:
```text
HTTP Request → Router → Controller → Service → Model → Database
```
Each layer only talks to the layer directly below it. Controllers handle HTTP only. Services contain business logic only. Models contain database queries only. All database code lives in `packages/db` — the API never imports Drizzle directly for queries.
---
## Data Model
Words are modelled as language-neutral concepts (`terms`) with per-language `translations`. Adding a new language requires no schema changes — only new rows. CEFR levels (A1C2) are stored per translation for difficulty filtering.
Core tables: `terms`, `translations`, `term_glosses`, `decks`, `deck_terms`
Auth tables (managed by Better Auth): `user`, `session`, `account`, `verification`
Vocabulary data is sourced from WordNet and the Open Multilingual Wordnet (OMW).
---
## API
```text
POST /api/v1/game/start — start a quiz session (auth required)
POST /api/v1/game/answer — submit an answer (auth required)
GET /api/v1/health — health check (public)
ALL /api/auth/* — Better Auth handlers (public)
```
The correct answer is never sent to the frontend — all evaluation happens server-side.
---
## Multiplayer
Rooms are created via REST, then managed over WebSockets. Messages are typed via a Zod discriminated union. The host starts the game; all players answer simultaneously with a 15-second server-enforced timer. Room state is held in-memory (Valkey deferred).
---
## Infrastructure
```tree
Internet → Caddy (HTTPS)
├── lilastudy.com → web (nginx, static files)
├── api.lilastudy.com → api (Express)
└── git.lilastudy.com → Forgejo (git + registry)
```
Deployed on a Hetzner VPS (Debian 13, ARM64). Images are built cross-compiled for ARM64 and pushed to the Forgejo container registry. CI/CD runs via Forgejo Actions on push to `main`. Daily database backups are synced to the dev laptop via rsync.
See `documentation/deployment.md` for the full infrastructure setup.
---
## Local Development
### Prerequisites
- Node.js 20+
- pnpm 9+
- Docker + Docker Compose
### Setup
```bash
# Install dependencies
pnpm install
# Create your local env file (used by docker compose + the API)
cp .env.example .env
# Start local services (PostgreSQL, Valkey)
docker compose up -d
# Build shared packages
pnpm --filter @lila/shared build
pnpm --filter @lila/db build
# Run migrations and seed data
pnpm --filter @lila/db migrate
pnpm --filter @lila/db seed
# Start dev servers
pnpm dev
```
The API runs on `http://localhost:3000` and the frontend on `http://localhost:5173`.
---
## Testing
```bash
# All tests
pnpm test
# API only
pnpm --filter api test
# Frontend only
pnpm --filter web test
│ ├── shared/ — Zod schemas + constants (API/web contract)
│ └── db/ — Drizzle schema, migrations, models, seeding
├── data-pipeline/ — Kaikki extraction → enrichment → PostgreSQL sync
├── documentation/ — Project docs (this directory)
└── Caddyfile, docker-compose.yml, etc.
```
---
## Roadmap
## License
| Phase | Description | Status |
| ----- | ---------------------------------------------------------------------- | ------ |
| 0 | Foundation — monorepo, tooling, dev environment | ✅ |
| 1 | Vocabulary data pipeline + REST API | ✅ |
| 2 | Singleplayer quiz UI | ✅ |
| 3 | Auth (Google + GitHub) | ✅ |
| 4 | Multiplayer lobby (WebSockets) | ✅ |
| 5 | Multiplayer game (real-time, server timer) | ✅ |
| 6 | Production deployment + CI/CD | ✅ |
| 7 | Hardening (rate limiting, error boundaries, monitoring, accessibility) | 🔄 |
See `documentation/roadmap.md` for task-level detail.
TBD