docs: rewrite CLAUDE.md for Nuanji project
- Replaced HMS CLAUDE.md with project-specific documentation - Covers architecture (base.git + erp-diary + Flutter), tech stack, design system - Defines PIPL compliance requirements and child safety rules - Specifies performance targets (handwriting < 16ms, 60fps, offline-first) - Includes commit conventions, scope names, and scenario-based instructions - References product spec v1.2 and implementation plan v2.1
This commit is contained in:
714
CLAUDE.md
714
CLAUDE.md
@@ -1,535 +1,375 @@
|
||||
@wiki/index.md
|
||||
整个项目对话都使用中文进行,包括文档、代码注释、事件名称等。
|
||||
# 暖记 (Warm Notes) — 项目协作规则
|
||||
|
||||
# HMS 健康管理平台 — 协作与实现规则
|
||||
> **Nuanji** — 温暖治愈风格的手账日记 app,以手写/涂鸦为核心输入,面向小学生首发。
|
||||
> **当前阶段: Phase 1 实施。** 基座剥离 + 项目初始化已完成,开始功能开发。
|
||||
|
||||
> **Health Management System (HMS)** — 面向体检中心/医疗机构的综合健康管理平台。从 ERP 底座分叉独立,继承身份权限/工作流/消息/配置等基础能力,`erp-health` 原生模块承载医疗业务。
|
||||
整个项目对话都使用中文进行,包括文档、代码注释、提交信息等。
|
||||
|
||||
> **当前阶段: erp-health 模块开发。** 设计规格已确认,开始实施。
|
||||
---
|
||||
|
||||
## 1. 项目定位
|
||||
|
||||
### 1.1 这是什么
|
||||
|
||||
一个 **健康管理 + ERP 基础设施** 架构的医疗 SaaS 平台:
|
||||
一个**手写优先的手账日记 app**,核心价值是保留用户真实笔迹:
|
||||
|
||||
- **医疗核心** — 患者管理、健康数据、预约排班、随访管理、咨询管理(原生 Rust 模块 erp-health)
|
||||
- **基础底座** — 身份权限、工作流引擎、消息中心、系统配置(继承自 ERP)
|
||||
- **多租户 + 私有化** — 默认 SaaS 共享数据库隔离,支持独立 schema 私有部署
|
||||
- **Web 优先** — 浏览器 SPA 是 PC 管理后台主力,小程序(患者端/医护端)独立开发
|
||||
- **手写引擎** — CustomPainter + perfect_freehand,< 16ms 延迟,掌心抑制,四种画笔
|
||||
- **手账体验** — 贴纸、涂鸦、照片、和纸胶带——不只是打字,是可以装饰的手账
|
||||
- **班级连接** — 老师布置主题 → 学生写作 → 老师点评,培养写作习惯
|
||||
- **成长记录** — 心情追踪、成就徽章、日历回顾,看见自己的变化
|
||||
|
||||
### 1.2 决策原则
|
||||
### 1.2 架构概览
|
||||
|
||||
**任何改动都要问:这对健康管理平台的医疗业务和可扩展性有帮助吗?**
|
||||
```
|
||||
nj/ (一个仓库)
|
||||
├── crates/ # Rust 后端 (Cargo Workspace)
|
||||
│ ├── erp-core/ # 基座 — 模块系统/事件/加密/错误
|
||||
│ ├── erp-auth/ # 基座 — JWT/RBAC/用户/角色
|
||||
│ ├── erp-config/ # 基座 — 字典/菜单/设置
|
||||
│ ├── erp-message/ # 基座 — 消息/通知/SSE
|
||||
│ ├── erp-workflow/ # 基座 — BPMN 工作流
|
||||
│ ├── erp-plugin/ # 基座 — WASM 插件运行时
|
||||
│ ├── erp-server/ # Axum 入口 + 迁移 + 路由组装
|
||||
│ │ └── migration/ # SeaORM 迁移 (53 基座 + 暖记迁移)
|
||||
│ └── erp-diary/ # 🆕 暖记业务模块 (~5800 行新增)
|
||||
│ ├── src/entity/ # ~15 Entity (日记/班级/贴纸/心情...)
|
||||
│ ├── src/service/ # ~12 Service
|
||||
│ ├── src/handler/ # ~10 Handler
|
||||
│ └── src/{dto,error,event,state}.rs
|
||||
├── app/ # Flutter 前端 (待创建)
|
||||
├── config/ # 服务器配置
|
||||
├── docker/ # Docker Compose (PG + Redis)
|
||||
├── docs/ # 产品文档
|
||||
│ └── superpowers/specs/ # 设计规格 v1.2
|
||||
└── plans/ # 实施规划
|
||||
```
|
||||
|
||||
- ✅ 完善模块接口和 trait 定义 → 最高优先
|
||||
- ✅ 确保多租户隔离的正确性 → 最高优先
|
||||
- ✅ 按计划推进 Phase 交付物 → 高优先
|
||||
- ✅ 清晰的模块边界和事件契约 → 高优先
|
||||
- ❌ 跳过 Phase 顺序提前实现远期功能 → 禁止
|
||||
### 1.3 基座继承 vs 新增开发
|
||||
|
||||
基座从 HMS (G:\hms) 剥离,推送到 `base.git`,nj 项目克隆后添加 `erp-diary`。
|
||||
|
||||
| 能力 | 来源 | 工作量 |
|
||||
|------|------|--------|
|
||||
| 用户/角色/权限 CRUD | erp-auth 继承 | 零开发 |
|
||||
| JWT + Token 轮换 | erp-auth 继承 | 零开发 |
|
||||
| RBAC 权限码守卫 | erp-auth 继承 | 零开发 |
|
||||
| 事件总线 + Outbox | erp-core 继承 | 零开发 |
|
||||
| PII 加密 + 盲索引 | erp-core 继承 | 零开发 |
|
||||
| 审计日志(哈希链) | erp-core 继承 | 零开发 |
|
||||
| 多租户隔离 (RLS) | erp-core 继承 | 零开发 |
|
||||
| 字典/菜单/设置 | erp-config 继承 | 零开发 |
|
||||
| 消息/通知/SSE | erp-message 继承 | 零开发 |
|
||||
| BPMN 工作流 | erp-workflow 继承 | 零开发 |
|
||||
| SeaORM 迁移框架 | erp-server 继承 | 零开发 |
|
||||
| OpenAPI 文档 | utoipa 继承 | 零开发 |
|
||||
| student/teacher/parent 角色 | erp-auth 扩展 | 🆕 ~200 行 |
|
||||
| 班级码认证 | erp-auth 扩展 | 🆕 ~500 行 |
|
||||
| 日记 CRUD + 同步 | erp-diary 新增 | 🆕 ~2000 行 |
|
||||
| 班级管理 | erp-diary 新增 | 🆕 ~800 行 |
|
||||
| 贴纸/模板管理 | erp-diary 新增 | 🆕 ~600 行 |
|
||||
| 心情/统计 API | erp-diary 新增 | 🆕 ~500 行 |
|
||||
| 内容安全过滤 | erp-diary 新增 | 🆕 ~300 行 |
|
||||
| 文件上传(照片/贴纸) | 参考健康模块 | 🆕 ~500 行 |
|
||||
| **新增合计** | | **~5800 行 Rust** |
|
||||
|
||||
### 1.4 仓库关系
|
||||
|
||||
```
|
||||
HMS (G:\hms) [只读,使用中的生产项目]
|
||||
│
|
||||
└─复制→ base.git https://git.stableeasy.com/iven/base.git
|
||||
│ (通用 ERP 基座,所有新项目的基础)
|
||||
│
|
||||
└─克隆→ nj.git https://git.stableeasy.com/iven/nj.git
|
||||
(暖记项目 = 基座 + erp-diary + Flutter 前端)
|
||||
```
|
||||
|
||||
**关键约束:G:\hms 只读,绝不修改。**
|
||||
|
||||
### 1.5 决策原则
|
||||
|
||||
**任何改动都要问:这对小学生的手写日记体验和数据安全有帮助吗?**
|
||||
|
||||
- ✅ 手写引擎性能优化 → 最高优先(核心价值)
|
||||
- ✅ 儿童数据安全与 PIPL 合规 → 最高优先
|
||||
- ✅ 离线优先体验 → 高优先
|
||||
- ✅ 模块边界清晰 → 高优先
|
||||
- ❌ 提前实现 Phase 2+ 功能 → 禁止
|
||||
- ❌ 在模块间创建直接耦合 → 永远不做
|
||||
- ❌ 硬编码租户 ID 或绕过多租户中间件 → 永远不做
|
||||
- ❌ 过度设计未来才需要的能力 → 永远不做
|
||||
|
||||
### 1.3 架构铁律
|
||||
|
||||
| 约束 | 原因 |
|
||||
|------|------|
|
||||
| 模块间只通过事件总线和 trait 通信 | 保证模块可独立拆分为微服务 |
|
||||
| 所有数据表必须含 `tenant_id` | 多租户是核心能力,不可事后补 |
|
||||
| 使用 UUID v7 作为主键 | 时间排序 + 唯一性,分布式友好 |
|
||||
| 软删除,不硬删除 | ERP 数据不可丢失,审计追溯需要 |
|
||||
| 所有 API 使用 `/api/v1/` 前缀 | 版本化是 SaaS 产品的基本要求 |
|
||||
- ❌ 硬编码密钥或绕过多租户中间件 → 永远不做
|
||||
|
||||
---
|
||||
|
||||
## 2. 工作风格
|
||||
## 2. 技术栈
|
||||
|
||||
### 2.1 按计划推进
|
||||
### 2.1 后端 (Rust)
|
||||
|
||||
- **严格按 Phase 顺序执行** — Phase 2 依赖 Phase 1 的基础设施
|
||||
- **每个 Task 完成后立即提交** — 不积压,保持可追溯
|
||||
- **先测试后实现** — TDD 流程:写失败测试 → 实现 → 通过 → 提交
|
||||
| 层级 | 技术 | 用途 |
|
||||
|------|------|------|
|
||||
| 框架 | Axum 0.8 | HTTP 服务 |
|
||||
| ORM | SeaORM 1.1 | 数据库操作 |
|
||||
| 数据库 | PostgreSQL 16 | 主存储 |
|
||||
| 缓存 | Redis 7 | 速率限制/会话 |
|
||||
| 认证 | JWT + Argon2 + RBAC | 继承基座 |
|
||||
| 加密 | AES-256-GCM + KEK/DEK | 儿童数据加密 |
|
||||
| 文档 | utoipa (OpenAPI) | API 文档 |
|
||||
| 事件 | EventBus + Outbox | 模块间通信 |
|
||||
|
||||
### 2.2 分步编写文档(强制)
|
||||
### 2.2 前端 (Flutter)
|
||||
|
||||
编写计划、设计文档、实施报告等长文档时,**必须分步编写**,禁止一次性输出全文:
|
||||
| 层级 | 技术 | 用途 |
|
||||
|------|------|------|
|
||||
| UI | Flutter 3.x | 跨平台 (Android/iOS 首发) |
|
||||
| 状态 | flutter_bloc (BLoC) | 复杂交互状态管理 |
|
||||
| 存储 | Isar | 本地数据库 + FTS + 加密 |
|
||||
| 手写 | CustomPainter + perfect_freehand | 笔迹保真 |
|
||||
| 图表 | fl_chart | 心情趋势/统计 |
|
||||
| 路由 | go_router | 声明式路由 |
|
||||
| 网络 | dio + connectivity_plus | API + 离线检测 |
|
||||
| 模型 | freezed + json_serializable | 不可变数据模型 |
|
||||
|
||||
1. **先写大纲** — 确认文档结构和章节划分
|
||||
2. **逐章编写** — 每次只写 1-2 个章节,写完确认后继续下一章
|
||||
3. **最终整合** — 所有章节完成后合并为完整文档
|
||||
### 2.3 设计系统
|
||||
|
||||
**原因:** 上下文过长会导致输出截断或卡死。分步编写保证每步都能完整输出,且用户可以中途调整方向。
|
||||
| Token | 浅色 | 深色 | 用途 |
|
||||
|-------|------|------|------|
|
||||
| bg | #FFF8F0 | #1A1614 | 奶油白背景 |
|
||||
| accent | #E07A5F | #E8907A | 珊瑚色主色 |
|
||||
| secondary | #81B29A | #8FBF9E | 鼠尾草绿 |
|
||||
| tertiary | #F2CC8F | #D4B878 | 暖金 |
|
||||
| fg | #2D2420 | #F0E8DF | 主文字 |
|
||||
| surface | #FFFFFF | #2A2520 | 卡片背景 |
|
||||
| rose | #D4A5A5 | #C4A0A0 | 玫瑰粉 |
|
||||
|
||||
**适用范围:** 超过 200 行的文档、实施计划、设计规格、技术报告等。简短的 bugfix 说明、单页 wiki 更新不受此限制。
|
||||
字体:Noto Sans SC (显示+正文) / Caveat (手写风格) / JetBrains Mono (等宽)
|
||||
圆角:10/16/22/28/pill | 触摸目标 ≥ 44px | 动画曲线 cubic-bezier(0.34, 1.56, 0.64, 1)
|
||||
|
||||
### 2.3 讨论记录
|
||||
---
|
||||
|
||||
每次发散式讨论(brainstorming、方案探索、需求梳理、技术选型等)**必须建立独立文档**:
|
||||
## 3. 工作风格
|
||||
|
||||
- **存放位置:** `docs/discussions/YYYY-MM-DD-{主题简称}.md`
|
||||
- **文档格式:**
|
||||
```markdown
|
||||
# {讨论主题}
|
||||
> 日期: YYYY-MM-DD | 参与者: ...
|
||||
### 3.1 闭环工作法
|
||||
|
||||
## 背景
|
||||
为什么会有这次讨论
|
||||
每次改动按顺序完成:
|
||||
|
||||
## 讨论要点
|
||||
- 要点 1
|
||||
- 要点 2
|
||||
1. **现状确认** — 搜索已有代码,明确"已有"和"缺失"
|
||||
2. **理解需求** — 确认改动目标模块和影响范围
|
||||
3. **最小实现** — 只改必要的代码,保持模块边界
|
||||
4. **验证通过**:
|
||||
- `cargo check` — 后端编译无错误
|
||||
- `cargo test` — 所有测试通过
|
||||
- `flutter analyze` — 前端分析无错误 (涉及前端时)
|
||||
5. **提交 + 推送** — 按 §6 规范提交,立即推送
|
||||
|
||||
## 结论 / 待定
|
||||
达成的共识或遗留问题
|
||||
```
|
||||
- **时机:** 讨论结束后立即创建,不要积压。如果讨论横跨多个主题,拆分为多份文档。
|
||||
- **用途:** 作为后续实施的输入和决策追溯的依据,避免"之前讨论过但忘了结论"。
|
||||
|
||||
### 2.4 模块化思维
|
||||
### 3.2 模块化思维
|
||||
|
||||
开发任何功能时先问:
|
||||
|
||||
1. **它属于哪个模块?** — 不确定就放到 `erp-core` 共享层
|
||||
2. **它的接口是什么?** — 先定义 trait,再实现
|
||||
3. **它需要发什么事件?** — 跨模块通知必须走事件总线
|
||||
4. **其他模块怎么发现它?** — 通过 `ErpModule` trait 注册
|
||||
1. **它属于哪个 crate?** — 后端在 `erp-diary`,前端在 `lib/features/`
|
||||
2. **它的接口是什么?** — 后端先定义 Entity + DTO,前端先定义 freezed model
|
||||
3. **它需要发什么事件?** — diary.created / diary.shared 等
|
||||
4. **它影响离线体验吗?** — 所有功能必须离线可用
|
||||
|
||||
### 2.5 闭环工作法(强制)
|
||||
### 3.3 分步编写文档
|
||||
|
||||
每次改动**必须**按顺序完成以下步骤,不允许跳过:
|
||||
|
||||
0. **阅读 Wiki(强制起点)** — 收到任何任务后,**先读 wiki 再动手**:
|
||||
- 读取 `wiki/index.md` 了解项目全貌和当前进度
|
||||
- 根据任务涉及的范围,读取相关 wiki 页面(`wiki/infrastructure.md`、`wiki/testing.md`、`wiki/wasm-plugin.md` 等)
|
||||
- wiki 中包含实际的环境配置(数据库连接、端口、登录凭据、启动方式),不看 wiki 就无法正确验证
|
||||
- **违反此步骤 = 盲目工作,浪费时间去猜环境配置,产出不可信**
|
||||
1. **现状确认(强制)** — 动手之前,先检查代码里已经有什么:
|
||||
- 用 Grep/Glob/Read 工具搜索相关文件,确认哪些能力已存在
|
||||
- 明确列出"已有"和"缺失",不允许凭印象断言缺失
|
||||
- 如果不确定现有实现状态,停下来问用户,不要编造
|
||||
- 违反此步骤 = 所有后续工作可能脱离实际,白费力气
|
||||
2. **理解需求** — 确认改动的目标模块和影响范围
|
||||
3. **最小实现** — 只改必要的代码,保持模块边界
|
||||
4. **验证通过** — 必须全部通过才可继续:
|
||||
- `cargo check` — 编译无错误
|
||||
- `cargo test --workspace` — 所有测试通过(有相关测试时)
|
||||
- 功能验证 — 启动后端 + 前端服务,在浏览器中实际操作验证改动生效(涉及 API 或 UI 时)
|
||||
- `pnpm build` — 前端生产构建通过(涉及前端时)
|
||||
5. **提交 + 文档 + 推送(三合一,强制)** — 验证通过后按顺序执行:
|
||||
- a. 按 §5 规范提交代码
|
||||
- b. 检查本次变更是否触发 wiki 更新(见下方 wiki 更新触发条件),触发则更新后单独 `docs(wiki)` 提交
|
||||
- c. `git push` 立即推送,不允许"等一下再推"
|
||||
- **禁止连续 5 个非 docs 提交而不更新 wiki 关键数字**
|
||||
|
||||
#### wiki 更新触发条件(步骤 5b 的判定标准)
|
||||
|
||||
以下任一条件满足时,**必须**更新 wiki 后才能继续下一任务:
|
||||
|
||||
- **fix 提交** → `wiki/index.md` 症状导航新增条目或标记"已修复"
|
||||
- **feat 提交(新功能)** → `wiki/index.md` 关键数字更新 + 对应模块 wiki 页更新(实体数/路由数/端点数等)
|
||||
- **数据库迁移变化** → 关键数字中的迁移数/表数更新
|
||||
- **API 路由变化** → 路由数更新
|
||||
- **测试数量变化** → 测试数/断言数更新
|
||||
- **连续 5 个代码提交** → 强制做一次 wiki/index.md 关键数字全文校正(对比代码实际数量)
|
||||
|
||||
**铁律:**
|
||||
- **步骤 0 阅读 Wiki 是绝对起点** — 不读 wiki 就开干 = 连环境配置都不知道,所有验证步骤都是空谈。
|
||||
- **步骤 1 现状确认是强制起点** — 不检查就开干 = 脱离实际,所有产出不可信。
|
||||
- **步骤 4 功能验证必须实际操作** — 只看编译通过不算验证,必须启动服务、在浏览器中确认功能正常。
|
||||
- **步骤 5 三合一是强制流程** — 提交后必须检查 wiki、必须推送,缺一不可。
|
||||
- **每次新会话开始时,先检查是否有未推送的提交并立即推送**。
|
||||
|
||||
### 2.6 Feature DoD — 功能完成定义(强制)
|
||||
|
||||
> 历史数据显示 24% 的提交是 fix,根因是缺少统一的完成标准。
|
||||
> 每个功能标记"完成"前,**必须**逐项检查以下清单,不允许跳过。
|
||||
|
||||
#### 后端
|
||||
|
||||
- [ ] Entity 包含所有标准字段(`id`/`tenant_id`/`created_at`/`updated_at`/`created_by`/`updated_by`/`deleted_at`/`version`)
|
||||
- [ ] Handler 添加 `require_permission` 权限守卫
|
||||
- [ ] 权限码已写入 seed 迁移(每个实体 `.list` + `.manage`,权限码前缀与实体名一致)
|
||||
- [ ] utoipa 注解已添加(`#[derive(utoipa::OpenApi)]` + path/response schema)
|
||||
- [ ] Service 层核心路径有单元/集成测试
|
||||
- [ ] 多租户隔离正确(所有查询含 `tenant_id` 过滤,无手写 SQL 拼接)
|
||||
- [ ] 输入验证完整(必填字段 + 格式校验 + 长度限制)
|
||||
- [ ] 错误处理统一(`AppError`,不 panic,不 unwrap 生产代码)
|
||||
- [ ] 关键操作有 `tracing` 日志(info/warn/error 级别合理)
|
||||
|
||||
#### 前端(Web)
|
||||
|
||||
- [ ] API 路径与后端 OpenAPI spec 一致(不手写路径,从 `api/health/` 模块调用)
|
||||
- [ ] 路由声明权限码(`permissions: [...]`),与后端 handler 一致
|
||||
- [ ] 菜单配置已更新(`parent_id` 正确 + `permission` 字段 + `menu_roles` 关联)
|
||||
- [ ] 错误状态有用户友好提示(不显示原始 error message)
|
||||
- [ ] 不使用 `any` 类型(用 `unknown` + 类型守卫)
|
||||
|
||||
#### 前端(小程序)
|
||||
|
||||
- [ ] Service 层接口契约与后端 DTO 一致(字段名/类型/结构体)
|
||||
- [ ] 登录态处理正确(`useDidShow` 恢复认证、退出清理 Storage)
|
||||
- [ ] 页面间数据通过 API 获取,不用 Storage 传递
|
||||
- [ ] 长者模式适配完成(字号 ≥ 22px)
|
||||
- [ ] 图片使用合法 URL(HTTPS 或相对路径,不用 HTTP)
|
||||
|
||||
#### 安全
|
||||
|
||||
- [ ] 新增端点有权限声明(默认拒绝,不是默认放行)
|
||||
- [ ] 敏感数据有脱敏/加密处理(PII 字段走 AES-256-GCM)
|
||||
- [ ] 用户输入已验证和消毒(防 SQL 注入、XSS、命令注入、路径穿越)
|
||||
- [ ] 无 CORS 通配符、无硬编码密钥、无 fallback 默认密钥
|
||||
- [ ] 日志中无敏感数据输出(密码、token、身份证号、手机号等)
|
||||
- [ ] 文件上传有 MIME 类型验证 + 大小限制 + 路径穿越防护
|
||||
- [ ] API 响应不暴露内部实现细节(数据库错误、堆栈跟踪、文件路径)
|
||||
- [ ] 速率限制已配置(认证端点更严格)
|
||||
- [ ] 密钥通过环境变量注入,`.env.example` 已同步更新
|
||||
|
||||
#### 文档一致性
|
||||
|
||||
- [ ] `wiki/index.md` 关键数字与代码实际状态一致(迁移数、路由数、实体数、测试数等)
|
||||
- [ ] 新增/修复的 bug 已记录在症状导航中(含根因+解决方案)
|
||||
- [ ] 新增功能已记录在对应模块 wiki 页面中(实体、端点、事件等)
|
||||
- [ ] wiki 页面的"最后更新"日期已刷新为当天
|
||||
|
||||
#### 端到端验证
|
||||
|
||||
- [ ] `cargo check` 全 workspace 通过
|
||||
- [ ] `cargo test` 全部通过
|
||||
- [ ] 浏览器中手动验证功能正常(列表/创建/编辑/删除/权限拦截)
|
||||
- [ ] 小程序中验证(涉及小程序页面时)
|
||||
- [ ] 相关路由权限按角色测试通过(至少 admin + 只读角色)
|
||||
- [ ] 本地提交已推送到远程仓库
|
||||
超过 200 行的文档必须分步编写:
|
||||
1. 先写大纲 → 2. 逐章编写 → 3. 最终整合
|
||||
|
||||
---
|
||||
|
||||
## 3. 实现规则
|
||||
## 4. 实现规则
|
||||
|
||||
### 3.1 错误处理
|
||||
### 4.1 后端 (Rust/erp-diary)
|
||||
|
||||
- **跨 crate 边界**:使用 `thiserror` 定义类型化错误,转换为 `AppError`
|
||||
- **crate 内部**:可以使用 `anyhow`,但**永远不**跨越 crate 边界
|
||||
- **数据库错误**:通过 `From<sea_orm::DbErr>` 自动转换为 `AppError`
|
||||
- **验证错误**:包含字段级详情,方便 UI 渲染
|
||||
#### 错误处理
|
||||
- 使用 `DiaryError` 枚举,转换为 `AppError`
|
||||
- 集成测试验证每个错误码的 HTTP 状态映射
|
||||
|
||||
### 3.2 数据库操作
|
||||
#### 数据库
|
||||
- 所有 Entity 包含标准字段:`id`, `tenant_id`, `created_at`, `updated_at`, `created_by`, `updated_by`, `deleted_at`, `version`
|
||||
- 所有查询带 `tenant_id` 过滤(中间件注入)
|
||||
- 软删除,不硬删除
|
||||
- `version` 字段乐观锁(同步冲突检测核心)
|
||||
|
||||
- 所有 SeaORM Entity 必须包含:`id`, `tenant_id`, `created_at`, `updated_at`, `created_by`, `updated_by`, `deleted_at`, `version`
|
||||
- 查询时**始终**带 `tenant_id` 过滤(中间件自动注入)
|
||||
- 更新时检查 `version` 字段实现乐观锁
|
||||
- 删除使用软删除(设置 `deleted_at`)
|
||||
#### API 设计
|
||||
- 端点使用 `/api/v1/diary/` 前缀
|
||||
- 权限守卫 `require_permission` 在 handler 层
|
||||
- utoipa 注解所有端点
|
||||
- 租户 ID 从 JWT 中间件注入,不在 API 路径中传递
|
||||
|
||||
### 3.3 API 设计
|
||||
#### 新增 Entity 检查清单
|
||||
- [ ] 包含所有标准字段(id/tenant_id/created_at/.../version)
|
||||
- [ ] handler 有 `require_permission` 权限守卫
|
||||
- [ ] 权限码写入 seed 迁移
|
||||
- [ ] utoipa 注解已添加
|
||||
- [ ] 多租户隔离正确
|
||||
- [ ] 输入验证完整(Validate derive)
|
||||
|
||||
- 所有端点使用 `/api/v1/` 前缀
|
||||
- 响应统一使用 `ApiResponse<T>` 包装
|
||||
- 分页使用 `Pagination` + `PaginatedResponse<T>`
|
||||
- utoipa 自动生成 OpenAPI 文档
|
||||
- 租户 ID 从 JWT 中间件注入,**不在** API 路径中传递(管理员接口除外)
|
||||
### 4.2 前端 (Flutter)
|
||||
|
||||
#### 新增 API 端点安全检查(强制)
|
||||
|
||||
> 默认拒绝是安全基线 — 绝大多数安全修复源于默认放行模式。
|
||||
> 新增端点时**必须**逐项确认:
|
||||
|
||||
- [ ] 端点已添加 `require_permission` 权限守卫(非公开端点)
|
||||
- [ ] 公开端点已显式标记为 `public`(不继承认证中间件)
|
||||
- [ ] 路由使用 `.nest()` 注册带中间件的子路由(禁止 `.merge()` 防止中间件泄漏)
|
||||
- [ ] 敏感操作有速率限制
|
||||
- [ ] 无 `format!` 拼接 SQL — 所有查询使用 SeaORM 参数化
|
||||
- [ ] FHIR/第三方端点有 `tenant_id` 和 `allowed_patient_ids` 范围过滤
|
||||
- [ ] 无硬编码密钥或 fallback 默认值
|
||||
|
||||
#### 前后端接口同步检查(强制)
|
||||
|
||||
> 前后端接口不一致是高频 bug 来源 — 任何 DTO 变更必须双向同步。
|
||||
> 后端 DTO 变更时**必须**同步检查前端:
|
||||
|
||||
- [ ] DTO 字段名变更 → 前端 TypeScript 接口同步更新
|
||||
- [ ] DTO 新增必填字段 → 前端表单和请求体同步更新
|
||||
- [ ] API 路径变更 → 前端 `api/` 模块路径同步更新
|
||||
- [ ] 返回数据结构变更(数组/对象/嵌套)→ 前端解析逻辑同步更新
|
||||
- [ ] 枚举值变更 → 前端类型定义和 UI 映射同步更新
|
||||
- [ ] 后端新增端点 → 前端 API 模块同步添加调用函数,不允许留空
|
||||
|
||||
#### DTO 输入校验检查(强制)
|
||||
|
||||
> DTO 输入校验是安全防线 — 缺失校验等于暴露攻击面,Update 和 Create 必须对称。
|
||||
> 新增/修改 DTO 时**必须**逐项确认:
|
||||
|
||||
- [ ] 所有请求结构体已 `derive(Validate)`(包括 Update\*Req、查询参数)
|
||||
- [ ] Update\*Req 与 Create\*Req 校验对称(不允许 Update 降级)
|
||||
- [ ] 字符串字段有 `#[validate(length(min, max))]`
|
||||
- [ ] 枚举/类型字段有 `#[validate(custom)]` 限制合法值
|
||||
- [ ] 集合字段有 `#[validate(length(min = 1))]` 非空检查
|
||||
- [ ] 数值范围字段有 `#[validate(range(min, max))]`
|
||||
- [ ] URL 字段有 SSRF 防护(禁止 localhost/内网地址,仅 http/https)
|
||||
- [ ] 密码字段有 `max = 128` 防止 DoS
|
||||
- [ ] handler 层已调用 `req.validate().map_err(|e| AppError::Validation(e.to_string()))?`
|
||||
|
||||
### 3.4 事件总线
|
||||
|
||||
- 模块间通信**只能**通过 `EventBus`
|
||||
- 事件必须持久化到 `domain_events` 表(outbox 模式)
|
||||
- 事件处理失败记录到 dead-letter 存储
|
||||
- 事件类型命名:`{模块}.{动作}` 如 `user.created`, `workflow.task.completed`
|
||||
- **铁律:每个事件必须有至少一个消费者,否则功能不算完成。** 新增事件发布时必须同步实现消费者和对应测试。详见 `docs/discussions/2026-04-28-architecture-retrospective.md` §4。
|
||||
|
||||
### 3.5 Rust 代码规范
|
||||
|
||||
```rust
|
||||
// 命名:snake_case (函数/变量), PascalCase (类型/trait), SCREAMING_SNAKE (常量)
|
||||
// 模块公开接口通过 lib.rs 统一导出
|
||||
// 每个 public 函数和 trait 必须有文档注释
|
||||
// 异步函数返回 Result 时使用 AppResult<T> 类型别名
|
||||
// 数据库操作使用 SeaORM 的 Entity + Model + Relation 模式
|
||||
#### 目录约定
|
||||
```
|
||||
lib/features/{feature}/
|
||||
├── bloc/ # BLoC (event + state + bloc)
|
||||
├── views/ # 页面
|
||||
└── widgets/ # 组件
|
||||
```
|
||||
|
||||
### 3.6 TypeScript / React 代码规范
|
||||
#### 状态管理
|
||||
- 每个功能模块一个 BLoC
|
||||
- Event/State 使用 freezed 生成不可变类
|
||||
- Repository 模式:抽象接口 + Isar 本地实现 + Dio 远程实现
|
||||
|
||||
```typescript
|
||||
// 避免 any,优先 unknown + 类型守卫
|
||||
// 函数组件 + hooks
|
||||
// 复杂状态收敛到 Zustand store
|
||||
// API 调用封装到独立的 service 层,不在组件中直接 fetch
|
||||
// 使用 Ant Design 组件,不自行实现已有组件
|
||||
// 国际化文案使用 i18n key,不硬编码中文
|
||||
```
|
||||
#### 响应式布局
|
||||
- 手机 < 600px:底部 TabBar,单列
|
||||
- 平板 600-1024px:侧边导航,双栏
|
||||
- 桌面 > 1024px:三栏布局
|
||||
|
||||
### 3.7 安全规范
|
||||
#### 离线优先
|
||||
- 所有数据先写 Isar,离线完全可用
|
||||
- SyncEngine 管理 WiFi 增量同步
|
||||
- 版本号冲突检测,本地优先策略
|
||||
|
||||
#### 密钥与凭据管理
|
||||
### 4.3 安全(PIPL 合规,最高优先)
|
||||
|
||||
- 所有密钥、token、密码**必须**通过环境变量或密钥管理服务注入,**禁止**硬编码在源码中
|
||||
- 开发环境密钥**必须**与生产环境严格隔离(`cfg(debug_assertions)` 编译期防护)
|
||||
- 生产密钥**禁止**有 fallback 默认值,缺失时启动 panic
|
||||
- 新增密钥时必须同步更新 `.env.example` 和 `wiki/infrastructure.md`
|
||||
#### 儿童数据保护
|
||||
- **未满 14 岁必须家长授权** — 注册时验证,分享功能锁定
|
||||
- **最小必要数据** — 仅收集昵称+年级,无需真实姓名/身份证
|
||||
- **数据加密** — Isar 内置加密 + AES-256-GCM 云端 + TLS 传输
|
||||
- **家长数据管理权** — 可查阅/更正/删除/导出孩子数据
|
||||
- **账号注销** — 30 天内删除所有关联数据
|
||||
|
||||
#### 依赖安全
|
||||
#### 班级码安全
|
||||
- 6 位字母数字混合(62^6 ≈ 568 亿种组合)
|
||||
- 有效期控制(学期结束自动失效)
|
||||
- 连续 5 次错误锁定 30 分钟
|
||||
- 老师可随时重置
|
||||
|
||||
- 新增依赖前**必须**检查已知漏洞(`cargo audit` / `npm audit`)
|
||||
- 禁止引入有未修补高危漏洞的依赖版本
|
||||
- 定期更新依赖到最新安全补丁版本
|
||||
|
||||
#### 数据安全
|
||||
|
||||
- PII 数据(姓名、身份证号、手机号、地址等)**必须**加密存储(AES-256-GCM)
|
||||
- 日志中**禁止**输出 PII 数据和认证凭据(密码、token、session key)
|
||||
- 敏感操作(登录、权限变更、数据导出、批量删除)**必须**记录审计日志(操作者、时间、目标、结果)
|
||||
- 文件上传**必须**验证 MIME 类型 + 限制文件大小 + 防止路径穿越(文件名 sanitize)
|
||||
|
||||
#### 传输安全
|
||||
|
||||
- 生产环境**必须**强制 HTTPS,**禁止**降级到 HTTP
|
||||
- HTTP 响应**必须**包含安全头(HSTS、CSP、X-Frame-Options、X-Content-Type-Options、Permissions-Policy)
|
||||
- SSE/WebSocket 长连接认证 token 不通过 URL query 参数传递(使用 header 或 cookie)
|
||||
- API 响应**禁止**暴露内部实现细节(堆栈跟踪、数据库错误、文件路径、SQL 语句)
|
||||
|
||||
#### 认证与授权
|
||||
|
||||
- 密码**必须**使用单向哈希(bcrypt/argon2),**禁止**明文或可逆加密存储
|
||||
- JWT **必须**设置合理过期时间,支持 token 吊销机制
|
||||
- 敏感操作(删除数据、权限变更)需要二次确认
|
||||
- 权限检查在 handler 层执行,**禁止**仅依赖前端隐藏控制访问
|
||||
- `tenant_id` **必须**从 JWT 中间件注入,**禁止**信任客户端传递的值
|
||||
|
||||
#### 速率限制
|
||||
|
||||
- 所有 API 端点**必须**配置速率限制
|
||||
- 认证相关端点(登录、注册、密码重置)限制更严格
|
||||
- 批量操作和数据导出需要独立的速率限制策略
|
||||
- 速率限制超出时返回 429 状态码,响应包含 `Retry-After` header
|
||||
#### 内容安全
|
||||
- 本地敏感词库过滤(含谐音/拼音变体)
|
||||
- 分享前自动检查
|
||||
- 老师可审核班级内容
|
||||
- 举报机制
|
||||
|
||||
---
|
||||
|
||||
## 4. 测试与验证
|
||||
## 5. 性能目标
|
||||
|
||||
### 4.1 测试要求
|
||||
|
||||
| 测试类型 | 覆盖目标 | 工具 |
|
||||
|----------|---------|------|
|
||||
| 单元测试 | 每个 service 函数 | `#[cfg(test)]` + `tokio::test` |
|
||||
| 集成测试 | API 端点 → 数据库 | Testcontainers + 真实 PostgreSQL |
|
||||
| 多租户测试 | 数据隔离验证 | 独立测试 crate |
|
||||
| E2E 测试 | 前端关键流程 | Playwright |
|
||||
| 插件测试 | 动态表 CRUD + 租户隔离 | Testcontainers |
|
||||
|
||||
### 4.2 验证命令
|
||||
|
||||
```bash
|
||||
# Rust 编译检查
|
||||
cargo check
|
||||
|
||||
# Rust 全量测试
|
||||
cargo test --workspace
|
||||
|
||||
# 后端服务启动
|
||||
cd crates/erp-server && cargo run
|
||||
|
||||
# Docker 环境
|
||||
cd docker && docker compose up -d
|
||||
|
||||
# 桌面端开发
|
||||
cd apps/desktop && pnpm tauri dev
|
||||
|
||||
# 数据库迁移检查
|
||||
docker exec erp-postgres psql -U erp -c "\dt"
|
||||
```
|
||||
|
||||
### 4.3 Phase 完成标准
|
||||
|
||||
每个 Phase 完成时必须满足:
|
||||
|
||||
- [ ] `cargo check` 全 workspace 通过
|
||||
- [ ] `cargo test` 全部通过
|
||||
- [ ] PostgreSQL 服务正常运行,迁移自动执行
|
||||
- [ ] 所有迁移可正/反向执行
|
||||
- [ ] API 端点可通过 Swagger UI 测试
|
||||
- [ ] 桌面端可正常启动并展示对应 UI
|
||||
- [ ] 所有代码已提交
|
||||
| 指标 | 目标 | 测试条件 |
|
||||
|------|------|---------|
|
||||
| 手写延迟 (p99) | < 16ms | Samsung Tab A9 / iPad 10th |
|
||||
| 日记列表滚动 | 60fps | 500 条数据 |
|
||||
| 冷启动 | < 2s | 100 条 Isar 文档 |
|
||||
| 全量同步 | < 10s | 100 篇日记 |
|
||||
| 照片压缩质量 | ≥ 85% SSIM | flutter_image_compress |
|
||||
| 单篇日记存储 | < 5MB | 含照片 |
|
||||
| 贴纸包大小 | < 5MB/包 | |
|
||||
|
||||
---
|
||||
|
||||
## 5. 提交规范
|
||||
## 6. 提交规范
|
||||
|
||||
```
|
||||
<type>(<scope>): <description>
|
||||
```
|
||||
|
||||
**类型:**
|
||||
- `feat` — 新功能
|
||||
- `fix` — 修复问题
|
||||
- `refactor` — 重构
|
||||
- `docs` — 文档更新
|
||||
- `test` — 测试相关
|
||||
- `chore` — 杂项(构建、配置等)
|
||||
- `perf` — 性能优化
|
||||
**类型:** feat / fix / refactor / docs / test / chore / perf
|
||||
|
||||
**Scope 对应 crate 或模块名:**
|
||||
**Scope:**
|
||||
|
||||
| scope | 范围 |
|
||||
|-------|------|
|
||||
| `core` | erp-core |
|
||||
| `diary` | erp-diary |
|
||||
| `auth` | erp-auth |
|
||||
| `workflow` | erp-workflow |
|
||||
| `message` | erp-message |
|
||||
| `config` | erp-config |
|
||||
| `core` | erp-core |
|
||||
| `server` | erp-server |
|
||||
| `health` | erp-health |
|
||||
| `ai` | erp-ai |
|
||||
| `dialysis` | erp-dialysis |
|
||||
| `plugin` | erp-plugin / erp-plugin-prototype / erp-plugin-test-sample |
|
||||
| `assessment` | erp-plugin-assessment |
|
||||
| `crm` | erp-plugin-crm |
|
||||
| `inventory` | erp-plugin-inventory |
|
||||
| `web` | Web 前端 |
|
||||
| `ui` | React 组件 |
|
||||
| `config` | erp-config |
|
||||
| `message` | erp-message |
|
||||
| `workflow` | erp-workflow |
|
||||
| `plugin` | erp-plugin |
|
||||
| `app` | Flutter 前端 |
|
||||
| `db` | 数据库迁移 |
|
||||
| `docker` | Docker 配置 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```
|
||||
feat(auth): 添加用户管理 CRUD
|
||||
feat(core): 实现事件总线和模块注册
|
||||
fix(server): 修复数据库连接池配置
|
||||
refactor(auth): 拆分 RBAC 和 ABAC 权限模型
|
||||
chore(docker): 添加 PostgreSQL 健康检查
|
||||
feat(diary): 添加日记 CRUD API
|
||||
feat(app): 实现手写引擎 Canvas 组件
|
||||
feat(auth): 添加 student/teacher/parent 角色支持
|
||||
fix(diary): 修复同步版本冲突检测逻辑
|
||||
chore(docker): 添加 PostgreSQL 16 + Redis 7 开发环境
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 反模式警告
|
||||
## 7. 反模式警告
|
||||
|
||||
- ❌ **不要**不看 wiki 就开干 — wiki 包含环境配置、数据库连接、启动方式、已知问题,不看就做等于盲猜,浪费时间且产出不可信
|
||||
- ❌ **不要**在业务 crate 之间创建直接依赖 — 只通过事件和 trait 通信
|
||||
- ❌ **不要**修改 G:\hms — 那是使用中的生产项目,所有操作在 nj 仓库进行
|
||||
- ❌ **不要**在业务 crate 间创建直接依赖 — 只通过事件和 trait 通信
|
||||
- ❌ **不要**跳过多租户中间件 — 所有数据操作必须带 `tenant_id` 过滤
|
||||
- ❌ **不要**硬编码配置值 — 使用 config.toml + 环境变量
|
||||
- ❌ **不要**跳过迁移直接建表 — 所有 schema 变更通过 SeaORM Migration
|
||||
- ❌ **不要**在前端组件中直接调用 HTTP — 封装到 service 层
|
||||
- ❌ **不要**使用 `anyhow` 跨越 crate 边界 — 内部可用,对外必须转 `AppError`
|
||||
- ❌ **不要**假设只有单租户 — 从第一天就按多租户设计
|
||||
- ❌ **不要**提前实现远期功能 — 严格按 Phase 计划推进
|
||||
- ❌ **不要**忽略 `version` 字段 — 所有更新操作必须检查乐观锁
|
||||
- ❌ **不要**在动态表 SQL 中拼接用户输入 — 使用 `sanitize_identifier` 防注入
|
||||
- ❌ **不要**在插件 crate 中直接依赖 erp-auth — 权限注册用 raw SQL,保持模块边界
|
||||
- ❌ **不要**在 plugin.toml 中使用与实体名不一致的权限码 — `permissions[].code` 前缀必须与 `schema.entities[].name` 完全一致(如实体 `customer_tag` → 权限码 `customer_tag.list`/`customer_tag.manage`,不能写成 `tag.manage`),否则页面 403
|
||||
- ❌ **不要**漏掉实体的 `.list` 权限 — 每个实体必须同时声明 `.list` 和 `.manage`,缺少 `.list` 导致列表页 403
|
||||
- ❌ **不要**跳过验证直接提交 — 编译/测试/功能验证必须全部通过
|
||||
- ❌ **不要**提交后忘记推送 — 不推送等于没完成,远程仓库必须同步。每次新会话开始先检查未推送提交
|
||||
- ❌ **不要**忘记更新文档 — 涉及架构、接口、模块变化时必须同步更新相关文档
|
||||
- ❌ **不要**连续 5 个代码提交不更新 wiki — wiki 是团队唯一真相源,过期数据比没有数据更有害
|
||||
- ❌ **不要**修复 bug 后跳过症状导航更新 — 每个修复都应该帮助未来遇到同类问题的人快速定位根因
|
||||
- ❌ **不要**新增功能后不更新 wiki 关键数字 — 迁移数/路由数/实体数/测试数必须与代码同步,否则 wiki 指标表就是废数据
|
||||
- ❌ **不要**一次性输出长文档 — 超过 200 行的文档必须分步编写(先大纲 → 逐章 → 整合),否则会因上下文过长卡死
|
||||
- ❌ **不要**忽略讨论记录 — 每次发散式讨论结束后必须建立文档到 `docs/discussions/`,不要口头确认后就忘
|
||||
- ❌ **不要**跳过 Feature DoD — 每个功能标记"完成"前必须通过 §2.6 检查清单,不全面验证就提交将导致后续反复修复
|
||||
- ❌ **不要**新增端点时默认放行 — 所有端点默认拒绝访问,必须显式声明权限
|
||||
- ❌ **不要**后端 DTO 变更不同步前端 — 字段名/路径/类型变更时必须同步更新前端 TypeScript 接口
|
||||
- ❌ **不要**写 Update DTO 时省略校验 — Update*Req 必须与 Create*Req 校验对称(Validate derive / 枚举 custom / Vec min=1 / 密码 max=128)
|
||||
- ❌ **不要**URL 字段不做 SSRF 防护 — 禁止 localhost/127.0.0.1/内网地址,仅允许 http/https 协议
|
||||
- ❌ **不要**handler 层跳过 `.validate()` — 所有 `Json<T>` handler 函数体第一行必须调 `req.validate().map_err(\|e\| AppError::Validation(e.to_string()))?`
|
||||
- ❌ **不要**在日志中输出敏感数据 — 密码、token、身份证号、手机号等 PII 信息禁止写入日志
|
||||
- ❌ **不要**信任客户端传递的 `tenant_id` — 必须从 JWT 中间件注入,客户端可伪造
|
||||
- ❌ **不要**在生产代码中使用 `unwrap()` — 必须处理所有错误,使用 `?` 或 `map_err`
|
||||
- ❌ **不要**将内部错误信息返回给客户端 — 数据库错误、堆栈跟踪、文件路径等必须转换为用户友好的错误消息
|
||||
- ❌ **不要**使用 HTTP 传输敏感数据 — 生产环境必须 HTTPS
|
||||
- ❌ **不要**跳过依赖安全检查 — 新增依赖前运行 `cargo audit` / `npm audit`,禁止引入有高危漏洞的版本
|
||||
- ❌ **不要**文件上传不做安全处理 — 必须验证 MIME 类型 + 限制大小 + sanitize 文件名防路径穿越
|
||||
- ❌ **不要**忽略儿童数据安全 — PIPL 合规是法律要求,不是可选项
|
||||
- ❌ **不要**过度平滑笔迹 — 笔迹保真是核心价值,保留个人书写特征
|
||||
- ❌ **不要**假设网络始终可用 — 所有功能必须离线可用
|
||||
- ❌ **不要**使用 `anyhow` 跨越 crate 边界 — 内部可用,对外转 `AppError`/`DiaryError`
|
||||
- ❌ **不要**提前实现 Phase 2+ 功能 — 严格按规划推进
|
||||
- ❌ **不要**跳过验证直接提交 — cargo check + cargo test + flutter analyze 必须通过
|
||||
- ❌ **不要**在 Flutter 中直接用 GestureDetector 处理手写 — 用 Listener 降低延迟
|
||||
- ❌ **不要**硬编码密钥 — 通过 config/default.toml + 环境变量注入
|
||||
|
||||
### 场景化指令
|
||||
|
||||
- 当遇到**新增模块** → 实现 `ErpModule` trait,在 `erp-server` 注册
|
||||
- 当遇到**跨模块通信** → 定义事件类型,通过 `EventBus` 发布/订阅
|
||||
- 当遇到**数据查询** → 确保包含 `tenant_id` 过滤,检查软删除条件
|
||||
- 当遇到**新增 API** → 添加 utoipa 注解,确保 OpenAPI 文档同步
|
||||
- 当遇到**新增表** → 创建 SeaORM migration + Entity,包含所有标准字段
|
||||
- 当遇到**新增页面** → 使用 Ant Design 组件,i18n key 引用文案
|
||||
- 当遇到**新增业务模块插件** → 参考 `wiki/wasm-plugin.md` 的插件制作完整流程和 `.claude/skills/plugin-development/SKILL.md`,创建 cdylib crate + 实现 Guest trait + 编译为 WASM Component。**权限码必须与实体名一致(每个实体声明 `.list` + `.manage`)**
|
||||
- 当遇到**新增/修改 DTO** → 参考 `wiki/architecture.md` §4 DTO 输入校验规范:`derive(Validate)` + 字段级校验 + handler 层 `validate()` 调用 + 单元测试
|
||||
- 当遇到**新增 API 端点** → 在 erp-diary/src/handler/ 添加,加 utoipa 注解 + 权限守卫
|
||||
- 当遇到**新增数据表** → 创建 SeaORM migration + Entity,包含所有标准字段
|
||||
- 当遇到**跨模块通信** → 定义事件类型到 erp-diary/src/event.rs,通过 EventBus 发布
|
||||
- 当遇到**新增 Flutter 功能** → 创建 features/{name}/ 目录,bloc/views/widgets 分层
|
||||
- 当遇到**手写性能问题** → 检查 shouldRepaint 守卫 + 笔画光栅化缓存 + Listener 替代 GestureDetector
|
||||
- 当遇到**同步冲突** → 版本号比对,Phase 1 使用"本地优先"简单策略
|
||||
- 当遇到**儿童数据** → 确认 PIPL 合规检查清单(家长授权/最小数据/加密/注销机制)
|
||||
|
||||
---
|
||||
|
||||
## 7. 详细参考(wiki)
|
||||
## 8. 参考文档
|
||||
|
||||
以下内容已从本文件迁移到 wiki,需要时查阅:
|
||||
| 文档 | 位置 |
|
||||
|------|------|
|
||||
| 产品设计规格 v1.2 | `docs/superpowers/specs/2026-05-31-nuanji-warm-notes-design.md` |
|
||||
| 实施规划 v2.1 | `plans/hazy-petting-lampson.md` |
|
||||
| 头脑风暴文档 (8 份) | `.superpowers/brainstorm/734-1780218658/` |
|
||||
| 基座仓库 | https://git.stableeasy.com/iven/base.git |
|
||||
| HMS 源码 (只读参考) | G:\hms |
|
||||
|
||||
| 主题 | wiki 页面 |
|
||||
|------|----------|
|
||||
| 目录结构、crate 依赖、技术栈 | `wiki/architecture.md` §2 |
|
||||
| 模块开发规范、ErpModule trait、迁移规范 | `wiki/architecture.md` §3 |
|
||||
| 安全注意事项(认证/多租户/通用) | `wiki/architecture.md` §4 |
|
||||
| UI 布局规范 | `wiki/frontend.md` §2 |
|
||||
| 常用命令(Rust/前端/数据库/WASM) | `wiki/infrastructure.md` §3 |
|
||||
| 设计文档索引 | `wiki/index.md` |
|
||||
| 开发进度、模块状态 | `wiki/index.md` 关键数字 |
|
||||
| 环境配置、连接信息、登录凭据 | `wiki/infrastructure.md` §2 |
|
||||
---
|
||||
|
||||
## graphify — 代码知识图谱
|
||||
## 9. 开发环境
|
||||
|
||||
> 项目知识图谱位于 `graphify-out/`,当前规模:18,517 节点 / 22,666 边 / 1,841 社区(纯 AST 解析,无 API 成本)。
|
||||
> 工具:`python -m graphify`(已安装 graphifyy 0.8.18)。
|
||||
### 后端
|
||||
|
||||
### 开发流程中的使用场景
|
||||
```bash
|
||||
# 编译检查
|
||||
cargo check
|
||||
|
||||
| 时机 | 命令 | 目的 |
|
||||
|------|------|------|
|
||||
| **接手新任务,理解代码关系** | `graphify query "概念名"` | 搜索相关节点,比 Grep 更精准(按调用/引用/包含关系) |
|
||||
| **排查 bug,追踪调用链** | `graphify path "A" "B"` | 查找两个模块/函数间的最短路径 |
|
||||
| **理解某个模块的职责** | `graphify explain "模块名"` | 自然语言解释节点及其邻居 |
|
||||
| **代码改动后** | `graphify update .` | 增量更新图谱(AST-only,秒级完成) |
|
||||
| **宏观架构审查** | 读 `graphify-out/GRAPH_REPORT.md` | 全局社区结构、跨文件关系概览 |
|
||||
# 运行测试
|
||||
cargo test
|
||||
|
||||
### 使用优先级(融入 §2.5 闭环工作法)
|
||||
# 启动后端 (需要 PG + Redis)
|
||||
cd crates/erp-server && cargo run
|
||||
|
||||
在 §2.5 步骤 1「现状确认」中,**优先使用 graphify 替代盲目 Grep**:
|
||||
# Docker 环境
|
||||
cd docker && docker compose up -d
|
||||
```
|
||||
|
||||
1. **先 `graphify query`** — 精确定位相关节点和社区(比 Grep 返回更结构化的结果)
|
||||
2. **再 `graphify path`** — 确认模块间依赖路径(避免遗漏间接依赖)
|
||||
3. **最后 Grep/Glob/Read** — 确认 graphify 发现的具体文件内容
|
||||
### 前端 (待创建)
|
||||
|
||||
### 注意事项
|
||||
```bash
|
||||
cd app
|
||||
flutter pub get
|
||||
flutter run
|
||||
flutter test
|
||||
```
|
||||
|
||||
- `graphify update .` 纯本地 AST 解析,不消耗 LLM token,每次代码改动后都可以运行
|
||||
- 查询结果比 GRAPH_REPORT.md 更精准,优先使用 query/path/explain,仅在需要全局视图时读报告
|
||||
- 首次生成需几分钟(1712 文件),后续增量更新秒级完成
|
||||
### 配置
|
||||
|
||||
配置文件:`config/default.toml`,环境变量覆盖前缀 `ERP__`,分隔符 `__`
|
||||
|
||||
数据库:PostgreSQL 16 (端口 5432)
|
||||
Redis:7-alpine (端口 6379)
|
||||
API:`http://localhost:8080/api/v1/`
|
||||
|
||||
Reference in New Issue
Block a user