Skip to content

feat: add product expansion suite#302

Closed
InfinityZero3000 wants to merge 20 commits into
devfrom
feature/product-expansion-suite
Closed

feat: add product expansion suite#302
InfinityZero3000 wants to merge 20 commits into
devfrom
feature/product-expansion-suite

Conversation

@InfinityZero3000

Copy link
Copy Markdown
Owner

Summary

  • Add Today Plan, Placement Test, Practice Lab, Premium entry/gates, Offline & Sync, Mistake Notebook, and game mistake capture in Flutter.
  • Add contextual book quiz and podcast transcript artifacts plus AI Quality Dashboard and Content QA Queue in admin/backend.
  • Improve AI/backend support and expand regression coverage across content agent, audit, proficiency, podcasts, books, games, and learning flows.

Verification

  • admin-service: npm test
  • admin-service: npm run build:check
  • backend-service: backend-service/venv/bin/python -m pytest backend-service/tests -q (1280 passed)
  • flutter-app: flutter analyze
  • flutter-app: flutter test (754 passed)
  • ai-service: ai-service/venv/bin/python -m pytest tests -q (561 passed)
  • jq empty flutter-app/assets/i18n/en.json flutter-app/assets/i18n/vi.json
  • git diff --check

Notes

  • Docs changes were intentionally excluded from the commit per request.

