Commit Graph

111 Commits

Author SHA1 Message Date
iven
6a44cbecf3 perf: Q3 N+1 查询优化 — user_service 和 plugin_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
- 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 生产化
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
- 创建 .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
iven
2bd274b39a docs: 添加 Q4 测试覆盖 + 插件生态实施计划
15 个 Task 覆盖:Testcontainers 集成测试框架、Playwright E2E、
进销存插件(6实体/6页面)、插件热更新、Wiki 文档更新
2026-04-17 17:30:29 +08:00
iven
d6dc47ab6a docs: 添加 Q3 架构强化 + 前端体验实施计划
17 个 Task 覆盖:ErpModule trait 重构(自动化路由)、N+1 查询优化、
Error Boundary、5 个 hooks 提取、i18n 基础设施、行级数据权限接线
2026-04-17 17:28:02 +08:00
iven
5e89aef99f docs: 修订 Q2 实施计划 — 修复审查发现的 14 个问题
关键修正:
- AuditLog::new() 签名与代码库一致 (tenant_id, user_id, action, resource_type)
- with_changes() 参数为 Option<Value>,调用时需 Some() 包装
- 限流 fail-closed 使用 (StatusCode, Json) 元组模式
- 添加缺失的 Task 7.5: 登录租户解析 (X-Tenant-ID)
- Task 7 添加 assign_roles 到修复列表
- Task 10 明确所有 auth 函数签名变更需求
- Task 12 添加 import 和参数说明
- Task 14 添加 docker-compose.override.yml 开发端口恢复
- 统一环境变量名为 ERP__SUPER_ADMIN_PASSWORD
2026-04-17 17:02:03 +08:00
iven
9f85188886 docs: 添加 Q2 安全地基 + CI/CD 实施计划
14 个 Task 覆盖:密钥外部化、启动强制检查、多租户加固、
限流 fail-closed、审计日志补全、Gitea Actions CI/CD、Docker 生产化
2026-04-17 16:51:51 +08:00
iven
b6c4e14b58 docs: 修订成熟度路线图 — 修复规格审查发现的 15 个问题
关键修正:
- ErpModule trait 基于实际签名设计,使用双路由模式
- CI/CD 添加 checkout/cache 步骤
- 环境变量名与现有代码一致 (ERP__SUPER_ADMIN_PASSWORD)
- .test_token 标记为需 BFG 清理
- Q4 拆分为 Q4a(测试) + Q4b(插件)
- 热更新添加回滚策略
- 添加 Windows Testcontainers 兼容性风险
2026-04-17 16:07:37 +08:00
iven
432eb2f9f5 docs: 添加平台全面成熟度提升路线图设计规格
覆盖安全地基、架构强化、测试覆盖、插件生态四个维度,
按 Q2-Q4 三季度分层推进的全面改进计划。
2026-04-17 15:58:31 +08:00
iven
9fb73788f7 fix(web): 修复 Dashboard 拆分后遗留问题
- dashboardConstants.ts → .tsx (包含 JSX 不能在 .ts 中)
- dashboardTypes.ts: AggregateItem 从 pluginData 导入而非 plugins
- PluginDashboardPage.tsx: 移除未使用的 Spin 导入
2026-04-17 12:53:35 +08:00
iven
0a57cd7030 refactor(web): 拆分 PluginGraphPage 为 graph 子模块 — 每个文件 < 800 行
- graphTypes.ts (39 行) — GraphNode/GraphEdge/GraphConfig/NodePosition/HoverState
- graphLayout.ts (41 行) — computeCircularLayout 环形布局算法
- graphRenderer.ts (293 行) — Canvas 绘制函数 + 常量 + helper
- PluginGraphPage.tsx (758 行) — 组件壳:state/effects/event handlers/JSX
2026-04-17 12:51:32 +08:00
iven
b96978b588 refactor(web): 拆分 PluginDashboardPage 为 dashboard 子模块 — 每个文件 < 400 行
将 981 行的 PluginDashboardPage.tsx 拆分为 4 个文件:
- dashboard/dashboardTypes.ts (25 行) — 类型定义
- dashboard/dashboardConstants.ts (85 行) — 常量和配置
- dashboard/DashboardWidgets.tsx (298 行) — Widget 子组件 + 共享工具
- PluginDashboardPage.tsx (397 行) — 页面壳

