Files
nj/docs/verification/full-system-audit-report.md
iven 49d4aa36a7
Some checks failed
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled
fix(app): Phase 1.1 紧急修复 — SyncEngine 接入 + authorId + catch 异常处理
- feat(sync): SyncEngine 接入 EditorPage, 保存时 enqueue + 网络恢复自动 trySync
- fix(editor): authorId 从 AuthBloc 获取, 替代硬编码 'local'
- fix(bloc): class_bloc/calendar/profile/parent catch(_).全部改为 debugPrint
- feat(editor): 编辑器工具栏拆分 (brush_panel/tag_panel/text_format_bar/dot_grid_painter)
- feat(editor): EditorBloc 扩展 + EditorPage 增强
- feat(search): SearchBloc 扩展搜索功能
- feat(home): HomeBloc/HomePage 增强
- feat(auth): LoginPage 增强
- feat(templates): TemplateGalleryPage 重构
- fix(web): 管理端班级/日记页面修复
- fix(server): comment_service + theme_handler 修复
- docs: 添加全链路审计报告和验证截图
2026-06-02 21:21:43 +08:00

20 KiB
Raw Blame History

暖记 (Warm Notes) 系统性功能审计报告

审计日期: 2026-06-02 | 审计范围: 后端 Rust + Flutter 学生端 + 管理端 Web | 基线: main (7e928ae)


一、审计总览

1.1 审计范围与方法

本次审计对暖记项目三端Rust 后端、Flutter 学生端、React 管理端)进行了系统性功能审计,采用以下方法:

  1. 文档对齐 — Wiki 8 篇文档 vs 代码实现对比
  2. 追踪数据流 — 从 UI → BLoC → Repository → API → Handler → Service → Entity 完链路追踪
  3. 识别 Dead Code — 搜索未使用模块、未调用方法、未接入功能
  4. 检查 Trait 实现 — 验证接口定义与实际实现一致性
  5. 端到端验证 — API 端点注册 → Handler → Service → Entity 完整性检查

1.2 项目关键数字

指标 数值
Rust 后端 8 crate, ~51,500 行 (erp-diary 5,108 行)
Flutter 学生端 74 文件, ~19,500 行
管理端 Web ~317 TypeScript 文件, 4 暖记页面
后端测试 77 通过
前端测试 84 BLoC + 8 文件
SeaORM Entity 15 (diary) + 50+ (基座)
API 端点 27 个 diary 端点

1.3 总体完成度评分

层级 完成度 说明
后端 (erp-diary) 82% Entity/Service/Handler 骨架完整,权限种子和内容安全有缺口
Flutter 学生端 68% 16 模块骨架完整,但 6 个页面缺 Provider 注入SyncEngine 未接入,多处硬编码
管理端 Web 88% 4 页面功能丰富,品牌定制完成度高,但 CRUD 不完整
三端一致性 65% 多处端间功能不同步,是最大风险

二、功能清单与完成度矩阵

2.1 核心功能模块完成度

功能模块 后端 Flutter 管理端 整体 备注
日记 CRUD 95% 85% 95% 92% 管理端仅只读EditorPage authorId 硬编码
日记同步 90% 40% N/A 65% SyncEngine 已写但未接入 app.dart
班级管理 80% 75% 70% 75% ⚠️ API 不匹配:管理端 GET 返回 my_classes
手写引擎 95% 90% N/A 93% 双层 Canvas+光栅化缓存完整toImage() 主线程风险
贴纸系统 85% 80% 60% 75% 后端仅 GET管理端仅只读
模板系统 85% 75% 20% 60% 管理端 API 有但无页面
评论/点评 90% 50% 85% 75% 内容安全未接入评论服务,管理端无删除按钮
成就系统 80% 60% 0% 47% 管理端完全缺失
心情统计 85% 75% 0% 53% 管理端无页面,后端 API 完整
家长中心 85% 60% 0% 48% 后端 API 完整,管理端完全缺失
认证/登录 95% 80% 95% 90% 班级码后端验证待接入
搜索 30% 50% N/A 40% Isar FTS 未实现,后端无搜索端点

