Files
nj/docs/audit-2026-06-03-full-report.md
iven 38592d61ce
Some checks failed
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled
refactor(diary): Phase 3 质量提升 — 201 状态码 + OpenAPI 文档 + DiaryEvent 类型安全
前端:
- fix(app): Isar native 文件直接导入 isar_database_native.dart,消除 5 个条件导出类型错误
- chore(app): build_runner 重新生成 .g.dart 文件 (102 outputs)
- fix(app): 移除 secure_token_store_factory 未使用的 kIsWeb import

后端:
- refactor(diary): 所有创建端点 POST 返回 201 Created (9 handler, 11 端点)
- feat(diary): DiaryApiDoc OpenApi derive — 42 路径 + 32 Schema 汇总到 Swagger
- feat(diary): DiaryEvent 枚举添加 event_type/payload/to_domain_event 方法 + 4 测试

测试: 84/84 erp-diary 通过, 509/509 全仓库通过, Flutter analyze 0 error
2026-06-03 17:06:03 +08:00

20 KiB
Raw Blame History

暖记 (Nuanji) 全系统穷尽审计报告

审计日期: 2026-06-03 代码规模: ~126,000 行 / 560+ 文件 审计方法: 10 维度 × 2 智能体 = 20 个并行审计智能体 审计范围: 安全 → 后端架构 → 前端质量 → 数据库 → API设计 → 基础设施 → 文档 → 性能 → 跨层一致性


执行摘要

总体统计

维度 CRITICAL HIGH MEDIUM LOW/INFO 合计
🔒 安全 (步骤1) 3 9 10 6 28
🏗️ 后端架构 (步骤2) 1 11 12 9 33
📱 前端质量 (步骤3) 1 2 17 10 30
🗄️ 数据库 (步骤4) 3 8 11 7 29
🌐 API设计 (步骤5) 6 8 10 7 31
🐳 基础设施 (步骤6) 9 13 16 14 52
📚 文档 (步骤7) 7 16 17 17 57
性能 (步骤8) 5 12 17 13 47
🔗 跨层一致性 (步骤9) 7 11 13 7 38
合计 42 90 123 90 345

风险等级分布

CRITICAL ██████████████████████ 42 (12%)  — 必须立即修复
HIGH     █████████████████████████████████████████████ 90 (26%)  — 本周内修复
MEDIUM   ██████████████████████████████████████████████████████████████████ 123 (36%) — 规划修复
LOW/INFO ████████████████████████████████████████████ 90 (26%)  — 记录跟踪

系统成熟度评估

领域 评分 说明
架构设计 ★★★★☆ 模块边界清晰,多租户架构合理
安全基础 ★★★☆☆ 加密体系完善,但输入验证/权限覆盖有缺口
数据库设计 ★★★★☆ Entity 一致性优秀RLS 有 bug 需修
API 设计 ★★★☆☆ DTO 验证系统性缺失REST 不规范
前端质量 ★★★☆☆ 手写引擎优秀,但 BLoC/无障碍需改进
基础设施 ★★★☆☆ Docker/备份设计好CI/CD 和密钥管理弱
测试覆盖 ★★☆☆☆ 单元测试尚可,集成/E2E 严重不足
文档准确性 ★★★★☆ 总体准确,细节有偏差

🔴 CRITICAL 发现汇总 (37 项)

按影响域分类

A. 数据安全与隐私 (12 项)

ID 问题 来源 影响
S-02 内容安全过滤器为空 — SENSITIVE_WORDS 无词条,所有内容通过检查 安全 儿童可能接触不安全内容
S-03 缺少家长同意验证 — 违反 PIPL 第28条 安全 法律合规风险
S-10 家长绑定无验证 — 任何人可绑定任何孩子 安全 儿童数据泄露
6b-C01 Flutter 默认 HTTP 明文传输 配置 JWT/日记内容可被截获
6b-C02 Flutter 无 SSL 证书固定 配置 中间人攻击风险
6b-C03 管理端 JWT 存 localStorage 配置 XSS 可窃取 token
6b-C04 Docker 默认密码硬编码 配置 生产环境安全风险
6a-C01 .env.example 包含默认密码 Docker 易被直接用于生产
6a-C02 dev.sh 硬编码 JWT Secret/KEK 脚本 泄露到版本控制
6a-C04 verify.sh 硬编码生产数据库密码 脚本 凭据泄露
5b-C01 审计日志端点无权限守卫 API 任何用户可查看审计日志
5b-C02 文件上传端点无权限守卫 API 任何用户可上传文件

