26 KiB
Raw Blame History

01 文档阅读 — 跨项目完整能力分析

试点能力一:从 C 端业务能力"文档阅读"出发,跨项目完整整理。 项目角色分类主链路iOS、Rust Document Runtime、主 API、数据库/COS、上游支撑Python RAG、下游消费Heavy Runtime、运维可观测Admin


1. 能力目标

用户能够在知习 App 中流畅地阅读上传到知识库的学习资料,支持多种文件格式,自动记录阅读位置,标记已读状态,并在下次打开时从上次中断处继续阅读。


2. C 端入口

用户可以从以下 iOS 页面进入文档阅读:

入口页面 触发方式 进入场景
学习主页 点击主操作卡片("继续上次学习" 继续上次未读完的资料
知识库详情页·来源 Tab 点击来源文件条目 阅读知识库中的资料
知识点详情页 点击"阅读原文件"或自动渲染 阅读知识点关联的原始资料
学习分析页 点击"继续阅读"卡片 从分析页继续阅读
AI 反馈页 "加入待巩固" → 学习主页 → 资料阅读 间接进入

在资料阅读页中,用户可以执行以下操作:

  • 阅读内容(滚动浏览,支持 Markdown/纯文本/图片/EPUB 的原生渲染)
  • 系统预览 PDF、Word、Excel通过 QuickLook
  • 外部打开 PowerPoint通过 ShareLink
  • 标记已读本地即时生效marked_as_read 事件异步上报)
  • 取消标记已读(本地即时生效,服务端同步方式暂未确认)
  • 打开 AI 对话(资料范围,需 RAG 已完成向量化才能获得语义检索结果)
  • 查看资料详情元数据、AI 处理状态、阅读进度)
  • 开始专注学习会话(主动计时)
  • 添加笔记(自动记录锚点位置)

3. 用户主流程

以下使用纯业务语言描述用户从进入资料到退出阅读的完整流程:

  1. 进入资料: 用户从知识库来源文件列表、继续学习推荐或知识点详情中点击资料,进入资料阅读页。

  2. 资料加载: App 检查设备上是否已有该文件。

    • 如果有本地文件:直接打开。
    • 如果没有:从云端 COS 下载文件到本地缓存目录。
    • 只要资料记录存在、用户有访问权限且 COS/本地文件可用,用户即可阅读原文件,不需要等待 Python RAG 的文本解析、分块、向量化和索引完成。
  3. 类型检测与渲染: 系统检测文件类型,根据类型选择渲染方式。

    • Markdown/文本/图片/EPUB由 Rust Document Runtime 解析并渲染为可读内容。
    • PDF/Word/Excel提供"系统预览"按钮,用户点击后使用 iOS QuickLook 预览。
    • PowerPoint提供"外部打开"按钮,用户点击后使用系统分享功能在外部应用打开。
    • 不支持的格式:显示"暂不支持此格式"提示。
  4. 自动阅读会话启动: 用户进入资料阅读页时系统自动创建阅读会话无需用户手动操作。iOS 调用 Rust Document Runtime 开启 V2 ReadingSession生成唯一的 client_session_id。该会话自动推送 material_opened 事件。

  5. 阅读位置恢复: 系统按优先级恢复上次阅读位置。

    • 优先:从服务端 API 查询该资料的阅读进度(上次位置)。
    • 其次:从本地缓存读取上次位置。
    • 最后:从当前 Rust 阅读会话的 lastPosition 恢复。
  6. 阅读中: 用户滚动浏览内容。

    • 系统自动记录阅读位置2 秒防抖iOS 调用 Rust push_position_changed
    • iOS 创建并管理 15 秒心跳定时器,仅在阅读会话为 active 且 App 位于前台时触发。每次 Tick 调用 Rust heartbeat 接口Rust 根据 ActiveTimeTracker 计算 activeSecondsDelta 后创建 heartbeat 事件并写入缓冲区。
    • Rust 不创建也不管理 iOS 的系统定时器。
  7. 前后台切换: 用户将 App 切到后台时iOS 暂停心跳定时器,阅读会话自动暂停,时间跟踪停止。切回前台时自动恢复。

  8. 标记已读: 用户点击工具栏"标记已读"按钮。该操作在本地 UserDefaults 立即更新,同时推送 marked_as_read 事件到 Rust 缓冲区,后续通过上传链路同步至服务端。取消标记已读可在本地即时生效,但服务端同步方式暂未确认(当前事件模型只有 marked_as_read没有 unmarked_as_read

  9. 添加笔记: 用户点击工具栏笔记按钮,弹出快速笔记 Sheet。系统自动捕获当前阅读位置作为笔记锚点。用户输入笔记文字并保存本地 UserDefaults 存储)。

  10. AI 对话(资料范围): 用户点击工具栏 AI 按钮,跳转到 AI 对话页。对话自动限定在当前资料范围内。如果 Python RAG 已完成该资料的向量化索引AI 可通过语义检索引用资料内容回答用户问题;如果 RAG 未完成AI 范围对话、语义检索和知识点候选提取可能暂不可用。

  11. 开始专注学习会话: 用户点击工具栏"开始学习"按钮,启动专注学习计时器。计时器以 1 秒精度运行,默认目标 30 分钟。该学习会话是用户主动发起的专注时段,与进入资料时自动创建的阅读会话是不同的业务对象。

  12. 退出阅读: 用户返回上一页或切换到其他 Tab。

    • iOS 调用 Rust close_reading_sessionRust 计算最终活跃时长增量,推送 material_closed 事件。
    • 阅读位置保存到本地缓存。
    • iOS 周期性地从 Rust 导出已缓冲事件,写入本地持久化上传队列,后续由队列负责 API 上传。