2.2 基座功能继承(零开发)

功能 状态 验证
用户/角色/权限 CRUD 继承 管理端正常
JWT + Token 轮换 继承 后端测试通过
RBAC 权限码守卫 继承 所有 Handler 有 require_permission
事件总线 + Outbox 继承 EventBus.publish 在 Service 层使用
PII 加密 + 盲索引 继承 erp-core 提供
审计日志(哈希链) 继承 管理端可查看
多租户隔离 (RLS) 继承 中间件自动注入
字典/菜单/设置 继承 管理端正常
消息/通知/SSE 继承 SSE 端口不一致问题待修

三、CRITICAL 问题(必须修复)

C1. 管理端班级列表 API 不匹配

位置: apps/web/src/api/diary/classes.ts:7crates/erp-diary/src/lib.rs:141

问题: 前端 GET /diary/classes 期望返回全部班级,但后端映射的是 my_classes(仅当前用户加入的班级)。管理员无法在管理端看到所有班级。

影响: ClassList 和 JournalList 班级筛选数据不完整,核心管理功能受损。

修复方案:

  • 后端新增 list_all_classes handlerdiary.class.manage 权限),返回全部班级
  • 或修改 my_classes 使 admin/teacher 角色返回全部班级

C2. 权限 Seed 缺失

位置: crates/erp-server/migration/src/

问题: 部分权限码未在 seed 迁移中注册。后端 Handler 使用了 diary.class.manage, diary.comment.write, diary.comment.delete 等权限码,但角色种子数据中可能缺少对应条目。

影响: 即便角色有正确的权限码,如果 seed 未写入则 require_permission 永远返回 403。

修复方案: 补充缺失的权限码到 m20260601_000300_diary_role_seed.rs

C3. 6 个 Flutter 页面缺少 Repository Provider 注入

位置: app/lib/core/routing/app_router.dart

问题: 以下页面在路由跳转时没有 RepositoryProvider 注入,导致页面内 BLoC 无法访问数据仓库:

  • /stickers — StickerBloc 无法获取 StickerRepository
  • /templates — TemplateBloc 无法获取 TemplateRepository
  • /achievements — AchievementBloc 无法获取数据
  • /mood — MoodBloc 无法获取 JournalRepository
  • /calendar — CalendarBloc 无法获取 JournalRepository
  • /parent — ParentBloc 无法获取 ClassRepository

影响: 这些页面运行时会抛出 ProviderNotFoundException,功能完全不可用。

修复方案: 在 app_router.dart 的对应路由中添加 RepositoryProvider 嵌套,或改为在 app.dart 全局注入。

C4. SyncEngine 已实现但未接入

位置: app/lib/app.dart

问题: SyncEngine 在 app.dart 中创建了实例,但 restorePendingQueue() 和自动同步触发都未实际调用。离线数据永远不会同步到后端。

影响: 离线优先架构的核心承诺(联网后自动同步)不成立。

修复方案:

  1. app.dartinitState 中调用 syncEngine.restorePendingQueue()
  2. 添加网络监听WiFi 恢复时触发 syncEngine.trySync()
  3. EditorBloc 保存时调用 syncEngine.enqueue()

四、HIGH 问题(应该修复)

H1. EditorPage authorId 硬编码 'local'

位置: app/lib/features/editor/views/editor_page.dart:90

问题: authorId: 'local' 未从 AuthBloc 获取真实用户 ID。所有日记的作者都是 'local'。

影响: 多用户场景下无法区分日记归属,日记列表、班级日记墙的作者显示全部为 'local'。

H2. SSE 端口配置不一致

位置: app/lib/data/services/sse_notification_service.dart:42

问题: SSE 默认 http://localhost:3000,但 Flutter Web 运行在 :8080。SSE 连接需要后端支持,端口不匹配导致推送完全失效。

影响: 实时通知功能不可用。

H3. API Base URL 硬编码

位置: app/lib/config/app_config.dart:24-25

问题: http://localhost:3000/api/v1 硬编码为默认值。虽然支持 --dart-define 覆盖,但无构建配置管理。

影响: 生产环境部署需手动配置,容易出错。