B. 数据完整性 (10 项)

ID 问题 来源 影响
4a-C01 RLS 变量名不一致app.current_tenant vs app.current_tenant_id 数据库 15 张日记表 RLS 完全失效/锁死
4a-C02 diary.comment.delete 权限未定义 种子数据 teacher 永远无删除评语权限
4b-C01 同 4a-C01确认问题存在 数据库
4b-C02 m000183 使用 FORCE RLS 与基座不一致 数据库 变量名错误时完全阻断访问
8a-C01 mood_stats 全量加载所有日记 性能 活跃用户 OOM
8a-C02 sync_service 循环内 N+1 查询 性能 50 条变更 = 100 次 DB 往返
8a-C03 parent_service 逐条软删除 性能 PIPL 删除不原子
8a-C04 sticker_service N+1 查询贴纸数量 性能 20 个包 = 21 次查询
8b-R01 笔画缓存 use-after-dispose Flutter 撤销/重做后笔画内容丢失
9a-SYNC-01 Flutter 与 Rust 使用两套不兼容同步协议 跨层 同步机制完全断裂

C. 输入验证系统性缺失 (8 项)

ID 问题 来源 影响
5a-C01 erp-diary 所有 DTO 无 Validate derive API 无字段级约束
5a-C02 DTO 字段无长度/范围约束 API 儿童/恶意输入可提交超大 payload
5a-C03 所有 handler 未调用 .validate() API 即使加 Validate 也形同虚设
5b-C03 OpenAPI 文档完全缺失 Diary 模块 API ~30 个端点不在文档中
7b-C01 班级码实际十六进制(16^6)非字母数字(62^6) 文档 安全强度低 3386 倍
7b-C02 同 5a-C01确认 Validate 缺失 文档
9a-AUTH-01 Flutter 无 Token 自动刷新 跨层 Token 过期直接踢回登录
9a-TENANT-01 Flutter 不传递 tenant_id 跨层 多租户上线需大规模改造

D. 端到端同步断裂 (4 项)

ID 问题 来源 影响
9a-SYNC-01 Flutter SyncEngine 与 Rust SyncService 协议不兼容 跨层 同步功能完全断裂
9a-SYNC-02 SyncEngine 超限后直接丢弃操作 跨层 用户数据静默丢失
9a-SYNC-03 SyncEngine 不使用后端 SyncChange 格式 跨层 数据格式不兼容
9a-SYNC-04 SyncEngine 不发送 version 字段 跨层 乐观锁失效

🟠 HIGH 发现汇总 (81 项)

安全 (9 项)

ID 问题 文件
S-04 JWT 缺少 iss/aud claims token_service.rs
S-05 RefreshReq 无输入验证 dto.rs, auth_handler.rs
S-06 开发 KEK 硬编码 crypto/mod.rs
S-07 日记列表 IDOR — 任何用户可查看他人日记 journal_handler.rs
S-08 无数据保留策略 parent_service.rs
S-09 无账号注销机制 全局缺失
S-11 Flutter API 默认 HTTP api_client.dart
S-12 默认存储密钥硬编码 config.rs

后端架构 (11 项)

ID 问题 文件
B-02 DiaryEvent 枚举是死代码 event.rs
B-03 所有请求 DTO 缺少 Validate dto.rs
B-04 DiaryModule 未实现 register_event_handlers lib.rs
B-05 日记端点缺失于 OpenAPI spec main.rs
B-06 generate_unique_code 未按 tenant_id 过滤 class_service.rs
B-07 create_class/join_class 两次写入无事务 class_service.rs
B-08 sticker_service 缺少乐观锁 sticker_service.rs
B-09 sync_service 版本冲突丢弃 journal_id sync_service.rs
B-10 sync_service 返回客户端刚提交的数据 sync_service.rs
B-11 parent_service 删除操作无事务 parent_service.rs

数据库 (8 项)