提取了 prepareChartData / WidgetCardShell / tagStrokeColor 等共享工具,
消除了图表组件间的重复代码。tsc --noEmit 通过。
2026-04-17 11:26:52 +08:00
iven
fb809f124c fix(web): 修复 TypeScript 编译错误 — 10 处类型/未使用变量问题
- EntitySelect: 未使用的 searchFields 改为 _searchFields
- PluginKanbanPage: DragEndEvent/DragStartEvent 改为 type import, lane_order 改为 optional
- PluginDashboardPage: 添加 PluginPageSchema import, 移除未使用的 CHART_COLORS/palette/totalCount
- PluginGraphPage: 移除未使用的 Title/textColor, 修复 hovered → hoverState
2026-04-17 11:19:44 +08:00
iven
60799176ca feat(crm): entity_select + kanban + 级联过滤声明
- PluginField 新增 ref_label_field / ref_search_fields / cascade_from / cascade_filter 字段
- PluginPageType 新增 Kanban 变体(lane_field / lane_order / card_title_field / card_subtitle_field / card_fields / enable_drag)
- CRM plugin.toml: contact.customer_id 和 communication.contact_id 添加 entity_select 声明
- CRM plugin.toml: communication.contact_id 添加 cascade_from/cascade_filter 级联过滤
- CRM plugin.toml: 新增销售漏斗 kanban 页面声明
- 新增 5 个解析测试(entity_select / cascade / kanban / 空值校验)
2026-04-17 11:10:31 +08:00
iven
4ea9bccba6 feat(web): Dashboard 图表增强 — bar/pie/funnel/line + 并行加载
- 新增基于 DashboardWidget 声明的图表渲染
- 支持 stat_card/bar_chart/pie_chart/funnel_chart/line_chart 五种类型
- 使用 @ant-design/charts 渲染 Column/Pie/Funnel/Line 图表
- Widget 数据通过 Promise.all 并行加载
- 保留原有基于实体的分布统计作为兜底
- 安装 @ant-design/charts 依赖
2026-04-17 11:04:36 +08:00
iven
9549f896b6 feat(web): CRUD 页面批量操作 — 多选 + 批量删除
- 新增 selectedRowKeys 状态管理
- Table 添加 rowSelection 支持多选
- 新增批量操作栏,显示已选数量和批量删除按钮
- 批量删除调用 batchPluginData API
- compact 模式下隐藏批量操作
2026-04-17 11:02:01 +08:00
iven
a333b3673f feat(plugin): timeseries 聚合 API — date_trunc 时间序列 2026-04-17 11:01:43 +08:00
iven
c9a58e9d34 feat(web): Kanban 看板页面 — dnd-kit 拖拽 + 跨列移动
- 新增 PluginKanbanPage 看板页面,支持 dnd-kit 拖拽
- 支持泳道分组、卡片标题/副标题/标签展示
- 乐观更新 UI,失败自动回滚
- 路由入口 /plugins/:pluginId/kanban/:entityName 自加载 schema
- PluginTabsPage 新增 kanban 页面类型支持
- PluginStore 新增 kanban 菜单项和路由生成
- 安装 @dnd-kit/core + @dnd-kit/sortable
2026-04-17 11:00:52 +08:00
iven
c487a94f19 feat(plugin): 批量操作端点 — batch_delete + batch_update 2026-04-17 10:58:34 +08:00
iven
022ac951c9 feat(web): visible_when 增强 — 支持 AND/OR/NOT/括号 表达式
- 新增 utils/exprEvaluator.ts 表达式解析器
- 支持 eq/and/or/not 四种节点类型和括号分组
- 支持 == 和 != 比较运算符
- PluginCRUDPage 替换简单正则为 evaluateVisibleWhen
2026-04-17 10:57:34 +08:00
iven
b0ee3e495d feat(plugin): PATCH 部分更新端点 — jsonb_set 字段合并 2026-04-17 10:56:37 +08:00
iven
e2e58d3a00 feat(web): EntitySelect 关联选择器 — 远程搜索 + 级联过滤
- 新增 EntitySelect 组件,支持远程搜索和级联过滤
- PluginCRUDPage 表单渲染新增 entity_select widget 支持
- 通过 ref_entity/ref_label_field 配置关联实体
- 通过 cascade_from/cascade_filter 实现级联过滤
2026-04-17 10:56:17 +08:00
iven
5b2ae16ffb feat(web): API 层扩展 — batch/patch/timeseries/kanban 类型
- PluginFieldSchema 新增 ref_entity/ref_label_field/ref_search_fields/cascade_from/cascade_filter
- PluginPageSchema 新增 kanban 页面类型(lane_field/card_title_field 等)
- PluginPageSchema dashboard 类型扩展 widgets 字段
- 新增 DashboardWidget 接口(stat_card/bar/pie/funnel/line 图表)
- pluginData 新增 batchPluginData/patchPluginData/getPluginTimeseries 三个 API 函数
2026-04-17 10:55:24 +08:00
iven
8bef5e2401 feat(crm): 启用客户实体 data_scope + owner_id + data_scope_levels
- customer 实体新增 data_scope = true 启用行级数据权限
- customer 新增 owner_id 字段 (scope_role = "owner") 标记数据所有者
- customer.list 和 customer.manage 权限新增 data_scope_levels 声明
  支持 self / department / department_tree / all 四种范围等级
