gwy-exam/docs/checks/task-03.md
2026-08-31 16:48:49 +08:00

4.3 KiB
Raw Permalink Blame History

任务 03 检查记录接口层路由、校验、错误处理、OpenAPI

日期2026-08-31

交付内容

  • server/src/schemas/entities.ts:全部领域实体的 Zod Schema题目、要闻、计划、模考、会话、错题等
  • server/src/schemas/api.ts34 个接口的请求/响应 Zod Schema路由共 31 个路径34 个操作)。
  • server/src/errors.tsApiError 业务异常 + 统一错误响应格式 { error: { code, message, details } }AJV 校验信息聚合翻译为中文(如"缺少必填字段 module"、"取值不符合预设选项")。
  • server/src/handlers/dashboard、practice、review、plans、mock、news、questions、ai、profile 九个域的处理器。
  • server/src/routes.ts路由集中注册Zod → JSON Schemaz.toJSONSchemadraft-7转换含 tags/summary/response。
  • server/src/server.tsbuildServer 拆分(可测试/可导出),注册 @fastify/swagger + @fastify/swagger-ui,并挂载运行时端点 GET /api/openapi.json(返回 app.swagger())。

命令检查

  • pnpm --filter @gwy/server typecheck:通过。
  • GET /api/openapi.json200OpenAPI 3.0.3,登记接口 31 个、文档路径 31 个,全部路由含请求/响应 Schema。
  • 服务启动:无 FSTWRN001 等 Schema 警告grep 计数为 0

接口实测curl

接口 结果
GET /health 200{status:"ok",routes:31}
GET /api/openapi.json 200约 81 KB
GET /api/docsSwagger UI 200
GET /api/dashboard/overview 200学习天数/正确率/待复习等字段齐全
GET /api/dashboard/trends?days=7 200返回 7 天趋势数组
GET /api/practice/modules 200五大模块题量
POST /api/practice/start(正确参数) 200返回 sessionId 并持久化到 data/practice-sessions.json
GET /api/practice/{sessionId}/question 200不含答案与解析
POST /api/practice/{sessionId}/answer 200{accepted:true,answeredCount:0}记录落库留给任务08
POST /api/practice/{sessionId}/finish(无请求体) 200返回结果骨架真实计算留给任务08
GET /api/questions/list?module=言语理解 200分页结构正确
GET /api/questions/export 200导出 JSON
GET /api/news/listGET /api/news/{id} 200
GET /api/review/listGET /api/plans/todayGET /api/plans/week 200
GET /api/mock-exams/analysis 200模块均分数组齐全
GET /api/profileGET /api/settings 200
POST /api/practice/start 缺字段 400 VALIDATION_ERRORdetails 中文提示"缺少必填字段 module"
POST /api/practice/start duration=7 400聚合为一条"取值不符合预设选项"
GET /api/questions/list?module=xingce 400"取值必须是允许的枚举值之一"
未注册路径 404 NOT_FOUND接口不存在GET ...

过程中发现并修复的问题

  1. response 对象中存在 400: undefined 键导致 Fastify 遍历报错 → 改为过滤后仅保留已定义状态码。
  2. 无 body 的 POST 路由(如 finish曾被占位空对象 Schema 误拒空请求体 → 无 body Schema 时直接省略 body 键。
  3. Zod union 字面量duration 5|10|15在 AJV anyOf 校验下报 4 条冗余英文错误 → 错误处理器按路径聚合并翻译为单条中文提示。
  4. practice/start 未持久化会话导致后续接口 404 → 补充 updateData 写入会话组卷题量、作答记录、结果计算仍为任务08 范围)。

浏览器检查

任务 03 仅涉及后端接口层未新增前端页面。Swagger UIhttp://127.0.0.1:3000/api/docsHTTP 200 可访问未做前端回归前端对接在任务04+)。

当前结论

接口层完成31 个路径全部注册并带完整 Schema统一错误格式400/404/500 均验证OpenAPI 文档由运行时端点 GET /api/openapi.json 提供不再导出静态文件核心业务链路start → question → answer → finish跑通且会话已持久化。剩余 TODO 已标注在 handlers 内归属任务08刷题业务规则

微调2026-08-31改为「不落盘、运行时提供」——删除 server/scripts/export-openapi.tsserver/openapi.jsonopenapi:export 脚本,前端直接消费 http://localhost:3000/api/openapi.json