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 |
|
iven
|
d07e476898
|
docs(spec): 新增 CRM 插件基座升级设计规格 v1.1
6 专家组深度评审后的基座优先改进方案:
- JSONB 存储优化 (Generated Column + pg_trgm + Keyset Pagination)
- 数据完整性框架 (ref_entity + 级联策略 + 字段校验 + 循环引用检测)
- 行级数据权限 (self/department/department_tree/all 四级)
- 前端页面能力增强 (entity_select + kanban + 批量操作 + Dashboard 图表)
|
2026-04-17 03:13:07 +08:00 |
|
iven
|
2866ffb634
|
feat(crm): 新增关系图谱和统计概览页面 + UI/UX 全面优化
后端:
- manifest.rs 新增 Graph 和 Dashboard 页面类型到 PluginPageType 枚举
- 添加 graph 页面验证逻辑(entity/relationship_entity/source_field/target_field)
CRM 插件:
- plugin.toml 新增关系图谱页面(graph 类型,基于 customer_relationship 实体)
- plugin.toml 新增统计概览页面(dashboard 类型)
- 侧边栏菜单从 5 项扩展到 7 项
前端 — 关系图谱 (PluginGraphPage):
- 渐变节点 + 曲线箭头连线 + 关系类型色彩区分
- 鼠标悬停高亮 + Canvas Tooltip + 点击设为中心节点
- 2-hop 邻居视图 + 统计卡片(客户总数/关系总数/当前中心)
- 关系类型图例(可点击筛选)+ 暗色主题适配
- ResizeObserver 自适应 + requestAnimationFrame 动画循环
前端 — 统计概览 (PluginDashboardPage):
- 5 实体统计卡片(渐变色条 + 图标 + 数字动画)
- 可筛选字段分布卡片(Progress 进度条 + Tag 标签)
- 响应式栅格布局 + 骨架屏加载态 + 错误状态持久展示
|
2026-04-17 01:28:19 +08:00 |
|
iven
|
b08e8b5ab5
|
perf: 前端 API 并行化 + 后端 Redis 连接缓存 — 响应时间从 2.26s 降至 2ms
后端:
- rate_limit 中间件新增 RedisAvailability 缓存
- Redis 不可用时跳过限流,30 秒冷却后再重试
- 避免 get_multiplexed_async_connection 每次请求阻塞 2 秒
前端:
- plugin store schema 加载改为 Promise.allSettled 并行(原为 for...of 顺序)
- 先基于 entities 渲染回退菜单,schema 加载完成后更新
- 移除 Home useEffect 中 unreadCount 依赖,消除双重 fetch
- MainLayout 使用选择性 store selector 减少重渲染
|
2026-04-17 01:12:17 +08:00 |
|
iven
|
f4dd228a67
|
feat(web): 插件侧边栏改为三级菜单结构 — 按插件名分组可折叠
插件菜单从扁平列表改为三级结构:
插件(分组)→ 插件名(可折叠子标题)→ 页面列表
- store 新增 PluginMenuGroup 类型和 pluginMenuGroups getter
- MainLayout 新增 SidebarSubMenu 组件,支持展开/收起
- 折叠侧边栏时子菜单显示插件图标 + tooltip
- 子菜单项增加缩进样式区分层级
- CRM 插件 name 改为 "CRM" 避免与页面标题重名
|
2026-04-17 01:01:19 +08:00 |
|