4. 项目参与关系

iOSAIStudyApp— 主链路参与者

职责:

  • 提供资料阅读页的用户界面
  • 调用 Rust Document Runtime通过 UniFFI FFI进行文件解析
  • 管理 COS 文件下载和本地文件缓存
  • 驱动自动阅读会话生命周期(调用 Rust V2 Session API
  • 创建并管理 15 秒心跳定时器(仅在 session active 且前台时触发)
  • 驱动阅读事件采集(调用 Rust push 函数 + heartbeat 接口)
  • 管理本地上传队列:将 Rust 导出事件映射为 UploadItem、写入持久化队列、确认 Rust 交接完成
  • 管理阅读位置本地缓存
  • 提供系统预览和外部打开能力
  • 提供笔记创建界面和本地存储
  • 提供标记已读本地缓存
  • 前台/后台切换时管理会话暂停/恢复和心跳定时器启停
  • App 被杀死后重启时执行崩溃恢复

Rust Document Runtimezhixi-document-runtime— 主链路参与者

职责:

  • 检测文件类型(根据扩展名和文件内容推断 MaterialType
  • 解析 Markdown 为结构化文档块树
  • 解析纯文本为段落块
  • 提取 EPUB 章节结构和元数据
  • 提取 PDF 页数和基本文本(用于搜索)
  • 提取图片元数据
  • 管理自动阅读会话V2 ReadingSessionstart、pause、resume、close、interrupt
  • 管理阅读事件缓冲区push、export、ack、reload
  • 根据 ActiveTimeTracker 计算 activeSecondsDelta由 iOS heartbeat tick 触发)
  • 提供阅读位置模型
  • 提供文件搜索能力
  • 提供笔记锚点模型
  • 提供活跃时间跟踪器
  • 提供崩溃恢复机制stale event reload、stale session cleanup

不负责: 网络请求、COS 下载、API 调用、用户认证、UI 渲染、Office 文件高清预览、PDF 完整渲染、iOS 系统定时器创建和管理。

主 APIapi-server— 主链路参与者

职责:

  • 提供资料信息查询
  • 提供文件下载 URLCOS 预签名 URL
  • 提供资料阅读进度查询
  • 接收并处理阅读事件批量上传
  • 将原始阅读事件聚合为自动阅读会话LearningSession、资料阅读进度、每日学习活动、学习记录
  • 提供文件上传 URL
  • 管理知识源的三个处理状态parseStatus、indexStatus、learningStatus
  • 提供继续学习推荐
  • 提供学习摘要
  • 提供阅读趋势

Python RAG Worker — 上游支撑

不直接参与文档阅读。 只要资料记录、文件访问权限和 COS/本地文件可用用户即可阅读原文件。Python RAG 负责文档导入后的异步处理(下载上传的文件 → 解析文本内容 → 分块 → 向量化嵌入 → 存入 Qdrant → AI 提取候选知识点。RAG 未完成时,阅读原文件不受影响,但资料范围 AI 问答的语义检索和知识点候选提取可能暂不可用。

Heavy Runtime — 下游数据消费者

不直接参与文档阅读。 消费已聚合的阅读数据,生成 AI 分析结果(掌握度评估、薄弱点识别、学习建议、测验题目、闪卡)。位于阅读数据采集链的下游,不属于用户阅读时的同步调用链。

Adminadmin-projects— 运维与可观测

不属于用户阅读时的同步调用链。 职责包括:

  • 知识库来源文件列表查看
  • 来源文件详情查看(含解析状态、索引状态)
  • 文件管理(查看、删除上传文件)
  • 资料阅读进度查看
  • 资料诊断
  • 文档导入监控与重试

5. 项目间调用关系

5.1 iOS → Rust Document Runtime

调用目的 调用方向 业务结果
检测文件类型 iOS → Rust 返回 MaterialType 和 PreviewMode 建议
解析 Markdown/文本文件 iOS → Rust 返回 DocumentBlock 数组
提取 EPUB/PDF/图片信息 iOS → Rust 返回对应元数据
搜索文档内容 iOS → Rust 返回 SearchResult 列表
开启自动阅读会话 iOS → Rust 创建 V2 ReadingSession返回 client_session_id
推送阅读事件 iOS → Rust 事件进入内存缓冲区Pending 状态)
心跳 Tick iOS → Rust Rust 计算 activeSecondsDelta创建 heartbeat 事件写入缓冲区
导出待交接事件 iOS → Rust 返回 Exported 状态的事件列表,交接给 iOS
确认事件交接完成 iOS → Rust 已 Ack 的事件从 Rust 缓冲区移除(交接给 iOS 本地队列后立即调用)
崩溃恢复 iOS → Rust Exported 未 Ack 事件重置为 Pending
清理过期会话 iOS → Rust 超时会话标记为 Interrupted 并从内存移除

5.2 iOS → 主 API

调用目的 调用方向 业务结果
获取文件下载 URL iOS → API 返回 COS 预签名下载链接
查询阅读进度 iOS → API 返回上次阅读位置、累计阅读时长、是否已读
上传阅读事件批次 iOS → API 从 iOS 本地持久化队列发起,返回 processed/duplicate/failed 计数
查询继续学习 iOS → API 返回最近阅读的资料信息
查询学习摘要/趋势 iOS → API 返回聚合数据
查询资料信息 iOS → API 返回知识源详情

5.3 主 API 内部调用

调用目的 调用方向 业务结果
阅读事件处理 API 内部(同步事务) 事件入库 → 聚合自动阅读会话 → 聚合阅读进度 → 聚合每日活动 → 创建学习记录
资料解析触发 API → Redis 队列 将资料加入 document-import 队列,由 Python RAG Worker 异步处理(不阻塞阅读)

5.4 Admin → 主 API运维可观测非同步调用链

调用目的 调用方向 业务结果
查看知识库来源文件 Admin → API 返回来源文件列表(含解析和索引状态)
查看/删除文件 Admin → API 文件管理
查看资料阅读进度 Admin → API 阅读进度详情
资料诊断 Admin → API 全部阅读数据和关联会话
文档导入监控/重试 Admin → API 导入任务列表、重试失败任务

6. 核心业务数据

6.1 资料Material / KnowledgeSource

  • 谁创建: iOS 用户在导入资料页或添加知识点页上传文件后API 创建 KnowledgeSource 记录。
  • 谁更新: Python RAG Worker 更新解析状态和索引状态异步不阻塞阅读API 在处理阅读事件时更新关联的阅读状态。
  • 谁查询: iOS 在知识库详情页来源 Tab 查询列表、在资料详情页查询详情Admin 在来源文件页查询列表。
  • 用于什么功能: 知识库内容组织、文档阅读入口、资料处理状态展示。

6.2 阅读位置ReadingPosition

  • 谁创建: Rust Document Runtime 在 iOS 推送 position_changed 事件时创建。
  • 谁更新: 每次用户滚动时更新2 秒防抖),由 Rust Document Runtime 维护 last_position。
  • 谁查询: iOS 在进入阅读页时恢复上次位置(优先 API、其次本地缓存、最后会话位置API 在阅读进度查询时返回。
  • 用于什么功能: 跨会话的阅读位置恢复、"继续学习"推荐。

6.3 自动阅读会话ReadingSessionRust V2

  • 谁创建: Rust Document Runtime 在 iOS 调用 start_reading_session 时创建(用户进入资料阅读页时自动触发,无需用户手动操作)。
  • 谁更新: Rust 在每次事件推送时更新内存中的会话状态lastEventAt、totalActiveSeconds、lastPosition
  • 谁查询: iOS 在恢复会话时查询 lastPosition 用于位置恢复。
  • 用于什么功能: 自动追踪单次阅读行为的持续时长和事件序号管理阅读会话生命周期active→paused→closed。产生 opened、closed、position_changed、heartbeat、marked_as_read 事件。

6.4 专注学习会话LearningSessionView 计时)

  • 谁创建: 用户主动点击资料阅读页工具栏"开始学习"按钮后iOS 创建本地计时器。
  • 谁更新: 用户操作暂停/继续/结束(含确认弹窗),计时器以 1 秒精度运行,默认目标 30 分钟。
  • 谁查询: iOS 学习会话页展示当前进度。
  • 用于什么功能: 用户主动发起的专注学习时段计时。与自动阅读会话ReadingSession是不同的业务对象。 当前 iOS 是否调用专注学习会话 APILearningSessionService持久化仍标记为"暂未确认"。

