Version: 0.1.22
A platform offering real-time translation and interactive language learning for multilingual users. Built as part of a university graduation project.
For the full architecture, technology rationale, and roadmap, see ARCHITECTURE.md. For the complete version history, see CHANGELOG.md. For the security review, see SECURITY.md. For running and deploying it, see DEPLOYMENT.md. For the test strategy across all four layers, see TESTING.md.
One line per version; the full story (rationale, tradeoffs, bugs caught) lives in CHANGELOG.md.
| Version | Summary |
|---|---|
| 0.0.1 | Backend skeleton: FastAPI + SQLModel, JWT auth, core translate/course/quiz endpoints (mock translation), seeded content. |
| 0.0.2 | Frontend: React + TypeScript (Vite) interface for every backend flow. |
| 0.0.3 | Browser speech recognition (dictation + pronunciation practice), streak & progress stats, lesson→quiz lookups. |
| 0.0.4 | Automatic language detection (with honest reliability gating), text-to-speech, SM-2 spaced repetition + /review. |
| 0.0.5 | Translation depth: confidence + alternatives, idiom warnings, personalized vocabulary suggestions, real-NLLB groundwork. |
| 0.0.6 | Pedagogy: four quiz types, adaptive difficulty, achievement badges, daily goals, grammar & cultural notes. |
| 0.0.7 | Security: refresh-token rotation, auth rate limiting, email verification & password reset, security headers, OWASP Top 10 audit, CI dependency scanning. |
| 0.0.8 | Test & CI infrastructure: pytest + coverage gate and frontend build on every push, app-wide rate limiting, paginated lists. |
| 0.0.9 | Alembic migrations (+ drift test), served-set quiz grading (QuizSession), admin content API; post-release: python-jose→PyJWT and Vite 8 — both dependency audits clean. |
| 0.1.0 | Ops: Docker + docker-compose (one command), Redis translation cache, CORS locked to the configured origin, deployment guide + Railway/Vercel configs. |
| 0.1.1 | UX: dark mode (token-level, no-flash), general toast system, copy-to-clipboard, accessibility audit — incl. fixing five measured WCAG failures the light theme had shipped with. |
| 0.1.2 | Test depth: first frontend unit tests (Vitest, 16), Playwright E2E journey in CI, Locust load testing with measured limiter verification, TESTING.md. |
| 0.1.3 | PWA (installable, offline shell, maskable icons, opt-in updates) and content as importable JSON packs — Turkish A1 + Spanish A2, tripling the catalogue. |
| 0.1.4 | Security review follow-up begins: client address resolved from TRUSTED_PROXY_HOPS instead of uvicorn's --forwarded-allow-ips "*", which trusted the caller-written end of X-Forwarded-For and made every per-IP rate limit bypassable. |
| 0.1.5 | Rate limiter memory: the attempt table is swept once per window, so it's bounded by keys seen in a window rather than every key seen since start-up. |
| 0.1.6 | Login budgets keyed per (address, username) — a successful login no longer clears an unrelated account's failures — plus a per-address failed-login cap so re-keying doesn't open the door to password spraying. |
| 0.1.7 | Security log integrity: field values are escaped, so a username containing a newline can no longer forge audit entries. |
| 0.1.8 | Refresh tokens survive a second browser tab: cross-tab Web Lock on the client, and a grace window for a just-rotated token on the server (never for logout or password reset). |
| 0.1.9 | Days are counted in each learner's timezone, not UTC — streaks, daily goals and review scheduling were rolling over at the wrong hour for everyone outside UTC. |
| 0.1.10 | API docs (/docs, /redoc, /openapi.json) off by default, and actually rendering when on — CSP had been blanking the Swagger page since v0.0.8. |
| 0.1.11 | Accuracy pass: bcrypt's silent 72-byte truncation fixed (bcrypt_sha256, migrating on login), SECURITY.md corrected where it described a fix that never existed and a role model that no longer matched, working npm run lint. |
| 0.1.12 | Email verification decided rather than drifted: not enforced (nothing in this app is harmed by an unverified address), but the status is now visible and there's a resend-verification endpoint to act on it. |
| 0.1.13 | Removed a SQLite file committed by accident in v0.0.9, and closed the cause: a .env value's inline ; comment became part of the filename, and .gitignore matched only the name it expected. |
| 0.1.14 | Page tests for all 13 pages, the layer whose only signal had been that it compiled — and the frontend suite made runnable on Node ≥ 24, where a global localStorage had been shadowing jsdom's since before it was noticed. Test counts across the docs now match what runs. |
| 0.1.15 | The backend suite stopped reading the developer's .env: following backend/README.md's own cp .env.example .env step failed three tests, and CI (no .env) never saw it. |
| 0.1.16 | Mail-server failures handled: registration no longer reports failure for an account it created, a failed resend no longer kills the link it was replacing, and a mail outage no longer turns password reset into the account-existence oracle it's written not to be. |
| 0.1.17 | /translate's language codes were the one user field with no validation — unbounded, stored verbatim, and colon-joined into the shared Redis cache key where two different pairs could collide. Validated against what the engine supports. |
| 0.1.18 | Login took ~200 ms for a real account and ~5 ms for one that doesn't exist — a 40x enumeration oracle behind a message written to reveal nothing. Equalised to 1.00x; registration's remaining leak decided and documented rather than left as a recommendation. |
| 0.1.19 | The badge check ran on every translation and counted by fetching every row to measure the list: /translate 60 ms → 4 ms, suggestions 230 ms → 14 ms. /users/me/stats still scales with the streak, and the two docs that called that negligible now carry the measurement. |
| 0.1.20 | Three tables that only ever grew now get purged — with retention windows set past the point a row can still matter, since deleting a revoked refresh token early turns a session-theft alarm into a silent 401. Request bodies bounded too. |
| 0.1.21 | Two ways the app showed a blank page, both without anything being broken: an unknown URL matched no route, and one thrown render error unmounted the whole tree. Catch-all route and an error boundary inside the nav. |
| 0.1.22 | The dependency gate fired for the first time — three advisories published against an unchanged tree. The High one fixed with an overrides pin rather than npm's suggested downgrade; the two Moderate router ones checked against the code, shown unreachable, and tracked. |
docker compose up --build→ Frontend: http://localhost:8080 · Backend + Swagger: http://localhost:8000/docs
(Swagger is development-only: ENABLE_API_DOCS defaults to off.)
(Environment variables and cloud deployment: DEPLOYMENT.md.)
Terminal 1 — Backend
cd backend
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
uvicorn app.main:app --reload→ http://localhost:8000 (Swagger: http://localhost:8000/docs)
Terminal 2 — Frontend
cd frontend
npm install
cp .env.example .env
npm run devSee backend/README.md and frontend/README.md for detailed instructions
and architecture notes.
- ✅ Backend: auth (+ refresh tokens, email verification, password reset, rate limiting, daily goals), translation (+ confidence/alternatives/idiom warnings/language detection), courses/lessons (+ grammar/cultural notes), quizzes (4 types + adaptive difficulty), progress/streak, spaced repetition, personalized suggestions, achievement badges — 305 backend + 80 frontend tests passing
- ✅ Frontend: a working interface for every flow (React + TypeScript)
- ✅ Speech: voice input (translation + pronunciation practice) and voice output (translations + vocabulary + listening quiz questions), both browser-based, no model download
- ✅ Progress tracking: daily streak, daily review goal, per-course completion percentage, achievement badges (
/progress) - ✅ Spaced repetition: SM-2-scheduled vocabulary review (
/review) - ✅ Security: app-wide + per-endpoint rate limiting, refresh token rotation, security headers, CI dependency scanning, real OWASP Top 10 audit (
SECURITY.md) - ✅ Test & CI infrastructure: pytest + coverage gate, frontend unit + page tests, and a type-check/build on every push (
.github/workflows/ci.yml), paginated list endpoints - ✅ Data layer & content ops: Alembic migrations (with a migration-drift test), served-set quiz grading via QuizSession, admin CRUD API for all course/quiz content (
scripts/make_admin.pyto promote) - ✅ Ops & deploy: Docker + docker-compose (one command), Redis translation cache with graceful degradation, CORS locked to the configured frontend origin, deployment guide + Railway/Vercel configs (
DEPLOYMENT.md) - ✅ UX & accessibility: dark mode with pre-paint theme resolution, app-wide toast notifications, copy-to-clipboard, WCAG AA-audited palette (30/30 pairs, both themes), landmarks + skip link + labeled controls
- ✅ Test depth: four-layer strategy (
TESTING.md) — backend pytest, frontend Vitest, Playwright E2E in CI, Locust load testing with measured rate-limiter verification - ✅ PWA & content: installable app with offline shell and opt-in updates; course content as validated JSON packs (
scripts/import_content.py) — Turkish A1 and Spanish A2 alongside the seeded course - ✅ AI/translation engine topic: complete except running the real NLLB model, which needs to happen on your own machine (this sandbox has no network access to huggingface.co)
- ✅ Language learning/pedagogy topic: complete
- ✅ Security topic: complete
- ⏳ Up next: academic deliverables (ER/use-case/sequence diagrams, user guide) and activating the real NLLB model
(Full roadmap: ARCHITECTURE.md §6 · Full version history: CHANGELOG.md · Security review: SECURITY.md)