fix: 前端深度审计全量修复 — 安全/功能/代码质量
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled

严重 BUG 修复:
- 修复 Token 过期后 hash 重定向导致无法跳转登录页
- 修复文章编辑器新建后提交审核使用错误 ID

安全加固:
- HTML 清理函数替换为 ammonia 专业库(替代自定义解析器)
- 文件上传添加 magic bytes 校验(防 Content-Type 伪造)
- 登录添加账户级失败锁定(5次失败→15分钟锁定)
- 审计日志 9 个关键更新操作补充变更前后值(with_changes)

功能缺陷修复:
- 登录/登出时清理 API 缓存(防多账户数据污染)
- 文章编辑器上传改用统一 HTTP 客户端(自动 token 刷新)
- 添加全局 HTTP 错误处理和后端错误消息展示
- PrivateRoute 增加路由级权限检查(系统管理页面)
- 健康数据三个 Tab 添加编辑/删除功能
- 预约创建增加排班可用性校验提示
- 医生详情 API 返回解密后的原始执照号

代码清理:
- 删除未使用的 auth.ts refresh() 函数
- 删除重复的 AuthGuard.tsx 组件
- 删除未使用的 getHealthSummary API
This commit is contained in:
iven
2026-04-26 21:47:26 +08:00
parent f0c3426792
commit 787e64d9a9
23 changed files with 1152 additions and 482 deletions

358
CLAUDE.md
View File