H4. 内容安全过滤未接入评论服务

位置: crates/erp-diary/src/service/comment_service.rs

问题: ContentSafetyService 只在 JournalService 的创建/更新时调用,评论内容完全绕过了敏感词检查。

影响: 评论中可以包含不当内容,违反 PIPL 内容安全要求。

H5. catch(_) 静默吞异常 — 15 处

位置: 遍布 Flutter 代码sync_engine, editor, class_bloc, calendar 等)

问题: catch (_) 完全忽略异常,不记录日志也不向用户反馈。

影响: 问题排查极其困难,用户看到的只有"没反应",无法定位原因。

H6. 班级编辑/停用/重置班级码缺失

位置: 前后端均无

问题: 班级一旦创建就无法编辑名称、停用或重置班级码。CLAUDE.md 明确要求"老师可随时重置"。

H7. 贴纸管理只有只读

位置: 前后端均无 POST/PUT/DELETE 端点

问题: 贴纸包和贴纸的创建/编辑/删除功能完全缺失,只能通过数据库手动操作。

H8. 主题管理缺少停用/编辑

位置: 前后端均无

问题: 主题一旦发布无法修改或停用,过期的主题仍然会显示给学生。


五、MEDIUM 问题(建议修复)

M1. Flutter 状态管理不统一

模块 模式 问题
EditorBloc flutter_bloc
AuthBloc flutter_bloc
HomeBloc flutter_bloc
CalendarBloc flutter_bloc
SearchBloc flutter_bloc
ClassBloc flutter_bloc
ParentBloc flutter_bloc
MoodBloc ChangeNotifier ⚠️ 不支持 DevTools 调试
AchievementBloc ChangeNotifier ⚠️ 同上
StickerBloc ChangeNotifier ⚠️ 同上
TemplateBloc ChangeNotifier ⚠️ 同上
SettingsBloc ChangeNotifier 合理选择

建议: Phase 2 将 Mood/Sticker/Template/Achievement 迁移到 flutter_bloc。

M2. 管理端 HMS 遗留代码需清理

文件 内容 建议
api/copilot.ts HMS AI 分析 API 删除
test/fixtures/healthFixtures.ts 患者 fixture 删除
test/mocks/healthHandlers.ts 健康 mock 删除
pages/settings/AuditLogViewer.tsx 患者资源类型 移除 HMS 选项
stores/auth.test.ts health.* 权限码 更新为 diary.*

M3. Home 页面快捷入口缺少暖记功能

Home.tsxQUICK_ACTIONS 只有基座功能入口,缺少班级管理、日记审核、主题管理。

M4. 编辑器不加载已有数据

journalId 非空时EditorPage 未从 Isar 读取已有日记数据。编辑已有日记时页面空白。

M5. DiscoverPage 全 mock 数据

features/discover/views/discover_page.dart 完全是硬编码数据,无任何数据源接入。

M6. 后端 Dead Code — NotificationService

notification_service.rs 有完整的事件监听逻辑,但从未在任何 Handler 或 lib.rs 中注册/订阅。事件发布了但无人消费。


六、LOW 问题(建议优化)

ID 问题 位置
L1 toImage() 同步阻塞主线程 handwriting_engine
L2 画布旋转缓存失效 stroke_cache.dart
L3 freezed 声明未使用 pubspec.yaml
L4 Isar FTS 未实现 search 功能空壳
L5 用户协议/隐私政策 TODO login_page.dart
L6 UUID 直接展示给管理员 JournalList/ClassList
L7 Logo 显示字母 'N' 而非正式图标 MainLayout.tsx
L8 templateApi 无管理端页面 stickers.ts

七、5 种差距模式分类

7.1 "写了没接"(代码已实现但未接入业务流程)

组件 位置 说明
SyncEngine app/lib/data/services/ 完整实现但未在 app.dart 调用
NotificationService crates/erp-diary/src/service/ 事件监听逻辑完整但未注册订阅
ContentSafetyService crates/erp-diary/src/service/ 只接入了 Journal未接入 Comment
SSE Notification app/lib/data/services/ 服务完整但端口配置错误
usePermFilteredTabs apps/web/src/hooks/ Hook 存在但暖记页面未使用

