规约范例:需求规约
公开教程 · 无需登录

规约范例:需求规约

四份文件里只有这一份能被逐条判定通过与不通过,其余三份都服务于它。

1第三份:specs/course-material-search/spec.md

每条能力一组场景,三段式:前置条件 / 操作 / 可观测结果。

# 需求规约:course-material-search
## 需求 1:混合检索返回带出处的命中
场景:学生按关键字检索本班已入库资料
  前置条件:学生属于班级 C;C 下已有 3 份解析完成的资料
  操作:    GET /api/search?q=事务隔离级别&mode=hybrid
  可观测结果:200;命中按 RRF 分值降序;每条含资料名、段落号、原文片段
## 需求 2:只检索本班资料
场景:携带他班资料标识直接请求
  前置条件:学生属于班级 C;资料 M 属于班级 D
  操作:    GET /api/search?q=事务&material_id=M
  可观测结果:404;错误码 1204;审计日志记录一次越权拒绝
## 需求 3:低于阈值的命中不进入结果
场景:查询与库内资料都不相关
  前置条件:已入库资料 3 份;SEARCH_VECTOR_MIN=0.35
  操作:    GET /api/search?q=食堂几点关门
  可观测结果:200;items 为空;响应含 empty_reason=below_threshold
## 需求 4:失败路径
场景:向量库不可用 → 200,降级为关键字结果,响应含 degraded=true
场景:未登录 → 401,错误码 1001,不返回任何命中
场景:q 为空或超过 200 字符 → 400,错误码 1101
场景:分页超出范围 → 200,items 为空,不报错
四类失败路径是这份文件的骨架:外部依赖故障、授权失败、输入非法、边界值。少任何一类,测试就只能覆盖「一切正常」这一种情形。需求 2 写的是 404 而不是 403——跨班资料按不存在处理,避免他人通过状态码差异推断出资源是否存在。

2三段式为什么这样写

三段各有硬性要求,缺一段场景就无法转成用例。

  1. 前置条件写清角色、数据归属与已有数据。缺了角色无从判定授权,缺了数据归属无从判定越权;本例的「班级 C」「资料 M 属于班级 D」就是为了这一条。
  2. 操作写清谁对哪个接口或页面做了什么。操作不可复述,场景就无法转成用例,也就进不了回归测试。
  3. 可观测结果写清返回值、数据变化与日志里各看到什么。只有这一段能被机器判定,形容词在这里一律无效。
对应的课程知识点:可验证需求(verifiable requirement)、等价类划分与边界值分析、需求—用例可追溯矩阵。四条需求各有一组场景,不存在没有场景的需求,也不存在找不到归属的场景——这是可追溯矩阵的最小形态。