4 Commits

Author SHA1 Message Date
wangdl
6a5ab31ddd fix(quota): remove duplicate quiz_generation reserve in router
Some checks failed
Deploy API Server / build-and-unit (push) Successful in 39s
Deploy API Server / current-integration (push) Successful in 33s
Deploy API Server / backward-compat (push) Successful in 0s
Deploy API Server / deploy (push) Has been cancelled
Quota reserve is now centralized in UserAiController.createAnalysisJob.
Router no longer needs QuotaGuardService injection.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 20:19:39 +08:00
wangdl
9566de63a2 feat(membership): implement subscription entitlement and quota backend
Some checks failed
Deploy API Server / build-and-unit (push) Failing after 29s
Deploy API Server / current-integration (push) Has been skipped
Deploy API Server / backward-compat (push) Has been skipped
Deploy API Server / deploy (push) Has been skipped
- Add User.appAccountToken, StoreProduct, PlanQuota models
- Extend UserMembership with Apple IAP fields + source/status
- Add AppStoreTransaction (immutable) + AppStoreNotification (Durable Inbox)
- Implement EffectiveMembershipService (multi-grant → effectivePlan)
- Implement EffectiveQuotaService (PlanQuota-driven, Legacy/Shadow/Enforced)
- Implement AppStoreJwsVerifier (x5c chain → Apple Root CA G3)
- Implement AppStoreTransactionService (JWS verify + atomic projection)
- Implement AppStoreNotificationService (9 event types + lifecycle)
- Wire QuotaGuard across 5 AI Job types (active_recall/feynman/quiz/learning/flashcard)
- Add Membership API: GET /plans, /me, /usage, POST /apple/transactions
- Add webhook: POST /webhooks/app-store/v2 (@Public)
- Add 11 unit tests for EffectiveMembershipService
- Migration: 3 SQL files (expand_schema, transaction_notification, quotausage_unique)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 20:03:03 +08:00
wangdl
ec2379eaf3 fix(M-AI-07): stabilize Quiz generation request idempotency
All checks were successful
Deploy API Server / build-and-unit (push) Successful in 39s
Deploy API Server / current-integration (push) Successful in 30s
Deploy API Server / backward-compat (push) Successful in 1s
Deploy API Server / deploy (push) Successful in 1m1s
Replace Date.now() fallback with deterministic content hash + time window.

Idempotency strategy:
  Priority 1: client-provided idempotencyKey → direct use
  Priority 2: SHA-256(normalized params) + 10min window → retry-safe
  Active re-generation: client provides new idempotencyKey

idempotencyKey format: quiz-generation:<contentHash24>:w<windowTs>

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-22 21:19:20 +08:00
wangdl
40e772cc3a feat(M-AI-07-05): quiz generation execution router + controller wiring
Some checks failed
Deploy API Server / build-and-unit (push) Successful in 36s
Deploy API Server / current-integration (push) Successful in 31s
Deploy API Server / backward-compat (push) Successful in 0s
Deploy API Server / deploy (push) Failing after 50s
- QuizExecutionRouter: QUIZ_GENERATION_ENGINE_MODE flag routing
- legacy: UserAiService.createAnalysisJob()
- unified: SnapshotBuilder + AiJobCreationService.createJob()
- Controller: quiz_generation routes through Router
- Response compat: legacy fields + optional engineMode/lifecycleStatus

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-22 20:46:54 +08:00