Skip to content

test(contracts): establish API response inventory and HTTP boundary fixtures - #74

Open
stanGSA wants to merge 3 commits into
AnnaSuSu:mainfrom
stanGSA:test/contracts-response-inventory
Open

stanGSA wants to merge 3 commits into
AnnaSuSu:mainfrom
stanGSA:test/contracts-response-inventory

Conversation

@stanGSA

@stanGSA stanGSA commented Sep 22, 2026

Copy link
Copy Markdown

Summary

建立 API 契约第一阶段基础设施,盘点当前 HTTP 响应面,并为后续响应 schema 收紧提供稳定测试基线。

Changes

  • 新增 API response inventory,覆盖当前 OpenAPI 中的 HTTP operations
  • 新增脱敏 JSON、SSE 和 Copilot 事件 fixture
  • 新增基于 app.request() 的 HTTP 边界测试
  • 增加 OpenAPI operation 与 response inventory 的一致性检查
  • 标记当前动态响应面,供后续阶段收紧
  • 补充 fixture 维护文档
  • 保持业务逻辑和正式 API schema 不变

Validation

  • bun install --frozen-lockfile
  • bun test tests-ts/contracts
  • bun test tests-ts/http-nullable-contracts.test.ts
  • bun run test:contracts
  • bun run typecheck
  • bun run typecheck:node
  • bun run check:boundaries
  • bun test apps packages tests-ts
  • bun test frontend/src/lib/*.test.js
  • bun run build:api
  • bun run --cwd frontend typecheck
  • bun run --cwd frontend build
  • bun run gen:api
  • git diff --check

Compatibility

  • 不改变现有 API 路由和业务逻辑
  • 不修改正式 OpenAPI schema
  • 不修改前端生成 API 类型
  • 不调用真实 LLM、Embedding、ASR 或外部服务
  • 不需要部署模型

@AnnaSuSu AnnaSuSu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个 PR 作为 API 响应契约的第一阶段基础设施,方向合理,且没有修改业务逻辑。合并前请修正下面两处与真实响应不一致的 fixture,并增加对应的 HTTP 边界断言,避免后续收紧 schema 时以错误样例为基线。

已在提交 438621a 上完成本地验证:后端测试 144/144 通过,typecheck、typecheck:node 和 check:boundaries 通过。两处差异均已通过真实 service 配合内存依赖的 app.request() 请求复现,不涉及真实外部模型调用。当前 GitHub CI 为 action_required,尚无通过结果。

{ operation: 'GET /api/interview/topics', routeFile: 'apps/api/src/routes/interview.ts', status: 200, contentType: 'application/json', transport: 'json', fixture: 'interview-topics.json', dynamic: false },
{ operation: 'GET /api/profile', routeFile: 'apps/api/src/routes/profile.ts', status: 200, contentType: 'application/json', transport: 'json', fixture: 'profile.json', dynamic: true },
{ operation: 'POST /api/profile/infer-target-role', routeFile: 'apps/api/src/routes/profile.ts', status: 200, contentType: 'application/json', transport: 'json', fixture: 'target-role.json', dynamic: false },
{ operation: 'POST /api/profile/viewed', routeFile: 'apps/api/src/routes/profile.ts', status: 200, contentType: 'application/json', transport: 'json', fixture: 'profile.json', dynamic: true },

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 为 profile/viewed 登记独立的浏览标记响应

这里复用了完整画像 profile.json,但 ProfileService.viewed() 返回的是浏览标记 { at, total_sessions, topic_scores },路由直接将其序列化为 JSON。我通过真实 ProfileService 的 app.request('/api/profile/viewed') 已确认这一差异。该 inventory 将作为后续收紧响应 schema 的依据,当前映射会把此接口定义成错误的完整画像结构。请新增独立 fixture,并通过真实 service 配合内存 repository 的 HTTP 边界测试验证返回结构。

@@ -0,0 +1,3 @@
data: {"progress":0.5,"message":"正在索引"}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 使用重建索引实际输出的 SSE 事件结构

这个样例使用 { progress, message },但 SettingsOperationsService.rebuildIndex() 实际输出 { completed, total, label, status };完成事件还带有 rebuilt 和 last_rebuild_at。经真实 service 的 HTTP SSE 请求确认,当前样例并不代表该接口的返回结构。现有 inventory 测试只检查这个文件存在,因此无法捕获这类偏差。请更新样例,并新增 /api/settings/rebuild-index 的 HTTP 边界测试,将解析后的真实事件与 fixture 对照(时间字段可规范化)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants