Skip to content

feat(auth): password reset deep link + auth UI polish + security fixes#258

Open
InfinityZero3000 wants to merge 63 commits into
mainfrom
dev
Open

feat(auth): password reset deep link + auth UI polish + security fixes#258
InfinityZero3000 wants to merge 63 commits into
mainfrom
dev

Conversation

@InfinityZero3000

Copy link
Copy Markdown
Owner

Summary

  • Deep link fix: Password reset emails now use lexilingo-app://reset-password?token=… (custom scheme) so Android opens the app directly — lexilingo.me was returning Cloudflare Error 1000 and missing assetlinks.json
  • Cold-start race fix: Added pendingResetToken to DeepLinkService so the token survives if the navigator isn't ready yet when the app launches from the link
  • Security fix: Reverted OAuth forgot-password response from HTTP 400 back to neutral HTTP 200 — the 400 was leaking whether an email belongs to a Google account (account enumeration)
  • Regression fix: Removed min-length-8 validator from the login password field — existing users with 6–7 char passwords were being locked out client-side even though the server would accept their credentials
  • Auth UI: Redesigned login, welcome, onboarding, and pre-auth questions pages; updated app logo

Config change required on server

Update .env.production on the server (already updated locally):

PASSWORD_RESET_URL_BASE=lexilingo-app://reset-password
PASSWORD_RESET_URL_BASE_PRODUCTION=lexilingo-app://reset-password

Test plan

  • Request password reset for a local-auth account → email arrives with lexilingo-app:// link
  • Tap link from email on Android with app installed → app opens on Reset Password screen with token pre-filled
  • Tap link cold (app not running) → same result (cold-start race fix)
  • Request password reset for a Google-OAuth account → gets neutral "check your inbox" response (no 400)
  • Login with a 6 or 7 character password → no client-side rejection

🤖 Generated with Claude Code