InfinityZero3000 and others added 20 commits June 23, 2026 11:48
Critical authorization bug: /login and /refresh never checked
user.is_verified, so accounts with unconfirmed emails (including
ones using addresses the registrant doesn't control) could log in
and stay logged in indefinitely via refresh-token rotation. Google/
Facebook OAuth is unaffected since it already sets is_verified from
the provider's own claim. Also fixes /resend-verification, which
checked a nonexistent `email_verified` attribute and never actually
fired. Flutter login page now detects the new 403 and routes the
user to the existing email-verification-pending screen to resend
the link instead of just showing a raw error.

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

Backfills is_verified=true for users created before commit 41613c4's
login/refresh enforcement so existing accounts aren't locked out. Adds
is_verified checks to admin login/OTP routes for consistency. Lets Google
OAuth link to (and verify) an existing unverified local account when the
email matches and Google confirms email_verified=true, instead of always
rejecting with "Cannot change provider". Expands auth route test coverage
to 56 tests covering Google/Facebook login, admin login/OTP, password
change, and resend-verification.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend's admin/verification routes return AUTH_FORBIDDEN for
inactive/unverified accounts, but the client had no mapping for it and
fell through to a generic server-error message. Maps it alongside the
other AUTH_* codes so the UI surfaces the real reason.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
story_repository.dart (the domain interface) and presentation widgets
imported data/models/* directly, violating Clean Architecture's
domain-never-imports-data rule. Adds Story/StoryListItem/TopicSession/
EducationalHints entities under domain/entities/, gives each data model
a toEntity() mapper, and updates the repository implementation and all
presentation call sites to depend on entities instead of models.

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

lexi_chat.py mixed route handling with pipeline orchestration and SSE
streaming, growing past 1400 lines. Moves the pipeline run, session
store/idempotency helpers, and the SSE generator into a new
lexi_chat_service.py; the route module now just parses requests, calls
the service, and serializes the response. No behavior change — pipeline
and streaming tests pass unmodified aside from updated monkeypatch
targets.

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

main.py imported a 2152-line app/routes/admin.py whose own docstring
called it deprecated, while the actual split files (admin_courses.py,
admin_gamification.py, admin_system.py) sat unwired and unused — an
abandoned refactor that left the "old" file as the only live one.
Verified the split files are an exact route-for-route, AST-identical
match (45 routes either way) before switching main.py to them and
deleting admin.py.

Also finishes the original refactor goal for the /admin/seed endpoint:
extracts its ~430 lines of literal seed data into
app/core/sample_data_catalog.py and the seeding loop into
app/services/admin_seed_service.py, deep-copying the course catalog
before the seeding loop mutates it in place so repeated seed runs stay
idempotent.

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

nodes_v2.py had grown to 2015 lines. Moves retrieve_node (budgeted hybrid
retrieval + fusion scoring) into trace_cag/retrieve.py, and generate_node
plus its build_generation_prompt/stream_llm_tokens helpers into
trace_cag/generate.py, leaving nodes_v2.py at 885 lines. Both are
re-exported from nodes_v2.py so existing imports (graph.py,
lexi_chat_service.py, tests) keep working unchanged. Pure move — no
logic changes; 114/114 trace_cag tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_ProfilePageState had grown to 1772 lines covering header, quick
actions, level progress, learning stats, weekly activity, badges, and
the admin shortcut all in one file. Extracts each section into its own
widget under presentation/widgets/profile_page/, dropping
profile_page.dart from 2223 to 232 lines. flutter analyze clean,
existing profile_page_test.dart (24 tests) passes unmodified.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_HomePageNewState had grown to 2031 lines. Extracts header, streak card,
level/daily-goal row, quick actions, enrolled/featured courses, and the
skeleton loading state into widgets under
presentation/widgets/home_page/, dropping home_page.dart from 2159 to
222 lines. Also deletes _buildQuickStats and _buildContinueSection —
both already carried `// ignore: unused_element` and had zero callers
anywhere in the codebase. flutter analyze clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…in, tracecag packaging

- lexi_chat: thread native_language (ISO 639-1) through request, idempotency
  hash, and all orchestrator calls (primary/retry/stream) via iso_to_language_name
- stt/transcript_normalizer: drop filler-only utterances and dedup leading
  repeated n-grams (Moonshine hallucination artifact)
- groq_key_pool: round-robin fallback over all GROQ_API_KEYS when the
  Redis-backed pool isn't initialized (standalone CLIs no longer burn one key)
- voice_session/metrics/sentence_finalizer/model_registry hardening
- trace_cag: cache_utils/l1_state_cache/nodes_v2/retrieve/state refinements;
  benchmark qa_generation + ranking fixes
- tests: native-language hint, benchmark model-strength, normalizer, lexi chat
  routes, tracecag chat integration
- fix(test): sync dependency-constraint expected pins to merged Dependabot
  bumps (torch 2.12.1, moonshine-voice 0.0.62, sherpa-onnx 1.13.3)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ce hardening

- shop_catalog: 10 in-game power-up consumables (time freeze, extra time, skip
  token, reveal/translate hint, shield, extra heart, lucky clover, score
  multiplier, pair swap) + GAME_POWERUP_ITEM_TYPES; alembic upsert migration
- item_effects_service: route power-ups to _handle_instant_game_powerup (echo
  effects payload, no server state); reject cosmetics from the use endpoint;
  null-safe hint accounting
- DailyChallengeService: idempotent claims via ChallengeRewardClaim unique
  index + single transaction (add_gems commit=False); guards double-claim
- admin shop CRUD now accepts JSON body (ShopItemAdminCreate/Update) with
  effects/icon_url; list endpoint returns them too
- services package: split achievement checker into its own module, lazy
  __getattr__ keeps imports light and backward compatible
- schemas: migrate to Pydantic v2 (ConfigDict/field_validator) + guard test
- quota_manager: UTC-keyed quotas, input validation (negative/zero cost,
  unknown API); content_agent_validation + artifact index; misc cleanup
- remove dead check_missing.py / test_vocab_definitions.py
- fix(test): admin RBAC create-shop test uses json body to match new contract

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…up types

- adminApi: create/update shop item send JSON body (was query params); add
  ShopItemEffects type, effects/icon_url fields
- ShopPage: item-type list mirrors backend shop_catalog; quick-create templates
  prefill name/description/price/effects per type
- i18n (en/vi) strings for the new shop fields

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…remony

- games: GamePowerupTray widget wired into fill-blank, grammar quiz, hangman,
  matching, spelling bee, word scramble; game_entities power-up support
- lexi_chat: send native_language through datasource/repository/provider/page
- gamification: shop_item/wallet entities + power-up provider plumbing; shop
  item card; league ceremony screen redesign
- vocabulary: native-language datasource params; daily review / word-of-day
  card tweaks; daily challenges widget
- tests: power-up provider/tray, wallet entity, shop item, lexi chat provider,
  vocabulary datasource, user model

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Dependabot bumped react-hook-form (#279), @types/node (#281), and
lucide-react (#280) in package.json without regenerating the lock, so
'npm ci' failed in CI. Sync the lockfile to unbreak the admin job.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Dependabot bumped kombu to >=5.6.2 (incompatible with the pinned
celery>=5.5.3,<5.6, which requires kombu<5.6), making 'pip install -r
requirements.txt' fail with ResolutionImpossible in CI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ficiency output)

Prevent CI-generated reports from being accidentally committed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Implemented quiz mode in DailyReviewCard with a modal bottom sheet for mode selection.
- Added QuizOptionCard widget for displaying quiz options with different states.
- Registered QuizProvider in vocabulary dependency injection setup.
- Created unit tests for QuizProvider to ensure quiz functionality works as expected.
- Updated various test files to include necessary dependencies and improve structure.
- Refactored existing tests for better readability and maintainability.
@vercel

vercel Bot commented Jul 2, 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 Jul 2, 2026 7:23am
lexilingo-app Ignored Ignored Jul 2, 2026 7:23am

@InfinityZero3000

Copy link
Copy Markdown
Owner Author

Closed in favor of #303, which is rebuilt from origin/dev and excludes docs/markdown files per request.

@InfinityZero3000 InfinityZero3000 deleted the feature/product-expansion-suite branch July 2, 2026 07:26
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