Commit Graph

128 Commits

Author SHA1 Message Date
iven
0bf1822fa9 fix: QA 第二轮修复 — PatientDetail 重构/测试覆盖/id_number 列宽/小程序 URL 规范化
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
- refactor(web): PatientDetail.tsx 拆分为 4 个子组件(737→334行)
- refactor(web): 提取 usePaginatedData hook 消除重复分页状态
- feat(db): patient.id_number varchar(20)→varchar(255) 容纳加密值
- test(health): 添加预约模块集成测试(创建/列表/租户隔离)
- test(plugin): 添加 6 个 SQL 注入 sanitize 测试
- fix(miniprogram): 7 个 service 文件 URL 构建规范化(params 对象)
- fix(miniprogram): 跨平台字段名对齐(birth_date/start_time/end_time)
2026-04-25 10:22:44 +08:00
iven
945ccd64ba fix: 全面 QA 审计修复 — 安全加固/代码质量/跨平台一致性/测试覆盖
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
Phase 0 安全热修复 (CRITICAL):
- 外部化微信 appid/secret 到 ERP__WECHAT__APPID/SECRET 环境变量
- 正确连接 HealthCrypto 到 ERP__HEALTH__AES_KEY/HMAC_KEY 环境变量
- 外部化小程序加密密钥到 TARO_APP_ENCRYPTION_KEY 环境变量
- 移除小程序 auth store 中的敏感信息 console.log

Phase 1 安全加固:
- 微信自动注册 display_name 添加 sanitize 防止 XSS
- 测试数据库凭据改为从 TEST_DB_URL 环境变量读取

Phase 2 代码质量:
- 提取 useThemeMode hook 消除 22 处重复暗色模式检测
- 提取共享健康常量到 constants/health.ts
- 拆分 patient_service.rs 脱敏函数到 masking.rs
- 移除未使用的 i18next/react-i18next 依赖
- 移除未使用的 api/errors.ts 和 erp-auth/anyhow 依赖

Phase 3 测试覆盖:
- 新增 5 个患者模块集成测试 (CRUD/租户隔离/验证/软删除)

Phase 4 跨平台一致性:
- 统一小程序 Patient.birthday → birth_date 匹配后端
- 统一小程序 Appointment.time_slot → start_time/end_time 匹配后端

Phase 5 架构:
- 微信登录添加多租户 TODO 注释
- 更新 wiki/infrastructure.md 环境变量文档
2026-04-25 10:00:49 +08:00
iven
07f4ba41ba fix(health): 穷尽审计修复 — 权限同步/编译错误/前端bug/审计日志
Some checks failed
CI / frontend-build (push) Has been cancelled
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / security-audit (push) Has been cancelled
审计发现并修复的问题:

HIGH:
- H1: ConsultationDetail 使用 getSession(id) 替代错误的列表搜索
- H2: SessionResp 添加 version/updated_at 字段
- H3: 移除 FollowUpRecordList 调用不存在的导出端点
- H4: 新增 articles.ts 前端 API 模块

MEDIUM:
- M1: article delete 添加乐观锁 (expected_version)
- M2: 取消预约排班释放传播错误 (log::warn -> ?)
- M3: FollowUpTaskList 日期格式 Dayjs -> string
- M4: 补充 15 个缺失审计日志

LOW:
- L1: 替换 follow_up_service 中的 .unwrap()
- L2: PatientListItem 添加 version 字段

