169 Commits

Author SHA1 Message Date
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
5a7ee670af feat: global API request/response logging in APIClient
Every API call now logs: method, path, statusCode, response preview.
Network errors caught and logged before re-throwing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 12:22:35 +08:00
wangdl
78d2c93b41 debug: add request logging to APIClient
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 12:14:10 +08:00
wangdl
4dea11a48b fix: use errorDescription instead of message in APIError log
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 12:13:34 +08:00
wangdl
53442c5a34 debug: add APIError detail logging to flush
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 11:57:25 +08:00
wangdl
8facd35e9e debug: add detailed network error logging to upload flush
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 11:55:26 +08:00
wangdl
88babf14f8 fix: prioritize filename extension in materialTypeFromMime for .md files
.md files are uploaded as text/plain mime, causing materialTypeFromMime
to return .text instead of .markdown. Extension now checked first.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 11:40:22 +08:00
wangdl
4059f0197e fix(IOS-INFO-043): set vm.filePath after COS download + cleanup
- MaterialReaderViewModel.filePath: let → var for runtime updates
- Set vm.filePath to downloaded temp path before vm.load()
- Remove unused downloadedFilePath/resolvedPath

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 11:37:38 +08:00
wangdl
915d5e3fe2 fix(IOS-INFO-043): change source list nav to MaterialReaderView + add COS download
- LibraryDetailPage source list: Route.materialDetail → Route.materialReader
- KnowledgeSource: add fileId field for COS download
- MaterialReaderView: add COS download fallback in .task
- MaterialReaderView: add resolvedPath for downloaded file

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 11:34:21 +08:00
wangdl
f25538cf5a fix(IOS-INFO-043): add parse progress overlay to MaterialReaderView
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 11:30:19 +08:00
wangdl
042256913e fix(IOS-INFO-043): move triggerParse inside MaterialReaderView struct
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 11:30:08 +08:00
wangdl
123efb1612 feat(IOS-INFO-043): add 详情 and 整理知识点 toolbar buttons to MaterialReaderView
- MaterialReaderView: add info.circle button → MaterialDetailView
- MaterialReaderView: add brain button → trigger parse API + status polling
- MaterialReaderView: add triggerParse() with 2s poll loop
- KnowledgeSourceService: add parse() method (POST /sources/:id/parse)
- ImportStatusResponse: add jobId, progress fields
- ParseResponse: new model for parse trigger response

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 11:26:13 +08:00
wangdl
fbf359ffe9 feat(IOS-INFO-043): trim MaterialDetailView + add toolbar to MaterialReaderView
- MaterialDetailView: remove 阅读原文件, 问这份资料, 开始学习 buttons
- MaterialReaderView: add 开始学习 toolbar button
- MaterialDetailView now serves as info page accessible from reader

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 11:21:43 +08:00
wangdl
bee1f2ac33 fix(IOS-INFO-042): KnowledgeDetailPage toolbar - remove edit/AI/review
KnowledgeItem is AI-generated artifact, should be read-only.
Removes: AI对话, 学习, 编辑, 加入复习, 收藏 from toolbar Menu.
Keeps: 笔记, 预览 (reading functions).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-19 11:20:04 +08:00
wangdl
a698c383bb chore: remove .bak file 2026-06-18 22:34:36 +08:00
wangdl
7c9d8e41a6 revert: undo ImportPage kbId parameter (user clicked wrong KB)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 22:34:29 +08:00
wangdl
c0b7dda8c6 debug: add logging to LibraryDetailPage loadSources + appear
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 22:32:40 +08:00
wangdl
c5ce70fa5a fix(IOS-INFO-040): ImportPage now creates KnowledgeSource via add API
- Use uploadDataWithKey to get fileId + objectKey
- Call KnowledgeSourceService.add() instead of DocumentImportService.create()
- Creates both KnowledgeSource and DocumentImport in one call
- Add missing fields to AddSourceRequest and KnowledgeSourceService.add()

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 22:30:36 +08:00
wangdl
488db840cb debug(IOS-INFO-041): add print logging to ImportPage handleFiles
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 22:24:15 +08:00
wangdl
f7d10f3f44 fix(IOS-INFO-041): load KB info on appear + fix initial loading state
- Set isLoadingSources = true initially to show spinner
- Load KnowledgeBase detail in appear() for header
- Prevents blank screen before data loads

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 22:09:47 +08:00
wangdl
5008e491a9 refactor(IOS-INFO-041): change default tab to sources + load on appear
- Set detailTab default to 1 (sources view)
- Load sources on appear via .task
- Refreshable reloads sources

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 22:05:51 +08:00
wangdl
4b3ef77342 fix(IOS-INFO-040): replace "添加知识点" with "上传资料" in toolbar
Knowledge items are AI-generated artifacts from source parsing, not
manually created entries. Route to ImportPage instead of AddKnowledgePage.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 21:57:26 +08:00
wangdl
bb9c9afb4d fix: make source items tappable in 资料来源 tab
Wraps each KnowledgeSource row in NavigationLink to MaterialDetailView.
Previously sources were display-only with no tap action.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 21:27:10 +08:00
wangdl
1c0a625192 feat: add "阅读原文件" button to KnowledgeDetailPage
Blue gradient button at bottom of plain text content view.
Writes content to temp .md file and navigates to MaterialReaderView,
which triggers reading event collection.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 21:19:05 +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
d28dba29fc fix: AuthManager has no currentUserId, use KeychainHelper.getUserId()
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 17:03:38 +08:00
wangdl
0cf727899a fix: add getLearningRecords adapter for cursor param mismatch
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 17:00:03 +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
b0df8ee58e feat: add en/ja localization support (IOS-INFO-037)
Some checks failed
iOS CI/CD / Build & Test (push) Has been cancelled
- en.lproj/Localizable.strings: English translations
- ja.lproj/Localizable.strings: Japanese translations
- Covers common, navigation, reader, progress, analysis, study, AI

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 14:26:24 +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
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
82bcbb9efb feat: iOS 学习功能增强 - 阅读API、材料阅读器、分析、学习首页
- ReadingAPI: 阅读进度同步
- MaterialPathResolver: 材料路径解析
- MarkedReadStore: 已读标记存储
- MaterialReaderView/DetailView/ReadingPositionAdapter: 阅读器增强
- AnalysisHomeView/ActivityViewModel: 分析首页
- StudyHomeView/StudyHomeViewModel: 学习首页
- LibrarySubpages: 图书馆子页面

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 11:22:26 +08:00
wangdl
12b73b7445 fix: extend APIError.statusCode to cover all cases
- unauthorized → 401
- serverError → extract code string as Int
- networkError → NSError.code

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-15 21:56:36 +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
wangdl
f421fbb721 fix: G1 context registry — prevent empty contexts from dropping all export events
- Add ReadingContextRegistry for SessionManager→Pipeline context sharing
- Wire registry into SessionManager (register on open, unregister on close)
- Fix Pipeline to auto-pull from registry when contexts not provided
- Fix ScenePhase to not pass empty contexts

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 22:08:03 +08:00
wangdl
51b9365ece feat: M-IOS-INFO Batch D-F complete (38/38)
Batch D: MarkedAsRead UI, reading progress query, position restore, continue learning, source reading status
Batch E: NetworkMonitor, summary/trend/heatmap alignment, learning records, error handling, background upload, debug/logging
Batch F: Test stubs, iOS integration doc
Batch G: V2 FFI/MarkedAsRead/export-ack coverage verification

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 21:26:03 +08:00
wangdl
80c1d660cd feat: #80 标记已读 UI + 乐观更新
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 20:49:41 +08:00
wangdl
697220de00 fix: APIConfig baseURL longde.cloud → api.longde.cloud
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 20:39:57 +08:00
wangdl
a6dde9f0c6 feat: M-IOS-INFO V2 reading event system + iOS 26 build fixes
- Add zx_documentFFI bridging header + modulemap
- Update zx_document.swift (patched for static linking + iOS 26 SDK)
- Replace XCFramework with V2 symbols
- Add V2 types: ReadingMaterialContext, ReadingEventUploadItem, ReadingRuntimeAdapter
- Add V2 session manager: ReadingRuntimeSessionManager
- Add V2 position adapter: ReadingPositionAdapter
- Add V2 event mapper: ReadingEventMapper
- Add upload queue + pipeline: ReadingEventUploadQueue
- Add reading API client: ReadingAPI
- Fix QuickNoteSheet for new NoteAnchor fields (positionSnapshot)
- Restore MaterialReaderView lifecycle events (onAppear/onDisappear)
- Add ScenePhase handling for app background/foreground

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 19:58:57 +08:00
wangdl
5fe29a7d8c feat: #24 公开库发现 + 订阅管理
- KnowledgeBaseService 新增 discover/subscribe/unsubscribe API
- DiscoverView: 浏览公开库 + 订阅/取消订阅
- Route.discoverPublic + ProfileView 入口

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:36:34 +08:00
wangdl
9e1a8982a3 fix: 修复 LibrarySubpages 多余 } 导致的编译错误 2026-06-06 19:33:03 +08:00
wangdl
c428a57d0d fix: #23 知识点详情增加来源信息 + 加入复习 + 收藏
- 内容区显示来源类型标签 (PDF/Word/Markdown等)
- 菜单新增「加入复习」(POST /reviews/generate-cards)
- 菜单新增「收藏/取消收藏」

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:28:04 +08:00
wangdl
1f75170b98 feat: #22 知识库分类管理页面
- KnowledgeFolder 模型 + CreateFolderRequest
- KnowledgeFolderService (list/create/update/delete)
- FolderManageView: 列表 + 新建/重命名/删除
- LibraryDetailPage 菜单「分类管理」入口

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:26:00 +08:00
wangdl
d9828bc3c8 fix: #34 #35 移除 contentHeightEstimate 80px 硬编码
- actualContentHeight 通过 GeometryReader 获取真实内容高度
- scrollProgress 使用实际高度计算,精度显著提升
- #36 ReadingEventCollector 已清理完毕(无 ObservableObject/Combine)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:22:08 +08:00
wangdl
5af29af549 fix: #21 设置页补全通知/存储/账号分组
- 通知: 复习提醒 + 导入完成 + 系统通知
- 数据与存储: 存储空间入口 + iCloud
- 账号: 个人资料 + 登录设备管理

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:19:31 +08:00
wangdl
695518b276 fix: #16 sortOption 接入后端排序 API
- KnowledgeItemService.list 加 sortBy/order 参数
- loadItems/refresh/loadMore 加 sortBy/order 参数
- sortOption onChange 触发重新加载
- sortParams 映射函数: 0→默认, 1→fileSize, 2→createdAt, 3→updatedAt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:07:33 +08:00
wangdl
99dc2807be feat: AIChat 全链路调试日志 + 错误详情展示
load/createSession/loadSession/send 都加了 print 日志:
- scope 参数
- 请求成功/失败状态
- 具体错误信息

sessionError 现在显示具体错误原因而非通用"创建对话失败"

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 18:19:30 +08:00
wangdl
9d0f426118 revert: 恢复 AddKnowledgePage 标签改动
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 18:15:51 +08:00
wangdl
4029da9c44 fix: DEBUG 调试标签放大 + 点击复制页面名
字号 9→13,padding 加大,背景加深,去掉 allowsHitTesting,点击复制 label

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 18:14:43 +08:00