ID 问题 说明
4a-H01 journal_entries.class_id 无外键 Entity 声明但迁移未实现
4a-H03 外键无 tenant_id 联合约束 多租户 FK 保护不足
4a-H04 class_members.user_id 无外键 用户删除后孤儿数据
4a-H05 parent_child_bindings 无外键 Entity Relation 为空
4b-H01 processed_events 无 RLS 保护 跨租户数据可见
4b-H03 diary.comment.delete 权限未定义 同 4a-C02
4b-H05 外键列缺少 tenant_id 前缀索引 RLS 查询效率低
4b-H06 domain_events_archive 无 tenant_id 索引 归档查询低效

API 设计 (8 项)

ID 问题 说明
5a-H01 创建资源返回 200 而非 201 ~15 个端点
5a-H03 update_user/update_role 未调用 validate() auth 模块也不完整
5a-H04 AssignRolesReq 无 Validate 空数组可致用户失角色
5a-H07 SyncReq.changes 无大小限制 DoS 风险
5b-H01 user.reset-password 未在 permissions.yaml 注册 权限注册不一致
5b-H02 tenant.managesystem.analytics.submit 永远 403 权限从未注册
5b-H03 OpenAPI 缺少 Plugin/upload/crypto_admin 端点 文档不完整
5b-H05 微信登录缺速率限制 API 配额消耗风险

基础设施 (13 项)

ID 问题 说明
6a-H01 CI 缺少管理端前端检查 React 代码可未经检查合入
6a-H02 无 CI/CD 部署流程 部署全手动
6a-H03 CI 不验证 Docker 构建 Dockerfile 可能无法构建
6a-H04 Redis 健康检查暴露密码 ps aux 可见
6a-H06 Prometheus 引用不存在的 exporter 持续报错
6a-H07 Grafana provisioning 目录为空 无预配置仪表盘
6b-H01 根目录 CORS allowed_origins="*" 与 erp-server 配置矛盾
6b-H02 rand crate 0.8 过时 密钥生成应升级 0.9
6b-H03 AES-CBC 用于加密 应统一 AES-GCM
6b-H04 Web 依赖未锁定精确版本 ^ 语义范围
6b-H05 管理端 URL 传递 JWT token 浏览器历史/日志泄露
6b-H06 Grafana 密码默认为空 生产环境风险

文档 (7 项)

ID 问题 说明
7b-H01 erp-diary 代码量 7021 行 vs 声明 5800 行 超出 21%
7b-H03 school_class.codeMaxUses 未实现 设计规格不一致
7b-H04 TeacherProfile.verificationStatus 未实现 设计规格不一致
7b-H05 内容安全词库为空 与 CLAUDE.md 声明不符
7b-H06 discover 功能目录存在但属 Phase 2 违反原则
7b-H07 Flutter 无 freezed 代码生成 与 CLAUDE.md 声明不符

性能 (12 项)

ID 问题 说明
8a-H01 mood_stats 全量加载后内存聚合 应使用 SQL GROUP BY
8a-H02 EventBus 每次 3 次 DB 操作 无事务包裹
8a-H03 sync_service 无事务 多条变更部分成功风险
8a-H04 export_child_data 无分页 潜在 OOM
8a-H05 list_all_classes/list_members 无分页 数据增长后退化
8b-D01 JournalEntryCollection 缺 authorId/dateEpoch 索引 全表扫描
8b-D02 Isar 分页在 Dart 层而非数据库层 内存浪费
8b-D03 MonthlyPage N+1 查询元素 30 篇 = 31 次查询
8b-N01 SyncEngine 串行无合并 10 次自动保存 = 10 次 HTTP
8b-N02 _persistState 每元素单独事务 10 元素 = 10 次事务
8b-M01 首页日记列表用 Column 非 ListView.builder 无懒加载
8b-M02 笔画光栅化用全画布尺寸 50 条笔画 = 1.6GB GPU

跨层一致性 (11 项)

ID 问题 说明
9a-AUTH-02 Flutter client_type='mobile' 后端不识别 潜在不一致
9a-SYNC-02 SyncEngine 丢弃冲突数据 数据丢失
9a-SYNC-03 同步数据格式不兼容 两端协议断裂
9a-SYNC-04 SyncEngine 不发送 version 乐观锁失效
9a-TENANT-02 管理端不传递 tenant_id 多租户切换缺失
9a-CROSS-01 Flutter 无前端权限检查 后端 403 用户困惑
9b (汇总) erp-diary 无集成测试 核心业务无 E2E 验证
9b (汇总) Flutter 无 BLoC 测试 状态逻辑未验证
9b (汇总) 管理端无组件测试 UI 未验证
9b (汇总) 管理端-后端 API 不匹配 贴纸更新/班级列表等

