# 故事 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，解决订单模块路由分离问题

### 调试日志
*实施期间填写*

### 文件列表
*实施期间填写*

### 待解决问题
*实施期间填写*

### 使用的代理模型
*实施期间填写*