Files
junhong_cmp_fiber/openspec/changes/archive/2026-09-11-fix-employee-collection-route-prefix/proposal.md
break 315a7de3e4
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 53s
docs(归档): 归档代理自充支付方式与员工代收款路由前缀两个变更
- add-agent-self-recharge-payment-methods 归档为 2026-09-11-add-agent-self-recharge-payment-methods,delta 应用后主规格 agent-funds-commission 完成 1 条 Requirement 改名并新增 4 条 Requirement
- 在可达操作索引补充代理自充支付方式配置与付款凭证识别共 3 个端点
- 同步 requirement-evidence.json 与 entry-capability-requirement-matrix.json 证据链
- fix-employee-collection-route-prefix 归档为 2026-09-11-fix-employee-collection-route-prefix 并勾选任务 2.5

门禁:context-health 通过、openspec validate --all 40 passed / 0 failed、doctor healthy
2026-09-11 15:50:15 +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 无文件重叠。