🟢 做得好的方面 (亮点)

安全

  • AES-256-GCM + KEK/DEK 分层加密架构达到银行级别
  • Argon2 密码哈希 + Refresh Token 轮换
  • 审计日志哈希链防篡改
  • 生产环境拒绝默认密钥启动 (cfg! 宏保护)
  • Flutter 使用 flutter_secure_storage 加密存储 token

架构

  • Feature Flag 干净隔离日记模块
  • 所有 15 个 Entity 标准字段完全一致 (id/tenant_id/created_at/.../version)
  • 15 张表迁移字段与 Entity 字段 100% 一一对应
  • 模块边界正确: erp-diary 仅依赖 erp-core + erp-auth
  • 统一 ApiResponse/PaginatedResponse 信封格式

前端

  • 手写引擎双层 Canvas + Listener 方案达到教科书级
  • shouldRepaint 守卫全部正确
  • 笔画数据保真 (x/y/pressure/timestamp)
  • 掌心抑制已实现
  • 无内存泄漏 (Controller/Stream/Timer 全部正确 dispose)
  • 响应式布局三档正确

基础设施

  • Docker 多阶段构建 + 非特权用户
  • Nginx 安全头配置全面 (HSTS/CSP/X-Frame-Options)
  • 备份加密 (AES-256-CBC + GPG) + 自动清理
  • Prometheus 告警规则分类清晰

🔧 修复路线图

Phase 0: 紧急修复 (本周)

阻断性问题,影响数据安全/完整性

# 问题 ID 修复项 预估工时
1 4a-C01 修复 RLS 变量名: app.current_tenantapp.current_tenant_id + 添加空值保护 1h
2 S-02 填充内容安全词库 + 在日记创建/同步中调用 4h
3 S-07 修复日记列表 IDOR: 按 author_id 限制访问 2h
4 5b-C01/02 添加权限守卫: 审计日志 + 文件上传 1h
5 B-01 修复 class_service unwrap(): 替换为安全错误处理 0.5h
6 B-07/B-11 添加事务: create_class/join_class/parent 删除 3h
7 8b-R01 修复笔画缓存 use-after-dispose 2h
合计 ~13.5h

Phase 1: 安全加固 (第 1-2 周)

# 问题 ID 修复项 预估工时
1 S-03 实现家长同意验证流程 8h
2 S-10 实现家长绑定实际验证流程 4h
3 S-01 Token 黑名单改用 SHA-256 1h
4 5a-C01/02/03 为所有 DTO 添加 Validate + handler 调用 validate() 8h
5 6b-C01 Flutter 强制 HTTPS + 证书固定 4h
6 7b-C01 班级码改用字母数字混合 2h
7 9a-AUTH-01 Flutter 添加 Token 自动刷新拦截器 4h
合计 ~31h

Phase 2: 性能优化 (第 3-4 周)

# 问题 ID 修复项 预估工时
1 8a-C01-04 修复后端 4 个 N+1 查询 8h
2 8b-D01-03 修复 Isar 索引 + 分页 + N+1 6h
3 8a-H01 mood_stats 改用 SQL GROUP BY 2h
4 8b-M02 笔画光栅化改为 BBox 裁剪 4h
5 8b-N01 SyncEngine 合并同资源操作 4h
合计 ~24h

Phase 3: 质量提升 (第 5-8 周)

# 问题 ID 修复项
1 9b 全部 补充后端集成测试 + Flutter BLoC 测试
2 9a-SYNC-01 统一同步协议
3 5a-H01 创建端点改返回 201
4 5b-C03 添加 DiaryApiDoc OpenAPI 文档
5 F-01 分阶段添加无障碍性 Semantics
6 B-03 DiaryEvent 枚举接入 EventBus

📊 各模块 CRITICAL+HIGH 热力图

                    CRITICAL  HIGH   风险等级
 ──────────────────────────────────────────
 安全               ████████  ████    🔴 极高
 后端架构           ███       ██████  🟠 高
 数据库             █████     ████    🔴 极高
 API 设计           ████████  ████    🔴 极高
 基础设施           ████████  ██████  🔴 极高
 文档               ██        ████    🟡 中
 性能               ██████    ██████  🔴 极高
 跨层一致性         ████████  ██████  🔴 极高
 前端质量           █         █       🟡 中

