All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 1m30s
- 新增 OpenSpec Change fix-employee-collection-route-prefix,承载已落地的 ff1362d 路由前缀修复(无规格 delta,skip_specs)
- 记录根因(Register 的 basePath 只服务文档)、影响面(7 条根级残留、15 条同层抢占)、修复方式与验证方式
- AUG26-017 全局健康门禁实际通过后勾选 5.7(tasks 27/27)
5.0 KiB
5.0 KiB
Why
员工代收款闭环(ce24d56,归档于 2026-09-11-add-employee-collection-bills)的三个注册函数把资源前缀写进了 Register 的 basePath。basePath 只参与 OpenAPI 文档拼接:internal/routes/registry.go 的 Register 用 router.Add(method, path, handler) 注册路由,只在 doc != nil 分支里把 basePath + path 拼成文档路径。因此 12 处注册实际落成的路径只剩相对段(""、/:id、/statistics、/:id/close),全部挂在 /api/admin 根上。
Fiber 按注册顺序匹配,没有静态路由优先。先注册的根级 GET /api/admin/:id(账单详情)因此抢占其后注册的同层静态 GET,PUT /api/admin/:id 抢占同层 PUT /api/admin/agent-self-recharge-payment-methods;同时 /api/admin 根上出现 4 条可写端点(POST /api/admin、PUT /api/admin/:id、DELETE /api/admin/:id、POST /api/admin/:id/close),与 OpenAPI 契约和归档规格描述的操作路径不一致。
离线路由表与真实 Fiber 路由复现结果:
- 缺陷版
/api/admin根级多出 10 条路由栈条目(7 条不同 method+path):GET|POST /api/admin、GET /api/admin/:id(重复注册 2 次)、PUT /api/admin/:id、DELETE /api/admin/:id、GET /api/admin/statistics、POST /api/admin/:id/close。 GET /api/admin/refunds、GET /api/admin/system-configs、GET /api/admin/agent-recharges、GET /api/admin/agent-self-recharge-payment-methods、GET /api/admin/order-package-invalidate-tasks、GET /api/admin/asset-package-batch-orders全部命中账单详情处理器并返回400 / 1001 无效的路径ID;这些端点分别属于order-refund-exchange、system-operations、agent-funds-commission、package-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-applications),12 处Register首参由 admin 根路由组改为该 group;basePath与文档路径拼接保持原样。- 修正后
/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.go的Register语义。 - 不承载
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 无文件重叠。