Files

152 lines
8.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 任务计划cc-web 使用统计看板
## 目标
在不改变现有聊天、会话列表、会话检索和消息发送行为的前提下,为 cc-web 增加一个可独立启停、只读、可回滚的使用统计看板。
## 当前阶段
已完成:功能、主题、回归、性能、浏览器与在线验收
## 实施阶段
### Phase 1边界与统计口径确认
- [x] 明确当前可可靠统计的数据
- [x] 明确当前不可可靠统计的数据
- [x] 定义“不影响现有功能”的不可变边界
- **状态:** complete
### Phase 2安全基线、只读统计核心与历史回填
- [x] 记录现有回归结果及消息发送、会话切换、检索的行为基线
- [x] 建立独立功能开关,`CC_WEB_USAGE_STATISTICS=0` 时不显示入口、不创建索引
- [x] 新增独立统计模块,读取保留期内的 `sessions/*.json`
- [x] 第一次打开看板时懒加载回填,不把 83.3 MB 扫描放进服务启动或消息处理链路
- [x] 将聚合结果写入独立索引文件,不回写任何会话 JSON
- [x] 索引就绪后通过防抖 save/delete 旁路钩子更新,钩子失败不进入主错误链路
- [x] 索引只保存统计事件、源文件指纹和会话元数据,可删除重建
- [x] 索引异常时返回看板错误,不阻塞聊天和会话持久化
- **状态:** complete
### Phase 3独立查询协议
- [x] 新增只读 `usage_stats_query/result/error` 协议
- [x] 响应携带稳定的 `schemaVersion=1`
- [x] 请求参数仅包含时间范围、时区和内部固定上限
- [x] 响应包含概览、趋势、MCP 明细、Skill 显式使用排行和会话明细
- [x] 不修改 `session_list``search_sessions``load_session` 等现有协议和负载结构
- [x] 增加排行/明细上限、频率限制和异常隔离
- **状态:** complete
### Phase 4独立看板工作区
- [x] 在侧栏固定 footer 增加独立“统计”入口
- [x] 看板使用自己的前端状态、DOM 根节点和样式命名空间
- [x] 顶部提供本周、本月、自定义时间和刷新
- [x] 展示可靠指标,不展示无法准确解释的“活跃会话”
- [x] MCP 支持明细窗口,会话行可返回对应会话
- [x] 关闭看板后恢复原聊天滚动、焦点和输入选区
- **状态:** complete
### Phase 5全部现有主题适配
- [x] 枚举 `THEME_OPTIONS` 中全部 11 个现有主题
- [x] 适配侧栏底部入口、概览、趋势、表格、空态、错误态和加载态
- [x] 主题差异只通过语义变量和主题限定选择器实现,没有复制业务 DOM 或 JS
- [x] 11 主题 × 5 视口完成真实浏览器几何验收
- [x] 检查 `prefers-reduced-motion`、文字对比度、日期图标和焦点可见性
- **状态:** complete
### Phase 6兼容性、性能与故障回归
- [x] 执行现有全量回归并记录结果
- [x] 增加统计协议、时间边界、失败状态、空数据、限额和隐私测试
- [x] 增加入口隔离、刷新、错误态和 reduced-motion 前端合同
- [x] 验证统计查询后会话加载、会话搜索及 `session_list` 均不受影响
- [x] 验证索引缓存复用、增量、删除、空文件和损坏文件隔离
- [x] 对当前 83.3 MB 会话数据完成性能验收
- **状态:** complete
### Phase 7灰度启用与回滚
- [x] 使用功能开关控制统计入口和统计查询服务
- [x] 当前环境已重启启用,用户已确认在线效果
- [x] 记录 CPU、内存、回填、查询耗时和索引比例
- [x] 回滚时可设 `CC_WEB_USAGE_STATISTICS=0`,不涉及会话数据迁移
- **状态:** complete
## 统计口径
| 指标 | 定义 | 时间归属 | 可靠性 |
|---|---|---|---|
| 新建会话 | `created` 落在时间范围内的会话数量,兼容 `createdAt` 历史兜底 | 会话创建时间 | 保留会话范围内高 |
| 发送消息 | 时间范围内当前仍被保留的用户消息数量 | 用户消息时间 | 保留数据范围内高 |
| 自动协作消息 | 非人工触发、由协作链路产生的消息数量 | 对应消息时间 | 先验证字段;无法稳定分类则首版不展示 |
| MCP 调用 | assistant message 中 `toolCalls` 的 MCP 调用条目数量 | 暂按所属 assistant 消息时间 | 中 |
| MCP 失败 | MCP 调用中 `status=failed` 的条目数量 | 暂按所属 assistant 消息时间 | 中 |
| Skill 显式使用 | 用户消息 `composerMentions` 中显式 `$skill` mention 数量 | 用户消息时间 | 保留数据范围内高 |
## 当前版本明确不做
- 不统计 Skill 文件被模型实际读取或执行的次数。
- 不将“活跃会话”作为指标。
- 不修改历史或未来的会话 JSON schema。
- 不把统计字段塞入 `session_list` 或会话列表负载。
- 不为统计而改造现有消息发送、会话检索或 MCP 执行链路。
- 不承诺历史 MCP 的精确调用时刻和耗时。
- 不在页面每次刷新时全量扫描所有会话 JSON。
## 核心架构决策
| 决策 | 理由 |
|---|---|
| 采用“历史回填 + 异步增量索引 + 独立查询” | 当前全量扫描可用但长期不适合每次看板请求执行 |
| 首版使用可重建的旁路索引,不引入数据库依赖 | 降低发布和 CentOS 单文件打包风险;当前数据规模足够使用 |
| 索引与会话源数据完全分离 | 索引可以删除重建,不给现有会话数据带来迁移风险 |
| 新增独立 WebSocket 消息类型 | 避免改变现有会话列表、搜索和加载协议 |
| 看板作为独立工作区 | 页面结构可复用现有外壳,同时隔离聊天状态和交互 |
| 提供可立即关闭的功能开关 | 用户确认落地后默认展示入口;出现问题时可只关闭看板,不回滚会话功能 |
| MCP 历史数据暂按 assistant 消息时间聚合 | 当前工具调用记录本身没有时间戳,必须在界面说明口径 |
## 看板界面基线
- **视觉主张:** 延续 cc-web 现有应用外壳,形成安静、紧凑、可快速扫描的运营工作区;不单独设计营销主题。
- **内容结构:** 时间与刷新控制 → 核心数字 → 趋势和 MCP 明细 → 状态与 Skill 排行 → 最近会话。
- **交互主张:** 切换看板时保留聊天现场;筛选刷新只更新看板区域;明细查看在看板内部完成,返回后保留筛选条件。
- **组件原则:** 只有可交互或需要独立语义的区域使用卡片,其余优先使用分栏、分隔线、图表和紧凑表格,避免卡片拼贴。
- **入口位置:** 固定在侧栏底部操作区,处于会话列表下方,与截图中的 `CC-Web` 设置入口同一区域;不插入会话列表滚动内容。
## 不影响现有功能的硬性验收门槛
1. 关闭功能开关时,前端 DOM、交互和服务端行为与改动前一致。
2. 统计模块异常、索引缺失或查询超时,消息发送和会话操作仍正常。
3. `session_list``search_sessions``load_session` 的请求和响应合同不变。
4. 不修改现有会话文件内容;统计索引可随时删除并从源数据重建。
5. 全量现有回归通过,新增统计回归通过后才允许灰度开启。
6. 不在正常消息处理的同步关键路径中执行全量扫描或重聚合。
7. 看板必须显示“基于当前保留数据”和最后更新时间,不能把保留期数据表述为永久审计数据。
8. `THEME_OPTIONS` 中全部现有主题都必须完成桌面和窄屏验收;侧栏入口位置一致,看板内容可读,且聊天恢复、会话切换、搜索、消息发送和 MCP 功能不受影响。
## 发布门禁建议
- 基线:先记录当前回归结果和典型聊天操作耗时。
- 开发态:仅显式开启功能开关后显示入口。
- 灰度态:限制单用户或指定环境开启,观察至少一个完整统计周期。
- 正式态只有错误率、CPU、内存和 P95 查询耗时满足阈值才默认开启。
- 回滚:关闭功能开关;保留独立索引无害,必要时可后续清理。
## 首版性能阈值
- 当前约 82 MB 会话数据的专项回填目标不超过 3 秒。
- 索引就绪后的本周/本月查询 P95 目标不超过 100 ms。
- 专项回填进程峰值 RSS 目标不超过 160 MB。
- 旁路索引文件目标不超过源会话 JSON 总量的 35%。
## 错误记录
| 错误 | 尝试 | 处理 |
|---|---:|---|
| 无 | 1 | — |
| `task.py list-context ... implement` 参数不被当前脚本接受 | 1 | `task.py validate` 已确认 context JSONL 合法;后续直接读取任务上下文文件,不重复该命令 |