CRITICAL (新发现):
- 权限未同步: 健康模块 14 个权限从未写入数据库,添加启动时自动同步
- migration 表名错误: patients -> patient
- 编译错误: health_trend entity 未导入, ToPrimitive trait 未导入
- HealthError 缺少 From<AppError> 实现
2026-04-25 08:58:58 +08:00
iven
02c96d9b45 test(health): validation.rs 纯函数测试 57 用例
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
覆盖所有枚举校验和状态机转换:
- gender/blood_type/appointment_type 等 13 种枚举白名单
- appointment 状态转换 8 条路径
- follow_up 状态转换 11 条路径(含 overdue)
2026-04-25 00:46:09 +08:00
iven
994119ded1 feat(health): 文章管理 CRUD 补充 create/update/delete
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
- article_dto 新增 CreateArticleReq/UpdateArticleReq 含 sanitize
- article_service 新增 create_article/update_article/delete_article 含审计日志
- article_handler 新增三个 handler 端点含权限校验
- module.rs 文章路由合并 POST/PUT/DELETE
2026-04-25 00:34:15 +08:00
iven
43e127d4f7 feat(health): 事件驱动集成 + 数据一致性修复 + 逾期随访检查
- event.rs 重写为有状态处理器(订阅 workflow.task.completed / message.sent)
- module.rs on_startup 初始化 HealthCrypto 并注册事件处理器
- consultation_service 消息发送改为事务包裹(INSERT + CAS 原子更新)
- appointment_service 取消预约释放排班名额增加下限保护
- appointment_service update_schedule 增加 max_appointments >= current_appointments 校验
- follow_up_service 新增 complete_task_by_system 和 check_overdue_tasks
- validation.rs 随访状态机增加 overdue 状态支持
- main.rs 启动时运行逾期随访检查后台任务
2026-04-25 00:30:32 +08:00
iven
6c70e2a783 feat(health): 身份证号 AES-256-GCM 加密 + HMAC 索引 + 字段级脱敏
- crypto.rs: AES-256-GCM 加密/解密 + HMAC-SHA256 索引
- create/update: id_number 加密存储, id_number_hash 索引
- list: 不返回 id_number, 手机号掩码
- detail: 解密后身份证掩码(前3后4), 手机号掩码
- 搜索: 改用 HMAC 精确匹配(不再模糊搜索加密列)
- 迁移 m000048: 添加 patients.id_number_hash 列
2026-04-25 00:21:49 +08:00
iven
479b5900c9 feat(health): 注入审计日志覆盖所有写入操作
17 个方法全覆盖:patient(4)、appointment(2)、consultation(3)、
follow_up(2)、doctor(3)、health_data(3)。使用 fire-and-forget 模式。
2026-04-25 00:12:19 +08:00
iven
1d1f01df81 feat(health): 为所有 DTO 添加 sanitize 防止存储型 XSS
覆盖 patient/health_data/appointment/follow_up/consultation/doctor
6 个 DTO 模块共 14 个请求结构体,在 handler 层统一调用 sanitize。
2026-04-25 00:04:25 +08:00
iven
6776a82926 feat(auth): 微信手机号真实 AES 解密替换 MVP 占位
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
- login 阶段缓存 session_key(内存 HashMap,5 分钟 TTL)
- bind_phone 用 AES-128-CBC + PKCS7 解密 encryptedData 获取真实手机号
- 新增 workspace 依赖:aes, cbc, hex, base64
- 移除硬编码 "13800000000" 占位逻辑
2026-04-24 12:56:12 +08:00
iven
2dc280a401 feat(health): 新增预约/随访单条查询 GET 端点 2026-04-24 12:22:52 +08:00
iven
e7b6bdfcac feat(health): 新增小程序专用今日体征摘要端点 GET /health/vital-signs/today 2026-04-24 12:17:17 +08:00
iven
a0ca156e2c fix(health): 精准审计修复 6 个真实问题 — 安全/一致性/性能
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
P0: consultation handler sender_role 从请求体移除,改为服务端推导(防伪造)
P1: 所有软删除操作统一使用 check_version 乐观锁(6个函数)
P1: 修复 health_trend 索引缺少 tenant_id 前导列 + follow_up_record 补 (tenant_id, executed_date) 索引
P2: Decimal->f64 使用 ToPrimitive::to_f64 替代脆弱的 to_string().parse()
P2: 预约取消释放槽位+状态更新包裹进同一事务
2026-04-24 08:36:22 +08:00
iven
6391a13467 fix(auth+miniprogram): 清除全部审计遗留问题
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
MEDIUM:
- WechatLoginReq/WechatBindPhoneReq 添加 Validate 派生 + 字段校验规则
- handler 中调用 req.validate() 并 map_err 转换
- 新增 AuthError::DbError 变体,wechat_service 所有 DB 错误从 Validation 改为 DbError
- DbError 映射到 AppError::Internal,不再误导前端

