|
|
@@ -0,0 +1,226 @@
|
|
|
+# Story 010.012: 统一广告模块响应格式规范化
|
|
|
+
|
|
|
+## Status
|
|
|
+Approved
|
|
|
+
|
|
|
+## Story
|
|
|
+
|
|
|
+**As a** 开发者,
|
|
|
+**I want** 统一广告模块的API响应格式与项目规范(`shared-crud`)保持一致,
|
|
|
+**so that** 前端UI可以使用统一的数据处理模式,确保系统架构的一致性和可维护性。
|
|
|
+
|
|
|
+## Acceptance Criteria
|
|
|
+
|
|
|
+1. 列表查询响应格式修改为标准格式:`{ data: [...], pagination: { total, current, pageSize } }`
|
|
|
+2. 单项查询(get/create/update)响应格式修改为直接返回资源对象:`{ id, ... }`
|
|
|
+3. 删除操作响应修改为 `204 No Content`(空响应)
|
|
|
+4. 统一广告管理UI适配新的响应格式
|
|
|
+5. 所有相关测试通过(模块测试、UI测试、集成测试)
|
|
|
+6. API文档/Schema定义更新为新的响应格式
|
|
|
+
|
|
|
+## Tasks / Subtasks
|
|
|
+
|
|
|
+- [ ] **任务1: 修改管理员广告路由响应格式** (AC: 1, 2, 3)
|
|
|
+ - [ ] 修改 `packages/unified-advertisements-module/src/routes/admin/unified-advertisements.admin.routes.ts`
|
|
|
+ - [ ] 列表响应:移除 `code`, `message`,将 `data.list` 改为 `data`(数组),将分页信息移到 `pagination` 对象,`page` 改为 `current`
|
|
|
+ - [ ] GET单项响应:移除 `code`, `message`,直接返回验证后的资源对象
|
|
|
+ - [ ] CREATE响应:返回201状态码,直接返回资源对象
|
|
|
+ - [ ] UPDATE响应:返回200状态码,直接返回资源对象
|
|
|
+ - [ ] DELETE响应:返回204状态码,空响应(`c.body(null, 204)`)
|
|
|
+
|
|
|
+- [ ] **任务2: 修改管理员广告类型路由响应格式** (AC: 1, 2, 3)
|
|
|
+ - [ ] 修改 `packages/unified-advertisements-module/src/routes/admin/unified-advertisement-types.admin.routes.ts`
|
|
|
+ - [ ] 应用与任务1相同的响应格式修改
|
|
|
+
|
|
|
+- [ ] **任务3: 修改用户端广告路由响应格式** (AC: 1, 2, 3)
|
|
|
+ - [ ] 修改 `packages/unified-advertisements-module/src/routes/unified-advertisements.crud.routes.ts`
|
|
|
+ - [ ] 列表响应:应用标准格式(注意:这是只读路由,只有GET操作)
|
|
|
+ - [ ] GET单项响应:直接返回资源对象
|
|
|
+
|
|
|
+- [ ] **任务4: 修改用户端广告类型路由响应格式** (AC: 1, 2, 3)
|
|
|
+ - [ ] 修改 `packages/unified-advertisements-module/src/routes/unified-advertisement-types.crud.routes.ts`
|
|
|
+ - [ ] 列表响应:应用标准格式
|
|
|
+
|
|
|
+- [ ] **任务5: 更新路由Schema定义** (AC: 6)
|
|
|
+ - [ ] 修改所有路由的 `responses.openapi` schema定义以匹配新格式
|
|
|
+ - [ ] 列表响应schema:`{ data: z.array(schema), pagination: { total, current, pageSize } }`
|
|
|
+ - [ ] 单项响应schema:直接使用资源schema(不包装)
|
|
|
+ - [ ] 删除响应schema:`204 No Content`
|
|
|
+
|
|
|
+- [ ] **任务6: 适配统一广告管理UI** (AC: 4)
|
|
|
+ - [ ] 修改 `packages/unified-advertisement-management-ui/src/hooks/useAdvertisementManagement.ts`
|
|
|
+ - [ ] 更新数据处理逻辑:适配新的响应格式(`response.data` 直接是数组,`response.pagination` 包含分页信息)
|
|
|
+ - [ ] 更新单项数据处理:适配直接返回资源对象的格式
|
|
|
+ - [ ] 修改 `packages/unified-advertisement-management-ui/src/hooks/useAdTypeManagement.ts` 应用相同修改
|
|
|
+
|
|
|
+- [ ] **任务7: 更新UI测试Mock数据** (AC: 5)
|
|
|
+ - [ ] 修改 `packages/unified-advertisement-management-ui/tests/` 中的所有mock响应
|
|
|
+ - [ ] 确保mock数据符合新的响应格式
|
|
|
+ - [ ] 验证所有UI测试通过
|
|
|
+
|
|
|
+- [ ] **任务8: 更新后端集成测试** (AC: 5)
|
|
|
+ - [ ] 修改 `packages/unified-advertisements-module/tests/integration/` 中的测试断言
|
|
|
+ - [ ] 验证列表响应包含 `data` 数组和 `pagination` 对象
|
|
|
+ - [ ] 验证单项响应直接返回资源对象
|
|
|
+ - [ ] 验证删除返回204状态码
|
|
|
+
|
|
|
+- [ ] **任务9: 更新Server包集成测试** (AC: 5)
|
|
|
+ - [ ] 检查 `packages/server/tests/integration/` 中涉及统一广告的测试
|
|
|
+ - [ ] 更新测试断言以匹配新的响应格式
|
|
|
+ - [ ] 验证测试通过
|
|
|
+
|
|
|
+- [ ] **任务10: 类型检查和代码质量** (AC: 5)
|
|
|
+ - [ ] 运行 `pnpm typecheck` 确保无TypeScript类型错误
|
|
|
+ - [ ] 运行 `pnpm lint` 确保代码规范检查通过
|
|
|
+ - [ ] 运行所有相关测试并确保通过
|
|
|
+
|
|
|
+## Dev Notes
|
|
|
+
|
|
|
+### 问题说明
|
|
|
+
|
|
|
+**当前响应格式(不符合规范)** [Source: packages/unified-advertisements-module/src/routes/admin/unified-advertisements.admin.routes.ts]:
|
|
|
+```typescript
|
|
|
+// 列表响应 - 当前格式
|
|
|
+{
|
|
|
+ code: 200,
|
|
|
+ message: 'success',
|
|
|
+ data: {
|
|
|
+ list: [...], // ← 嵌套在 list 中
|
|
|
+ total: 100,
|
|
|
+ page: 1, // ← 使用 page 而非 current
|
|
|
+ pageSize: 10
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 单项响应 - 当前格式
|
|
|
+{
|
|
|
+ code: 200,
|
|
|
+ message: 'success',
|
|
|
+ data: { id: 1, ... } // ← 嵌套在 data 中
|
|
|
+}
|
|
|
+
|
|
|
+// 删除响应 - 当前格式
|
|
|
+{
|
|
|
+ code: 200,
|
|
|
+ message: 'Advertisement deleted successfully' // ← 有内容
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**标准响应格式(generic-crud.routes.ts)** [Source: packages/shared-crud/src/routes/generic-crud.routes.ts]:
|
|
|
+```typescript
|
|
|
+// 列表响应 - 标准格式
|
|
|
+{
|
|
|
+ data: [...], // ← 数组直接在根级别
|
|
|
+ pagination: {
|
|
|
+ total: 100,
|
|
|
+ current: 1, // ← 使用 current
|
|
|
+ pageSize: 10
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 单项响应 - 标准格式
|
|
|
+{ id: 1, name: "..." } // ← 直接返回资源对象
|
|
|
+
|
|
|
+// 删除响应 - 标准格式
|
|
|
+204 No Content // ← 空响应
|
|
|
+```
|
|
|
+
|
|
|
+### 需要修改的文件清单
|
|
|
+
|
|
|
+**后端路由文件**:
|
|
|
+1. `packages/unified-advertisements-module/src/routes/admin/unified-advertisements.admin.routes.ts`
|
|
|
+2. `packages/unified-advertisements-module/src/routes/admin/unified-advertisement-types.admin.routes.ts`
|
|
|
+3. `packages/unified-advertisements-module/src/routes/unified-advertisements.crud.routes.ts`
|
|
|
+4. `packages/unified-advertisements-module/src/routes/unified-advertisement-types.crud.routes.ts`
|
|
|
+
|
|
|
+**前端UI文件**:
|
|
|
+1. `packages/unified-advertisement-management-ui/src/hooks/useAdvertisementManagement.ts`
|
|
|
+2. `packages/unified-advertisement-management-ui/src/hooks/useAdTypeManagement.ts`
|
|
|
+3. `packages/unified-advertisement-management-ui/tests/` 中的所有测试文件
|
|
|
+
|
|
|
+**测试文件**:
|
|
|
+1. `packages/unified-advertisements-module/tests/integration/` 中的所有集成测试
|
|
|
+2. `packages/server/tests/integration/` 中涉及统一广告的测试(如有)
|
|
|
+
|
|
|
+### 相关标准规范
|
|
|
+
|
|
|
+**后端模块开发规范** [Source: docs/architecture/backend-module-package-standards.md]:
|
|
|
+- 使用 `OpenAPIHono` 定义路由
|
|
|
+- 使用 `createRoute` 定义路由schema
|
|
|
+- 响应格式应与 `shared-crud` 保持一致
|
|
|
+
|
|
|
+**编码标准** [Source: docs/architecture/coding-standards.md]:
|
|
|
+- 自定义路由必须使用 `parseWithAwait` 验证响应数据
|
|
|
+- 使用 `z.coerce.date<Date>()` 和 `z.coerce.number<number>()`(Zod 4.0需要泛型参数)
|
|
|
+
|
|
|
+### 前一故事关键要点
|
|
|
+
|
|
|
+**来自故事 010.011(集成统一文件模块)**:
|
|
|
+- 统一广告模块已完成迁移到 `UnifiedFile` 实体
|
|
|
+- 统一广告管理UI已集成统一文件选择器
|
|
|
+- 测试覆盖:57/57 模块测试通过,51/51 UI测试通过
|
|
|
+- 关联查询:`relations: ['imageFile', 'advertisementType']`
|
|
|
+
|
|
|
+**来自故事 010.003(路由路径规范问题)**:
|
|
|
+- 模块内路由使用相对路径(如 `/` 和 `/:id`)
|
|
|
+- Server包注册时添加完整前缀(如 `/api/v1/admin/unified-advertisements`)
|
|
|
+
|
|
|
+### API端点参考
|
|
|
+
|
|
|
+**管理员广告API**:
|
|
|
+- `GET /api/v1/admin/unified-advertisements` - 列表(需修改响应格式)
|
|
|
+- `GET /api/v1/admin/unified-advertisements/:id` - 单项(需修改响应格式)
|
|
|
+- `POST /api/v1/admin/unified-advertisements` - 创建(需修改响应格式)
|
|
|
+- `PUT /api/v1/admin/unified-advertisements/:id` - 更新(需修改响应格式)
|
|
|
+- `DELETE /api/v1/admin/unified-advertisements/:id` - 删除(需修改响应格式)
|
|
|
+
|
|
|
+**管理员广告类型API**:
|
|
|
+- `GET /api/v1/admin/unified-advertisement-types` - 列表(需修改响应格式)
|
|
|
+- `GET /api/v1/admin/unified-advertisement-types/:id` - 单项(需修改响应格式)
|
|
|
+- `POST /api/v1/admin/unified-advertisement-types` - 创建(需修改响应格式)
|
|
|
+- `PUT /api/v1/admin/unified-advertisement-types/:id` - 更新(需修改响应格式)
|
|
|
+- `DELETE /api/v1/admin/unified-advertisement-types/:id` - 删除(需修改响应格式)
|
|
|
+
|
|
|
+**用户展示API**(只读):
|
|
|
+- `GET /api/v1/advertisements` - 列表(需修改响应格式)
|
|
|
+- `GET /api/v1/advertisements/:id` - 单项(需修改响应格式)
|
|
|
+- `GET /api/v1/advertisement-types` - 列表(需修改响应格式)
|
|
|
+
|
|
|
+### Testing
|
|
|
+
|
|
|
+**测试文件位置** [Source: docs/architecture/testing-strategy.md]:
|
|
|
+- 后端模块测试:`packages/{module-name}/tests/`
|
|
|
+- UI包测试:`packages/{ui-name}/tests/`
|
|
|
+- Server集成测试:`packages/server/tests/integration/`
|
|
|
+
|
|
|
+**测试框架**:
|
|
|
+- 后端:Vitest + hono/testing
|
|
|
+- UI:Vitest + Testing Library
|
|
|
+
|
|
|
+**测试要求**:
|
|
|
+- 更新所有涉及响应格式的测试断言
|
|
|
+- 验证新响应格式的正确性
|
|
|
+- 确保测试覆盖率不低于修改前水平
|
|
|
+
|
|
|
+## Change Log
|
|
|
+
|
|
|
+| Date | Version | Description | Author |
|
|
|
+|------|---------|-------------|--------|
|
|
|
+| 2026-01-04 | 1.0 | 初始创建故事 | James (Dev Agent) |
|
|
|
+
|
|
|
+## Dev Agent Record
|
|
|
+
|
|
|
+### Agent Model Used
|
|
|
+_待开发时填写_
|
|
|
+
|
|
|
+### Debug Log References
|
|
|
+_待开发时填写_
|
|
|
+
|
|
|
+### Completion Notes List
|
|
|
+_待开发时填写_
|
|
|
+
|
|
|
+### File List
|
|
|
+_待开发时填写_
|
|
|
+
|
|
|
+## QA Results
|
|
|
+_待QA评审时填写_
|