2026-04-17 10:50:53 +08:00
iven
a7342f83e9 feat(plugin): 数据范围查询基础设施 — get_data_scope + get_dept_members 辅助函数
- 新增 get_data_scope() 查询当前用户对指定权限的 data_scope 等级
- 新增 get_dept_members() 获取部门成员 ID 列表(预留递归部门树查询)
- 在 list_plugin_data handler 中标记 data_scope 注入点 TODO
- 这些基础设施函数将在前端 Chunk 4 完成完整集成
2026-04-17 10:49:57 +08:00
iven
41a0dc8bd6 feat(plugin): 实体级 data_scope + scope_role + data_scope_levels 声明
- PluginEntity 新增 data_scope: Option<bool> 字段,控制是否启用行级数据权限
- PluginField 新增 scope_role: Option<String> 字段,标记数据权限的"所有者"字段
- PluginPermission 新增 data_scope_levels: Option<Vec<String>> 字段,声明支持的数据范围等级
- 更新 default_for_field() 测试辅助和 dynamic_table.rs 中的 PluginEntity 构造
- 新增 parse_entity_with_data_scope 和 parse_permission_with_data_scope_levels 测试
2026-04-17 10:45:49 +08:00
iven
89684313d9 feat(plugin): 级联删除 — relations OnDeleteStrategy 支持
delete 方法扩展为处理三种级联策略:Restrict(存在关联时拒绝删除)、
Nullify(置空外键字段)、Cascade(级联软删除关联记录)。
在软删除主记录之前按声明顺序处理所有关联关系。
2026-04-17 10:40:05 +08:00
iven
e24b820d80 feat(plugin): 循环引用检测 — no_cycle 字段支持
新增 check_no_cycle 异步函数,通过沿 parent 链上溯检测
是否存在循环引用。在 update 方法中集成,对声明 no_cycle
的字段执行检测,最多遍历 100 层防止无限循环。
2026-04-17 10:38:41 +08:00
iven
e6aaa18ceb fix(plugin): 移除权限 fallback — 必须显式分配实体级权限
所有 7 个数据 handler 方法不再回退到 plugin.list/plugin.admin
粗粒度权限。现在必须为每个实体显式分配 {plugin}.{entity}.list
或 {plugin}.{entity}.manage 权限,否则返回 403。
2026-04-17 10:38:05 +08:00
iven
314580243e feat(plugin): 字段正则校验 — validation.pattern 支持
Cargo.toml 新增 regex 依赖。validate_data 函数扩展支持
FieldValidation.pattern 正则校验,空值非必填字段跳过校验,
校验失败时返回自定义 message 或默认提示。
2026-04-17 10:37:37 +08:00
iven
dadb826804 feat(plugin): SQL 构建支持行级数据范围条件
DynamicTableManager 新增 build_data_scope_condition_with_params 方法,
支持 all/self/department/department_tree 四种数据范围过滤。
部门成员为空时自动退化为 self 范围,支持 Generated Column 路由。
附带 6 个单元测试覆盖所有场景。
2026-04-17 10:36:01 +08:00
iven
649334e862 feat(plugin): 外键校验 — ref_entity 字段验证引用记录存在性
新增 validate_ref_entities 异步函数,在 create/update 时检查
ref_entity 字段指向的记录是否存在于对应动态表中。自引用
场景下 create 跳过校验,update 跳过自身引用。
2026-04-17 10:35:46 +08:00
iven
f4b1a06d53 feat(auth): JWT 中间件预留 department_ids 填充位置
当前 department_ids 为空列表,附带 TODO 注释说明
待 user_positions 关联表建立后补充查询逻辑。
2026-04-17 10:34:06 +08:00
iven
527a57df9e feat(plugin): PluginRelation 级联删除声明 + OnDeleteStrategy
新增 OnDeleteStrategy 枚举(Nullify/Cascade/Restrict)和
PluginRelation 结构体声明实体关联关系。PluginEntity 增加
relations 字段(serde(default) 向后兼容)。
2026-04-17 10:33:58 +08:00
iven
62f17d13ad feat(core): TenantContext 新增 department_ids 字段
为行级数据权限做准备,TenantContext 新增 department_ids 字段
存储用户所属部门 ID 列表。当前阶段 JWT 中间件填充为空列表,
待 user_positions 关联表建立后补充查询逻辑。
2026-04-17 10:33:28 +08:00
iven
6f286acbeb feat(db): role_permissions 添加 data_scope 列
行级数据权限基础设施 — role_permissions 表新增 data_scope 列,
支持 all/self/department/department_tree 四种数据范围。
2026-04-17 10:32:12 +08:00
iven
f697b5fd6d feat(plugin): PluginField 扩展 — ref_entity / validation / no_cycle
新增 FieldValidation 类型支持正则校验规则,PluginField 增加
ref_entity(外键引用实体名)、validation(字段校验规则)、
no_cycle(禁止循环引用)三个可选字段。
2026-04-17 10:31:37 +08:00
iven
abc3086571 chore(crm): 验证 Generated Column 自动生成 — 无需修改 plugin.toml
验证所有实体的 unique/filterable/sortable 标记已正确配置,
build_create_table_sql 将自动为以下字段生成 Generated Column:
- customer: code(unique), customer_type/industry/region/level/status(filterable)
- communication: type(filterable), occurred_at(sortable)
- customer_relationship: relationship_type(filterable)