LOW:
- fetch_session 改用 reqwest Client.query() 构建参数,自动 URL 编码
- app.tsx PropsWithChildren<any> 改为 Record<string, unknown>
- login handleGetPhone 回调 e: any 改为内联类型
- appointment/create 4 个事件回调 e: any 改为内联类型
- health/input catch (e: any) 改为 catch (e: unknown) + instanceof 守卫
- report/detail Object.entries 去掉 [string, any] 类型断言
- wechat_service 移除 decrypt_phone_placeholder 函数,内联占位注释
2026-04-24 08:16:01 +08:00
iven
ef6d76ef6c fix(miniprogram+auth): 二次审计修复 — 3 HIGH + 2 MEDIUM
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
HIGH:
- wechat_users 迁移补充 created_by/updated_by/version 标准字段
- Entity 同步更新,bind_phone 创建记录时填充新字段
- appointment create 移除 schedule_id 空字符串,改为可选
- appointment list 用 useRef 替代 useCallback 的 loading 依赖,消除 stale closure

MEDIUM:
- report 页 patientId 从顶层读取改为 useDidShow 内动态获取,就诊人切换后正确刷新
- profile/reports 同上修复
- profile/followups 移除 useDidShow 非法的第二参数
2026-04-24 08:05:58 +08:00
iven
4867202437 fix(health): 四次审计修复 — 6 CRITICAL + 8 HIGH + 4 MEDIUM
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
CRITICAL:
- C-1: consultation sender_id 改为从 JWT ctx.user_id 注入,防伪造
- C-2: consultation session 更新改为 CAS 原子操作,防并发丢失
- C-3: 随访记录创建包裹在事务中,保证记录/任务/后续任务一致性
- C-4/C-5/C-6: 唯一索引改为 partial index WHERE deleted_at IS NULL

HIGH:
- H-1: manage_patient_tags 添加 tag_ids 租户归属校验
- H-2: assign_doctor 添加重复关联检查
- H-3: calendar_view 限制日期范围最多 90 天
- H-4: export_sessions 添加 10000 条上限
- H-5: patient_tag_relation/patient_doctor_relation 添加 version 字段
- H-6: create_schedule 添加医生存在性检查
- H-7: 预约取消排班释放错误改为日志记录
- H-8: follow_up_task.related_appointment_id 添加 FK 约束

MEDIUM:
- M-2: 修复 search LIKE 双重 % 包裹问题
- M-3: article_service 错误类型改为 ArticleNotFound
- M-4: patient.created 事件移除 PII(姓名)
- M-6: lab_report 添加 (tenant_id, report_type) 索引
2026-04-24 07:50:14 +08:00
iven
6fbe7ec530 fix(health): 三次审计批次B修复 — 12个HIGH问题
Some checks failed
CI / frontend-build (push) Has been cancelled
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / security-audit (push) Has been cancelled
- H-6: appointment_service 状态转换复用 validation.rs 函数
- H-7: 添加 validate_record_type (checkup/outpatient/inpatient)
- H-8: 添加 validate_patient_status + validate_verification_status 白名单
- H-9: 添加 validate_online_status + online_status 变更事件
- H-10: create_appointment 添加 doctor_id 存在性检查
- H-12/H-13/H-14: 添加 lab_report GIN/health_trend/follow_up_record 索引
2026-04-24 01:07:04 +08:00
iven
9ef65b9a9f feat(health+miniprogram): 预约/报告/随访/资讯/家庭管理 — Chunk 4-6
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
后端:
- 添加 articles 表迁移 + Entity + Service + Handler
- 健康数据趋势 API (get_mini_trend) 注册路由
- article CRUD (list/get) + DTO

前端 (11个新页面 + 5个服务):
- 预约挂号: 列表/创建向导/详情页
- 报告管理: 列表/详情页
- 随访管理: 任务列表/记录详情页
- 资讯文章: 文章详情页
- 个人中心: 就诊人管理/新增/我的报告/我的随访/用药提醒/设置
- 更新 app.config.ts 注册全部路由
- 更新 profile/article 页面为真实功能
2026-04-24 00:58:40 +08:00
iven
ee9a5c4da1 fix(health): 三次审计批次A修复 — 7个CRITICAL问题
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
- C-1: create_record handler 添加 Path(task_id) 提取,校验路径与body一致
- C-2: appointment CAS+INSERT 包裹在数据库事务中,防止幽灵占位
- C-3: appointment 取消释放名额添加 current_appointments > 0 下限保护
- C-4: create_lab_report 添加 patient_id 存在校验
- C-5: create_health_record 添加 patient_id 校验 + record_type 默认值 "routine"→"checkup"
- C-6: health_data update 操作添加 patient_id 归属校验(vital_signs/lab_report/health_record)
- C-7: follow_up_type 校验值改为设计规格定义的 phone/face_to_face/online
- 修复 article_service.rs 编译错误(未使用import + 缺少QuerySelect + 错误变体)
2026-04-24 00:46:11 +08:00
iven
affb3a5578 feat(health+miniprogram): 健康数据录入 + 趋势图
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
后端:
- 新增 GET /health/vital-signs/trend 小程序趋势查询 API
- 通过 JWT user_id 自动关联 patient,支持 range 参数 (7d/30d/90d)
- 新增 MiniTrendQueryParams, MiniTrendResp, DataPoint DTO

