wangdl
e2511855fe
feat(membership): add StoreKit subscription and membership center
...
- StoreKitManager: purchase, Transaction.updates, restore, finish
- MembershipView: plan cards, purchase section, usage grid, compliance
- MembershipService: API client for /membership/* endpoints
- MembershipModels: Codable DTOs for plans/grants/transactions
- Route.membership + ProfileView entry point
- Products.storekit: Sandbox test products (monthly/yearly)
- Remove hardcoded price fallback (displayPrice nil → 价格暂不可用)
- Add MembershipModelsTests (12 tests)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 20:08:41 +08:00
wangdl
f445906fa7
feat(quiz): integrate QuizQuestionType enum into iOS quiz views
...
- Add QuizQuestionType Swift enum with safe factory and displayAnswer
- Add QuizQuestion.questionType computed property
- Replace bare string comparisons with enum switch in QuizTakerView
- Add empty state, unknown type error state, judge localization
- Use displayAnswer in QuizResultView for choice index→text + judge CN
- Add QuizQuestionTypeTests (19 tests)
- Update QuizService with createAttempt/getAttemptQuestions endpoints
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-24 20:11:27 +08:00
wangdl
def8c4c93a
fix: all iOS compile errors - protocols, missing fields, colors, shadowed max
...
- Protocol conformance: list→listAll with extension defaults
- ContinueLearningResponse has no lastPosition→use nil
- LearningSession has no readingTargetType/materialId→use defaults
- Color.zxBlue→Color.blue, Color.zxIndigo→Color.indigo
- Shadowed max parameter→Swift.max
- ForEach Identifiable→explicit id: \.id
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 17:14:34 +08:00
wangdl
d8125ddf34
fix: iOS compile errors - protocol mismatches + void return
...
- ReadingRuntimeAdapter: clearExportedEvents is void, return count separately
- ActivityViewModel: FocusItemServicing.list→listAll, add days/type? params
- ActivityViewModelTests: update mocks to match new protocol signatures
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 16:58:23 +08:00
wangdl
de384dc027
test: fill iOS coverage gaps - fromBlockScroll, refresh, View helpers
...
- fromBlockScroll: success + empty/negative/OOB guard tests (4)
- StudyHomeViewModel.refresh: stats update + mainAction update (2)
- View helpers: statusLabel(4) + formatSeconds(7) standalone tests
- formatFileSize smoke test (indirect via View init)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:44:54 +08:00
wangdl
c7de97279b
test: add P1-fallback + refresh tests for StudyHomeViewModel
...
- P1 fallback: continueService throws → falls to unfinished session
- refresh: updates stats without setting loadingState
- Fix: remove nonexistent materialId/readingTargetType from LearningSession mock
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:25:41 +08:00
wangdl
9ec6fdc3d5
test: add StudyHomeViewModel unit tests with DI (IOS-INFO-037)
...
- Add 6 service protocols (SessionServicing, ReviewServicing,
KBListServicing, QuizListServicing, ActivityHomeServicing,
ContinueLearningServicing)
- ViewModel init supports DI with defaults to .shared
- 16 tests: initial state, loadAll stats, all 5 priority levels
(continueSession→todaysReview→selfTest→startLearning→empty),
banner, weekly stats from summary/streak
- Priority P1 continueSession tested with mock API + temp file
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:23:08 +08:00
wangdl
3a8266ece2
test: add ActivityViewModel unit tests with DI (IOS-INFO-036)
...
- Add 5 service protocols (ActivityServicing, FocusItemServicing,
ReadingContinueServicing, LearningStatusServicing)
- ViewModel init supports DI with defaults to .shared
- Mock services for all 10 parallel calls in loadAll/refresh
- 20 tests: initial state, summary/focus/heatmap/streak/trends/recos,
learningSummary/readingTrend/continueReading/recentRecords,
errorMessage on nil summary, refresh clears error
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:19:07 +08:00
wangdl
203e45df34
test: remove View helper tests from ViewModel test file
...
- statusLabel/formatSeconds belong to MaterialDetailView, not ViewModel
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:15:26 +08:00
wangdl
833bc70121
test: add load() tests with mock service DI (IOS-INFO-035)
...
- Add service protocols (KnowledgeBaseServicing, KnowledgeItemServicing,
QuizServicing, ReadingProgressServicing) for dependency injection
- ViewModel init accepts optional mock services, defaults to .shared
- Mock service classes for test isolation
- load() tests: itemCount, quizCount, aiStatus ready/processing,
isLoading, readingStatus/seconds, isMarkedRead, progress error,
nil materialId skips progress
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:14:49 +08:00
wangdl
61de3e1d57
test: add MaterialDetailViewModel unit tests (IOS-INFO-035)
...
- 20 tests covering initial state + helpers
- Initial state: isLoading, aiStatus, itemCount, quizCount, isMarkedRead,
readingSeconds, readingStatus, knowledgeBaseId, materialId
- init without materialId defaults to nil
- statusLabel: completed/in_progress/unknown/nil → Chinese labels
- formatSeconds: seconds(0/30/59), minutes(60/3599), hours(3600/3660/7200)
- Edge: nil materialId skips progress fetch
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:11:36 +08:00
wangdl
4348823ca1
test: add ReadingPositionAdapter.fromValue unit tests (IOS-INFO-034)
...
- 23 tests: fromValue (12) + clamp (2) + blockId (8)
- fromValue: Markdown/Text/Pdf/Image/Epub complete + defaults
- fromValue: nil blockId→nil for Markdown, nil chapterId→nil for Epub
- fromValue: unknown/nil type → .unknown
- clamp: > 1 → 1.0, < 0 → 0.0
- blockId: all 7 DocumentBlock variants + horizontalRule
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:09:05 +08:00
wangdl
86054edd5f
test: add resolveKnowledgeSource + full type inference tests
...
- Add resolveKnowledgeSource path test (knowledge_sources/<id>/)
- Add empty knowledge_sources directory test
- Add .txt→text and .epub→epub type inference
- Add .png/.jpg/.jpeg/.webp→image inference
- Remove misleading test that only asserted nil
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:07:30 +08:00
wangdl
2fa459d9ea
test: add MaterialPathResolver unit tests (IOS-INFO-033)
...
- 7 tests covering resolve and materialType inference
- resolve nil for nonexistent file
- resolve finds file in Documents directory
- resolve finds file in Caches directory
- type inference: .md→markdown, .pdf→pdf
- unknown apiType defaults to .unknown
- temp file creation + cleanup in test
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:04:37 +08:00
wangdl
335859df0e
test: remove redundant singleton test in MarkedReadStore tests
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:04:03 +08:00
wangdl
cdc5c10076
test: add MarkedReadStore unit tests (IOS-INFO-032)
...
- 10 tests covering MarkedReadStore full API
- contains: unmarked=false, after-mark=true, after-unmark=false
- mark: persists to UserDefaults, idempotent, multiple IDs
- unmark: removes from persisted array, nonexistent safe
- Persistence: survives re-init (UserDefaults-backed)
- Edge case: empty string as materialId
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:00:26 +08:00
wangdl
3abe17a84e
test: add queue UUID path coverage in LocalQueueTests
...
- Add test_markRetry_works_with_queue_item_id (uses queue UUID not eventId)
- Update test_markDead_after_max_retries to use queue item id from batch
- Fixes review finding: tests previously only used eventId, not queue UUID
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-15 21:58:04 +08:00
wangdl
4ba747af46
feat: iOS learning info P0 complete (IOS-INFO-000~017, 038~039)
...
Models: ReadingMaterialContext, ReadingEventUploadItem, AppContext
Runtime: ReadingRuntimeAdapter, SessionManager, RecoveryService
Reader: MaterialReaderView lifecycle, Heartbeat Timer, Position Adapter
Export: EventMapper, UploadQueue, export→queue→ack flow
Tests: 16 test files covering models, runtime, lifecycle, upload
Docs: ios-learning-info-architecture.md
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-15 21:53:36 +08:00
7066200b7b
feat: MVVM 架构、全套 UI 页面、浅深色主题、本地持久化、等待名单、AI 动效
...
- 架构层:ViewModel/ObservableObject、Service/Repository、网络层 APIClient/APIEndpoint/APIError
- 设计系统:Color(light:dark:) 自适应 28 色 Token、ColorSchemeManager 深浅色切换
- 全页面:AI 对话/反馈/回忆/薄弱点、知识库 CRUD、学习工作台、复习计划、学习分析、个人中心/设置
- 登录与引导:Sign in with Apple、AppSession 状态管理、引导流程、演示模式
- 本地持久化:FileCache + PersistenceController(学习任务/复习任务/学习记录)
- 本地化:zh-Hans Localizable.strings ~120 条、ZXStrings 程序化引用、LanguageManager
- 组件库:ZXTabBar/ZXBackHeader/ZXSTaskRow/ZXChartView/ZXTypingIndicator 等 22 个共享组件
- 等待名单:WaitlistView 邮箱收集表单
- 动效:ZXTypingIndicator AI 打字动画、ZXShimmerModifier 骨架屏
- 测试:StudyHomeViewModel/AIChatViewModel/ReviewPlanViewModel/FileCache 共 28 条
- Dynamic Type 支持 + 范围限制
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 22:22:50 +08:00