6.5 阅读事件ReadingEvent

  • 谁创建: Rust Document Runtime 创建5 种事件类型material_opened、material_closed、position_changed、heartbeat、marked_as_read
  • 谁更新: 事件创建后不可修改。API 更新其处理状态processing → processed/failed/duplicate
  • 谁查询: API 在批处理时查重Admin 在阅读事件列表和异常检测页查询。
  • 用于什么功能: 所有学习分析的原始数据源。API 根据事件聚合自动阅读会话、阅读进度、每日活动、学习记录。

6.6 资料阅读进度MaterialReadingProgress

  • 谁创建: API 在收到该资料的第一个阅读事件时自动创建。
  • 谁更新: API 在每次事件处理事务中 upsert递增总时长、更新最后位置、更新会话数、标记已读状态
  • 谁查询: iOS 在进入阅读页时查询恢复位置Admin 在阅读进度页查询。
  • 用于什么功能: 资料级别的阅读进度追踪、"继续学习"推荐的数据源、阅读统计。

6.7 笔记QuickNote

  • 谁创建: iOS 用户在快速笔记 Sheet 中输入并保存时创建。
  • 谁更新: 当前不支持修改(仅创建和删除)。
  • 谁查询: iOS 在资料阅读页和知识点详情页查询(本地 UserDefaults
  • 用于什么功能: 阅读过程中的快速记录。当前仅本地存储,未同步到服务端。

7. 查询入口

用户在哪里查看

  • 阅读内容: iOS 资料阅读页直接渲染文档内容。
  • 阅读进度: iOS 资料详情页的阅读进度卡片(累计时长、阅读状态、上次阅读时间)。
  • 资料信息: iOS 资料详情页文件名、格式、大小、上传日期、AI 处理状态)。
  • 来源文件列表: iOS 知识库详情页的来源 Tab。
  • 继续阅读: iOS 学习主页的主操作卡片(继续上次学习)。

