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

43 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 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 无文件重叠。