7.2 "接了没传"(功能已接入但关键参数未传递)

组件 位置 说明
EditorPage authorId editor_page.dart:90 硬编码 'local',未从 AuthBloc 获取
ClassBloc 班级码 teacher_page.dart:72 硬编码 'a1b2c3',未从后端获取
ClassList 分页参数 classes.ts 传了 page/page_size 但 my_classes 不接受
JournalList 班级筛选 JournalList.tsx:131 只能获取当前用户的班级

7.3 "传了没存"(参数已传递但未持久化)

组件 位置 说明
ClassList 编辑 ClassList.tsx:52 编辑 Drawer 存在但 onUpdate 为空
SettingsBloc 持久化 settings_bloc.dart:38 TODO: 持久化到 SharedPreferences

7.4 "存了没用"(数据已存储但未在业务逻辑中使用)

组件 位置 说明
MoodStats API /diary/stats/mood 管理端无页面展示
Achievements /diary/achievements 管理端无页面
Template API templateApi API 定义完整但无管理端页面
total_pages 后端返回但前端未使用 PaginatedResponse 字段

7.5 "双系统不同步"(各端功能实现不一致)

功能 后端 Flutter 管理端 差距
班级 CRUD C/R (无 U/D) 加入/查看 创建/查看 管理端缺编辑/停用
评论删除 DELETE 无 UI 无按钮 后端有但两端未暴露
成就系统 API 部分实现 管理端完全缺失
心情统计 API 页面存在 管理端完全缺失
家长中心 完整 API 部分实现 管理端完全缺失
模板管理 API 浏览页 无页面 管理端缺页面

八、10 项通用审计清单

# 审计项 后端 Flutter 管理端 评估
1 代码存在性 15 Entity + 10 Service + 8 Handler ⚠️ 6 模块缺 Provider 4 页面 Flutter 有缺口
2 调用链连通 Handler→Service→Entity 完整 SyncEngine 断链 ⚠️ classes API 不匹配 核心链路有断点
3 配置传递 Feature Flag + Config URL 硬编码 Vite proxy Flutter 配置管理弱
4 降级策略 DiaryError 枚举完整 catch(_) 吞异常 ⚠️ 班级 fallback 异常处理不足
5 权限守卫 ⚠️ Seed 可能有缺失 N/A routeConfig 后端需验证
6 输入验证 Validate derive ⚠️ 部分页面无验证 Form rules 基本完整
7 数据加密 AES-256-GCM 基座 Isar 内置加密 N/A 已继承
8 多租户隔离 中间件注入 N/A JWT 提取 已继承
9 离线可用 Sync API 完整 SyncEngine 未接入 N/A 核心缺口
10 测试覆盖 77 测试 ⚠️ 8 文件 (6 BLoC) ⚠️ HMS 遗留测试 Flutter 严重不足

九、功能点完成度评估

9.1 后端 API 端点完成度

