Extends ../CLAUDE.md
THIS IS THE MOST IMPORTANT SECTION IN THIS FILE.
The ultimate goal is a guiding star — not necessarily achievable, but the direction we always move toward:
Maximize the efficiency of foreign language vocabulary acquisition based on modern cognitive science. The shortest possible path from zero to fluent word knowledge.
Every decision, every feature, every change must be evaluated against this goal. Code is a means, not the goal.
Language learning web application using spaced repetition for vocabulary mastery.
Full-stack application with React frontend and Python backend.
Live: lingua-quiz.org
- Frontend: React 19, Vite 7, TypeScript
- Backend: Python 3.13, FastAPI, PostgreSQL
- Testing: Playwright (E2E), Python integration tests
- Monorepo: npm workspaces
lingua-quiz/
├── apps/
│ ├── frontend/ # React 19 application
│ └── backend/ # Python FastAPI application
├── packages/
│ ├── core/ # Quiz business logic (TypeScript)
│ ├── domain/ # Shared domain models (TypeScript)
│ └── api-client/ # Generated API client (TypeScript)
├── tools/
│ └── vocab-tools/ # Vocabulary generation pipeline (Python)
├── tests/
│ └── e2e/ # Playwright E2E tests
├── schema/ # OpenAPI schema
├── infra/
│ └── nginx/ # nginx configurations
├── docs/
│ └── proposals/ # Design documents
├── Dockerfile # Multi-stage build
├── docker-compose.yml # Local development
└── package.json # Workspace configuration
# Code quality
npm run format # Format all code
npm run lint # Lint all code
npm run typecheck # Type checking
# Testing (ONLY via docker compose)
docker compose --profile test-all up --build # Run all tests
docker compose --profile test-all run --rm test-all pytest tests/test_backend_integration.py -v # Run specific testsTesting Policy: All tests MUST be run via docker compose --profile test-all. Never run tests directly on the host machine.
npm install@lingua-quiz/core: Standalone TypeScript package with learning algorithm. Framework-agnostic.- Frontend: Executes core logic locally for zero-latency UX. Manages session state in memory.
- Backend: Stateless CRUD API for persistence only. No business logic validation.
- Client fetches word data and saved progress from backend
- Core module builds learning queues in client memory
- Session runs locally (answering, queue updates, leveling)
- Progress saved asynchronously via debounced bulk save (1000ms)
Level-based mastery system (not traditional time-based SRS).
Parameters:
- Focus Loop Size (F): 5
- Promotion Coefficient (K): 2
- Promotion Threshold: 3 correct answers
- Degradation: 3 mistakes in last 10 attempts
Mastery Levels:
- 0: New (unseen)
- 1-2: Learning (source→target, then reverse)
- 3-4: Examples (primary, then reverse)
- 5: Mastered
Progression:
- Correct: Move to position
(K × F) × consecutiveCorrect, promote at 3 correct - Incorrect: Reset streak, move to position 5, degrade if 3 mistakes in window
| Separator | Rule | Example |
|---|---|---|
, |
All parts required | floor, apartment → both needed |
| |
Any part required | car|automobile → either works |
() |
Grouped alternatives | (equal|same), (now|immediately) |
[] |
Optional content | world [universe] |
Normalization: Case-insensitive, whitespace removed, diacritics stripped, German chars converted (ä→a, ß→ss), Cyrillic normalized (ё→е).
The tools/vocab-tools/ generates CEFR-level vocabulary from subtitle frequency data.
vocab-tools generate es # Generate frequency list
vocab-tools analyze es-a1 # Analyze vocabulary
vocab-tools fill es-a1 # Fill placeholders
vocab-tools validate # Validate all migrations
vocab-tools export es-a1 # Export vocabulary from production DB
vocab-tools import ./data/ # Import vocabulary to production DBImport/export commands connect directly to production PostgreSQL via kubectl port-forward.
Setup (one-time):
# Start port-forward (run in separate terminal, keep running)
kubectl port-forward -n shared-database svc/shared-database-shared-postgres 5433:5432Credentials: Stored in macOS Keychain (see gitops/CLAUDE.md for details).
| Keychain Key | Description |
|---|---|
lingua-quiz-words-db-host |
localhost (via port-forward) |
lingua-quiz-words-db-port |
5433 |
lingua-quiz-words-db-name |
linguaquiz_words |
lingua-quiz-words-db-user |
linguaquiz_words |
lingua-quiz-words-db-password |
DB password |
Fallback: Environment variables WORDS_DB_* override Keychain if set.
Pipeline: Normalization → Lemmatization (Stanza) → NLP Analysis → Validation → Inflection Filtering → Deduplication
See tools/vocab-tools/CLAUDE.md for details.
| Level | Words | Cumulative |
|---|---|---|
| A1 | 1,000 | 1,000 |
| A2 | 1,000 | 2,000 |
| B1 | 2,000 | 4,000 |
| B2 | 2,000 | 6,000 |
| C1 | 4,000 | 10,000 |
| C2 | 4,000 | 14,000 |
Migrations run automatically via Alembic before application starts.
CD managed externally via GitOps.