Bladeren bron

docs(standards): 添加自定义路由响应parseWithAwait规范

- 新增4.3节:自定义路由响应规范
- 强调必须使用parseWithAwait验证响应数据
- 说明createZodErrorResponse的错误处理模式
- 提供数组响应的Promise.all批量验证示例
- 更新检查清单,添加parseWithAwait和createZodErrorResponse检查项

🤖 Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 3 weken geleden
bovenliggende
commit
aad5da97eb
1 gewijzigde bestanden met toevoegingen van 50 en 1 verwijderingen
  1. 50 1
      docs/architecture/backend-module-package-standards.md

+ 50 - 1
docs/architecture/backend-module-package-standards.md

@@ -305,12 +305,58 @@ export * from './channel-custom.routes';
 export * from './channel-crud.routes';
 ```
 
-### 4.3 关键要点
+### 4.3 自定义路由响应规范
+
+**重要**: 自定义路由(非CRUD路由)在返回响应前**必须使用 `parseWithAwait`** 验证和转换数据。
+
+**实际实现**:
+```typescript
+import { parseWithAwait, createZodErrorResponse } from '@d8d/shared-utils';
+import { z } from '@hono/zod-openapi';
+import { ChannelSchema } from '../schemas/channel.schema';
+
+// 自定义路由
+channelCustomRoutes.get('/statistics/:id', async (c) => {
+  try {
+    const id = c.req.param('id');
+    const channelService = new ChannelService(AppDataSource);
+    const result = await channelService.getStatistics(Number(id));
+
+    // ✅ 必须:使用 parseWithAwait 验证和转换响应数据
+    const validatedResult = await parseWithAwait(ChannelSchema, result);
+    return c.json(validatedResult, 200);
+  } catch (error) {
+    if (error instanceof z.ZodError) {
+      // ✅ 推荐:使用 createZodErrorResponse 处理Zod验证错误
+      return c.json(createZodErrorResponse(error), 400);
+    }
+    return c.json({ code: 500, message: error.message }, 500);
+  }
+});
+```
+
+**数组响应处理**:
+```typescript
+// 处理数组数据
+const validatedData = await Promise.all(
+  result.data.map(item => parseWithAwait(ChannelSchema, item))
+);
+return c.json({ data: validatedData, total: result.total }, 200);
+```
+
+**关键要点**:
+- **必须使用 `parseWithAwait`**: 所有自定义路由返回前必须使用 `parseWithAwait` 验证数据
+- **捕获 ZodError**: 在catch块中处理 `z.ZodError` 异常
+- **使用 `createZodErrorResponse`**: 提供统一的错误响应格式
+- **数组使用 `Promise.all`**: 批量验证数组数据
+
+### 4.4 关键要点
 
 - **使用 `OpenAPIHono`**: 而非普通的 `Hono`
 - **使用 `AuthContext` 泛型**: 提供类型安全的认证上下文
 - **路由聚合**: 分别定义自定义路由和CRUD路由,然后聚合
 - **不设置 `basePath`**: 在聚合路由时处理路径
+- **自定义路由必须使用 `parseWithAwait`**: 验证响应数据符合Schema定义
 
 ## 5. Schema规范
 
@@ -691,7 +737,10 @@ override async create(data: Partial<Channel>, userId?: string | number): Promise
 - [ ] 软删除实现:使用 `status` 字段
 - [ ] Schema使用 `.openapi()` 装饰器
 - [ ] Schema不导出推断类型(类型由RPC自动推断)
+- [ ] Schema使用 `z.coerce.date<Date>()` 和 `z.coerce.number<number>()` 泛型语法
 - [ ] 路由使用 `OpenAPIHono` 和 `AuthContext`
+- [ ] 自定义路由使用 `parseWithAwait` 验证响应数据
+- [ ] 自定义路由使用 `createZodErrorResponse` 处理Zod错误
 - [ ] 测试数据工厂使用时间戳保证唯一性
 - [ ] vitest.config.ts 设置 `fileParallelism: false`
 - [ ] 类型检查通过