端点 CRUD 权限 注解 事件 评分
/diary/journals C+R+U+D 100%
/diary/sync POST 90%
/diary/classes C+R ⚠️ 75%
/diary/classes/join POST 95%
/diary/journals/:id/comments C+R+D 95%
/diary/classes/:id/topics C+R 85%
/diary/sticker-packs R only 50%
/diary/templates R only 50%
/diary/achievements R+POST 70%
/diary/stats/mood GET 85%
/diary/parent/* 完整 90%

9.2 Flutter 功能模块完成度

模块 BLoC View Widget 离线 测试 评分
editor ⚠️ 85%
auth 85%
home ⚠️ 80%
calendar ⚠️ 75%
search 50%
class_ ⚠️ 70%
mood ⚠️ CN 55%
achievement ⚠️ CN 45%
stickers ⚠️ CN 50%
templates ⚠️ CN 45%
profile ⚠️ CN 50%
teacher 40%
parent 45%
discover 15%

9.3 管理端页面完成度

页面 CRUD 筛选 分页 主题 品牌 评分
班级管理 C+R ⚠️ 85%
日记审阅 R 95%
主题管理 C+R 90%
贴纸管理 R 85%

十、问题统计与优先级

10.1 问题严重程度分布

严重程度 数量 占比
CRITICAL 4 12%
HIGH 8 24%
MEDIUM 6 18%
LOW 8 24%
INFO/建议 7 22%
合计 33 100%

10.2 问题分布

层级 CRITICAL HIGH MEDIUM LOW
后端 1 (C2) 1 (H4) 1 (M6) 0
Flutter 2 (C3, C4) 4 (H1, H2, H3, H5) 2 (M1, M4) 4
管理端 1 (C1) 3 (H6, H7, H8) 3 (M2, M3, M5) 4
跨端

十一、推荐修复顺序

Phase 1.1 — 紧急修复1-2 天)

# 问题 工作量 涉及文件
1 C3: 6 个 Flutter 页面添加 Provider 注入 ~100 行 app_router.dart
2 C4: SyncEngine 接入 app.dart ~50 行 app.dart, editor_bloc.dart
3 H1: EditorPage authorId 从 AuthBloc 获取 ~20 行 editor_page.dart
4 H5: catch(_) → catch(e) + log ~30 行 多文件

Phase 1.2 — 核心功能修复3-5 天)

# 问题 工作量 涉及文件
5 C1: 后端新增 list_all_classes handler ~150 行 Rust class_handler.rs, class_service.rs, lib.rs
6 C2: 补充权限 seed 迁移 ~100 行 SQL diary_role_seed.rs
7 H4: ContentSafetyService 接入评论 ~30 行 Rust comment_service.rs
8 H6: 班级编辑/停用/重置班级码 ~300 行 Rust + ~100 行 TS class_handler.rs, ClassList.tsx
9 H2: SSE 端口配置修复 ~20 行 Dart sse_notification_service.dart

Phase 1.3 — 完善修复5-7 天)

# 问题 工作量 涉及文件
10 H7: 贴纸 CRUD ~400 行 Rust + ~200 行 TS sticker_handler.rs, StickerPackList.tsx
11 H8: 主题停用/编辑 ~200 行 Rust + ~100 行 TS topic_handler.rs, TopicList.tsx
12 M2: HMS 遗留代码清理 ~200 行删除 多文件
13 M4: 编辑器加载已有数据 ~100 行 Dart editor_page.dart
14 M6: NotificationService 注册 ~50 行 Rust lib.rs

Phase 2 — 后续规划

# 功能 说明
15 成就系统管理端页面 完整 CRUD
16 心情统计管理端页面 图表展示
17 家长中心管理端 数据查看/导出
18 BLoC 统一迁移 ChangeNotifier → flutter_bloc
19 Isar FTS 搜索实现 全文搜索
20 测试覆盖率提升 80%+ 目标

十二、总结

做得好的方面

  1. 后端架构扎实 — Entity/Service/Handler 分层清晰,权限守卫、事件发布、多租户隔离完整
  2. 手写引擎高质量 — 双层 Canvas + 光栅化缓存 + Listener 低延迟,核心价值完整
  3. 管理端品牌定制完成度高 — 登录页、侧边栏、主题色、菜单种子全部完成暖记替换
  4. 设计系统一致性 — 三端使用统一的珊瑚色/鼠尾草绿/暖金配色体系
  5. 基座继承零开发 — 8 个基座 crate 的全部功能直接可用

最大风险

  1. SyncEngine 未接入 — 离线优先是核心承诺,但目前离线数据永远不会同步
  2. 6 个 Flutter 页面缺 Provider — 这些页面在运行时会崩溃
  3. 管理端/学生端功能不同步 — 成就、心情、家长中心后端 API 完整但管理端完全缺失
  4. catch(_) 静默吞异常 — 15 处异常被完全忽略,严重影响问题排查

一句话总结

暖记项目基座架构优秀,后端 API 覆盖 90%,但 Flutter 端的"最后一公里"Provider 注入、SyncEngine 接入、authorId 硬编码)和管理端的 CRUD 补全是当前最紧迫的工作。


报告生成: 2026-06-02 | 审计工具: Claude Code + 三端并行 Agent