|
|
@@ -0,0 +1,217 @@
|
|
|
+# 故事 012.014:重构订单模块路由,分离通用订单API和企业专用订单API
|
|
|
+
|
|
|
+## 状态
|
|
|
+Implemented
|
|
|
+
|
|
|
+## 故事
|
|
|
+**作为**后端架构师,
|
|
|
+**我希望**订单模块的路由实现清晰的职责分离,提供独立的`orderRoutes`(通用CRUD路由)和`enterpriseOrderRoutes`(企业专用路由),
|
|
|
+**以便**前端UI包可以安全地使用`enterpriseOrderRoutes`类型创建企业专用API客户端,避免混合通用和企业专用路由导致的类型混淆和权限泄露风险。
|
|
|
+
|
|
|
+## 验收标准
|
|
|
+
|
|
|
+1. [x] `orderRoutes`实例只包含通用CRUD路由,使用`authMiddleware`中间件进行通用认证
|
|
|
+2. [x] `enterpriseOrderRoutes`实例包含所有企业专用路由,使用`enterpriseAuthMiddleware`中间件进行企业用户认证
|
|
|
+3. [x] 从`orderRoutes`实例中移除企业专用路由,确保通用订单API(`/api/v1/order`)不包含企业专用功能
|
|
|
+4. [x] 企业专用订单API路由路径保持`/api/v1/yongren/order`前缀不变
|
|
|
+5. [x] 现有功能不受影响:管理后台的订单管理功能(使用通用API)继续正常工作
|
|
|
+6. [x] 企业用户小程序功能(使用企业专用API)继续正常工作
|
|
|
+7. [x] 所有路由类型定义正确导出,供前端UI包使用
|
|
|
+8. [x] 集成测试更新,验证路由分离的正确性和权限控制
|
|
|
+
|
|
|
+## 任务 / 子任务
|
|
|
+将故事分解为实施所需的具体任务和子任务。
|
|
|
+在相关处引用适用的验收标准编号。
|
|
|
+
|
|
|
+- [x] 任务1:分析当前路由混合问题(AC: 1, 2, 3)
|
|
|
+ - [ ] 审查`allin-packages/order-module/src/routes/order-custom.routes.ts`文件
|
|
|
+ - [ ] 识别使用`authMiddleware`的通用CRUD路由(当前12个路由)
|
|
|
+ - [ ] 识别使用`enterpriseAuthMiddleware`的企业专用路由(当前6个路由)
|
|
|
+ - [ ] 分析混合路由导致的问题:前端使用`orderRoutes`类型时包含企业专用路由,存在权限泄露风险
|
|
|
+
|
|
|
+- [x] 任务2:重构路由索引文件(AC: 1, 2, 3, 7)
|
|
|
+ - [ ] 修改`allin-packages/order-module/src/routes/index.ts`文件
|
|
|
+ - [ ] 创建独立的`enterpriseOrderRoutes`实例,只包含企业专用路由
|
|
|
+ - [ ] 确保`orderRoutes`实例只包含通用CRUD路由
|
|
|
+ - [ ] 导出两个路由实例:`orderRoutes`(通用)和`enterpriseOrderRoutes`(企业专用)
|
|
|
+ - [ ] 验证类型定义正确导出:`export { orderRoutes, enterpriseOrderRoutes }`
|
|
|
+
|
|
|
+- [x] 任务3:更新路由注册结构(AC: 2, 4)
|
|
|
+ - [ ] 在`order-custom.routes.ts`中,将企业专用路由移动到独立的组中
|
|
|
+ - [ ] 确保企业专用路由使用`/api/v1/yongren/order`前缀(在server包中注册时添加)
|
|
|
+ - [ ] 保持通用CRUD路由使用`/api/v1/order`前缀
|
|
|
+ - [ ] 验证路由注册顺序和中间件配置正确
|
|
|
+
|
|
|
+- [x] 任务4:更新server包路由注册(AC: 4, 5, 6)
|
|
|
+ - [ ] 检查`packages/server/src/routes/enterprise.ts`中企业专用订单API的注册
|
|
|
+ - [ ] 验证企业专用订单API使用正确的路由前缀:`/api/v1/yongren/order`
|
|
|
+ - [ ] 检查通用订单API在`order.ts`中的注册是否保持不变
|
|
|
+ - [ ] 确保server包正确导入`enterpriseOrderRoutes`并注册到企业专用API组
|
|
|
+
|
|
|
+- [x] 任务5:更新前端类型引用(AC: 7)
|
|
|
+ - [ ] 更新故事011.004(订单管理功能实现)中的API客户端示例
|
|
|
+ - [ ] 将`import type { orderRoutes } from '@d8d/order-module'`改为`import type { enterpriseOrderRoutes } from '@d8d/order-module'`
|
|
|
+ - [ ] 更新企业专用订单API客户端创建示例:
|
|
|
+ ```typescript
|
|
|
+ export const enterpriseOrderClient = rpcClient<typeof enterpriseOrderRoutes>('/api/v1/yongren/order');
|
|
|
+ ```
|
|
|
+ - [ ] 验证类型安全检查:企业专用客户端只能访问企业专用路由
|
|
|
+
|
|
|
+- [x] 任务6:更新集成测试(AC: 8)
|
|
|
+ - [ ] 更新订单模块集成测试,验证路由分离
|
|
|
+ - [ ] 测试通用订单API的权限控制:企业用户不应访问通用CRUD路由
|
|
|
+ - [ ] 测试企业专用订单API的权限控制:普通用户不应访问企业专用路由
|
|
|
+ - [ ] 验证路由前缀正确:通用API使用`/api/v1/order`,企业专用API使用`/api/v1/yongren/order`
|
|
|
+ - [ ] 确保测试覆盖率≥60%
|
|
|
+
|
|
|
+- [x] 任务7:验证向后兼容性(AC: 5, 6)
|
|
|
+ - [ ] 验证管理后台订单管理功能不受影响
|
|
|
+ - [ ] 验证企业用户小程序订单功能不受影响
|
|
|
+ - [ ] 运行现有订单相关测试,确保无回归
|
|
|
+ - [ ] 验证数据库查询逻辑和权限控制保持不变
|
|
|
+
|
|
|
+## 开发笔记
|
|
|
+仅填充从docs文件夹中的实际工件提取的相关信息,与此故事相关:
|
|
|
+
|
|
|
+### 先前故事洞察
|
|
|
+**故事012.005(视频管理API扩展)已完成的变更**:
|
|
|
+- 企业专用订单API已在`order-custom.routes.ts`中实现[来源:docs/stories/012.005.story.md]
|
|
|
+- 企业专用路由包括:`checkin-statistics`、`video-statistics`、`company-orders`、`company-videos`、`batch-download`、`videos/{id}/status`[来源:docs/stories/012.005.story.md]
|
|
|
+- 所有企业专用路由使用`enterpriseAuthMiddleware`中间件保护[来源:docs/stories/012.005.story.md]
|
|
|
+
|
|
|
+**故事012.004(订单统计与数据统计API)已完成的变更**:
|
|
|
+- 订单统计API(打卡数据统计、视频统计)已实现[来源:docs/stories/012.004.story.md]
|
|
|
+- 企业维度订单查询和视频查询功能已实现[来源:docs/stories/012.004.story.md]
|
|
|
+
|
|
|
+**故事011.004(订单管理功能实现)的依赖**:
|
|
|
+- 企业专用订单API客户端需要在UI包内创建[来源:docs/stories/011.004.story.md#API规范]
|
|
|
+- 前端需要正确的路由类型定义进行类型安全检查[来源:docs/stories/011.004.story.md#技术集成]
|
|
|
+
|
|
|
+### 当前问题分析
|
|
|
+**路由混合问题**(基于代码审查发现):
|
|
|
+- **文件位置**:`allin-packages/order-module/src/routes/order-custom.routes.ts`
|
|
|
+- **问题描述**:当前`orderRoutes`实例混合了12个通用CRUD路由(使用`authMiddleware`)和6个企业专用路由(使用`enterpriseAuthMiddleware`)
|
|
|
+- **风险**:前端UI包使用`orderRoutes`类型创建企业专用客户端时,会包含通用CRUD路由,存在权限泄露风险
|
|
|
+- **正确模式参考**:`packages/core-module/auth-module/src/routes/index.ts`已正确分离`authRoutes`和`enterpriseAuthRoutes`
|
|
|
+
|
|
|
+**现有路由统计**:
|
|
|
+- **通用CRUD路由**(12个):使用`authMiddleware`
|
|
|
+ - `GET /` - 订单列表查询
|
|
|
+ - `GET /{id}` - 订单详情查询
|
|
|
+ - `POST /` - 订单创建
|
|
|
+ - `PUT /{id}` - 订单更新
|
|
|
+ - `DELETE /{id}` - 订单删除
|
|
|
+ - `POST /activate/{orderId}` - 激活订单
|
|
|
+ - `POST /close/{orderId}` - 关闭订单
|
|
|
+ - `POST /{orderId}/persons/batch` - 批量添加人员
|
|
|
+ - `POST /assets/create` - 创建订单人员资产
|
|
|
+ - `GET /assets/query` - 查询订单人员资产
|
|
|
+ - `DELETE /assets/delete/{id}` - 删除订单人员资产
|
|
|
+ - `PUT /persons/work-status` - 更新订单人员工作状态
|
|
|
+- **企业专用路由**(6个):使用`enterpriseAuthMiddleware`
|
|
|
+ - `GET /checkin-statistics` - 打卡数据统计
|
|
|
+ - `GET /video-statistics` - 视频分类统计
|
|
|
+ - `GET /company-orders` - 企业维度订单查询
|
|
|
+ - `GET /company-videos` - 企业维度视频查询
|
|
|
+ - `POST /batch-download` - 批量下载视频
|
|
|
+ - `PUT /videos/{id}/status` - 更新视频审核状态
|
|
|
+
|
|
|
+### 数据模型
|
|
|
+基于现有实体定义和架构文档:
|
|
|
+
|
|
|
+**订单实体**(`allin-packages/order-module/src/entities/employment-order.entity.ts`):
|
|
|
+- 表名:`employment_order`(@Entity('employment_order'))
|
|
|
+- 主键:`id`(映射到`order_id`列)
|
|
|
+- 字段:`orderName`、`orderStatus`、`companyId`、`jobId`、`expectedPersonCount`、`actualPersonCount`、`startDate`、`expectedEndDate`等[来源:docs/stories/012.005.story.md#数据模型]
|
|
|
+- 关联:`companyId`关联`EmployerCompany`,`jobId`关联`Job`
|
|
|
+
|
|
|
+**订单人员实体**(`allin-packages/order-module/src/entities/order-person.entity.ts`):
|
|
|
+- 表名:`order_person`(@Entity('order_person'))
|
|
|
+- 主键:`id`(映射到`op_id`列)
|
|
|
+- 字段:`orderId`、`personId`、`joinDate`、`salaryDetail`、`workStatus`等[来源:docs/stories/012.013.story.md#数据模型]
|
|
|
+- 关联:`personId`关联`DisabledPerson`,`orderId`关联`EmploymentOrder`
|
|
|
+
|
|
|
+**订单人员资产实体**(`allin-packages/order-module/src/entities/order-person-asset.entity.ts`):
|
|
|
+- 表名:`order_person_asset`(@Entity('order_person_asset'))
|
|
|
+- 主键:`id`(映射到`opa_id`列)
|
|
|
+- 字段:`orderPersonId`、`assetType`、`fileId`、`status`等[来源:docs/stories/012.005.story.md#数据模型]
|
|
|
+- 关联:`orderPersonId`关联`OrderPerson`,`fileId`关联`File`
|
|
|
+
|
|
|
+### API规范
|
|
|
+**API路径约定**(来自史诗012):
|
|
|
+- 所有用人方小程序的API路径统一使用 `api/v1/yongren` 前缀[来源:docs/prd/epic-012-api-supplement-for-employer-mini-program.md#API路径约定]
|
|
|
+- 通用订单API路径:`/api/v1/order`(管理后台使用)
|
|
|
+- 企业专用订单API路径:`/api/v1/yongren/order`(用人方小程序使用)
|
|
|
+
|
|
|
+**路由设计规范**(来自架构文档和auth-module参考):
|
|
|
+- 模块包内应提供清晰的路由分离[来源:packages/core-module/auth-module/src/routes/index.ts]
|
|
|
+- 通用路由使用`authMiddleware`进行基础认证[来源:docs/architecture/backend-module-package-standards.md#中间件模式]
|
|
|
+- 企业专用路由使用`enterpriseAuthMiddleware`进行企业用户认证[来源:docs/stories/012.002.story.md#开发笔记]
|
|
|
+- 路由实例分离确保类型安全和权限控制[来源:最佳实践分析]
|
|
|
+
|
|
|
+**验证系统规范**(来自架构文档):
|
|
|
+- 使用Zod Schema进行请求验证和响应类型定义[来源:docs/architecture/backend-module-package-standards.md#验证系统规范]
|
|
|
+- 企业专用API的查询参数应包含`companyId`或从认证用户自动获取[来源:docs/stories/012.005.story.md#API规范]
|
|
|
+
|
|
|
+### 文件位置
|
|
|
+基于项目结构指南:
|
|
|
+- 路由文件:`allin-packages/order-module/src/routes/order-custom.routes.ts`[来源:代码审查发现]
|
|
|
+- 路由索引文件:`allin-packages/order-module/src/routes/index.ts`[来源:项目结构验证]
|
|
|
+- Server包路由注册:`packages/server/src/routes/enterprise.ts`(企业专用)、`packages/server/src/routes/order.ts`(通用)[来源:项目结构验证]
|
|
|
+- 集成测试文件:`allin-packages/order-module/tests/integration/order-custom.integration.test.ts`[来源:项目结构验证]
|
|
|
+
|
|
|
+### 技术栈约束
|
|
|
+- 运行时:Node.js 20.18.3[来源:docs/architecture/tech-stack.md]
|
|
|
+- 框架:Hono 4.8.5(Web框架和API路由)[来源:docs/architecture/tech-stack.md]
|
|
|
+- ORM:TypeORM 0.3.25(数据库操作抽象)[来源:docs/architecture/tech-stack.md]
|
|
|
+- 数据库:PostgreSQL 17[来源:docs/architecture/tech-stack.md]
|
|
|
+- 测试框架:Vitest[来源:docs/architecture/tech-stack.md]
|
|
|
+
|
|
|
+### 测试要求
|
|
|
+**测试策略**(来自架构文档):
|
|
|
+- 单元测试覆盖率目标:≥ 80%[来源:docs/architecture/testing-strategy.md#单元测试]
|
|
|
+- 集成测试覆盖率目标:≥ 60%[来源:docs/architecture/testing-strategy.md#集成测试]
|
|
|
+- 测试文件位置:`tests/integration/`文件夹与源码并列[来源:docs/architecture/testing-strategy.md#集成测试]
|
|
|
+- 测试框架:Vitest + hono/testing[来源:docs/architecture/testing-strategy.md#集成测试]
|
|
|
+- 集成测试应验证完整的用户流程,而不仅仅是单个操作[来源:docs/architecture/testing-strategy.md#验证完整的用户流程]
|
|
|
+
|
|
|
+**路由测试重点**:
|
|
|
+- 验证路由分离:通用路由不应包含企业专用功能
|
|
|
+- 验证权限控制:企业用户不应访问通用CRUD路由
|
|
|
+- 验证路径前缀:企业专用API使用`/api/v1/yongren/order`前缀
|
|
|
+- 验证类型导出:前端可正确导入`enterpriseOrderRoutes`类型
|
|
|
+
|
|
|
+### 编码标准
|
|
|
+- 代码风格:TypeScript严格模式,一致的缩进和命名[来源:docs/architecture/coding-standards.md#现有标准合规性]
|
|
|
+- linting规则:已配置ESLint,支持TypeScript和React[来源:docs/architecture/coding-standards.md#现有标准合规性]
|
|
|
+- 路由设计规范:遵循auth-module的分离模式[来源:最佳实践分析]
|
|
|
+- 类型安全:确保路由类型定义正确导出,供前端使用[来源:架构要求]
|
|
|
+
|
|
|
+### 项目结构注意事项
|
|
|
+- 模块包结构遵循`allin-packages/{module-name}-module/`模式[来源:docs/architecture/backend-module-package-standards.md#包结构规范]
|
|
|
+- 路由聚合模式:主路由文件聚合自定义路由和CRUD路由[来源:docs/architecture/backend-module-package-standards.md#路由聚合模式]
|
|
|
+- 企业专用路由应在模块内明确分离,提供独立的实例[来源:auth-module参考实现]
|
|
|
+
|
|
|
+## 变更日志
|
|
|
+| 日期 | 版本 | 描述 | 作者 |
|
|
|
+|------|------|------|------|
|
|
|
+| 2025-12-21 | 1.0 | 初始故事创建,解决订单模块路由混合问题 | Claude Code |
|
|
|
+| 2025-12-21 | 1.1 | 实施路由分离:重构order-custom.routes.ts,分离orderRoutes和enterpriseOrderRoutes,更新server包路由注册,修复集成测试 | Claude Code |
|
|
|
+
|
|
|
+## Dev Agent Record
|
|
|
+*此部分由开发代理在实施期间填写*
|
|
|
+
|
|
|
+### 进展更新
|
|
|
+- 2025-12-21: 创建故事012.014,解决订单模块路由分离问题
|
|
|
+
|
|
|
+### 调试日志
|
|
|
+*实施期间填写*
|
|
|
+
|
|
|
+### 文件列表
|
|
|
+*实施期间填写*
|
|
|
+
|
|
|
+### 待解决问题
|
|
|
+*实施期间填写*
|
|
|
+
|
|
|
+### 使用的代理模型
|
|
|
+*实施期间填写*
|