同步更新 Cargo.lock(moka 依赖引入)
2026-04-17 10:26:13 +08:00
iven
16b7a36bfb feat(plugin): list 方法集成 Generated Column 路由
- list 方法新增 cache 参数,使用 resolve_entity_info_cached 替代直接查库
- 查询改用 build_filtered_query_sql_ex,自动路由到 Generated Column
- handler 传递 entity_cache 到 list 方法
2026-04-17 10:25:43 +08:00
iven
28c7126518 feat(plugin): 聚合查询 Redis 缓存骨架
- 新增 aggregate_cached 方法,预留 Redis 缓存接口
- 当前直接委托到 aggregate 方法,未来版本添加缓存层
2026-04-17 10:24:26 +08:00
iven
091d517af6 feat(plugin): Schema 缓存 — moka LRU Cache 消除 resolve_entity_info 重复查库
- 添加 moka 0.12 依赖到 erp-plugin 和 erp-server
- 重写 state.rs: 新增 EntityInfo (含 generated_fields) 和 moka Cache
- AppState 新增 plugin_entity_cache 字段
- data_service.rs: 旧 resolve_entity_info 保留兼容,新增 resolve_entity_info_cached
2026-04-17 10:23:43 +08:00
iven
3b0b78c4cb docs: 强化闭环工作法 — 验证通过才能提交,提交后必须推送
§3.3 闭环工作法改为 6 步:理解→实现→验证→提交→文档同步→推送
§13 反模式新增 3 条:禁止跳过验证、禁止不推送、禁止忘记更新文档
2026-04-17 10:19:35 +08:00
iven
2616e83ec6 feat(plugin): Keyset Pagination — cursor 编解码 + 游标分页 SQL 2026-04-17 10:18:43 +08:00
iven
20734330a6 feat(plugin): SQL 查询路由 — Generated Column 字段优先使用 _f_ 前缀列 2026-04-17 10:16:35 +08:00
iven
a897cd7a87 feat(plugin): create_table 使用 Generated Column + pg_trgm + 覆盖索引 2026-04-17 10:15:05 +08:00
iven
32dd0f72c1 feat(plugin): PluginFieldType 添加 Generated Column 类型映射 2026-04-17 10:12:52 +08:00
iven
67bdf9e942 feat(db): 添加 pg_trgm 扩展 + plugin_entity_columns 元数据表
- 启用 pg_trgm 扩展加速 ILIKE '%keyword%' 模糊搜索
- 新增 plugin_entity_columns 表,记录插件动态表中哪些字段被提取为 Generated Column
- 添加 plugin_entity_id 外键关联 plugin_entities 表
- down 方法仅删表不卸载 pg_trgm(其他功能可能依赖)
2026-04-17 10:08:09 +08:00
iven
a7cf44cd46 docs: CRM 插件基座升级实施计划 — 4 Chunk 36 Task
Chunk 1: JSONB 存储优化 (Generated Column + pg_trgm + Keyset + Schema 缓存)
Chunk 2: 数据完整性框架 (ref_entity + 级联删除 + 字段校验 + 循环检测)
Chunk 3: 行级数据权限 (data_scope + TenantContext 扩展 + fallback 收紧)
Chunk 4: 前端页面能力增强 (entity_select + kanban + 批量操作 + 图表)
2026-04-17 09:57:58 +08:00