Admin 在哪里查看(运维可观测)

  • 来源文件列表: Admin 知识库→来源文件页(含解析状态、索引状态)。
  • 文件管理: Admin 文件与 COS 管理页(按类型筛选、查看详情、删除)。
  • 阅读进度: Admin 学习数据→阅读进度页(按用户/资料查看进度)。
  • 资料诊断: Admin 学习数据→资料诊断页。
  • 导入监控: Admin 知识库→文档导入监控页(任务状态、步骤日志、重试)。

系统内部在哪里使用

  • 继续学习推荐: API GET /learning/continue → iOS 学习主页优先级算法。
  • 学习摘要: API GET /learning/summary → iOS 分析页 + 学习主页每周摘要。
  • 阅读趋势: API GET /learning/trend → iOS 分析页阅读时长趋势图。
  • 学习记录: API GET /learning/records → iOS 分析页最近学习记录。
  • 资料范围 AI 问答: API 在 RAG 对话中根据资料范围检索相关 Chunk依赖 Python RAG 的向量化结果RAG 未完成时不可用)。

8. 修改入口

用户主动修改

  • 标记已读: iOS 资料阅读页工具栏按钮。本地 MarkedReadStore 即时生效marked_as_read 事件通过事件采集链路上报。服务端同步已完成。
  • 取消标记已读: 本地 MarkedReadStore 即时生效。服务端同步方式暂未确认(当前事件模型无 unmarked_as_read 事件类型)。
  • 添加笔记: iOS 快速笔记 Sheet本地 UserDefaults 存储)。
  • 删除来源文件: iOS 知识库详情页来源 Tab 滑动删除API 软删除)。
  • 开始/结束专注学习会话: iOS 资料阅读页工具栏学习按钮 / 学习会话页结束按钮。
  • 上传新资料: iOS 导入资料页(文件/相册/链接)。