@@ -43,78 +43,50 @@
---
## 2. 项目结构
## 2. 工作风格
```text
hms/
├── crates/ # Rust Workspace
│ ├── erp-core/ # L1: 基础类型、错误、事件、模块 trait
│ ├── erp-auth/ # L2: 身份与权限模块
│ ├── erp-workflow/ # L2: 工作流引擎模块
│ ├── erp-message/ # L2: 消息中心模块
│ ├── erp-config/ # L2: 系统配置模块
│ ├── erp-health/ # L2: 健康管理模块 ★ HMS 核心
│ └── erp-server/ # L3: Axum 服务入口,组装所有模块
│ └── migration/ # SeaORM 数据库迁移
├── apps/
│ └── web/ # Vite + React 19 SPA (主力前端)
├── packages/
│ └── ui-components/ # React 共享组件库
├── desktop/ # (可选) Tauri 桌面端,行业需要时启用
├── docker/ # Docker 开发环境配置
├── docs/ # 文档
│ └── superpowers/
│ ├── specs/ # 设计规格文档
│ └── plans/ # 实施计划
├── Cargo.toml # Workspace root
└── CLAUDE.md # 本文件 — 协作规则
```
### 2.1 Crate 依赖关系
```text
erp-core (无业务依赖)
erp-auth (→ core)
erp-config (→ core)
erp-workflow (→ core)
erp-message (→ core)
erp-health (→ core) ★ HMS 核心
erp-server (→ 所有 crate组装入口)
```
**规则:**
- `erp-core` 不依赖任何业务 crate
- 业务 crate 之间**禁止**直接依赖,只通过事件总线和 `erp-core` trait 通信
- `erp-server` 是唯一的组装点
### 2.2 技术栈
| 层级 | 技术 |
|------|------|
| 后端框架 | Axum 0.8 + Tokio |
| ORM | SeaORM (异步、类型安全) |
| 数据库 | PostgreSQL 18 |
| 缓存 | Redis 7+ |
| 前端框架 | React 19 + TypeScript 6 (Vite 8) |
| UI 组件库 | Ant Design 6 |
| 状态管理 | Zustand 5 |
| 路由 | React Router 7 |
| 样式 | TailwindCSS + CSS Variables |
| API 文档 | utoipa (OpenAPI 3) |
---
## 3. 工作风格
### 3.1 按计划推进
### 2.1 按计划推进
- **严格按 Phase 顺序执行** — Phase 2 依赖 Phase 1 的基础设施
- **每个 Task 完成后立即提交** — 不积压,保持可追溯
- **先测试后实现** — TDD 流程:写失败测试 → 实现 → 通过 → 提交
### 3.2 模块化思维
### 2.2 分步编写文档(强制)
编写计划、设计文档、实施报告等长文档时,**必须分步编写**,禁止一次性输出全文:
1. **先写大纲** — 确认文档结构和章节划分
2. **逐章编写** — 每次只写 1-2 个章节,写完确认后继续下一章
3. **最终整合** — 所有章节完成后合并为完整文档
**原因:** 上下文过长会导致输出截断或卡死。分步编写保证每步都能完整输出,且用户可以中途调整方向。
**适用范围:** 超过 200 行的文档、实施计划、设计规格、技术报告等。简短的 bugfix 说明、单页 wiki 更新不受此限制。
### 2.3 讨论记录
每次发散式讨论brainstorming、方案探索、需求梳理、技术选型等**必须建立独立文档**
- **存放位置:** `docs/discussions/YYYY-MM-DD-{主题简称}.md`
- **文档格式:**
```markdown
# {讨论主题}
> 日期: YYYY-MM-DD | 参与者: ...
## 背景
为什么会有这次讨论
## 讨论要点
- 要点 1
- 要点 2
## 结论 / 待定
达成的共识或遗留问题
```
- **时机:** 讨论结束后立即创建,不要积压。如果讨论横跨多个主题,拆分为多份文档。
- **用途:** 作为后续实施的输入和决策追溯的依据,避免"之前讨论过但忘了结论"。
### 2.4 模块化思维
开发任何功能时先问:
@@ -123,7 +95,7 @@ erp-server (→ 所有 crate组装入口)
3. **它需要发什么事件?** — 跨模块通知必须走事件总线
4. **其他模块怎么发现它?** — 通过 `ErpModule` trait 注册
### 3.3 闭环工作法(强制)
### 2.5 闭环工作法(强制)
每次改动**必须**按顺序完成以下步骤,不允许跳过:
@@ -144,7 +116,7 @@ erp-server (→ 所有 crate组装入口)
- `cargo test --workspace` — 所有测试通过(有相关测试时)
- 功能验证 — 启动后端 + 前端服务,在浏览器中实际操作验证改动生效(涉及 API 或 UI 时)
- `pnpm build` — 前端生产构建通过(涉及前端时)
5. **提交** — 验证通过后按 §10 规范提交
5. **提交** — 验证通过后按 §5 规范提交
6. **文档同步** — 更新相关文档(如果涉及架构、接口、模块变化)
7. **推送到仓库** — 提交后立即 `git push`,确保远程仓库同步
@@ -156,23 +128,23 @@ erp-server (→ 所有 crate组装入口)
---
## 4. 实现规则
## 3. 实现规则
### 4.1 错误处理
### 3.1 错误处理
- **跨 crate 边界**:使用 `thiserror` 定义类型化错误,转换为 `AppError`
- **crate 内部**:可以使用 `anyhow`,但**永远不**跨越 crate 边界
- **数据库错误**:通过 `From<sea_orm::DbErr>` 自动转换为 `AppError`
- **验证错误**:包含字段级详情,方便 UI 渲染
### 4.2 数据库操作
### 3.2 数据库操作
- 所有 SeaORM Entity 必须包含:`id`, `tenant_id`, `created_at`, `updated_at`, `created_by`, `updated_by`, `deleted_at`, `version`
- 查询时**始终**带 `tenant_id` 过滤(中间件自动注入)
- 更新时检查 `version` 字段实现乐观锁
- 删除使用软删除(设置 `deleted_at`
### 4.3 API 设计
### 3.3 API 设计
- 所有端点使用 `/api/v1/` 前缀
- 响应统一使用 `ApiResponse<T>` 包装
@@ -180,14 +152,14 @@ erp-server (→ 所有 crate组装入口)
- utoipa 自动生成 OpenAPI 文档
- 租户 ID 从 JWT 中间件注入,**不在** API 路径中传递(管理员接口除外)
### 4.4 事件总线
### 3.4 事件总线
- 模块间通信**只能**通过 `EventBus`
- 事件必须持久化到 `domain_events` 表outbox 模式)
- 事件处理失败记录到 dead-letter 存储
- 事件类型命名:`{模块}.{动作}` 如 `user.created`, `workflow.task.completed`
### 4.5 Rust 代码规范
### 3.5 Rust 代码规范
```rust
// 命名snake_case (函数/变量), PascalCase (类型/trait), SCREAMING_SNAKE (常量)
@@ -197,7 +169,7 @@ erp-server (→ 所有 crate组装入口)
// 数据库操作使用 SeaORM 的 Entity + Model + Relation 模式
```
### 4.6 TypeScript / React 代码规范
### 3.6 TypeScript / React 代码规范
```typescript
// 避免 any优先 unknown + 类型守卫
@@ -210,58 +182,9 @@ erp-server (→ 所有 crate组装入口)
---
## 5. 模块开发规范
## 4. 测试与验证
### 5.1 新建业务模块清单
每个新模块(如 erp-auth, erp-workflow**必须**包含:
1. `Cargo.toml` — 依赖 `erp-core`
2. `src/lib.rs` — 模块入口,实现 `ErpModule` trait
3. `src/error.rs` — 模块错误类型wrap `AppError`
4. `src/entity/` — SeaORM Entity 定义
5. `src/service/` — 业务逻辑层
6. `src/handler/` — Axum 路由处理器
7. `src/event.rs` — 模块事件定义和处理器
### 5.2 ErpModule trait 实现
```rust
pub struct AuthModule;
impl ErpModule for AuthModule {
fn name(&self) -> &str { "auth" }
fn version(&self) -> &str { env!("CARGO_PKG_VERSION") }
fn dependencies(&self) -> Vec<&str> { vec![] } // auth 是基础模块,无依赖
fn register_routes(&self, router: Router) -> Router {
router.nest("/api/v1", auth_routes())
}
fn register_event_handlers(&self, bus: &EventBus) {
// 订阅其他模块的事件
}
async fn on_tenant_created(&self, tenant_id: Uuid) -> AppResult<()> {
// 初始化默认角色、管理员等
Ok(())
}
}
```
### 5.3 数据库迁移
- 迁移文件放在 `crates/erp-server/migration/src/`
- 命名格式:`m{YYYYMMDD}_{6位序号}_{描述}.rs`
- 迁移必须可回滚(实现 `down` 方法)
- 新增表必须包含所有标准字段§1.3
- 迁移必须幂等(使用 `if_not_exists`
---
## 6. 测试与验证
### 6.1 测试要求
### 4.1 测试要求
| 测试类型 | 覆盖目标 | 工具 |
|----------|---------|------|
@@ -271,7 +194,7 @@ impl ErpModule for AuthModule {
| E2E 测试 | 前端关键流程 | Playwright |
| 插件测试 | 动态表 CRUD + 租户隔离 | Testcontainers |
### 6.2 验证命令
### 4.2 验证命令
```bash
# Rust 编译检查
@@ -293,7 +216,7 @@ cd apps/desktop && pnpm tauri dev
docker exec erp-postgres psql -U erp -c "\dt"
```
### 6.3 Phase 完成标准
### 4.3 Phase 完成标准
每个 Phase 完成时必须满足:
@@ -307,102 +230,7 @@ docker exec erp-postgres psql -U erp -c "\dt"
---
## 7. 安全注意事项
### 7.1 认证安全
- **密码存储**: Argon2 哈希,禁止明文
- **JWT**: access token 15min + refresh token 7d
- **Refresh Token 轮换**: 每次使用后签发新的,旧的作废
- **Token 存储**: 桌面端使用 Tauri secure store
- **密码修改**: 使所有已签发的 JWT 失效
### 7.2 多租户安全
- **中间件注入**: `tenant_id` 从 JWT 中提取,应用层不可伪造
- **数据隔离**: 所有查询自动过滤 `tenant_id`
- **越权防护**: 禁止跨租户数据访问
- **租户 provisioning**: `on_tenant_created` 钩子初始化数据
### 7.3 通用安全
- **不硬编码密钥** — 使用环境变量或配置文件
- **用户输入验证** — 所有 API 端点验证输入
- **SQL 注入防护** — SeaORM 参数化查询
- **限流** — Redis token bucket登录等敏感接口限流
- **CORS** — 白名单制,默认拒绝
- **审计日志** — 所有关键操作记录变更前后状态
---
## 8. 桌面端 UI 规范
### 8.1 布局结构
经典 SaaS 后台管理布局(响应式,支持移动端):
```
┌─────────────────────────────────────────────┐
│ LOGO 搜索... 🔔 5 👤 Admin ▾ │ ← 顶部导航栏
├─────────┬───────────────────────────────────┤
│ 📊 首页 │ │
│ 👥 用户 │ 主内容区域 │
│ 🔐 权限 │ (多标签页切换) │
│ 📋 流程 │ │
│ 💬 消息 │ │
│ ⚙️ 设置 │ │
│─────────│ │
│ 📦 进销存│ │
│ 🏭 生产 │ │
│ 💰 财务 │ │
│─────────│ │
│ ▸ 更多 │ │
└─────────┴───────────────────────────────────┘
```
### 8.2 UI 规则
- 使用 Ant Design 组件库,不自造轮子
- 中文优先,所有文案通过 i18n key 引用
- 支持暗色/亮色主题切换
- 侧边栏按模块分组:基础模块 / 行业模块
- 表单验证使用 Ant Design Form 的 validateRules
---
## 9. 常用命令
```bash
# === Rust ===
cargo check # 编译检查
cargo test --workspace # 运行所有测试
cargo run -p erp-server # 启动后端服务(需从 crates/erp-server 目录 + 环境变量)
cargo fmt --check # 检查格式
cargo clippy -- -D warnings # Lint 检查
# === 前端 ===
cd apps/web && pnpm install # 安装依赖
cd apps/web && pnpm dev # 开发模式(固定端口 5174
cd apps/web && pnpm build # 构建生产版本
# === 数据库Windows 原生 PostgreSQL ===
PGPASSWORD=123123 "D:\postgreSQL\bin\psql.exe" -U postgres -h localhost -d erp # 连接数据库
# === WASM 插件 ===
cargo build -p erp-plugin-test-sample --target wasm32-unknown-unknown --release # 编译测试插件
wasm-tools component new target/wasm32-unknown-unknown/release/erp_plugin_test_sample.wasm -o target/erp_plugin_test_sample.component.wasm # 转为 Component
cargo test -p erp-plugin-prototype # 运行插件集成测试
# === 一键启动 (PowerShell) ===
.\dev.ps1 # 启动前后端(自动清理端口占用)
.\dev.ps1 -Stop # 停止前后端
.\dev.ps1 -Restart # 重启前后端
.\dev.ps1 -Status # 查看端口状态
```
---
## 10. 提交规范
## 5. 提交规范
```
<type>(<scope>): <description>
@@ -447,68 +275,7 @@ chore(docker): 添加 PostgreSQL 健康检查
---
## 11. 设计文档索引
| 文档 | 说明 |
|------|------|
| `docs/superpowers/specs/2026-04-23-health-management-module-design.md` | **HMS 健康模块设计规格** ★ 当前 |
| `docs/superpowers/specs/2026-04-10-erp-platform-base-design.md` | 平台底座设计规格 |
| `docs/superpowers/specs/2026-04-13-wasm-plugin-system-design.md` | WASM 插件系统设计规格 |
| `docs/superpowers/specs/2026-04-16-crm-plugin-design.md` | CRM 客户管理插件设计规格 |
所有设计决策以设计规格文档为准。实施计划按阶段拆分,每阶段开始前细化。
---
<!-- ARCH-SNAPSHOT-START -->
<!-- 此区域随开发进度更新 -->
## 12. 当前架构快照
### 开发进度
| Phase | 内容 | 状态 |
|-------|------|------|
| Phase 1 | 基础设施 (workspace + core + Docker + 桌面端) | ✅ 完成 |
| Phase 2 | 身份与权限 (Auth) | ✅ 完成 |
| Phase 3 | 系统配置 (Config) | ✅ 完成 |
| Phase 4 | 工作流引擎 (Workflow) | ✅ 完成 |
| Phase 5 | 消息中心 (Message) | ✅ 完成 |
| Phase 6 | 整合与打磨 | ✅ 完成 |
| - | WASM 插件原型 (V1-V6) | ✅ 验证通过 |
| - | 插件系统集成到主服务 | ✅ 已集成 |
| - | CRM 插件 (Phase 1-3) | ✅ 完成 |
| - | Q2 安全地基 + CI/CD | ✅ 完成 |
| - | Q3 架构强化 + 前端体验 | ✅ 完成 |
| - | Q4 测试覆盖 + 插件生态 | ✅ 完成 |
| - | 健康模块迭代 (安全地基 + 后端补完 + Web 前端 10 页面) | ✅ 完成 |
### 已实现模块
| Crate | 功能 | 状态 |
|-------|------|------|
| erp-core | 错误类型、共享类型、事件总线、ErpModule trait、审计日志 | ✅ 完成 |
| erp-server | Axum 服务入口、配置、数据库连接、CORS、模块注册、后台任务 | ✅ 完成 |
| erp-auth | 身份与权限 (用户/角色/权限/组织/部门/岗位/行级数据权限) | ✅ 完成 |
| erp-workflow | 工作流引擎 (BPMN 解析/Token 驱动/任务分配) | ✅ 完成 |
| erp-message | 消息中心 (CRUD/模板/订阅/通知面板) | ✅ 完成 |
| erp-config | 系统配置 (字典/菜单/设置/编号规则/主题) | ✅ 完成 |
| erp-plugin | 插件管理 (WASM 运行时/生命周期/动态表/数据CRUD/热更新/行级数据权限) | ✅ 已集成 |
| erp-plugin-prototype | WASM 插件 Host 运行时 (Wasmtime + bindgen + Host API) | ✅ 原型验证 |
| erp-plugin-test-sample | WASM 测试插件 (Guest trait + Host API 回调) | ✅ 原型验证 |
| erp-plugin-crm | CRM 客户管理插件 (5 实体/9 权限/6 页面) | ✅ 完成 |
| erp-plugin-inventory | 进销存管理插件 (6 实体/12 权限/6 页面) | ✅ 完成 |
| erp-plugin-freelance | 自由职业者管理插件 | ✅ 完成 |
| erp-plugin-itops | IT 运维管理插件 | ✅ 完成 |
| erp-health | 健康管理原生模块 (16 实体/12 权限/13 页面) | ✅ 完成 |
<!-- ARCH-SNAPSHOT-END -->
---
<!-- ANTI-PATTERN-START -->
## 13. 反模式警告
## 6. 反模式警告
- ❌ **不要**不看 wiki 就开干 — wiki 包含环境配置、数据库连接、启动方式、已知问题,不看就做等于盲猜,浪费时间且产出不可信
- ❌ **不要**在业务 crate 之间创建直接依赖 — 只通过事件和 trait 通信
@@ -527,6 +294,8 @@ chore(docker): 添加 PostgreSQL 健康检查
- ❌ **不要**跳过验证直接提交 — 编译/测试/功能验证必须全部通过
- ❌ **不要**提交后忘记推送 — 不推送等于没完成,远程仓库必须同步
- ❌ **不要**忘记更新文档 — 涉及架构、接口、模块变化时必须同步更新相关文档
- ❌ **不要**一次性输出长文档 — 超过 200 行的文档必须分步编写(先大纲 → 逐章 → 整合),否则会因上下文过长卡死
- ❌ **不要**忽略讨论记录 — 每次发散式讨论结束后必须建立文档到 `docs/discussions/`,不要口头确认后就忘
### 场景化指令
@@ -538,4 +307,19 @@ chore(docker): 添加 PostgreSQL 健康检查
- 当遇到**新增页面** → 使用 Ant Design 组件i18n key 引用文案
- 当遇到**新增业务模块插件** → 参考 `wiki/wasm-plugin.md` 的插件制作完整流程和 `.claude/skills/plugin-development/SKILL.md`,创建 cdylib crate + 实现 Guest trait + 编译为 WASM Component。**权限码必须与实体名一致(每个实体声明 `.list` + `.manage`**
<!-- ANTI-PATTERN-END -->
---
## 7. 详细参考wiki
以下内容已从本文件迁移到 wiki需要时查阅
| 主题 | 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 |