dependabot Bot and others added 27 commits June 15, 2026 02:35
Updates the requirements on [pytest](https://github.com/pytest-dev/pytest) to permit the latest version.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](pytest-dev/pytest@9.0.3...9.1.0)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 9.1.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [fastapi](https://github.com/fastapi/fastapi) to permit the latest version.
- [Release notes](https://github.com/fastapi/fastapi/releases)
- [Commits](fastapi/fastapi@0.136.3...0.137.0)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-version: 0.137.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [google-auth](https://github.com/googleapis/google-cloud-python) to permit the latest version.
- [Release notes](https://github.com/googleapis/google-cloud-python/releases)
- [Changelog](https://github.com/googleapis/google-cloud-python/blob/main/packages/google-cloud-documentai/CHANGELOG.md)
- [Commits](googleapis/google-cloud-python@google-auth-v2.53.0...google-auth-v2.54.0)

---
updated-dependencies:
- dependency-name: google-auth
  dependency-version: 2.54.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [redis](https://github.com/redis/redis-py) to permit the latest version.
- [Release notes](https://github.com/redis/redis-py/releases)
- [Changelog](https://github.com/redis/redis-py/blob/master/CHANGES)
- [Commits](redis/redis-py@v6.4.0...v7.4.1)

---
updated-dependencies:
- dependency-name: redis
  dependency-version: 7.4.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [fastapi](https://github.com/fastapi/fastapi) to permit the latest version.
- [Release notes](https://github.com/fastapi/fastapi/releases)
- [Commits](fastapi/fastapi@0.136.3...0.137.0)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-version: 0.137.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [accelerate](https://github.com/huggingface/accelerate) to permit the latest version.
- [Release notes](https://github.com/huggingface/accelerate/releases)
- [Commits](huggingface/accelerate@v0.25.0...v0.34.2)

---
updated-dependencies:
- dependency-name: accelerate
  dependency-version: 0.34.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…246)

Updates the requirements on [sentence-transformers](https://github.com/huggingface/sentence-transformers) to permit the latest version.
- [Release notes](https://github.com/huggingface/sentence-transformers/releases)
- [Commits](huggingface/sentence-transformers@v4.1.0...v5.5.1)

---
updated-dependencies:
- dependency-name: sentence-transformers
  dependency-version: 5.5.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [pytest](https://github.com/pytest-dev/pytest) from 9.0.3 to 9.1.0.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](pytest-dev/pytest@9.0.3...9.1.0)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 9.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [langchain-core](https://github.com/langchain-ai/langchain) to permit the latest version.
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](langchain-ai/langchain@langchain-core==1.4.1...langchain-core==1.4.7)

---
updated-dependencies:
- dependency-name: langchain-core
  dependency-version: 1.4.7
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [peft](https://github.com/huggingface/peft) to permit the latest version.
- [Release notes](https://github.com/huggingface/peft/releases)
- [Commits](huggingface/peft@v0.8.0...v0.19.1)

---
updated-dependencies:
- dependency-name: peft
  dependency-version: 0.19.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [langgraph](https://github.com/langchain-ai/langgraph) to permit the latest version.
- [Release notes](https://github.com/langchain-ai/langgraph/releases)
- [Commits](langchain-ai/langgraph@1.2.4...1.2.5)

---
updated-dependencies:
- dependency-name: langgraph
  dependency-version: 1.2.5
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.9.1 to 25.9.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.9.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [react-hook-form](https://github.com/react-hook-form/react-hook-form) from 7.78.0 to 7.79.0.
- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)
- [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md)
- [Commits](react-hook-form/react-hook-form@v7.78.0...v7.79.0)

---
updated-dependencies:
- dependency-name: react-hook-form
  dependency-version: 7.79.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [axios](https://github.com/axios/axios) from 1.17.0 to 1.18.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](axios/axios@v1.17.0...v1.18.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
#255)

Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.17.0 to 1.18.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.18.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [vercel](https://github.com/vercel/vercel/tree/HEAD/packages/cli) from 54.6.1 to 54.14.0.
- [Release notes](https://github.com/vercel/vercel/releases)
- [Changelog](https://github.com/vercel/vercel/blob/main/packages/cli/CHANGELOG.md)
- [Commits](https://github.com/vercel/vercel/commits/vercel@54.14.0/packages/cli)

---
updated-dependencies:
- dependency-name: vercel
  dependency-version: 54.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [antd](https://github.com/ant-design/ant-design) from 6.4.3 to 6.4.4.
- [Release notes](https://github.com/ant-design/ant-design/releases)
- [Changelog](https://github.com/ant-design/ant-design/blob/master/CHANGELOG.en-US.md)
- [Commits](ant-design/ant-design@6.4.3...6.4.4)

---
updated-dependencies:
- dependency-name: antd
  dependency-version: 6.4.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [transformers](https://github.com/huggingface/transformers) to permit the latest version.
- [Release notes](https://github.com/huggingface/transformers/releases)
- [Commits](huggingface/transformers@v4.40.0...v5.12.1)

---
updated-dependencies:
- dependency-name: transformers
  dependency-version: 5.12.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
… fixes (#237)

* docs(stt): design streaming ensemble architecture

* docs(stt): clarify engine contracts and readiness

* feat(production): Phase 0-2 production readiness — retention, growth, security

- JWT issuer/audience validation hardening (security.py, config.py)
- Sentry DSN error tracking integration (opt-in via SENTRY_DSN env)
- Lesson context sanitization to strip answer fields from API response
- GDPR hard-delete endpoint with full cascade (users.py)
- GitHub Actions security scanning workflow + gitleaks secret detection
- CLAUDE.md + AGENTS.md project instruction files

- InAppReview after 5 completed lessons (RatingService, one-shot guard)
- Achievement share button via share_plus (static Share.share API)
- Offline SRS flashcard cache: 6h TTL via LocalCacheService.getOrFetchList()
- FCM streak-at-risk push notifications (PushNotificationService.send_streak_at_risk)
- Celery beat task send_streak_alerts at 20:00 UTC via crontab (not fixed offset)
- i18n: achievements.share key in all 7 languages

- Deep link routing (app_links): course/lesson/vocabulary/leaderboard/referral
- RevenueCat premium paywall (PurchasesService wrapper, PaywallScreen, PremiumGate)
- PurchasesService.init() wired in main.dart; DeepLinkService.dispose() on app teardown
- Referral system: 8-char code (secrets module), GET /referral/my-code, POST /referral/claim/{code}
- Race condition prevention via SELECT ... FOR UPDATE on claim endpoint
- 50 gems reward to both referrer and new user (WalletTransaction)
- pendingReferralCode claimed automatically after sign-in (auth_provider)
- Alembic migration: referral_code (unique, indexed) + referred_by FK (SET NULL)
- Prometheus + Grafana monitoring stack in docker-compose (ports 9090, 3001)
- Alert rules: HighErrorRate, SlowResponseTime, BackendDown, HighMemoryUsage
- Referral & premium i18n keys in all 7 languages

- referral.py: random → secrets.choice, with_for_update(), func.count(), Path length validation
- streak_reminders.py: datetime.now(timezone.utc).date() instead of date.today()
- celery_app.py: crontab(hour=20) instead of 3600*24 offset
- purchases_service.dart: PlatformException + PurchasesErrorHelper, rethrow non-cancel errors
- paywall_screen.dart: show error snackbar on failed purchase
- learning_provider.dart: unawaited() for onLessonCompleted()
- auth_provider.dart: body= not data=, claim referral on all 3 sign-in paths
- test_referral_routes.py: 10 test cases covering all edge cases

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): correct WalletTransaction.amount field name and gitleaks path allowlist

- referral.py: gems_balance → gems (UserWallet), gems_amount → amount (WalletTransaction)
- test_referral_routes.py: update wallet assertions to use correct field names
- .gitleaks.toml: add gateway/kong/kong.yml, backend-service/test_firebase_api.py,
  scripts/clean-git-history.sh to legacy allowlist paths (pre-existing history findings)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): extend gitleaks legacy allowlist to cover remaining historical paths

Add scripts/start-all.sh and flutter-app/build/web/main.dart.js to the
pre-existing commit allowlist. These are known historical findings from
commits already listed; credentials are revoked per team policy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: ship streaming STT and phase 3-5 hardening

* chore: ignore generated build and KG metadata

* fix(backend): patch prometheus routing for Starlette 1.x _IncludedRouter

Starlette 1.x adds _IncludedRouter objects to app.routes when include_router
is called. These objects implement matches() but have no .path attribute,
causing AttributeError in prometheus-fastapi-instrumentator routing.py:55
and returning 500 on every request when metrics are enabled.

Monkey-patches _get_route_name to guard hasattr(route, "path") and recurse
into _IncludedRouter.routes when FULL match is found without a path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: design CEFR content agent pipeline

* fix(notifications): wire FSRS reminder pipeline and add in-app review banner

- Auto-enable push notifications for new users (UserReminderPreference.enabled=True)
- Register notification tap callbacks so tapping navigates to /vocabulary/review
- Add showImmediateReviewReminder() for on-demand push when words are due
- Add ReviewReminderBanner widget on home screen showing due word count
- Clarify REMINDERS_ENABLED/REMINDER_DRY_RUN must be set true in production .env
- Fix test_reminder_settings_have_safe_defaults to check types, not hardcoded values
- Add 59-test suite covering FSRS stability/difficulty/state/scheduling and SM-2
  correctness against hand-computed reference values

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(content-agent): backend models, routes, services, Celery task, CLI

Adds the CEFR content-agent pipeline to the backend service:
- ContentAgentJob model + Alembic migration (add_cefr_content_agent)
- REST routes: POST /content-agent/jobs, GET status, PATCH approve/reject
- Services: job orchestration, ai-service client, upload handling, apply-to-lesson
- Celery beat task: nightly cleanup of expired upload artefacts
- CLI entrypoint for manual job management (app/cli/content_agent.py)
- VocabularyCRUD now joins LessonVocabularyItem so agent-created vocab appears in filters
- CONTENT_AGENT_* config keys added; feature is opt-in (CONTENT_AGENT_ENABLED=false default)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(content-agent): AI service pipeline, licensed ETL layer, remove legacy crawlers

Content-agent AI service:
- FastAPI route: POST /content-agent/generate accepting job spec + assets
- Pydantic models for request/response contracts
- Service layer: planner (exercise blueprint), generator (LLM-powered), adapters
  (normalise output to backend schema), policies (CEFR gating, quality checks), store

Licensed content ETL (replaces scrapers):
- Downloader: fetch assets from pre-approved licensed sources with checksum verify
- Archive: zip artefacts for upload to backend storage
- Registry: track known licensed sources and their metadata
- Storage: local staging + pre-signed URL upload integration
- Contracts: shared type definitions consumed by both ETL and content-agent

KG pipeline cleanup:
- Remove 5 legacy web-scraping crawlers (cefr_lists, conceptnet, web_crawler,
  wiktionary_kaikki, wordnet_extractor) that scraped third-party sites
- Replace with the safer ETL approach for sourcing CEFR content

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(content-agent): admin UI components, i18n keys, JSON contracts

Admin interface for reviewing and approving content-agent jobs:
- ContentAgentDrawer: full-page slide-over for job creation and multi-step review flow
- ContentAgentModal: compact modal variant for quick approval/rejection
- Both wired into CoursesPage via a new "Generate content" action button
- contentAgentApi.ts: typed fetch client covering job CRUD + asset upload endpoints
- i18n: contentAgent namespace added in both EN and VI translations
- contracts/: JSON Schemas (course-artifact-v2, source-record-v2) and
  exercise-types-v1 registry consumed by both UI and backend for contract parity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(content-agent): unit and integration tests across backend, ai-service, admin

Backend (7 files): apply-to-lesson, contract parity, job orchestration, routes,
Celery tasks, upload handling — covering happy path and error branches.

AI service (13 files): adapters, generator, planner, policies, routes, store,
ETL subsystems (archive, contracts, downloader, registry, storage), and a
KG-pipeline source-safety gate that enforces no direct web scraping.

Admin (1 file): contentAgentApi fetch client mock tests covering all endpoints.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(admin-ui): replace alert() with inline errors, add delete guards, polish flows

- AdminManagementPage, AiChatSettingsPage, ContentLabPage: swap browser alert()
  for inline error state rendered in the UI
- TopicsPage: add edit flow (previously only create/delete existed)
- LessonsPage: fix placeholder '_' courseId bug in lesson create call
- LessonExercisesPage, VocabularyPage: minor UX and fetch-size fixes
- UserDetailModal: remove "Coming soon" streak label
- adminApi.ts: UI_TYPES now derived from exercise-types-v1.json contract
  instead of a hard-coded array, keeping UI and backend in sync
- styles.css: add form/input/table utility classes used by new admin pages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(deploy): wire CONTENT_AGENT env vars into compose files

Add CONTENT_AGENT_ENABLED, CONTENT_AGENT_SERVICE_TOKEN, CONTENT_AGENT_AI_TIMEOUT_SECONDS,
and CONTENT_AGENT_UPLOAD_TTL_DAYS to backend-service and celery-worker containers
in both docker-compose.yml and docker-compose.production.yml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update CEFR content-agent spec and add ETL/agent implementation plans

- Updated spec (2026-06-14) to reflect final architecture decisions
- New plan (2026-06-15-cefr-content-agent): step-by-step implementation guide
  for the content-agent pipeline across backend, AI service, and admin UI
- New plan (2026-06-15-licensed-content-etl): licensed-content ETL design,
  source registry, artefact contracts, and storage strategy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: mark TRACE-CAG bulk topic corpus plan as complete

Generator already implemented: 60 topics, 18,240 quadruples, 14,640 edges.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: require source_id for repeat-sensitive XP sources, isolate backend tests

- Add REPEAT_SENSITIVE_SOURCES set (game/lesson/daily_challenge) with 422 on missing source_id
- Fix 2 existing XP tests + add 7 new parametrized tests (70 total pass)
- Add DEBUG=false guard and _test DB name check to conftest.py
- Add .env.test.example documenting test database setup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(games): add pronunciation service, completion/load/accessibility tests

- GamePronunciationService: prefers audio_url, TTS fallback, retryable error (Task 11)
- game_completion_test.dart: 13 tests across all 6 games, XP award states (Task 10)
- game_load_state_test.dart: 13 tests, loading/error/retry/stale-isolation (Task 12)
- game_accessibility_test.dart: 14 tests, semantics/touch targets/responsive layout (Task 13)
- Wire GamePronunciationService into SpellingBeeScreen and DI
- Add audioError/listenButtonLabel i18n keys (en + vi)
- 104 game tests passing, flutter analyze clean

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(etl): admin UI dynamic sources, Docker volumes, runbook (Tasks 14-15)

- ContentAgentModal: replaced hardcoded sources with dynamic getSourceCatalog() call
- Shows license/version/record count/status per snapshot; core sources auto-preselected
- Upload attestation checkbox required for admin_upload source type
- ContentAgentDrawer: blocking validation errors disable Apply button
- 12 new i18n keys in en.ts + vi.ts (sourceCatalog, uploadAttestation, etc.)
- docker-compose: content_etl_data volume for /data/content-etl (dev + prod)
- backend/.env.example: CONTENT_ETL_ENABLED=false
- ai-service/.gitignore: exclude data/content-etl/
- docs/runbooks/licensed-content-etl.md: installation, activation, rollback
- 30 admin tests passing, pnpm build:check clean

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(etl): add backend source resolution, validation, vocab catalog, Celery flow (Tasks 10-13)

- content_agent_sources.py: snapshot catalog client + pinned resolution at job creation
- content_agent_validation.py: pure 16-gate artifact validator → ValidationReport
- vocabulary_catalog.py: concurrency-safe upsert with SELECT FOR UPDATE, curated field preservation
- Provenance-v2 Alembic migration: 10 new nullable columns (backward-compatible)
- Updated Celery flow: resolving_sources → loading_snapshots → normalizing_upload → ... → preview_ready
- Upload rights attestation required for admin_upload source type
- 51 new tests, all passing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(etl): AI service pipeline, CLI, and source adapters (Tasks 1-9)

- pipeline.py: ETLPipeline with run/resume, quarantine ratio guard, dedup, PipelineReport
- cli.py: Typer CLI — list/sync/validate/activate commands (dry-run by default)
- adapters/: base protocol + OEWN (defusedxml), CMUdict (ARPAbet), CEFR-J (CSV),
  Wikidata (EntityData), Tatoeba (per-row license), LibriSpeech, Common Voice
- contracts.py: added timezone-aware retrieved_at, license-per-source allowlist validators
- storage.py: write_manifest validates raw presence, JSONL line count, quarantine
- routes/content_agent.py: GET /sources + POST /jobs/{id}/snapshots endpoints
- services/content_agent/service.py: block direct existing_cefr ingestion
- tests/content_etl/fixtures/: 10 minimal hand-authored fixture files
- 143 tests passing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(content-agent): fix test fixture unicode normalization and mark CEFR agent plan complete

- Add schema_version + source_manifest to _artifact() test helper so
  validate_artifact() gate passes in apply tests
- Import normalize_word in test to derive existing VocabularyItem.word
  from the same function, avoiding typography apostrophe U+2019 vs U+0027
  mismatch in dedup test
- Mark all 52 steps in 2026-06-15-cefr-content-agent.md as complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: record game system release verification (Task 15)

- Create docs/qa/game-system-acceptance.md with automated test results:
  26 backend game/XP tests, 104 Flutter game tests, flutter analyze clean
- Update RPT-024 with server-authoritative XP, pronunciation service, and
  Flutter test coverage added in the stability sprint
- Update RPT-025 with source_id security model and test coverage details
- Mark all 2026-06-07-game-system-stability.md tasks as complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(deps): update sentence-transformers requirement in /ai-service (#246)

Updates the requirements on [sentence-transformers](https://github.com/huggingface/sentence-transformers) to permit the latest version.
- [Release notes](https://github.com/huggingface/sentence-transformers/releases)
- [Commits](huggingface/sentence-transformers@v4.1.0...v5.5.1)

---
updated-dependencies:
- dependency-name: sentence-transformers
  dependency-version: 5.5.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump @types/node in /admin-service (#250)

Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.9.1 to 25.9.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.9.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix(admin, docker): resolve admin TypeScript compile errors & Celery healthcheck issues

* feat: implement daily login rewards, streak restore, and training activity streak updates

* feat(production): Phase 0-2 production readiness — retention, growth, security

- JWT issuer/audience validation hardening (security.py, config.py)
- Sentry DSN error tracking integration (opt-in via SENTRY_DSN env)
- Lesson context sanitization to strip answer fields from API response
- GDPR hard-delete endpoint with full cascade (users.py)
- GitHub Actions security scanning workflow + gitleaks secret detection
- CLAUDE.md + AGENTS.md project instruction files

- InAppReview after 5 completed lessons (RatingService, one-shot guard)
- Achievement share button via share_plus (static Share.share API)
- Offline SRS flashcard cache: 6h TTL via LocalCacheService.getOrFetchList()
- FCM streak-at-risk push notifications (PushNotificationService.send_streak_at_risk)
- Celery beat task send_streak_alerts at 20:00 UTC via crontab (not fixed offset)
- i18n: achievements.share key in all 7 languages

- Deep link routing (app_links): course/lesson/vocabulary/leaderboard/referral
- RevenueCat premium paywall (PurchasesService wrapper, PaywallScreen, PremiumGate)
- PurchasesService.init() wired in main.dart; DeepLinkService.dispose() on app teardown
- Referral system: 8-char code (secrets module), GET /referral/my-code, POST /referral/claim/{code}
- Race condition prevention via SELECT ... FOR UPDATE on claim endpoint
- 50 gems reward to both referrer and new user (WalletTransaction)
- pendingReferralCode claimed automatically after sign-in (auth_provider)
- Alembic migration: referral_code (unique, indexed) + referred_by FK (SET NULL)
- Prometheus + Grafana monitoring stack in docker-compose (ports 9090, 3001)
- Alert rules: HighErrorRate, SlowResponseTime, BackendDown, HighMemoryUsage
- Referral & premium i18n keys in all 7 languages

- referral.py: random → secrets.choice, with_for_update(), func.count(), Path length validation
- streak_reminders.py: datetime.now(timezone.utc).date() instead of date.today()
- celery_app.py: crontab(hour=20) instead of 3600*24 offset
- purchases_service.dart: PlatformException + PurchasesErrorHelper, rethrow non-cancel errors
- paywall_screen.dart: show error snackbar on failed purchase
- learning_provider.dart: unawaited() for onLessonCompleted()
- auth_provider.dart: body= not data=, claim referral on all 3 sign-in paths
- test_referral_routes.py: 10 test cases covering all edge cases

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: ship streaming STT and phase 3-5 hardening

* fix(admin-ui): replace alert() with inline errors, add delete guards, polish flows

- AdminManagementPage, AiChatSettingsPage, ContentLabPage: swap browser alert()
  for inline error state rendered in the UI
- TopicsPage: add edit flow (previously only create/delete existed)
- LessonsPage: fix placeholder '_' courseId bug in lesson create call
- LessonExercisesPage, VocabularyPage: minor UX and fetch-size fixes
- UserDetailModal: remove "Coming soon" streak label
- adminApi.ts: UI_TYPES now derived from exercise-types-v1.json contract
  instead of a hard-coded array, keeping UI and backend in sync
- styles.css: add form/input/table utility classes used by new admin pages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(deploy): wire CONTENT_AGENT env vars into compose files

Add CONTENT_AGENT_ENABLED, CONTENT_AGENT_SERVICE_TOKEN, CONTENT_AGENT_AI_TIMEOUT_SECONDS,
and CONTENT_AGENT_UPLOAD_TTL_DAYS to backend-service and celery-worker containers
in both docker-compose.yml and docker-compose.production.yml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(etl): admin UI dynamic sources, Docker volumes, runbook (Tasks 14-15)

- ContentAgentModal: replaced hardcoded sources with dynamic getSourceCatalog() call
- Shows license/version/record count/status per snapshot; core sources auto-preselected
- Upload attestation checkbox required for admin_upload source type
- ContentAgentDrawer: blocking validation errors disable Apply button
- 12 new i18n keys in en.ts + vi.ts (sourceCatalog, uploadAttestation, etc.)
- docker-compose: content_etl_data volume for /data/content-etl (dev + prod)
- backend/.env.example: CONTENT_ETL_ENABLED=false
- ai-service/.gitignore: exclude data/content-etl/
- docs/runbooks/licensed-content-etl.md: installation, activation, rollback
- 30 admin tests passing, pnpm build:check clean

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(agents): implement Ranking Agent + Notification Campaign Agent with LangGraph

Ranking Agent (backend + admin UI):
- RankingAgentJob model + Alembic migration (queued→calculating→validating→preview_ready→applying→completed)
- Three job types: league_reset (promotion/demotion), xp_event (boost items), achievement_batch
- LeagueResetEngine, XPEventEngine, AchievementBatchEngine with dry-run preview artifacts
- Celery tasks: run_ranking_agent_job + auto_league_reset (Monday beat schedule)
- Admin routes /admin/ranking-agent/jobs (create/list/get/apply/cancel/retry)
- RankingAgentPage + Modal (3-tab) + Drawer (polling + preview + apply)
- ai-service ranking insights route with Groq-based league commentary

Notification Campaign Agent (backend + ai-service + admin UI):
- NotificationCampaignJob model + Alembic migration (9-state machine)
- Audience segmentation: CEFR, leagues, streak, inactive_days, FCM token filter
- FCM batch sender (500 tokens/batch) + in-app broadcast via notifications table
- LangGraph pipeline (ai-service): analyze_audience → generate_variants (Groq, 3 variants)
  → evaluate_variants → [conditional loop ≤2 retries, threshold 0.70] → finalize
- X-Admin-Api-Key service-to-service auth on /api/notification-agent/generate-content
- Celery task: segment → generate (optional AI copy) → validate → preview_ready
- Admin routes /admin/notification-campaign/jobs with scheduled_push send_at enforcement
- NotificationCampaignPage + Modal (3-tab) + Drawer (polling + preview + delivery stats)

Bug fixes (from two-pass code review):
- set_preview/set_failed now go through transition() to enforce state machine
- list_jobs filters by requested_by_id for non-superadmins
- _fetch_ai_copy: add X-Admin-Api-Key header + use settings timeout (was hardcoded env var)
- _fetch_ai_copy: fix response parsing (best_variant at root, not nested under data)
- notification_agent route: use pipeline final_title/body for best_variant (not variants[0])
- in_app_broadcast overrides has_fcm_token=False before segmentation
- Markdown fence stripping fixed with re.sub (handles uppercase JSON tag + closing fence)
- rebalance_basic_vocabulary migration: guard against empty vocab catalog
- Removed dead preview_ready→queued transition from ALLOWED_TRANSITIONS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(content-agent): licensed ETL pipeline, upload rights attestation, enhanced validation

Content ETL pipeline (ai-service):
- Full source adapter registry: OEWN, CEFR-J, CMU Pronouncing Dict, Tatoeba, Wikidata
- ETL pipeline with SHA-256 integrity checks, quarantine threshold guard, defusedxml XML parsing
- Storage layer: immutable snapshot store, record-level checksums, dedup by content hash
- CLI (typer): etl run, status, validate-manifest, list-sources commands
- Dockerfile import guard: fails build if ETL runtime deps are missing

Content Agent validation (backend-service):
- Expanded `validate_artifact` to accept `pinned_snapshots` + `admin_upload` context
- New gates: MANIFEST_FIELDS_MISSING (14 required fields), MANIFEST_DUPLICATE_SOURCE,
  PINNED_SNAPSHOT_MISMATCH, UPLOAD_MISSING, UPLOAD_EXPIRED, RIGHTS_NOT_CONFIRMED,
  SHA256_INVALID, RECORD_CHECKSUM_MISMATCH, EXERCISE_TYPE_UNKNOWN
- `_exercise_type_mapping()` loads ui_type→type from contract JSON (lru_cache)
- `detect_upload_format()` in uploads service (CSV vs JSON by filename + magic bytes)

Content Agent apply (backend-service):
- Validate upload expiry + rights_confirmed before running artifact gates
- Write full provenance fields on apply: source_version, license_id, license_url,
  attribution_text, raw_checksum, record_checksum, lineage, content_usage,
  rights_confirmed_at, rights_statement_version

Content Agent routes (backend-service):
- `POST /upload`: require rights_confirmed=True attestation; detect format via
  detect_upload_format() instead of MIME-type allowlist
- `GET /sources`: new endpoint returning available snapshot catalog from ai-service

Content Agent admin UI (admin-service):
- ContentAgentModal: dynamic source picker (fetches /sources, shows version + license)
- ContentAgentDrawer: upload section with rights attestation checkbox
- contentAgentApi.ts: typed SourceSnapshot + listSources() + rights_confirmed field
- Tests updated for new modal structure + API shape

Flutter admin screens:
- analytics_screen.dart: full rewrite with TabController (Overview/Courses/Users tabs),
  fl_chart bar charts, StaggeredEntrance entrance animations, skeleton loading states
- dashboard_screen.dart: KpiCountCard grid, StaggeredEntrance wrappers, chart sections
- New shared widgets: AdminSkeleton, KpiCountCard, StaggeredEntrance

Contracts:
- course-artifact-v2.schema.json: add provenance fields (source_version, license_id, etc.)
- source-record-v2.schema.json: tighten required fields

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(content-agent): address post-review correctness issues

- tasks/content_agent.py: add lock=True to exception handler get() — prevents
  concurrent workers from racing on fail() writes
- models/content_agent.py: add FK(users.id, SET NULL) to uploader_id — removes
  dangling-UUID risk if the user row is deleted
- pipeline.py: read normalized file once (read_bytes) and decode for line
  iteration — eliminates TOCTOU checksum mismatch window on double read
- pipeline.py: move `import re` from inside _error_code to module level
- content_agent_sources.py: fix docstring — virtual sources are SKIPPED not
  returned with a synthetic descriptor
- ai-service/routes/content_agent.py: log warning when Redis._instance is None
  and local fallback is disabled, making misconfiguration visible in logs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(v1.7.0): Lexi session management, STT ensemble, topic chat service, translate API

AI Service:
- Lexi Chat major refactor: extracted session store (LexiSessionStore), idempotency
  store, and pipeline helpers into dedicated service modules
- Added SSE streaming with heartbeat keep-alive, per-turn story_ctx pre-fetch fix
  (bug: story_ctx was fetched after AI response, now fetched before pipeline runs)
- New /lexi/stream endpoint with typewriter chunk streaming + TTS after last chunk
- Added cursor-based pagination utils (api/utils/cursor.py) for lexi message history
- New /translate route for contextual word translation
- Topic chat extracted to topic_chat_service.py; persist uses insert_many for atomicity
- Replaced private _env_float import in topic_chat_service with local definition
- Expanded test suite: lexi routes, topic chat, translate, TTS, admin, lifespan, ollama

Backend Service:
- ai_service_client.py: added Lexi session/chat/stream client methods
- YouTube route: contextual translation cache with word+lang key
- Expanded test coverage for YouTube, notification campaigns, ranking agent XP events,
  vocabulary catalog normalization

Flutter App:
- Lexi Chat fix: SSE done event now carries lexi_response fullText fallback — resolves
  empty bubble (only Nghe button) when LLM stream fails but TTS audio succeeds
- Notifications: new ReviewReminderNotificationSyncService + DI wiring, notification
  local datasource and provider updates
- Settings: theme provider refactor + tests
- Deleted unused ReviewReminderBanner widget
- YouTube provider and repository improvements
- New icon assets (002_star, 008_gear, hearts, gems, crown, arrows, etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lexi): resolve empty response and missing text in Lexi chat

Root cause: Qwen3-32b on Groq uses thinking tokens that consume the
max_tokens=512 budget, leaving no room for actual response content.
The /no_think fix existed across the codebase but was missing in
stream_llm_tokens, generate_node, and diagnose_node in nodes_v2.py.

- ai-service: prepend /no_think to first user message for Qwen3 in
  stream_llm_tokens (streaming path), generate_node (non-streaming),
  and diagnose_node (grammar analysis)
- ai-service: fix sanitize_lexi_response("") returning "" instead of
  fallback message (early return bug)
- flutter: prefer server-sanitized fullText over raw accumulated chunks
  in LexiStreamDone handler to avoid rendering leaked <think> blocks
- flutter: fix locale sync race condition on Flutter web (Consumer2
  rebuild triggering redundant setLocale() calls on theme change)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style(dashboard): adjust padding, spacing, and font sizes for improved layout consistency
style(admin-shell): refine padding, sizes, and font styles for better UI alignment
style(kpi-count-card): update padding, sizes, and font attributes for enhanced visual appeal

* fix(voice): resolve speaking practice stuck in processing state

- Create assets/animation/ directory with Lottie JSON files (PulseLoader,
  Sandy Loading, SuccessCheck) — fixes 404 errors and eliminates the
  hourglass fallback icon in the processing state
- Improve LottieAnimationWidget errorBuilder: shows CircularProgressIndicator
  for loading variants, icons for success/heart/star fallbacks
- Add errorBuilder to LottieLoadingWidget so RecordButton always shows a
  visible spinner even when Lottie fails to parse
- Add 30s timeout to STT and TTS HTTP requests so processing can never
  hang indefinitely
- Wrap _assessPronunciation in try/finally so _isProcessing is always
  reset even if an unexpected exception escapes the provider
- Localize RecordButton labels (Processing.../Tap to record/Tap to stop)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): resolve Flutter clearMilestone syntax, lockfile sync, and Gitleaks test false-positive

- streak_provider.dart: add missing closing brace for claimDailyReward — clearMilestone was inadvertently nested inside the method during conflict resolution
- admin-service/package-lock.json: regenerate to match bumped package.json versions (antd 6.4.4, axios 1.18.0, vercel 54.14.2)
- .gitleaks.toml: allowlist test_admin_routes.py fake API key fixtures to eliminate false-positive CI failures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ai-service): restore sentence-transformers/transformers/numpy to torch-2.2.x compatible versions

Rebase conflict resolution incorrectly bumped:
- sentence-transformers from >=4.1.0,<5.0.0 to >=5.5.1 (conflicts with constraints-ai.txt pin ==4.1.0)
- transformers from >=4.41.0,<5.0.0 to >=5.12.1 (contradicts the comment and constraint ==4.57.6)
- numpy from >=1.26.4,<2.0.0 to >=2.4.6 (conflicts with constraint ==1.26.4)

Restored to versions verified compatible with torch==2.2.2 on both macOS x86_64 and CI Ubuntu.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(backend): pin kombu<5.6 to resolve redis>=7.4.1 dependency conflict

kombu 5.6.x added a redis<6.5 constraint that conflicts with redis>=7.4.1.
Pin kombu[redis]>=5.5.0,<5.6 (uses no upper bound on redis) and align
celery to 5.5.x accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(backend): remove kombu[redis] extra to resolve redis>=7 conflict

kombu[redis] 5.5.x pins redis<=5.2.1; dropping the extra lets pip
resolve redis 7.x freely since redis-py is already a direct dep.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* ci: trigger CI run after kombu requirements fix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(backend): remove leftover conflict markers from main.py

Stray <<<<<<< HEAD / >>>>>>> markers caused SyntaxError on import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): fix XP test failures and flutter analyze errors

- test_xp_routes: add source_id to lesson-source tests (REPEAT_SENSITIVE_SOURCES requires it)
- streak_provider: remove duplicate restoreStreak/claimDailyReward methods from rebase replay
- flutter: fix BuildContext async gap, replace withOpacity with withValues, remove unused import, fix underscore naming

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…d service extraction

Applies Clean Architecture across Flutter features, extracts backend auth/xp/settings services.
# Conflicts:
#	.gitleaks.toml
#	AGENTS.md
#	backend-service/app/core/celery_app.py
#	backend-service/app/main.py
#	backend-service/app/services/push_notification_service.py
#	docker-compose.yml
#	flutter-app/lib/features/learning/presentation/providers/learning_provider.dart
#	flutter-app/lib/features/user/presentation/pages/settings_page.dart
- Route password reset emails to lexilingo-app:// custom scheme so Android
  opens the app directly instead of a broken web URL (lexilingo.me was 404)
- Add pendingResetToken to DeepLinkService to survive cold-start navigator race
- Add reset-password case to DeepLinkService._route() with token extraction
- Add arguments support to AppNavigationService.openRoute()
- Revert forgot-password OAuth path from HTTP 400 back to neutral 200 response
  to prevent account-existence enumeration
- Remove spurious min-length-8 validator from login password field (lockout risk
  for existing users with shorter passwords)
- Add HTTP 400 → INVALID_INPUT mapping in global exception handler
- Auth UI: redesigned login, welcome, onboarding, pre-auth questions pages
- Update app logo asset

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
lexilingo-admin Ignored Ignored Jun 22, 2026 9:26am
lexilingo-app Ignored Ignored Jun 22, 2026 9:26am

InfinityZero3000 and others added 30 commits June 19, 2026 23:28
…ction upgrade keep-alives, and expose ports for testing
…v testing

Render's FastAPI CORS only allowed lexilingo.me domains, blocking local
Flutter dev builds (pointed at api.lexilingo.me) with a CORS preflight
failure. Extend CORS_ALLOW_ORIGIN_REGEX to also match localhost/127.0.0.1
on any port, mirroring what the nginx gateway already allows.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eaders, email HTML escaping, timezone & flutter drag-and-drop fixes

- Security Hardening:
  - Docker container running as non-root user (appuser:appuser)
  - Isolated database & telemetry ports to 127.0.0.1 in docker-compose
  - Added SecurityHeadersMiddleware (CSP, HSTS, frame options, XSS)
  - HTML-escaped dynamic fields in EmailService templates (OTP, reset, verification, reminders)
  - Secured monitoring & telemetry endpoints in AI service using Depends(verify_admin_api_key)
  - Restricted tempfile suffix uploads in pronunciation API
  - Blocked /metrics route in nginx configuration
- Bug Fixes:
  - Resolved daily challenges claim boundary timezone bugs by adding local_tz to today_start/end
  - Fixed vocabulary drag-and-drop categorization in learning session screen via Draggable/DragTarget
  - Added conftest.py idempotent admin_user fixture
- Verification:
  - Created new unit & integration tests covering security, container hardening, monitoring, and email escaping
- Updated SuccessCheck animation to version 5.9.0 with new properties and optimized keyframes.
- Updated Welcome animation to version 5.9.0 with simplified structure.
- Removed unused animation files: Confetti, HeartBeat, LevelUpOrbit, Live Love Learn, PulseLoader, Sandy Loading, SpinningDots, StarBurst, and Welcome.
…map numbering consistency, home featured course thumbnails, new user starter gem reward, balanced basic vocabulary, game vocabulary API compatibility, lesson speaking STT, and CEFR content agent. These documents are no longer relevant to the current project scope and have been deleted to maintain a clean and organized documentation structure.
Updates the requirements on [fastapi](https://github.com/fastapi/fastapi) to permit the latest version.
- [Release notes](https://github.com/fastapi/fastapi/releases)
- [Commits](fastapi/fastapi@0.137.0...0.138.0)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-version: 0.138.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [kombu](https://github.com/celery/kombu) to permit the latest version.
- [Release notes](https://github.com/celery/kombu/releases)
- [Changelog](https://github.com/celery/kombu/blob/main/Changelog.rst)
- [Commits](celery/kombu@v5.5.0...v5.6.2)

---
updated-dependencies:
- dependency-name: kombu
  dependency-version: 5.6.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [google-auth](https://github.com/googleapis/google-cloud-python) to permit the latest version.
- [Release notes](https://github.com/googleapis/google-cloud-python/releases)
- [Changelog](https://github.com/googleapis/google-cloud-python/blob/main/packages/google-cloud-documentai/CHANGELOG.md)
- [Commits](googleapis/google-cloud-python@google-auth-v2.54.0...google-auth-v2.55.0)

---
updated-dependencies:
- dependency-name: google-auth
  dependency-version: 2.55.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) to permit the latest version.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-version: 2.0.51
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [sentry-sdk](https://github.com/getsentry/sentry-python) to permit the latest version.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](getsentry/sentry-python@2.20.0...2.63.0)

---
updated-dependencies:
- dependency-name: sentry-sdk
  dependency-version: 2.63.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [redis](https://github.com/redis/redis-py) to permit the latest version.
- [Release notes](https://github.com/redis/redis-py/releases)
- [Changelog](https://github.com/redis/redis-py/blob/master/CHANGES)
- [Commits](redis/redis-py@v7.4.1...v8.0.0)

---
updated-dependencies:
- dependency-name: redis
  dependency-version: 8.0.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…#266)

Updates the requirements on [pydantic-settings](https://github.com/pydantic/pydantic-settings) to permit the latest version.
- [Release notes](https://github.com/pydantic/pydantic-settings/releases)
- [Commits](pydantic/pydantic-settings@v2.14.1...v2.14.2)

---
updated-dependencies:
- dependency-name: pydantic-settings
  dependency-version: 2.14.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [llama-cpp-python](https://github.com/abetlen/llama-cpp-python) to permit the latest version.
- [Release notes](https://github.com/abetlen/llama-cpp-python/releases)
- [Changelog](https://github.com/abetlen/llama-cpp-python/blob/main/CHANGELOG.md)
- [Commits](abetlen/llama-cpp-python@v0.3.28...v0.3.31)

---
updated-dependencies:
- dependency-name: llama-cpp-python
  dependency-version: 0.3.31
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [langchain-core](https://github.com/langchain-ai/langchain) to permit the latest version.
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](langchain-ai/langchain@langchain-core==1.4.7...langchain-core==1.4.8)

---
updated-dependencies:
- dependency-name: langchain-core
  dependency-version: 1.4.8
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [fastapi](https://github.com/fastapi/fastapi) to permit the latest version.
- [Release notes](https://github.com/fastapi/fastapi/releases)
- [Commits](fastapi/fastapi@0.136.0...0.138.0)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-version: 0.138.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [torch](https://github.com/pytorch/pytorch) from 2.2.2 to 2.12.1.
- [Release notes](https://github.com/pytorch/pytorch/releases)
- [Changelog](https://github.com/pytorch/pytorch/blob/main/RELEASE.md)
- [Commits](pytorch/pytorch@v2.2.2...v2.12.1)

---
updated-dependencies:
- dependency-name: torch
  dependency-version: 2.12.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
)

---
updated-dependencies:
- dependency-name: sherpa-onnx
  dependency-version: 1.13.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [langgraph](https://github.com/langchain-ai/langgraph) to permit the latest version.
- [Release notes](https://github.com/langchain-ai/langgraph/releases)
- [Commits](langchain-ai/langgraph@1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: langgraph
  dependency-version: 1.2.6
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
#274)

Bumps [moonshine-voice](https://github.com/moonshine-ai/moonshine) from 0.0.59 to 0.0.62.
- [Release notes](https://github.com/moonshine-ai/moonshine/releases)
- [Commits](moonshine-ai/moonshine@v0.0.59...v0.0.62)

---
updated-dependencies:
- dependency-name: moonshine-voice
  dependency-version: 0.0.62
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
)

Bumps [vercel](https://github.com/vercel/vercel/tree/HEAD/packages/cli) from 54.14.0 to 54.14.5.
- [Release notes](https://github.com/vercel/vercel/releases)
- [Changelog](https://github.com/vercel/vercel/blob/main/packages/cli/CHANGELOG.md)
- [Commits](https://github.com/vercel/vercel/commits/vercel@54.14.5/packages/cli)

---
updated-dependencies:
- dependency-name: vercel
  dependency-version: 54.14.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 7.17.0 to 7.18.0.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/react-router-dom@7.18.0/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@7.18.0/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-version: 7.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
#280)

Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.18.0 to 1.21.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.21.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.9.3 to 25.9.4.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.9.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [react-hook-form](https://github.com/react-hook-form/react-hook-form) from 7.79.0 to 7.80.0.
- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)
- [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md)
- [Commits](react-hook-form/react-hook-form@v7.79.0...v7.80.0)

---
updated-dependencies:
- dependency-name: react-hook-form
  dependency-version: 7.80.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ig fixes

- Add GameIcon/AppGameIcon registry (core/widgets/game_icon.dart) backed by
  assets/icon-library + assets/icon-library/learning-icons, with Material
  fallbacks for icons not yet supplied
- Redesign Home page (header, streak card, quick actions, course cards) to
  use the new game icons and a chunkier "game button" visual style
- Fix login page to fit content within the viewport using a continuous
  scale based on actual usable height (accounts for the on-screen keyboard),
  replacing a static isCompact cutoff that could push the Google/Facebook
  buttons off screen
- Fix profile header text overflow on narrow screens
- Replace hand-animated streak fire icon with real Lottie fire/flame loops
  (LottieAnimationWidget.fire/.flame) and simplify LargeStreakFireWidget
- Fix iOS Runner bundle identifier to match GoogleService-Info.plist/Firebase
  console (com.lexilingo.lexilingoApp) and wire GoogleService-Info.plist into
  the Xcode Resources build phase (previously not bundled into the app)
- Add SMTP/email env vars to backend render.yaml for forgot-password /
  verify-email sending; tighten prod CORS regex to drop localhost

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant