docs(评审):架构与设计评审报告
This commit is contained in:
@@ -0,0 +1,146 @@
|
|||||||
|
# 学习进度跟踪系统(LPT)— 架构与设计评审
|
||||||
|
|
||||||
|
> 评审日期:2026-07-03
|
||||||
|
> 评审范围:learning-progress-tracker(后端 Spring Boot) + lpt-fe(前端 Vue 3)
|
||||||
|
> 代码基线:feature/review-completion 分支
|
||||||
|
|
||||||
|
## 一、整体评价
|
||||||
|
|
||||||
|
系统的底层方向是正确的:
|
||||||
|
- **量化学习投入**(番茄钟 + 学习简报)→ 解决缺乏时间感知
|
||||||
|
- **优先级排序**(五维度算法)→ 解决缺乏计划性
|
||||||
|
- **主动回忆式复习**(碎片滚动 + 思维导图对比)→ 解决缺乏复习习惯
|
||||||
|
|
||||||
|
三个痛点对应三个解决方案,逻辑链成立。代码质量方面,前后端分离、RESTful API 设计、Flyway 数据库迁移、Sa-Token 鉴权、MyBatis-Plus 多租户拦截等基础设施做得相当规范,超出业余项目的平均水准。
|
||||||
|
|
||||||
|
但在**业务设计的心理学层面**,存在几个结构性矛盾:有些地方把"功能完整"等同于"有用",对用户的实际行为模式考虑不足。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、不科学之处
|
||||||
|
|
||||||
|
### 2.1 番茄钟被当作计时器而非学习节奏工具
|
||||||
|
|
||||||
|
当前实现把 25 分钟当作一个硬性倒计时,超时 50 分钟自动暂停,"仅计 25 分钟有效时间"。但番茄钟的核心价值不是"学够 25 分钟",而是**强迫休息—回忆—重置**的节奏。
|
||||||
|
|
||||||
|
**问题**:
|
||||||
|
- 允许用户连续学习远超 25 分钟而不触发强制休息提醒
|
||||||
|
- 超时被视为"违规"(自动暂停),而不是自然的节奏重置
|
||||||
|
- 后端 session 状态机里没有独立的"休息中"状态
|
||||||
|
- 前端虽有 5 分钟倒计时但后端无法感知
|
||||||
|
|
||||||
|
**改进方向**:番茄钟应该循环——25 分钟学习 → 强制 5 分钟休息并提示填写残片 → 自动进入下一轮。每一轮结束都是自然的"复习锚点"。
|
||||||
|
|
||||||
|
### 2.2 优先级五维度权重有重叠,且缺乏解释
|
||||||
|
|
||||||
|
| 维度 | 权重 | 问题 |
|
||||||
|
|------|------|------|
|
||||||
|
| 主观判断 | 10% | 跟"重要性"、"未来价值"高度相关,用户难以区分 |
|
||||||
|
| 未来价值 | 10% | 同上 |
|
||||||
|
| 内容难度 | 20% | 假设"越难越值得优先学"不一定成立 |
|
||||||
|
| 必要性 | 25% | 与"紧急性"边界模糊 |
|
||||||
|
| 紧急性 | 35% | 权重最高,但优先级 ≠ 紧迫性 |
|
||||||
|
|
||||||
|
核心矛盾:紧急性 + 必要性占 0.60,主观判断 + 未来价值仅占 0.20。系统会自动把"明天要交的报告"排在"你想真正学会的英语"前面——但用户做这个系统是为了后者的。
|
||||||
|
|
||||||
|
**改进方向**:两套排序模式——"紧急模式"(按紧迫性)和"重要模式"(按主观+未来价值),用户在不同时间段切换,而不是混合成一个不伦不类的综合分。此外权重应当可配置(当前硬编码在 CalculatedPriorityTool 中)。
|
||||||
|
|
||||||
|
### 2.3 学习预期是系统强约束但无闭环
|
||||||
|
|
||||||
|
PRD 明确要求"每次学习开始前必须填写学习预期(不可为空)",数据库也建了 study_expectations 表。但:
|
||||||
|
- 后端没有对应的 Entity / Service / Controller
|
||||||
|
- 前端 StartTask 页面没有预期输入框
|
||||||
|
- 预期没有与实际学习报告做任何对比
|
||||||
|
|
||||||
|
被强制填写却不被使用的字段,比没有更糟——用户费心填了,却发现系统根本不看。学习预期的价值在于事后对比:"我打算学什么 vs 我实际学了什么",这是元认知训练的核心。
|
||||||
|
|
||||||
|
**改进方向**:始于创建 session 时弹窗必填预期,终于结束时展示"预期 vs 实际"对比。
|
||||||
|
|
||||||
|
### 2.4 复习模块的认知负荷偏高
|
||||||
|
|
||||||
|
当前复习模块有三个独立概念和入口:
|
||||||
|
- 碎片化提醒(Welcome 页滚动)
|
||||||
|
- 思维导图上/下载(ReviewDetail)
|
||||||
|
- 回忆对比(ReviewRecall)
|
||||||
|
|
||||||
|
但用户的真实行为大概是:打开复习页 → 看到滚动条闪过很多内容 → 不知道先看哪个 → 关掉。太多碎片而没有"今天需要复习什么"的引导。
|
||||||
|
|
||||||
|
复习行为的心理阻力主要来源于**不知道从哪开始**。
|
||||||
|
|
||||||
|
**改进方向**:复习应该"推"给用户一条清晰路径——"你今天有 3 个知识点需要复习,先看第一个"。而不是拉出一个 feed 让用户自己挑。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、改进空间
|
||||||
|
|
||||||
|
### 3.1 学习报告的长度决策
|
||||||
|
|
||||||
|
当前,残片是"休息时记录的内容片段",报告是"结束时生成的完整总结"。但在前端两者几乎无差异——都是文本、都在同一个 feed 中滚动、都在详情页逐行显示。
|
||||||
|
|
||||||
|
实际问题:学完 25 分钟后,用户是否真的有动力写一篇"完整报告"?大概率不会——草草写一句"学了线程池"然后开始下一轮。
|
||||||
|
|
||||||
|
**改进方向**:降低报告的仪式感。残片应该是主力的学习记录单元,报告改为"自动将本次会话的残片聚合为摘要",用户只需要微调即可。
|
||||||
|
|
||||||
|
### 3.2 断点续传的粒度
|
||||||
|
|
||||||
|
当前用 pointerPosition(毫秒级指针)支持关闭页面后恢复学习,设计很好。但问题在于:学习结束后,断点续传数据变成死数据。
|
||||||
|
|
||||||
|
用户周五回来面对的不是"上次学了什么"的摘要,而是"继续上次倒计时"——但用户可能想重新开始一个关于同一任务的新会话,或者先回顾上次的残片再做决定。
|
||||||
|
|
||||||
|
**改进方向**:断点续传配合"上次学习回顾"一起出现——"你上次学了 X、Y、Z,生成了 N 个残片。继续?还是开始新的?"
|
||||||
|
|
||||||
|
### 3.3 有效学习时间的 10 分钟阈值
|
||||||
|
|
||||||
|
后端逻辑:effective_time < 10 分钟 → 不计入总学习时间,置为 0。
|
||||||
|
|
||||||
|
意图是过滤掉"开启后很快就关"的无效学习。但 10 分钟阈值对番茄钟来说太高——25 分钟的 session 如果被电话打断 8 分钟后回来,系统判定"白学了"。
|
||||||
|
|
||||||
|
**改进方向**:降低阈值到 3-5 分钟,或改为比例制(有效比 < 30% 才标记低效而不是直接归零)。数据是分析原材料,不是评判工具。
|
||||||
|
|
||||||
|
### 3.4 回忆覆盖率的误导性
|
||||||
|
|
||||||
|
当前:recall_ratio = matched / (matched + missed)。问题在于它衡量"记得多少节点"而非"记得多少重要节点"。
|
||||||
|
|
||||||
|
假如一个任务 100 个节点,其中 3 个核心、97 个细节。
|
||||||
|
- 用户回忆出 3 个核心 → 覆盖率 3%
|
||||||
|
- 用户回忆出 97 个细节但漏了 3 个核心 → 覆盖率 97%
|
||||||
|
|
||||||
|
显然后者更差,但指标显示前者好。
|
||||||
|
|
||||||
|
**改进方向**:节点加权——"应用场景"和"从报告中提取的关键概念"级别更高。或至少同时展示"核心节点覆盖"和"全部节点覆盖"两个指标。
|
||||||
|
|
||||||
|
### 3.5 多租户隔离的泛化成本
|
||||||
|
|
||||||
|
系统通过 created_by 做租户隔离,每个查询多一个 WHERE 条件、新增数据要注入用户 ID、测试要绕过拦截器。开发笔记中作者自问"这玩应儿除了自己,还能有别人用么"。
|
||||||
|
|
||||||
|
多租户本身没有错,但在当前单人使用场景下带来了不必要的复杂度。
|
||||||
|
|
||||||
|
**改进方向**:如果未来真有多人需求可还原。当前去掉租户拦截可简化 80% 的查询,减少隐式 bug。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、优先级建议
|
||||||
|
|
||||||
|
### P0 —— 影响核心使用
|
||||||
|
- 学习预期的闭环(创建→填写→事后对比)
|
||||||
|
- 番茄钟循环节律(25分→5分休息 + 自动残片)
|
||||||
|
|
||||||
|
### P1 —— 明显改善体验
|
||||||
|
- 复习引导路径("今天有 N 个知识点需要复习")
|
||||||
|
- 降低报告仪式感(残片为主、报告自动聚合)
|
||||||
|
- 优先级权重用户可配置
|
||||||
|
|
||||||
|
### P2 —— 优化与完善
|
||||||
|
- 有效时间阈值下调
|
||||||
|
- 回忆覆盖率高阶指标(核心节点 vs 全部节点)
|
||||||
|
- 断点续传配合历史回顾
|
||||||
|
- 移除不必要的多租户拦截(或标记可选)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、总结
|
||||||
|
|
||||||
|
系统在基础设施层面(前后端分离、RESTful、Flyway、Sa-Token、MyBatis-Plus)做得相当规范。主要问题不在技术而在设计:**把"功能完整"当成了"有用"**。学习预期无闭环、番茄钟无节奏感、复习无引导路径——这些不需要更多技术投入,而是需要重新理解用户行为。
|
||||||
|
|
||||||
|
> 一句话:系统已经可以做很多事情,但用户不一定知道"现在应该做什么"。
|
||||||
|
> 下一步的改进目标是降低用户决策成本,引导而非开放。
|
||||||
Reference in New Issue
Block a user