结论

暖记项目的架构设计和基础建设质量优秀(模块边界、加密体系、多租户框架、手写引擎),但在实施完整性和工程纪律方面存在系统性缺口:

  1. 输入验证系统性缺失 — erp-diary 全部 DTO 无 Validate是最高频问题
  2. RLS 变量名 bug — 一个拼写错误导致 15 张表 RLS 失效,是最高优先修复
  3. 同步协议断裂 — Flutter 和 Rust 实现了两套不兼容的同步机制
  4. 权限覆盖不完整 — 审计日志/文件上传无守卫,多个权限码未注册
  5. 性能 N+1 查询 — 后端 4 处 + Flutter 3 处 N+1随数据增长将严重影响体验

建议: 按 Phase 0 → Phase 3 路线图推进修复,优先解决数据安全和完整性问题。


附录 A: 步骤 7a — Wiki + 规划文档准确性审计

审计范围: wiki/ (7文件), plans/ (6文件), docs/tech-debt-board.md

CRITICAL — 文档数字严重过时

ID 问题 文件 说明
7a-C1 erp-diary 代码量严重过时 wiki/index.md, architecture.md, erp-diary.md 三处文档分别声称 5,108/5,100/5,500 行。实际 7,021 行。handler/service/dto 行数全部过时
7a-C2 前端测试状态严重错误 wiki/frontend.md, tech-debt-board.md, project-health.md 声称"前端测试为零"。实际已有 8 个测试文件、85 个测试用例 (4c743e1 起存在)
7a-C3 Dart 文件数与代码量过时 wiki/index.md 声称 74 个文件/19,500 行。实际 100 个文件/29,617 行,偏差超 50%
7a-C4 Git 提交数过时 wiki/index.md 声称 22 次提交。实际 69 次提交,基线 8111471 → HEAD d482497
7a-C5 管理端 TS 文件数过时 wiki/index.md 声称约 317 个。实际 143 个,差异极大

HIGH — 重要不准确

ID 问题 文件
7a-H1 Feature Flag 状态自相矛盾 — 实际已落地 wiki/architecture.md
7a-H2 Dockerfile 不存在的描述已过时 architecture.md, erp-diary.md, tech-debt-board.md
7a-H3 isar_database.dart 行数声称 72 行实际 14 行 wiki/data-layer.md
7a-H4 data-layer.md 多个文件行数全部偏低 wiki/data-layer.md
7a-H5 erp-diary.md 缺少 parent_handler 和 parent_service wiki/erp-diary.md
7a-H6 admin-web.md 描述不存在的目录 (api/ai/, Copilot/) wiki/admin-web.md
7a-H7 tech-debt-board TD-5 "前端测试为零" 严重过时 docs/tech-debt-board.md
7a-H8 tech-debt-board TD-1 authorId 已部分修复但状态未更新 docs/tech-debt-board.md
7a-H9 tech-debt-board TD-3 Docker 部署描述不完整 docs/tech-debt-board.md

做得好的方面 (文档体系)

  • 文档结构规范 — 所有 wiki 页面遵循 5 节结构(设计决策/关键文件/代码逻辑/活跃问题/变更记录)
  • 交叉引用体系 — [[wikilink]] 引用 + 症状导航表构成知识网络
  • 集成契约表 — 清晰描述模块间调用方向、接口和触发时机
  • 不变量标注 — 闪电符号标记开发守则("所有查询带 tenant_id"等)
  • 变更记录 — 每个文档底部有 commit hash 可追溯
  • 历史教训记录 — 记录具体踩坑经历Isar import、GestureDetector 延迟等)

文档修复建议

  1. 以 wiki/index.md 的"关键数字"表为单一事实来源,其他页面引用而非重复声明
  2. 更新 wiki/index.md 关键数字表(提交数 69, Dart 文件 100, erp-diary 行 7,021
  3. 更新 wiki/erp-diary.md 的代码量分布表和 Service/Handler 清单
  4. 更新 docs/tech-debt-board.md 的 TD-5已有测试、TD-3Dockerfile 已存在)
  5. 更新 wiki/architecture.md 的 Feature Flag 状态和 Docker 部署描述
  6. 更新 wiki/admin-web.md 的目录树和 API 目录描述