新增 wiki/ 知识库 (遵循 HMS wiki-methodology.md 5 节结构): - index.md (84 行) — 症状导航 13 条 + 模块索引 + 系统数据流 - architecture.md (120 行) — 基座剥离 7 耦合点 + Feature Flag + PIPL 合规 - handwriting-engine.md (124 行) — 双层 Canvas + O(1) 点缓冲 + 光栅化缓存 - data-layer.md (127 行) — Isar + SyncEngine 离线同步 + 踩坑记录 - frontend.md (118 行) — 16 模块地图 + BLoC 注入链 + 设计系统 - erp-diary.md (101 行) — 15 Entity / 10 Service / 8 Handler + API 端点 新增 docs/: - tech-debt-board.md (110 行) — 10 条技术债 + 偿还优先级排名 其他更新: - .gitignore: 添加 .understand-anything/ (待初始化) - CLAUDE.md §9: 添加 wiki 参考文档链接
102 lines
4.1 KiB
Markdown
102 lines
4.1 KiB
Markdown
---
|
||
title: erp-diary 后端模块
|
||
updated: 2026-06-01
|
||
status: active
|
||
tags: [rust, axum, seaorm, diary, api]
|
||
---
|
||
|
||
# erp-diary — 暖记后端业务模块
|
||
|
||
> 从 [[index]] 导航。关联: [[architecture]] [[data-layer]]
|
||
|
||
## 1. 设计决策
|
||
|
||
### Q: 为什么独立 erp-diary crate?
|
||
|
||
基座解耦原则:erp-diary 通过 Feature Flag (`cargo build --features diary`) 按需引入。基座 crate 不依赖业务模块,其他项目可复用基座而不引入日记功能。
|
||
|
||
### Q: DiaryError 设计?
|
||
|
||
15 种变体枚举(NotFound / VersionConflict / Unauthorized / ContentUnsafe 等),实现 `Into<AppError>` 转换为 HTTP 状态码映射。集成测试验证每个错误码的正确 HTTP 响应。
|
||
|
||
### Q: 为什么内容安全过滤在 Service 层?
|
||
|
||
日记标题、文字元素的文本需要敏感词检查(含谐音/拼音变体)。放在 Service 层而非 Handler 层,确保即使有新的入口点(事件消费、管理 API)也不会绕过检查。
|
||
|
||
## 2. 关键文件 + 数据流
|
||
|
||
### 模块结构
|
||
|
||
```
|
||
crates/erp-diary/src/
|
||
├── lib.rs (206 行) — DiaryModule 实现 + Feature Flag 注册
|
||
├── dto.rs (569 行) — 请求/响应 DTO + Validate 注解
|
||
├── error.rs (193 行) — DiaryError 15 种变体 → HTTP 状态码
|
||
├── event.rs (61 行) — 事件定义 (diary.created 等)
|
||
├── state.rs (13 行) — DiaryState (DiaryModule 专用状态)
|
||
├── entity/ (15 文件) — SeaORM Entity
|
||
├── service/ (10 文件) — 业务逻辑
|
||
└── handler/ (8 文件) — HTTP Handler + utoipa 注解
|
||
```
|
||
|
||
### Entity 清单 (15 个)
|
||
|
||
achievement, class_member, comment, handwriting_stroke, journal_element, journal_entry, parent_child_binding, school_class, sticker, sticker_pack, teacher_profile, template, topic_assignment, user_achievement, user_settings
|
||
|
||
### Service 清单 (10 个)
|
||
|
||
journal, class, comment, content_safety, achievement, mood_stats, notification, sticker, sync, topic
|
||
|
||
### API 端点
|
||
|
||
| 端点前缀 | Handler | 主要操作 |
|
||
|---------|---------|---------|
|
||
| `/api/v1/diary/journals` | journal_handler | CRUD + 列表过滤 |
|
||
| `/api/v1/diary/journals/:id/elements` | journal_handler (同) | 元素 CRUD |
|
||
| `/api/v1/diary/classes` | class_handler | 班级 CRUD + 班级码 |
|
||
| `/api/v1/diary/comments` | comment_handler | 评论 CRUD |
|
||
| `/api/v1/diary/topics` | topic_handler | 主题布置 |
|
||
| `/api/v1/diary/achievements` | achievement_handler | 成就系统 |
|
||
| `/api/v1/diary/stickers` | sticker_handler | 贴纸管理 |
|
||
| `/api/v1/diary/stats` | stats_handler | 心情/写作统计 |
|
||
| `/api/v1/diary/sync` | sync_handler | 增量同步 API |
|
||
|
||
### 集成契约
|
||
|
||
| 方向 | 模块 | 接口 | 触发时机 |
|
||
|------|------|------|---------|
|
||
| 提供 → | erp-server | `DiaryModule::routes()` | 启动 feature=diary |
|
||
| 调用 → | erp-core | `EventBus::publish()` | 日记创建/更新/删除 |
|
||
| 调用 → | erp-auth | `require_permission()` | 每个 handler 入口 |
|
||
| 调用 → | erp-message | 通知服务 | 评论/班级事件 |
|
||
|
||
## 3. 代码逻辑
|
||
|
||
### 不变量
|
||
|
||
⚡ **所有 Entity 含标准字段** — id / tenant_id / created_at / updated_at / created_by / updated_by / deleted_at / version
|
||
|
||
⚡ **软删除** — 查询带 `deleted_at IS NULL` 过滤,不做硬删除
|
||
|
||
⚡ **多租户隔离** — 中间件注入 tenant_id,handler 不从 API 路径获取
|
||
|
||
⚡ **权限守卫** — 每个 handler 方法第一行 `require_permission("diary.xxx")`
|
||
|
||
⚡ **输入验证** — DTO 使用 `#[derive(Validate)]` + handler 层调 `.validate()`
|
||
|
||
⚡ **内容安全** — 日记标题/文字通过 ContentSafetyService 检查
|
||
|
||
## 4. 活跃问题 + 陷阱
|
||
|
||
| 问题 | 级别 | 状态 | 说明 |
|
||
|------|------|------|------|
|
||
| Docker 部署未验证 | HIGH | 待做 | docker/ 目录存在但未实际运行 |
|
||
| CI/CD 未建立 | MEDIUM | 待做 | 无自动化构建/测试/部署 |
|
||
| 文件上传未实现 | MEDIUM | 待做 | 照片/贴纸文件上传参考健康模块 |
|
||
|
||
## 5. 变更记录
|
||
|
||
| 日期 | 变更 |
|
||
|------|------|
|
||
| 2026-06-01 | 初始创建 — Entity/Service/Handler 清单、API 端点、集成契约 |
|