前端:
- 实现健康数据首页(今日概览 + 趋势入口 + 录入按钮)
- 实现健康数据录入页(指标选择 + 数值输入 + 提交)
- 实现趋势图页(时间范围切换 + 柱状图 + 数据列表)
- 新增 health service 和 store(趋势缓存 + 今日摘要)
- 修复所有页面相对路径引用问题
2026-04-24 00:36:30 +08:00
iven
47817bae7d fix(health): 二次审计修复 — 状态机/枚举校验/归属验证/事件补全
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
- 状态机验证: patient.status (active→inactive/deceased/inactive→active),
  patient.verification_status (pending→verified/rejected), follow_up_task.status
  (pending→in_progress/cancelled, in_progress→completed/cancelled)
- 枚举白名单: gender/blood_type/appointment_type/period_type/schedule_status/
  follow_up_type/sender_role/content_type/consultation_type
- 归属验证: family_member update/delete 校验 patient_id 匹配
- 事件补全: patient.deceased/verified 条件事件, consultation close 允许 waiting
- 默认值修正: appointment_type "regular"→"outpatient", period_type "morning"→"am",
  consultation_type "text"→"customer_service"
- 新增 validation.rs 通用校验模块
2026-04-24 00:21:05 +08:00
iven
ba132921cc feat(auth): 添加微信小程序登录支持
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
- 新增 wechat_users 表迁移和 SeaORM Entity
- 实现微信登录 Service(code→openid→绑定状态查询)
- 实现手机号绑定 Service(创建/关联 user + 签发 JWT)
- 添加公开路由 POST /auth/wechat/login 和 /auth/wechat/bind-phone
- 新增 WechatConfig 到 AppConfig(appid/secret 通过环境变量配置)
- 添加 reqwest 依赖用于调用微信 jscode2session API
2026-04-24 00:05:43 +08:00
iven
2e9eb55f2c fix(health): 修复审计发现的 10 个 CRITICAL 问题
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
权限与安全:
- 为全部 51 个 handler 端点添加 require_permission 权限检查
- 修复 CAS 预约操作中 doctor_id 为 None 时使用 Uuid::nil() 的问题

状态机修复:
- 预约初始状态从 "scheduled" 改为 "pending"(匹配设计规格)
- 排班状态从 "active" 改为 "enabled"
- 咨询会话添加 waiting→active 自动触发(首条消息时)
- 新增 create_session 端点和 DTO

数据完整性:
- doctor_profile 表添加 name 列(entity + migration + service)
- lab_report/health_trend 的 json 列改为 json_binary(支持 GIN 索引)
- 添加关键索引:patient.id_number UNIQUE、patient_tag UNIQUE、
  doctor_schedule 唯一排班槽位、health_trend、doctor_profile.name
- 随访记录完成后自动检查 next_follow_up_date 创建后续任务

事件总线:
- 实现 10 种核心事件发布(patient/appointment/follow_up/consultation/lab_report)
- 实现 workflow.task.completed 和 message.sent 事件订阅框架

