No description
- Add optionalAuth middleware: attaches session when present, never blocks (guests pass through) - Make game endpoints (start/answer) accept optional auth - GameSessionStore.userId: string → string | null - Rate limiter falls back to IP for unauthenticated users - Frontend: remove /play route guard, show 'Create account' CTA on score screen for guests - Add tests for guest session creation, answer submission, and cross-user session isolation |
||
|---|---|---|
| .forgejo/workflows | ||
| .husky | ||
| apps | ||
| data-pipeline | ||
| documentation | ||
| packages | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .prettierignore | ||
| .prettierrc | ||
| Caddyfile | ||
| docker-compose.yml | ||
| eslint.config.mjs | ||
| mise.toml | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| tsconfig.base.json | ||
| tsconfig.json | ||
| vitest.config.ts | ||
Lila
Learn words. Beat friends.
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.
Quickstart
# 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 for production infrastructure details.
Documentation Index
| Document | What you'll find there |
|---|---|
| STATUS.md | Current state — what's working, what's blocked, what we're building now |
| BACKLOG.md | Prioritized task list: now / next / later / changelog |
| ARCHITECTURE.md | Monorepo structure, layered architecture, data flow |
| DECISIONS.md | Why we chose X over Y — tool choices, schema design, trade-offs |
| DATA_PIPELINE.md | Kaikki → CEFR enrichment → production PostgreSQL |
| MODEL_STRATEGY.md | LLM voter architecture for sense-disambiguated CEFR assignment |
| LLM_SETUP.md | Local and cloud LLM provider configuration |
| DEPLOYMENT.md | Hetzner VPS, Caddy, Docker Compose, CI/CD, backups |
| design/GAME_MODES.md | Planned multiplayer and singleplayer game modes |
Stack
| 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 (2–4 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 for the full picture.
Repository Structure
lila/
├── apps/
│ ├── api/ — Express backend
│ └── web/ — React frontend
├── packages/
│ ├── 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.
License
TBD