diff --git a/docs/use-cleaner-refactor-overview.md b/docs/use-cleaner-refactor-overview.md new file mode 100644 index 0000000..3f80666 --- /dev/null +++ b/docs/use-cleaner-refactor-overview.md @@ -0,0 +1,247 @@ +# useCleaner 重构说明 + +本文档记录 `src/renderer/src/hooks/useCleaner.ts` 的第一阶段重构工作。目标不是一次性把整个 Cleaner 页面完全组件化,而是优先拆出共享类型、纯函数和 IPC 编排逻辑,让 `useCleaner` 从“大而全逻辑容器”逐步收敛为“组合层”。 + +## 1. 重构背景 + +重构前,`useCleaner.ts` 同时负责: + +- 页面初始化 +- 权限判断 +- sessionStorage 持久化 +- 校验请求 +- 结果筛选 +- 勾选状态处理 +- 删除计划构建 +- 保存物料变更 +- Cleaner 执行编排 +- 导出编排 +- 弹窗确认 +- 报告状态维护 + +这导致它虽然名义上是一个 hook,但实际上已经接近一个“前端页面服务总线”。 + +## 2. 重构目标 + +本次重构目标是: + +- 提取共享类型,消除重复定义 +- 提取纯函数,隔离无副作用逻辑 +- 提取 IPC / 异步编排,隔离对 `window.electron` 的直接调用 +- 保持 `useCleaner()` 返回值和 `CleanerPage.tsx` 使用方式不变 + +## 3. 重构后结构 + +```mermaid +graph TD + Page[CleanerPage.tsx] + Hook[useCleaner.ts] + + subgraph CleanerHookModules[Cleaner Hook Modules] + Types[hooks/cleaner/types.ts] + Helpers[hooks/cleaner/helpers.ts] + Api[hooks/cleaner/api.ts] + end + + subgraph ExternalDeps[External Dependencies] + Electron[window.electron] + Store[useAppStore / Toast] + Dialog[ConfirmDialog] + end + + Page --> Hook + Hook --> Types + Hook --> Helpers + Hook --> Api + Hook --> Store + Hook --> Dialog + Api --> Electron +``` + +## 4. 本次拆分内容 + +### 4.1 共享类型 + +新增: + +- `src/renderer/src/hooks/cleaner/types.ts` + +统一收敛了以下类型: + +- `ValidationRequest` +- `ValidationResult` +- `ValidationStats` +- `ValidationResponsePayload` +- `CleanerProgress` +- `CleanerReportData` +- `CleanerInitializationResult` +- `CleanerConfigResult` + +这一步解决了原来多个文件重复定义同类类型的问题,比如: + +- `useCleaner.ts` +- `useValidation.ts` +- `ExecutionReportDialog.tsx` + +### 4.2 纯函数与数据构造 + +新增: + +- `src/renderer/src/hooks/cleaner/helpers.ts` + +提取出的纯函数包括: + +- `getStoredBoolean()` +- `getStoredValidationMode()` +- `filterValidationResults()` +- `buildDeletionPlan()` +- `buildExportItems()` + +这些逻辑之前都散落在 `useCleaner.ts` 的 `useMemo` 或事件处理函数里,现在可以单独测试。 + +### 4.3 IPC 与异步编排 + +新增: + +- `src/renderer/src/hooks/cleaner/api.ts` + +提取出的异步编排包括: + +- `initializeCleanerPage()` +- `loadCleanerConfig()` +- `runValidationRequest()` +- `saveDeletionPlan()` +- `reloadManagers()` +- `runCleanerExecution()` +- `exportCleanerResults()` + +这样做之后,`useCleaner.ts` 不再需要在每个 handler 里直接拼接 `window.electron.xxx` 调用细节。 + +## 5. useCleaner 的角色变化 + +```mermaid +flowchart LR + subgraph Before[重构前] + A[useCleaner.ts] + A --> A1[本地状态] + A --> A2[筛选逻辑] + A --> A3[删除计划构建] + A --> A4[执行清理请求] + A --> A5[导出请求] + A --> A6[初始化请求] + A --> A7[共享类型定义] + end + + subgraph After[重构后] + B[useCleaner.ts] + B --> B1[组合状态] + B --> B2[调用 helpers] + B --> B3[调用 api] + + C[helpers.ts] + D[api.ts] + E[types.ts] + + B --> C + B --> D + B --> E + end +``` + +重构后,`useCleaner.ts` 更接近“组合层”: + +- 管理 React state +- 串联用户交互流程 +- 调用 helpers 和 api +- 将最终能力暴露给页面 + +## 6. 受影响的文件 + +### 6.1 主体修改 + +- `src/renderer/src/hooks/useCleaner.ts` +- `src/renderer/src/hooks/useValidation.ts` +- `src/renderer/src/components/ExecutionReportDialog.tsx` + +### 6.2 新增模块 + +- `src/renderer/src/hooks/cleaner/types.ts` +- `src/renderer/src/hooks/cleaner/helpers.ts` +- `src/renderer/src/hooks/cleaner/api.ts` + +### 6.3 新增测试 + +- `tests/unit/cleaner-helpers.test.ts` + +## 7. 具体收益 + +### 7.1 类型一致性提升 + +之前 `ValidationResult`、`CleanerProgress` 在多个文件重复定义,修改字段时容易遗漏。 +现在统一从 `hooks/cleaner/types.ts` 引用,降低了类型漂移风险。 + +### 7.2 可测试性提升 + +原先删除计划构建、筛选和导出映射逻辑只能通过 hook 间接覆盖。 +现在这些逻辑已经被抽成纯函数,可以直接做单测。 + +### 7.3 Hook 复杂度下降 + +虽然 `useCleaner.ts` 还没有变成一个很小的文件,但其中的“细节密度”已经明显下降: + +- 数据变换逻辑外提 +- API 编排逻辑外提 +- 重复类型移除 + +### 7.4 为下一步组件拆分做准备 + +后续如果要拆 `CleanerPage.tsx`: + +- 左侧筛选区 +- 表格工具栏 +- 底部执行区 + +这些组件就可以直接消费已经整理好的 hook 能力,而不是继续把逻辑往页面里塞。 + +## 8. 验证方式 + +本次重构后执行了以下验证: + +- `npm run typecheck:node` +- `tests/unit/cleaner-helpers.test.ts` +- `tests/unit/cleaner.test.ts` + +## 9. 新增测试覆盖点 + +`tests/unit/cleaner-helpers.test.ts` 覆盖了: + +- 非管理员筛选逻辑 +- 删除计划构建逻辑 +- 导出数据构建逻辑 + +## 10. 仍然保留在 useCleaner 中的内容 + +为了控制改动风险,这次没有继续下沉以下能力: + +- `ConfirmDialog` 的 Promise 封装 +- 编辑状态 `editingCell / editValue` +- `isRunning / isExecuting / isReportDialogOpen` 等 UI 状态 +- 页面层直接依赖的完整返回对象 + +这些能力仍然保留在 `useCleaner.ts`,因为它们和当前页面交互绑定较深。 + +## 11. 下一步建议 + +基于目前的结构,建议下一阶段继续做: + +1. 拆 `CleanerPage.tsx` 为“左侧筛选区”和“右侧结果与执行区”两个子组件。 +2. 将 `showConfirmDialog()` 封装为独立 hook,例如 `useConfirmDialogController()`。 +3. 将 inline edit 相关逻辑提取到更专门的 manager-assignment controller。 +4. 视情况把 Cleaner 相关状态进一步收敛到专门 store 或 domain hook 中。 + +## 12. 总结 + +这次 `useCleaner` 重构的核心价值,不是“让文件立刻变得很小”,而是先把最容易复用、最适合测试、最不应继续堆在 hook 里的部分拆出来。 + +它为接下来的页面组件拆分提供了一个更稳的基础,也让 Cleaner 模块开始从“页面驱动逻辑”向“模块化前端能力”转变。 + diff --git a/docs/validation-handler-refactor-overview.md b/docs/validation-handler-refactor-overview.md new file mode 100644 index 0000000..f810ced --- /dev/null +++ b/docs/validation-handler-refactor-overview.md @@ -0,0 +1,218 @@ +# validation-handler 重构说明 + +本文档记录 `src/main/ipc/validation-handler.ts` 的第一阶段重构工作,目标是把“超大 IPC Handler”拆回到更清晰的职责边界中,同时保持对外 IPC 协议和业务行为不变。 + +## 1. 重构背景 + +重构前,`validation-handler.ts` 同时承担了以下职责: + +- IPC 通道注册 +- 跨页面共享 `Production ID` 状态 +- 数据库连接创建与释放 +- MySQL / SQL Server 方言分支 +- 输入识别与订单号解析 +- 物料校验结果组装 +- Cleaner 执行前数据准备 +- 物料查询与富化 + +这种结构的主要问题是: + +- 文件过大,理解成本高 +- 数据库和业务规则直接堆叠在 IPC 层 +- 复用困难,后续其他模块无法直接复用这些逻辑 +- 单元测试难以细粒度编写 + +## 2. 重构目标 + +本次重构聚焦在“职责下沉、行为不变”: + +- 保留原有 IPC channel 和返回结构 +- 将共享状态、数据库工厂、输入解析、验证业务流程拆出 +- 让 `validation-handler.ts` 回归为薄 IPC 壳层 +- 为后续继续拆 `cleaner-handler`、前端校验流程提供复用基础 + +## 3. 重构后结构 + +```mermaid +graph TD + Renderer[Renderer / Preload] + Handler[validation-handler.ts] + + subgraph ValidationServices[Validation Services] + Store[shared-production-ids-store.ts] + DbFactory[validation-database.ts] + InputSvc[production-input-service.ts] + AppSvc[validation-application-service.ts] + end + + subgraph ExistingServices[Existing Services] + MaterialsDAO[MaterialsToBeDeletedDAO] + PlanDAO[DiscreteMaterialPlanDAO] + Session[SessionManager] + end + + Renderer --> Handler + Handler --> Session + Handler --> Store + Handler --> AppSvc + Handler --> MaterialsDAO + + AppSvc --> Store + AppSvc --> DbFactory + AppSvc --> InputSvc + AppSvc --> MaterialsDAO + AppSvc --> PlanDAO +``` + +## 4. 新增与调整的文件 + +### 4.1 IPC 薄壳 + +- `src/main/ipc/validation-handler.ts` + +职责收敛为: + +- 注册 IPC handler +- 从 `SessionManager` 读取当前用户 +- 调用应用服务 +- 对简单 DAO 操作做最轻量转发 + +### 4.2 共享状态模块 + +- `src/main/services/validation/shared-production-ids-store.ts` + +职责: + +- 管理按 `senderId` 隔离的共享 `Production IDs` +- 提供 `set/get/clear` + +价值: + +- 将原本散落在 handler 文件顶部的状态提升为独立服务 +- 后续如果要迁移到更持久的 session store,只需替换这一层 + +### 4.3 数据库创建与表名适配 + +- `src/main/services/validation/validation-database.ts` + +职责: + +- 创建用于 validation 相关流程的数据库服务 +- 提供 `getValidationTableName()` 做表名方言转换 + +价值: + +- 收敛 MySQL / SQL Server 的连接逻辑 +- 避免 IPC 文件里反复出现数据库构造代码 + +### 4.4 输入解析服务 + +- `src/main/services/validation/production-input-service.ts` + +职责: + +- 读取 Production ID 文件 +- 识别输入是 `production_id`、`order_number` 还是 `unknown` +- 从输入解析出订单号列表 + +价值: + +- 把“输入解析规则”变成可复用、可测试的纯业务模块 + +### 4.5 应用服务 + +- `src/main/services/validation/validation-application-service.ts` + +职责: + +- 校验流程编排 +- Cleaner 数据准备 +- 物料按负责人查询 / 全量查询的富化逻辑 +- 统一管理数据库生命周期 + +价值: + +- 形成明确的 application service 层 +- 让后续业务扩展不再从 IPC 文件开刀 + +## 5. 重构前后职责对比 + +```mermaid +flowchart LR + subgraph Before[重构前] + A1[validation-handler.ts] + A1 --> A2[IPC 注册] + A1 --> A3[共享状态] + A1 --> A4[数据库连接] + A1 --> A5[输入解析] + A1 --> A6[校验编排] + A1 --> A7[物料富化] + A1 --> A8[Cleaner 数据准备] + end + + subgraph After[重构后] + B1[validation-handler.ts] + B2[shared-production-ids-store.ts] + B3[validation-database.ts] + B4[production-input-service.ts] + B5[validation-application-service.ts] + + B1 --> B5 + B1 --> B2 + B5 --> B3 + B5 --> B4 + end +``` + +## 6. 本次保留不变的部分 + +为了控制风险,这次没有修改以下内容: + +- IPC channel 名称 +- Preload / Renderer 调用方式 +- 物料匹配规则 +- Cleaner 数据准备规则 +- DAO 层的既有 SQL 结构 + +也就是说,这次更像是一次“结构性搬迁”,不是业务规则改造。 + +## 7. 验证方式 + +本次重构完成后,做了以下验证: + +- `npm run typecheck:node` +- `tests/unit/shared-production-ids-store.test.ts` +- `tests/unit/production-input-service.test.ts` +- 既有 `tests/unit/ipc-index.test.ts` + +## 8. 新增测试 + +新增测试文件: + +- `tests/unit/shared-production-ids-store.test.ts` +- `tests/unit/production-input-service.test.ts` + +覆盖内容: + +- sender 隔离存储 +- 去重行为 +- 清空逻辑 +- 输入类型识别 + +## 9. 收益总结 + +这次重构带来的直接收益: + +- `validation-handler.ts` 不再承担过多业务职责 +- validation 相关逻辑形成了可复用服务层 +- 输入解析与共享状态有了独立测试入口 +- 后续继续拆 `cleaner-handler` 时,可以直接复用订单号解析和 cleaner 数据准备逻辑 + +## 10. 后续建议 + +建议在这个基础上继续推进: + +1. 将 `validation-application-service.ts` 中的 SQL Server / MySQL 分支继续下沉到 repository 或 dialect adapter。 +2. 逐步给 `getCleanerData()`、`getMaterialsByManager()` 这类编排逻辑补更多单测。 +3. 把和 validation 强耦合的 renderer 逻辑改成显式依赖 application contract,而不是隐式依赖 payload shape。 +