种子数据:
- 实现 seed_tenant_health(8 个默认患者标签)
- 实现 soft_delete_tenant_data(16 张表级联软删除)
2026-04-23 23:25:53 +08:00
iven
d6678d001e feat(health): Handler 接线 + Doctor Service + DTO 统一
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
- 重写全部 6 个 handler 文件,从占位错误改为调用 service 层
- 删除 handler 内联 DTO,统一使用 dto/ 模块类型
- 新增 dto/doctor_dto.rs 和 dto/follow_up_dto.rs
- 新增 service/doctor_service.rs 实现医护档案 CRUD
- 将 follow_up_service 内联 DTO 迁移到 dto/follow_up_dto.rs
- 修复 consultation_session 列名 type→consultation_type(数据库+entity+迁移同步)
- 全部 51 个 API 端点已验证可用

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 21:31:42 +08:00
iven
1824f84467 feat(health): 实现 5 大 Service 层完整业务逻辑
Some checks failed
CI / rust-check (push) Has been cancelled
CI / security-audit (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
将所有 todo!() 占位替换为真实 SeaORM 数据库操作:

- patient_service: 患者CRUD + 乐观锁 + 软删除 + 标签管理 + 家庭成员 + 医生关联 + 健康摘要
- health_data_service: 体征/化验/体检CRUD + 趋势分析 + 指标时间序列查询
- appointment_service: 预约CRUD + 原子CAS排班占位 + 状态机 + 取消释放名额 + 日历视图
- follow_up_service: 随访任务CRUD + 执行记录 + 自动完成任务状态推进
- consultation_service: 咨询会话管理 + 消息收发 + 未读计数 + 会话关闭

所有操作均包含 tenant_id 过滤 + deleted_at 软删除检查 + 乐观锁版本校验。
2026-04-23 20:54:46 +08:00
iven
ca50d32f6e feat(health): 添加 erp-health 健康管理模块骨架
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
新建 erp-health 原生 Rust crate,覆盖设计规格中定义的 5 大业务域:

- 16 个 SeaORM Entity(患者/家属/标签/医生/健康档案/体征/化验单/预约/排班/随访/咨询等)
- 16 表数据库迁移(含索引、外键、默认值、可回滚)
- 40+ API 路由骨架(患者管理/健康数据/预约排班/随访/咨询/医生管理)
- 12 个权限声明(health.patient/health-data/appointment/follow-up/consultation/doctor 各 .list/.manage)
- DTO / Service / Handler / Event 四层架构,Service 使用 todo!() 占位
- erp-server 集成:模块注册 + AppState FromRef 桥接 + 路由挂载

同步更新 CLAUDE.md 项目进度、wiki 知识库、设计规格文档。
2026-04-23 19:59:22 +08:00
iven
40b37cc776 feat(plugin,freelance,itops,web): P5-P6 dashboard widgets 平台扩展 + 仪表盘声明
P5 平台扩展:
- manifest.rs: Dashboard 变体新增 widgets 字段
- manifest.rs: 定义 PluginWidget/StatCard/ActionQuery 类型
- 前端: 扩展 DashboardWidget 类型支持 stat_cards/action_list/funnel/card_list
- 前端: 新增 4 个 widget 渲染器 (StatCardsWidget/ActionListWidget/FunnelStageWidget/CardListWidget)
- 前端: PluginDashboardPage widget 数据加载支持新类型

P6 仪表盘 widgets:
- freelance: 工作台仪表盘 4 个 widgets (财务概览/紧急待办/商机漏斗/活跃项目)
- itops: 新增运维概览仪表盘 2 个 widgets (运维概览/紧急待办)
2026-04-20 09:35:27 +08:00
iven
301178067c feat(freelance,itops): P1-P4 智能业务引擎 + PDF 模板
freelance (P1+P3):
- settings: 7 配置项 (公司/财务/提醒)
- trigger_events: 5 个触发事件 (商机/合同/发票/任务/支出)
- cascade: 5 处级联过滤 (合同→商机/报价, 发票→项目/合同, 工时→任务)
- visible_when: 4 处条件显示 (收款日期/已付金额/实际工时/总金额)
- validation: 2 处校验 (手机号/邮箱)
- templates: 3 个 PDF 模板 (报价单/发票/合同)

itops (P2+P4):
- settings: 4 配置项 (SLA/提醒)
- trigger_events: 4 个触发事件 (工单/合同/巡检)
- cascade: 2 处级联过滤 (工单→合同, 巡检记录→合同)
- visible_when: 6 处条件显示 (解决方案/响应时间/解决时间/关闭时间/问题/措施)
- validation: 1 处校验 (合同编号格式)
- templates: 1 个 PDF 模板 (维保合同)
2026-04-20 09:15:57 +08:00
iven
59339c2929 feat(itops): 创建 IT 运维服务台插件 — 4 实体/8 权限/4 页面 2026-04-20 00:09:24 +08:00
iven
813df3688c feat(freelance): 添加 plugin.toml — 10 实体/20 权限/7 页面 2026-04-19 23:49:40 +08:00
iven
fcf20dded1 feat(freelance): 创建插件 crate 骨架 2026-04-19 23:45:43 +08:00
iven
a7a48167ca feat(plugin): P1-P4 审计修复 — 第三批 (配置变更通知 + 自定义视图)
3.1 配置变更通知:
- update_config 增加 EventBus 参数
- 更新成功后发布 plugin.config.updated 事件
- handler 传入 event_bus

3.2 自定义视图:
- plugin_user_views 表迁移 (id/tenant_id/user_id/plugin_id/entity/view_name/view_config/is_default)
- CRUD API: GET/POST /plugins/{id}/{entity}/views, DELETE /plugins/{id}/{entity}/views/{view_id}
- 默认视图互斥逻辑
2026-04-19 18:25:03 +08:00
iven
0a041c3d22 feat(plugin): P1-P4 审计修复 — 第二批 (运行时监控 + 通知引擎 + 编号reset)
2.1 运行时监控:
- LoadedPlugin 新增 RuntimeMetrics (调用次数/错误/响应时间/燃料消耗)
- execute_wasm 自动采集每次调用的耗时和状态
- GET /admin/plugins/{id}/metrics 端点

2.2 通知规则引擎:
- notification.rs: 订阅 plugin.trigger.* 事件
- 触发时自动给管理员发送消息通知
- emit_trigger_events 增加 manifest_id 到 payload

2.3 编号 reset_rule:
- 替换 PostgreSQL SEQUENCE 为表行 + pg_advisory_xact_lock
- 支持 daily/monthly/yearly/never 重置周期
- 每个周期独立计数,切换时自动重置为 1
2026-04-19 14:41:17 +08:00
iven
4bcb4beaa5 feat(plugin): P1-P4 审计修复 — 第一批 (Excel/CSV导出 + 市场API + 对账扫描)
1.1 Excel/CSV 导出:
- 后端 export 支持 format 参数 (json/csv/xlsx)
- rust_xlsxwriter 生成带样式 Excel
- 前端导出按钮改为 Dropdown 格式选择 (JSON/CSV/Excel)
- blob 下载支持 CSV/XLSX 二进制格式

1.2 市场后端 API + 前端对接:
- SeaORM Entity: market_entry, market_review
- API: 浏览/详情/一键安装/评论列表/提交评分
- 一键安装: upload → install → enable 一条龙 + 依赖检查
- 前端 PluginMarket 对接真实 API (搜索/分类/安装/评分)

1.3 对账扫描:
- reconcile_references() 扫描跨插件引用悬空 UUID
- POST /plugins/{plugin_id}/reconcile 端点
2026-04-19 14:32:06 +08:00
iven
120f3fe867 feat(plugin): P2-4 数据导入导出 — 后端 export/import API + 前端 UI + TS 修复
- data_service: export 方法查询匹配行(上限10000),import 方法逐行校验+插入
- data_handler: export_plugin_data / import_plugin_data 处理函数
- module: 注册 GET /export + POST /import 路由
- pluginData.ts: exportPluginData / importPluginData API 函数
- PluginCRUDPage: 根据 entity importable/exportable 标志显示导出/导入按钮
- PluginMarket: 修复 TS 错误 (unused imports, type narrowing)
- PluginSettingsForm: 修复 TS 错误 (Rule type, Divider orientation)
2026-04-19 13:28:12 +08:00
iven
e429448c42 feat(plugin): P2-P4 插件平台演进 — 通用服务 + 质量保障 + 市场
P2 平台通用服务:
- manifest 扩展: settings/numbering/templates/trigger_events/importable/exportable 声明
- 插件配置 UI: PluginSettingsForm 自动表单 + 后端校验 + 详情抽屉 Settings 标签页
- 编号规则: Host API numbering-generate + PostgreSQL 序列 + manifest 绑定
- 触发事件: data_service create/update/delete 自动发布 DomainEvent
- WIT 接口: 新增 numbering-generate/setting-get Host API

P3 质量保障:
- plugin_validator.rs: 安全扫描(WASM大小/实体数量/字段校验) + 复杂度评分
- 运行时监控指标: RuntimeMetrics (错误率/响应时间/Fuel/内存)
- 性能基准: BenchmarkResult 阈值定义
- 上传时自动安全扫描 + /validate API 端点

P4 插件市场:
- 数据库迁移: plugin_market_entries + plugin_market_reviews 表
- 前端 PluginMarket 页面: 分类浏览/搜索/详情/评分
- 路由注册: /plugins/market

测试: 269 全通过 (71 erp-plugin + 41 auth + 57 config + 34 core + 50 message + 16 workflow)
2026-04-19 12:16:24 +08:00
iven
841766b168 fix(用户管理): 修复用户列表页面加载失败问题
修复用户列表页面加载失败导致测试超时的问题,确保页面元素正确渲染
2026-04-19 08:46:28 +08:00
iven
0ee9d22634 fix(plugin): P1 跨插件引用修复 — DateTime generated column + resolve-labels UUID 类型 + EntitySelect manifest→UUID 映射
- manifest.rs: DateTime 类型 generated column 改为 TEXT 存储(PostgreSQL TIMESTAMPTZ cast 非 immutable)
- data_handler.rs: resolve-labels 查询参数从 String 改为 UUID 类型避免类型不匹配
- data_dto.rs: PublicEntityResp 新增 plugin_id 字段
- EntitySelect.tsx: 跨插件查询先通过 registry 解析 manifest_id→plugin UUID
- pluginData.ts: PublicEntity 接口增加 plugin_id
- plugin_tests.rs: 适配 PluginField/PluginEntity 新增字段
2026-04-19 08:44:45 +08:00
iven
08252c10f1 feat(crm,inventory): P1 验证 — 插件 manifest 跨插件引用声明
- CRM: customer 实体新增 is_public = true,允许其他插件引用
- 进销存: sales_order.customer_id 新增 ref_plugin/ref_entity/ref_label_field/ref_fallback_label
- 进销存: metadata 版本升至 0.2.0,dependencies 添加 erp-crm
2026-04-19 00:56:32 +08:00
iven
ef89ed38a1 feat(plugin): P1 跨插件数据引用系统 — 后端 Phase 1-3
实现跨插件实体引用的基础后端能力:

Phase 1 — Manifest 扩展 + Entity Registry 数据层:
- PluginField 新增 ref_plugin/ref_fallback_label 支持跨插件引用声明
- PluginRelation 新增 name/relation_type/display_field(CRM 已在用的字段)
- PluginEntity 新增 is_public 标记可被其他插件引用的实体
- 数据库迁移:plugin_entities 新增 manifest_id + is_public 列 + 索引
- SeaORM Entity 和 install 流程同步更新

Phase 2 — 后端跨插件引用解析 + 校验:
- data_service: 新增 resolve_cross_plugin_entity/is_plugin_active 函数
- validate_ref_entities: 支持 ref_plugin 字段,目标插件未安装时跳过校验(软警告)
- host.rs: HostState 新增 cross_plugin_entities 映射,db_query 支持点分记号
- engine.rs: execute_wasm 自动构建跨插件实体映射

Phase 3 — API 端点:
- POST /plugins/{id}/{entity}/resolve-labels 批量标签解析
- GET /plugin-registry/entities 公开实体注册表查询
2026-04-19 00:49:00 +08:00
iven
5ba11f985f fix(web,plugin): 前端审计修复 — 401 消除 + 统计卡片 crash + 销售漏斗 500 + antd 6 废弃 API
- API client: proactive token refresh(请求前 30s 检查过期,提前刷新避免 401)
- Plugin store: fetchPlugins promise 去重,防止 StrictMode 并发重复请求
- Home stats: 简化 useEffect 加载逻辑,修复 tagColor undefined crash
- PluginGraphPage: valueStyle → styles.content, Spin tip → description(antd 6)
- DashboardWidgets: trailColor → railColor(antd 6)
- data_service: build_scope_sql 参数索引修复(硬编码 $100 → 动态 values.len()+1)
- erp-core error: Internal 错误添加 tracing::error 日志输出
2026-04-18 20:31:49 +08:00
iven
790991f77c test: E2E auth fixture 修复 + Workflow 集成测试
- E2E: 用 addInitScript 替代 goto+evaluate 注入 localStorage,
  解决 Zustand store 初始化时序问题 (10/10 通过)
- E2E: 修复 Modal 按钮选择器 (OK/Cancel 替代中文)
- E2E: Playwright 配置对齐端口 5174
- 集成测试: 新增 workflow_tests 模块 (4 个测试)
2026-04-18 08:40:33 +08:00
iven
40bac74f5c fix: 审计修复 — ErrorBoundary 接入 + data_scope 全端点接线 + inventory.wasm
1. H1: App.tsx 接入 ErrorBoundary 包裹 Suspense,防止页面渲染错误导致白屏
2. H2: data_scope 行级权限扩展到 count/aggregate/timeseries 端点,
   所有数据查询操作现在都受 data_scope 过滤
3. M3: 进销存插件 WASM 编译部署到 apps/web/public/inventory.wasm
2026-04-18 08:12:40 +08:00
iven
e8739e80c7 feat: Q4 测试覆盖 + 插件生态 — 集成测试/E2E/进销存插件/热更新
Q4 成熟度路线图全部完成:

1. 集成测试框架 (Testcontainers + PostgreSQL):
   - auth_tests: 用户 CRUD、租户隔离、用户名唯一性
   - plugin_tests: 动态表创建查询、租户数据隔离

2. Playwright E2E 测试:
   - 登录页面渲染和表单验证测试
   - 用户管理、插件管理、多租户隔离占位测试

3. 进销存插件 (erp-plugin-inventory):
   - 6 实体: 产品/仓库/库存/供应商/采购单/销售单
   - 12 权限、6 页面、完整 manifest
   - WASM 编译验证通过

4. 插件热更新:
   - POST /api/v1/admin/plugins/{id}/upgrade
   - manifest 对比 + 增量 DDL + WASM 热加载
   - 失败保持旧版本继续运行

5. 文档更新: CLAUDE.md + wiki/index.md 同步 Q2-Q4 进度
2026-04-17 22:17:47 +08:00
iven
62eea3d20d feat(auth,plugin): Q3 行级数据权限 — user_departments 表 + JWT 注入 department_ids + data_scope 接线
- 新增 user_departments 关联表(migration + entity)
- JWT 中间件查询用户部门并注入 TenantContext.department_ids
- role_permission entity 添加 data_scope 字段
- data_handler 接线行级数据权限过滤(list/count/aggregate)
- DataScopeParams + build_scope_sql + merge_scope_condition 实现全链路
2026-04-17 21:42:40 +08:00
iven
6a44cbecf3 perf: Q3 N+1 查询优化 — user_service 和 plugin_service
- user_service::list() 循环内单查询改为 fetch_batch_user_role_resps 批量查询
- plugin_service::list() 循环内单查询改为 find_batch_plugin_entities 批量查询
- RoleResp 和 PluginEntityResp 添加 Clone derive
2026-04-17 19:30:12 +08:00
iven
eef264c72b ci: Q2 Chunk 4 — Gitea Actions CI/CD + Docker 生产化
- 创建 .gitea/workflows/ci.yml 四 job 并行流水线
  (rust-check, rust-test, frontend-build, security-audit)
- Docker Compose 端口不暴露到宿主机(使用 expose)
- Redis 添加 requirepass 密码认证
- 添加容器资源限制 (1 CPU / 512MB)
- Redis URL 格式更新为带密码认证
2026-04-17 19:24:32 +08:00
iven
7c14bf83ca feat(audit): Q2 Chunk 3 — 审计日志补全
- 登录成功/失败均写入审计日志(含 IP、User-Agent)
- 登出、密码修改添加审计日志
- 用户/角色 update 记录变更前后值(old_value/new_value)
- 插件数据 CRUD(create/update/delete)添加审计日志
- auth handler 提取 X-Forwarded-For/X-Real-IP/User-Agent
2026-04-17 19:21:43 +08:00
iven
080d2cb3d6 fix(security): Q2 Chunk 2 — 多租户安全加固 + 限流 fail-closed
- auth_service::refresh() 添加 tenant_id 校验
- user_service get_by_id/update/delete/assign_roles 改为数据库级 tenant_id 过滤
- 限流中间件改为 fail-closed:Redis 不可达时返回 429 而非放行
2026-04-17 17:45:59 +08:00
iven
39a12500e3 fix(security): Q2 Chunk 1 — 密钥外部化与启动强制检查
- default.toml 敏感值改为占位符,强制通过环境变量注入
- 启动时拒绝默认 JWT 密钥和数据库 URL
- 移除 super_admin_password 硬编码 fallback
- 移除 From<AppError> for AuthError 反向映射,5 处调用点改为显式 map_err
- .gitignore 添加 .test_token 和测试产物
2026-04-17 17:42:19 +08:00