## [ERR-20260425-002] ADP Time Off API 即使勾选权限后仍返回 404 Canonical URI Not Found

**日期**: 2026-04-25
**类别**: ADP API / 权限
**严重度**: 中（阻塞 PTO 同步功能开发）

### 问题描述
ADP 管理员在 Developer Portal 上"已开通" Time Off → List Of Requests 权限后，访问以下端点全部 404 `Canonical URI Not Found`：
- `/time/v2/workers/{aoid}/time-off-requests`（带/不带 $filter 都 404）
- `/time/v1/workers/{aoid}/time-off-requests`
- `/time/v2/time-off-requests`

同 token 下 `/hr/v2/workers` 正常工作，说明 token + mTLS 没问题，纯粹是 Time Off scope 没生效。

### 可能根因（待确认）
1. Portal 上勾选后没点保存
2. 权限改动需要 ADP 后台审核才生效（不是即时）
3. 还需要勾选额外的子 scope
4. 需要 ADP 客户成功经理介入开通服务

### 排查方法
- 用 `/hr/v2/workers` 验证基础 token 和 mTLS 健康
- Time Off 全部端点变体一起试，统一 404 = scope 问题；只某个变体 404 = 路径问题
- 让管理员截图 Portal 权限页确认实际状态

### 解决方案（暂定）
等管理员二次确认。开发侧并行推进员工基本信息同步（不依赖 Time Off）。

### 关键启示
1. ADP "权限已开通" ≠ "API 立即可用"。下次类似场景，先用一个目标端点冒烟测试，确认 200 后再展开开发。
2. **不要凭印象给 ADP 管理员"勾哪个权限"的具体指引**。ADP Developer Portal 是按 API Product 维度授权，product 名（如 "Worker Time Off Requests v2"）需要管理员在 Portal 上实际看到才能确认；agent 之前指引的 "List Of Requests" 没有任何 ADP 官方文档来源，属于猜测。正确做法：让管理员把 app 当前已添加的 API product 列表截图给我们，再反查目标端点对应的是哪个 product。

### 2026-04-25 更新：实际根因不是权限，而是 URL 版本号
看到管理员 Portal 截图（Time Off 6 个权限 toggle off）后，进一步排查发现：**Time Off scope 实际从来就是开通的**，过去四次 404 "Canonical URI Not Found" 全部是因为我们用了 `/time/v2/workers/{aoid}/time-off-requests`，而 ADP WFN 的正确路径是 **`/time/v3/...`**。改 v3 后立即 200。详见 ERR-20260425-003。

**这次真正的教训**：ADP API 返 "Canonical URI Not Found" 时，**先怀疑 URL 路径（版本号、参数格式），再怀疑权限**。404 在 ADP 这边对路径错和 scope 错给出的错误码一样，无法从 HTTP 码区分。判别方法：拿同 token 调一个**已知能通**的别的端点（如 `/hr/v2/workers`）作对照，能通 = token/mTLS 健康，问题就是路径或 scope 二选一；然后查官方 PDF guide 对端点路径，路径对了还报错才是 scope。