Admin 人工修改(运维可观测)

  • 删除文件: Admin 文件管理页删除上传文件。
  • 重试导入: Admin 文档导入监控页重试失败任务。
  • 重新解析: Admin 可触发知识源的重新解析。

系统自动修改

  • 阅读位置更新: iOS 2 秒防抖自动调用 Rust push_position_changed。
  • 心跳: iOS 15 秒定时器 Tick → 调用 Rust heartbeat 接口 → Rust 计算 activeSecondsDelta 并创建事件。
  • 阅读会话状态切换: iOS 前后台切换时自动暂停/恢复 Rust ReadingSession同步控制心跳定时器。
  • 阅读进度聚合: API 在每次事件处理事务中自动更新 MaterialReadingProgress。
  • 会话中断检测: API 在事件处理前自动清理 30 分钟无新事件的活跃会话(标记为 interrupted
  • 解析状态更新: Python RAG Worker 异步更新 KnowledgeSource 的 parseStatus不阻塞阅读
  • 文件过期处理: API 自动检测临时资料是否过期。

系统配置修改

  • 文件大小限制: API 配置(待确认具体配置入口)。
  • COS 预签名 URL 有效期: API 文件上传服务配置。
  • 解析触发轮询间隔: iOS 端硬编码60×2s非配置化。

9. 异常与恢复

9.1 文件加载失败

  • 场景: 本地文件不存在或 COS 下载失败。
  • iOS 处理: 资料阅读页进入错误状态,显示错误提示和重试按钮。自动尝试从 COS 重新下载。
  • API 处理: 文件下载 URL 返回 COS 预签名链接,含过期时间。过期后 iOS 需重新请求。

9.2 解析失败

  • 场景: 文件内容损坏、格式不支持、或解析器报错。
  • iOS 处理: 资料阅读页显示"暂不支持此格式"或错误提示。
  • API 处理: Python RAG Worker 解析失败时更新 DocumentImport 状态为 FAILED记录错误步骤。Admin 可查看步骤日志并重试。解析失败不影响用户阅读原文件。

9.3 网络中断

  • 场景: 阅读过程中网络断开。
  • iOS 处理: Rust Document Runtime 继续在本地采集事件事件缓冲区正常运行。iOS 本地持久化队列中的事件暂停上传NetworkMonitor 检测到网络恢复后自动触发队列 flush。阅读会话继续心跳和位置事件照常写入 Rust 缓冲区。

9.4 App 被关闭(强制杀死或系统回收)

  • 场景: 用户在阅读过程中 App 被系统杀死或用户强制关闭。
  • iOS 处理App 重新启动时):
    1. RuntimeRecoveryService.run() 执行崩溃恢复
    2. Rust reload_stale_events_v2所有 Exported 但未 Ack 的事件重置为 Pending处理 export 后、本地写入前崩溃的场景)
    3. Rust cleanup_stale_sessions_v2清理超过 24 小时的非活跃会话
    4. iOS 本地队列 reloadOnLaunch重新从 Rust 导出事件、映射为 UploadItem、写入持久化队列、立即 Ack。已持久化但未上传的队列条目继续上传。
    5. 服务器端API 在下次处理事件前,清理超过 30 分钟的活跃会话(标记为 interrupted

9.5 Export/Ack 链路中的三种崩溃场景

  • export 后、本地写入前崩溃: Rust reload_stale_events_v2 将 Exported 事件重置为 Pending下次启动重新导出。
  • 本地写入成功、Ack 前崩溃: 重新启动后重新导出API 端通过 eventId 去重已在队列中的重复事件不会产生重复数据iOS 再调用 Ack 完成交接。
  • Ack 后、API 上传前崩溃: 事件已从 Rust 缓冲区安全交接至 iOS 本地持久化队列。重启后本地队列继续上传Rust 不需要再参与。

9.6 阅读位置恢复失败

  • 场景: API 未返回阅读进度(首次打开)或本地缓存丢失。
  • iOS 处理: 三级回退——API 位置 → 本地缓存位置 → Rust 会话位置 → 从头开始。

9.7 事件上传失败

  • 场景: 上传请求返回错误或超时。上传完全由 iOS 本地持久化队列负责,失败时不再调用 Rust markFailed。
  • iOS 本地队列处理:
    • 401 错误:暂停队列(保留 pending 状态),等待 Token 刷新
    • 403/404 错误标记条目为永久失败dead
    • 其他错误:标记条目为 failed进入指数退避重试5s × 2^n最多 3 次,最长 5 分钟)
    • 重试次数耗尽:条目进入 dead 状态,不再重试
  • API 处理:
    • 重复事件(相同 userId + eventId标记为 duplicate返回已处理
    • 验证失败(无效类型/超限/无权限):标记为 failed返回错误码
    • 材料不存在:标记为 failed

9.8 资料被删除或失去权限

  • 场景: 用户正在阅读的资料被管理员删除或用户失去访问权限。
  • API 处理: 事件处理时校验材料存在性、归属性和状态。不存在的材料标记事件为 failed无权限的标记为 failed已过期的临时材料标记为 failed。
  • iOS 处理: 当前的阅读会话仍可继续(本地文件未被删除),但后续事件上传将被拒绝。

10. 当前完成情况

统一使用以下口径:

  • 已完成: 跨项目链路已接通,用户可以获得最终结果。
  • 部分完成: 只有部分项目、部分页面或部分场景完成。
  • 占位实现: 存在结构,但使用 Mock、硬编码或静态数据。
  • 暂未确认: 无法确认完整调用链。
组件 状态 说明
iOS 多格式渲染Markdown/文本/图片/EPUB 已完成 Rust FFI 解析 + SwiftUI 渲染
iOS 系统预览PDF/Word/Excel/PPT 已完成 QuickLook + ShareLink
iOS 阅读位置记录与恢复 已完成 三级优先级API→本地→会话
iOS 标记已读(服务端同步) 已完成 本地 UserDefaults + marked_as_read 事件上报链路已接通
iOS 取消标记已读(服务端同步) 暂未确认 本地即时生效,但当前事件模型无 unmarked_as_readAPI 是否支持待确认
iOS 自动阅读会话管理 已完成 Rust V2 ReadingSession含前后台自动切换
iOS 专注学习会话计时 暂未确认 本地计时已完成API 持久化调用待确认
iOS 快速笔记 已完成 锚点记录,本地 UserDefaults 存储
iOS 15 秒心跳定时器 已完成 iOS 创建 Timer仅在 session active 且前台时触发
Rust Document Runtime 文件解析 已完成 9 种 MaterialType 检测 + Markdown/文本/EPUB/图片/PDF 基础解析
Rust Document Runtime V2 自动阅读会话 已完成 完整生命周期 + 5 种事件类型 + 缓冲区管理
Rust 活跃时间跟踪器 已完成 ActiveTimeTracker由 iOS heartbeat tick 驱动
Rust 崩溃恢复 已完成 stale event reload + stale session cleanup
Rust → iOS 事件交接链路 已完成 export → 本地队列写入 → Ack交接在本地完成不依赖网络
iOS 本地上传队列 已完成 JSON 持久化,独立于 Rust 缓冲区的网络上传队列
iOS 上传重试与网络恢复 已完成 指数退避重试 + NetworkMonitor 自动恢复
API 文件上传与下载 已完成 COS 预签名 URL 流程
API 阅读事件处理管线 已完成 去重→验证→事件入库→自动阅读会话聚合→进度聚合→每日活动→学习记录
API 阅读进度查询 已完成 GET /materials/:id/reading-progress
API 继续学习推荐 已完成 最近的未读完资料
Admin 来源文件查看 已完成 列表+筛选+解析状态(运维可观测)
Admin 资料诊断 已完成 material-diagnose 端点(运维可观测)
Admin 阅读进度查看 已完成 列表+详情(运维可观测)
原文件阅读(不依赖 RAG 已完成 只要资料记录+权限+COS/本地文件可用即可阅读
资料范围 AI 问答(依赖 RAG 部分完成 需 RAG 完成向量化后才可用RAG 未完成时语义检索不可用
iOS 解析触发轮询 部分完成 使用硬编码 60×2s 轮询,非事件驱动
笔记服务端同步 未完成 当前仅本地 UserDefaults 存储
Office 文件高清预览 暂未确认 Word/Excel/PPT 依赖系统预览或外部打开,无内置高清渲染