Files
junhong_cmp_fiber/openspec/changes/fix-employee-collection-route-prefix/proposal.md
break 5ee8e3cb4a
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 1m30s
docs(员工代收款): 新增路由前缀修复治理变更并勾选 AUG26-017 门禁
- 新增 OpenSpec Change fix-employee-collection-route-prefix,承载已落地的 ff1362d 路由前缀修复(无规格 delta,skip_specs)
- 记录根因(Register 的 basePath 只服务文档)、影响面(7 条根级残留、15 条同层抢占)、修复方式与验证方式
- AUG26-017 全局健康门禁实际通过后勾选 5.7(tasks 27/27)
2026-09-11 15:38:05 +08:00

5.0 KiB
Raw Blame History

Why

员工代收款闭环(ce24d56,归档于 2026-09-11-add-employee-collection-bills)的三个注册函数把资源前缀写进了 RegisterbasePathbasePath 只参与 OpenAPI 文档拼接:internal/routes/registry.goRegisterrouter.Add(method, path, handler) 注册路由,只在 doc != nil 分支里把 basePath + path 拼成文档路径。因此 12 处注册实际落成的路径只剩相对段(""/:id/statistics/:id/close),全部挂在 /api/admin 根上。

Fiber 按注册顺序匹配,没有静态路由优先。先注册的根级 GET /api/admin/:id(账单详情)因此抢占其后注册的同层静态 GETPUT /api/admin/:id 抢占同层 PUT /api/admin/agent-self-recharge-payment-methods;同时 /api/admin 根上出现 4 条可写端点(POST /api/adminPUT /api/admin/:idDELETE /api/admin/:idPOST /api/admin/:id/close),与 OpenAPI 契约和归档规格描述的操作路径不一致。

离线路由表与真实 Fiber 路由复现结果:

  • 缺陷版 /api/admin 根级多出 10 条路由栈条目7 条不同 method+pathGET|POST /api/adminGET /api/admin/:id(重复注册 2 次)、PUT /api/admin/:idDELETE /api/admin/:idGET /api/admin/statisticsPOST /api/admin/:id/close
  • GET /api/admin/refundsGET /api/admin/system-configsGET /api/admin/agent-rechargesGET /api/admin/agent-self-recharge-payment-methodsGET /api/admin/order-package-invalidate-tasksGET /api/admin/asset-package-batch-orders 全部命中账单详情处理器并返回 400 / 1001 无效的路径ID;这些端点分别属于 order-refund-exchangesystem-operationsagent-funds-commissionpackage-lifecycle 的既有能力,agent-self-recharge-payment-methods 由在途 AUG26-017 引入。
  • 员工代收款自身的账单详情/统计/关闭、核销申请创建/详情/重提、收款方式增删改在文档路径下不可达(/api/admin/employee-collection-* 在缺陷版不存在)。

What Changes

  • internal/routes/employee_collection.go 的三个注册函数各自引入 router.Group("<资源前缀>")/employee-collection-payment-methods/employee-collection-bills/employee-collection-applications12 处 Register 首参由 admin 根路由组改为该 groupbasePath 与文档路径拼接保持原样。
  • 修正后 /api/admin 根级不再有员工代收款路由:缺陷版 7 条全部消失12 条路由回到 /api/admin/employee-collection-*;同层抢占候选(同方法下先注册的参数路由命中后注册的静态路由)由缺陷版 29 条原始命中 / 15 条按「方法 + 被抢占静态路由」去重降为 0。
  • 生成产物 docs/admin-openapi.yaml 逐字节不变(缺陷版、修复版与当前工作区 md5 均为 274f45440597aaafb1e168ac266cbb85),路径、方法、鉴权标记、中间件包装与描述文本均未改变。

Capabilities

New Capabilities

  • 无。

Modified Capabilities

  • 无。本 Change 不改变任何可观察行为契约,属于对已归档规格的实现收敛:主规格 employee-collection-bill 的 5 条行为 Requirement 描述账单来源、余额状态、核销申请、审批幂等与字典/退款联动,从不描述 HTTP 路径被阻断的端点属于既有能力其主规格本来就要求它们可用。规格侧唯一描述路径的产物OpenAPI 文档)在修复前后逐字节相同。

Non-Goals

  • 不改变任何业务行为、金额、状态机、权限可见性与幂等语义;不新增、删除或修改 handler、application/service、domain、查询与迁移。
  • 不改变 OpenAPI 契约:不新增或删除接口,不改路径、方法、鉴权标记、请求响应结构或描述文本。
  • 不修复其它模块可能存在的同层路由抢占,也不调整 internal/routes/registry.goRegister 语义。
  • 不承载 employee-collection-bill 的证据链补齐与可达操作索引(已由 e687a26 单独落地并列出本修复恢复的 12 条路由)。

Impact

  • 代码:internal/routes/employee_collection.go,仅 3 处 router.Group 与 12 处 Register 首参17 insertions / 12 deletions
  • 运行时:/api/admin 根级残留(含 4 条可写端点消失6 个命名 GET 端点及其同层 PUT/DELETE 端点恢复可达;员工代收款 12 条端点回到文档路径 /api/admin/employee-collection-*。无迁移、无配置、无外部渠道调用。
  • 契约:docs/admin-openapi.yaml 逐字节不变;主规格文件不变。
  • 回归风险:任何按缺陷路径(/api/admin/:id/api/admin/statistics 等)写死的调用方必须迁移;仓库源码、注释与 OpenAPI 文档均使用 /api/admin/employee-collection-*,未发现此类调用方。
  • 依赖:证据链与可达操作索引修复已由 e687a26 落地(openspec/specs/employee-collection-bill/spec.md## 可达操作索引 + docs/verification/context-reset/*.json),与本 Change 无文件重叠。