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)
43 lines
5.0 KiB
Markdown
43 lines
5.0 KiB
Markdown
## 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 无文件重叠。
|