docs(03-01): 完成 Phase 3 Plan 01 — CRED-05 客户端 GET 接口落地
- 新增 03-01-SUMMARY.md:4.5 min × 3 task / 2 commit / 2 修改文件 / 6 truth × 15 断言全 PASS - STATE.md 切到 Phase 3 In Progress(5/6 plan complete,83%),决策段累积 5 条 [Plan 03-01] 决策 - ROADMAP.md 更新 Phase 3 进度(1/2 plan complete) - REQUIREMENTS.md 标记 CRED-05 → Done - 3 处 deviations 全 auto-fixed(Rule 1 docstring 字面量误报 / Rule 3 Windows shell 行级 REPL / Rule 3 GBK 编码);plan acceptance criteria 全部达成 Hand-off to Plan 03-02:DB 探针态保持 / _phase3_01_verify.py 留仓库根待删除 / 不写 docs/修改记录.md(由 03-02 Task 4 一并写)
This commit is contained in:
parent
50dcf1c8e2
commit
a58980fd73
@ -99,7 +99,7 @@
|
|||||||
- [x] **CRED-02** Django Admin 注册:列表态/查看态对 `access_token` 字段脱敏;新增/编辑态可见明文(运营录入需要);隐藏"新增"按钮(强制单例语义) ✓ Plan 01-02 完成(2026-05-07,commit 653f057;Task 2 由 orchestrator Django test client 程序化验收 10/10 PASS)
|
- [x] **CRED-02** Django Admin 注册:列表态/查看态对 `access_token` 字段脱敏;新增/编辑态可见明文(运营录入需要);隐藏"新增"按钮(强制单例语义) ✓ Plan 01-02 完成(2026-05-07,commit 653f057;Task 2 由 orchestrator Django test client 程序化验收 10/10 PASS)
|
||||||
- [x] **CRED-03** 管理端 GET `/api/v1/admin/credential-slot/`:admin token 鉴权(`admin_token:{token}` Redis key 体系);返回 `{ app_id, access_token: <masked>, updated_at }`,Access Token 仅返回末 4 位脱敏掩码
|
- [x] **CRED-03** 管理端 GET `/api/v1/admin/credential-slot/`:admin token 鉴权(`admin_token:{token}` Redis key 体系);返回 `{ app_id, access_token: <masked>, updated_at }`,Access Token 仅返回末 4 位脱敏掩码
|
||||||
- [x] **CRED-04** 管理端 PUT `/api/v1/admin/credential-slot/`:admin token 鉴权;接受 `{ app_id, access_token }` 全字段覆写更新;空记录场景自动 `get_or_create`;变更写入 `updated_at`
|
- [x] **CRED-04** 管理端 PUT `/api/v1/admin/credential-slot/`:admin token 鉴权;接受 `{ app_id, access_token }` 全字段覆写更新;空记录场景自动 `get_or_create`;变更写入 `updated_at`
|
||||||
- [ ] **CRED-05** 客户端 GET `/api/credential-slot/`:user token 鉴权(`token:{token}` Redis key 体系,复用 `RedisTokenAuthentication`);**明文**返回 `{ app_id, access_token, updated_at }`(手机端 / 设备端实际调用第三方服务需要)
|
- [x] **CRED-05** 客户端 GET `/api/credential-slot/`:user token 鉴权(`token:{token}` Redis key 体系,复用 `RedisTokenAuthentication`);**明文**返回 `{ app_id, access_token, updated_at }`(手机端 / 设备端实际调用第三方服务需要)
|
||||||
- [ ] **CRED-06** Access Token 日志过滤:阿里云日志格式化器 / 自定义日志过滤器中识别 `access_token` 字段并脱敏,覆盖 PUT 请求体、admin GET 响应体两条最易泄露路径
|
- [ ] **CRED-06** Access Token 日志过滤:阿里云日志格式化器 / 自定义日志过滤器中识别 `access_token` 字段并脱敏,覆盖 PUT 请求体、admin GET 响应体两条最易泄露路径
|
||||||
|
|
||||||
### 候选优先级(已转移自 brownfield 文档化阶段,本期不消化)
|
### 候选优先级(已转移自 brownfield 文档化阶段,本期不消化)
|
||||||
|
|||||||
@ -58,7 +58,7 @@
|
|||||||
3. 在生产日志(阿里云日志服务)中检索 Phase 2 / Phase 3 的请求轨迹:`PUT /api/v1/admin/credential-slot/` 请求体里的 `access_token` 字段被脱敏;管理端 `GET` 响应体里的 `access_token` 同样脱敏;客户端明文 GET 端点的响应体不写入日志(或同样脱敏),无任何位置暴露完整 Access Token 明文
|
3. 在生产日志(阿里云日志服务)中检索 Phase 2 / Phase 3 的请求轨迹:`PUT /api/v1/admin/credential-slot/` 请求体里的 `access_token` 字段被脱敏;管理端 `GET` 响应体里的 `access_token` 同样脱敏;客户端明文 GET 端点的响应体不写入日志(或同样脱敏),无任何位置暴露完整 Access Token 明文
|
||||||
4. 端到端验证:管理后台用 PUT 写入一组凭据 → 手机端调用客户端 GET 拿到的 `app_id` / `access_token` 与管理端写入的一致(往返一致性成立)
|
4. 端到端验证:管理后台用 PUT 写入一组凭据 → 手机端调用客户端 GET 拿到的 `app_id` / `access_token` 与管理端写入的一致(往返一致性成立)
|
||||||
**Plans:** 2 plans
|
**Plans:** 2 plans
|
||||||
- [ ] 03-01-PLAN.md — 客户端凭据槽位 GET 接口(CRED-05:CredentialSlotClientView 明文返回 + /api/credential-slot/ 路由注册)
|
- [x] 03-01-PLAN.md — 客户端凭据槽位 GET 接口(CRED-05:CredentialSlotClientView 明文返回 + /api/credential-slot/ 路由注册)
|
||||||
- [ ] 03-02-PLAN.md — 阿里云日志 access_token 脱敏(CRED-06:AccessTokenMaskFilter + LOGGING 配置 + 修改记录)
|
- [ ] 03-02-PLAN.md — 阿里云日志 access_token 脱敏(CRED-06:AccessTokenMaskFilter + LOGGING 配置 + 修改记录)
|
||||||
|
|
||||||
## Progress
|
## Progress
|
||||||
|
|||||||
@ -2,16 +2,16 @@
|
|||||||
gsd_state_version: 1.0
|
gsd_state_version: 1.0
|
||||||
milestone: v1.0
|
milestone: v1.0
|
||||||
milestone_name: 通用凭据槽位
|
milestone_name: 通用凭据槽位
|
||||||
status: Phase 2 整体完成,等待启动 Phase 3 规划
|
status: Phase 3 Plan 03-01 完成(CRED-05 客户端 GET 已落地),等待执行 Plan 03-02
|
||||||
stopped_at: Phase 2 完成(Plan 02-01 + 02-02 全部交付;端到端 8 条 success criteria 全 PASS;两端修改记录互引闭环);下一步启动 Phase 3 规划(CRED-05 + CRED-06)
|
stopped_at: Plan 03-01 完成(CRED-05 客户端 GET 落地,6 truth × 15 断言全 PASS);下一步 Plan 03-02(CRED-06 日志脱敏)
|
||||||
last_updated: "2026-05-08T02:10:10.851Z"
|
last_updated: "2026-05-08T02:17:57.222Z"
|
||||||
last_activity: 2026-05-08
|
last_activity: 2026-05-08
|
||||||
progress:
|
progress:
|
||||||
total_phases: 3
|
total_phases: 3
|
||||||
completed_phases: 2
|
completed_phases: 2
|
||||||
total_plans: 6
|
total_plans: 6
|
||||||
completed_plans: 4
|
completed_plans: 5
|
||||||
percent: 67
|
percent: 83
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project State — QY LTY Backend
|
# Project State — QY LTY Backend
|
||||||
@ -29,21 +29,21 @@ progress:
|
|||||||
## 当前位置
|
## 当前位置
|
||||||
|
|
||||||
```
|
```
|
||||||
Phase: 2 of 3(管理端 REST 接口)— Complete ✓
|
Phase: 3 of 3(客户端读取与日志脱敏)— In Progress
|
||||||
Plan: 02 of 02(端到端 verify + 互引)— Complete ✓
|
Plan: 01 of 02(CRED-05 客户端 GET 接口)— Complete ✓
|
||||||
Status: Phase 2 整体完成,等待启动 Phase 3 规划
|
Status: Plan 03-01 完成,等待执行 Plan 03-02(CRED-06 日志脱敏)
|
||||||
Last activity: 2026-05-08
|
Last activity: 2026-05-08
|
||||||
```
|
```
|
||||||
|
|
||||||
Progress: [██████████] 100%(已完成 plan:4/4 — Phase 1 全部 + Phase 2 全部;Phase 3 plans 数 TBD,按当前 milestone 规划范围统计)
|
Progress: [████████░░] 83%(已完成 plan:5/6 — Phase 1 全部 + Phase 2 全部 + Phase 3 Plan 01)
|
||||||
|
|
||||||
## 性能指标
|
## 性能指标
|
||||||
|
|
||||||
**速度:**
|
**速度:**
|
||||||
|
|
||||||
- 已完成 plan 数:4
|
- 已完成 plan 数:5
|
||||||
- 平均耗时:~430 s(顺序执行模式)
|
- 平均耗时:~398 s(顺序执行模式)
|
||||||
- 总执行时间:1720 s(Plan 01-01: 184 s + Plan 01-02: ~600 s + Plan 02-01: 216 s + Plan 02-02: ~720 s)
|
- 总执行时间:1990 s(Plan 01-01: 184 s + Plan 01-02: ~600 s + Plan 02-01: 216 s + Plan 02-02: ~720 s + Plan 03-01: 270 s)
|
||||||
|
|
||||||
**按 Phase:**
|
**按 Phase:**
|
||||||
|
|
||||||
@ -51,11 +51,12 @@ Progress: [██████████] 100%(已完成 plan:4/4 — Phase
|
|||||||
|-------|-------|--------|----------|
|
|-------|-------|--------|----------|
|
||||||
| 1 | 2/2 | 784 s | 392 s |
|
| 1 | 2/2 | 784 s | 392 s |
|
||||||
| 2 | 2/2 | 936 s | 468 s |
|
| 2 | 2/2 | 936 s | 468 s |
|
||||||
|
| 3 | 1/2 | 270 s | 270 s |
|
||||||
|
|
||||||
**最近趋势:**
|
**最近趋势:**
|
||||||
|
|
||||||
- 最近 5 个 plan:01-01(184 s,3 task)/ 01-02(~600 s,4 task + checkpoint 验收)/ 02-01(216 s,3 task / 3 commit / 3 文件)/ 02-02(~720 s,2 task / 2 commit / 1 创建 + 2 修改文件 + 端到端 28 项断言)
|
- 最近 5 个 plan:01-01(184 s,3 task)/ 01-02(~600 s,4 task + checkpoint 验收)/ 02-01(216 s,3 task / 3 commit / 3 文件)/ 02-02(~720 s,2 task / 2 commit / 1 创建 + 2 修改文件 + 端到端 28 项断言)/ 03-01(270 s,3 task / 2 commit / 2 修改文件 + 1 临时验收脚本未入 git + 端到端 15 项断言)
|
||||||
- 趋势:纯 auto 代码落地 plan 速度稳定 200-220 s;端到端验收 plan(含 Django test client 跑 28 项断言 + Swagger schema 校验 + 跨项目互引)放大到 ~720 s(多走两次脚本编写 / 调试);checkpoint 验收 plan 显著放大耗时
|
- 趋势:纯 auto 代码落地 plan 速度稳定 200-270 s;Plan 03-01 是 1:1 复刻 Phase 2 admin view 模板的最简形态(删 _ensure_admin / _build_response_data / def put,仅保留 GET 明文),加上端到端验收,落地速度接近 Plan 02-01;3 处 Windows 环境兼容偏差全部 auto-fixed
|
||||||
|
|
||||||
*每完成一个 plan 后更新*
|
*每完成一个 plan 后更新*
|
||||||
|
|
||||||
@ -89,6 +90,11 @@ Progress: [██████████] 100%(已完成 plan:4/4 — Phase
|
|||||||
- **[Plan 02-02]** DB 探针态主动还原:脚本最后 slot.app_id='probe_app' / slot.access_token='probe_secret_xxxx' / slot.save() 还原,给 Phase 3 留下稳定起点
|
- **[Plan 02-02]** DB 探针态主动还原:脚本最后 slot.app_id='probe_app' / slot.access_token='probe_secret_xxxx' / slot.save() 还原,给 Phase 3 留下稳定起点
|
||||||
- **[Plan 02-02]** qy-lty-admin 改动通过父级 Lila-Server/.git 提交:qy-lty-admin/ 没有自己的 .git;commit 46d72b8 在父仓库同时入两端 docs/修改记录.md
|
- **[Plan 02-02]** qy-lty-admin 改动通过父级 Lila-Server/.git 提交:qy-lty-admin/ 没有自己的 .git;commit 46d72b8 在父仓库同时入两端 docs/修改记录.md
|
||||||
- **[Plan 02-02]** 临时验收脚本验完即删:`_phase2_verify.py` / `_phase2_swagger_verify.py` 是一次性证据生成器,证据落地 02-VERIFICATION.md 后无需保留
|
- **[Plan 02-02]** 临时验收脚本验完即删:`_phase2_verify.py` / `_phase2_swagger_verify.py` 是一次性证据生成器,证据落地 02-VERIFICATION.md 后无需保留
|
||||||
|
- **[Plan 03-01]** CredentialSlotClientView 完全独立 APIView 类,不继承 admin view;不调 _ensure_admin / _build_response_data / mask_token,明文返回;与 admin view 形成对称命名 + 反向行为
|
||||||
|
- **[Plan 03-01]** 路由放顶层 qy_lty/urls.py:api_urlpatterns(参考 common/upload/ 风格),最终 URL = /api/credential-slot/,不挂任何 sub-include 命名空间
|
||||||
|
- **[Plan 03-01]** 客户端响应 schema 独立命名 _credential_slot_client_data_schema,access_token description 显式标注「明文」,与 admin 端 _credential_slot_data_schema 对照避免混用脱敏掩码语义
|
||||||
|
- **[Plan 03-01]** 不调用 logger.info / logger.debug 输出 access_token,未引入新泄露源;Plan 03-02 的 AccessTokenMaskFilter 是兜底防御
|
||||||
|
- **[Plan 03-01]** 验收脚本 `_phase3_01_verify.py` 不入 git,留在仓库根;Plan 03-02 Task 4 末尾统一删除 + 一并写两端 docs/修改记录.md 互引条目
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@ -116,19 +122,18 @@ Progress: [██████████] 100%(已完成 plan:4/4 — Phase
|
|||||||
## 下一步
|
## 下一步
|
||||||
|
|
||||||
```
|
```
|
||||||
/gsd-plan-phase 3
|
执行 Phase 3 Plan 02:CRED-06 阿里云日志脱敏 + 两端修改记录互引 + 临时验收脚本删除
|
||||||
```
|
```
|
||||||
|
|
||||||
Phase 2 已整体完成(commits 6820fe7 / 192d0a1 / 9d02021 / 2dec1fd / 3cfd481 / 46d72b8):
|
Phase 3 Plan 03-01 已完成(commits 5269a08 / 50dcf1c):
|
||||||
|
|
||||||
- Plan 02-01:`CredentialSlotSerializer` + `CredentialSlotAdminView` + 路由注册(commits 6820fe7 / 192d0a1 / 9d02021)
|
- Task 1:`CredentialSlotClientView` + `_credential_slot_client_data_schema` 追加到 `aiapp/views.py` 末尾(commit 5269a08)
|
||||||
- Plan 02-02:
|
- Task 2:`/api/credential-slot/` 路由注册到 `qy_lty/urls.py:api_urlpatterns`(commit 50dcf1c)
|
||||||
- Task 1:端到端 8 条 success criteria 全 PASS — Django test client 跑 28 项独立断言 + `/swagger.json/` schema 校验(commit 3cfd481)
|
- Task 3:端到端 6 条 truth × 15 项独立断言全 PASS — Django test client 跑 user/admin token 双 200 + 401 × 2 + Swagger schema + DB 探针态(脚本 `_phase3_01_verify.py` 留在仓库根未入 git)
|
||||||
- Task 2:qy_lty + qy-lty-admin 两端 docs/修改记录.md 各写一条 Phase 2 互引条目,跨项目联动闭环(commit 46d72b8)
|
|
||||||
|
|
||||||
URL `/api/v1/admin/credential-slot/` GET / PUT 已端到端验证;DB 探针态已还原 `probe_app` / `probe_secret_xxxx`;CRED-03 / CRED-04 已在 REQUIREMENTS.md 标记 Done。
|
URL `/api/credential-slot/` GET 已端到端验证(明文返回 access_token);DB 探针态保持 `probe_app` / `probe_secret_xxxx`;CRED-05 已在 REQUIREMENTS.md 标记 Done。
|
||||||
|
|
||||||
下一步规划 Phase 3:CRED-05(客户端 GET `/api/credential-slot/`,user token 鉴权,**明文**返回)+ CRED-06(阿里云日志 formatter 用 `mask_token` 过滤 access_token,覆盖 PUT 请求体 / admin GET 响应体两条最易泄露路径)。
|
下一步执行 Plan 03-02:CRED-06(`common/logging/filters.py:AccessTokenMaskFilter` + `qy_lty/settings.py:LOGGING.filters/handlers` + 两端 docs/修改记录.md 互引 + 删除 `_phase3_01_verify.py`)。
|
||||||
|
|
||||||
## 工作流配置
|
## 工作流配置
|
||||||
|
|
||||||
@ -158,8 +163,8 @@ CLAUDE.md 两条强制规则(任何 phase 都必须遵守):
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-05-07T15:07:54Z
|
Last session: 2026-05-08T02:17:57.220Z
|
||||||
Stopped at: Phase 2 完成(Plan 02-01 + 02-02 全部交付;端到端 8 条 success criteria 全 PASS;两端修改记录互引闭环);下一步启动 Phase 3 规划(CRED-05 + CRED-06)
|
Stopped at: Plan 03-01 完成(CRED-05 客户端 GET 落地,6 truth × 15 断言全 PASS);下一步 Plan 03-02(CRED-06 日志脱敏)
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
184
qy_lty/.planning/phases/03-client-and-log-mask/03-01-SUMMARY.md
Normal file
184
qy_lty/.planning/phases/03-client-and-log-mask/03-01-SUMMARY.md
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
---
|
||||||
|
phase: 03-client-and-log-mask
|
||||||
|
plan: 01
|
||||||
|
subsystem: api
|
||||||
|
tags: [drf, apiview, redis-token-auth, swagger, credential-slot, plaintext-client]
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 01-credential-slot-foundation
|
||||||
|
provides: aiapp.models.CredentialSlot 单例 + get_solo() / common.utils.mask_token / aiapp.serializers.CredentialSlotSerializer
|
||||||
|
- phase: 02-admin-rest
|
||||||
|
provides: aiapp.views.CredentialSlotAdminView(1:1 复刻起点)+ DB 探针态 pk=1/probe_app/probe_secret_xxxx
|
||||||
|
provides:
|
||||||
|
- aiapp.views.CredentialSlotClientView:客户端只读 GET,明文返回 access_token,user/admin token 双兼容
|
||||||
|
- _credential_slot_client_data_schema:drf-yasg 客户端响应 schema(access_token description 标注「明文」)
|
||||||
|
- 路由 /api/credential-slot/(顶层 api_urlpatterns,name=client_credential_slot)
|
||||||
|
- 端到端验收脚本 _phase3_01_verify.py(仓库根,未入 git,留给 Plan 03-02 Task 4 删除)
|
||||||
|
affects:
|
||||||
|
- Phase 3 Plan 02(CRED-06 阿里云日志脱敏):以本 plan 落地的客户端 view 为日志脱敏的兜底防御目标之一
|
||||||
|
- Unity 客户端 LTY_App_Project_URP / LTY_Project:未来通过 /api/credential-slot/ 拉取明文凭据调用第三方服务
|
||||||
|
|
||||||
|
# Tech tracking
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "客户端 view 与 admin view 行为反向(admin 脱敏 / client 明文),同一份 serializer,差异隔离在 view 层"
|
||||||
|
- "客户端命名空间路由直接挂顶层 api_urlpatterns(不走任何 sub-include),保证最终 URL 是 /api/credential-slot/ 而非 /api/<app>/credential-slot/"
|
||||||
|
- "drf-yasg 客户端响应 schema 单独命名(_credential_slot_client_data_schema),与 admin 端 _credential_slot_data_schema 形成对称对照,避免混用脱敏掩码语义"
|
||||||
|
- "端到端验收沿用 Phase 2 模式:Django test client in-process + Redis 临时 token + DB 探针态主动还原"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- .planning/phases/03-client-and-log-mask/03-01-SUMMARY.md
|
||||||
|
- _phase3_01_verify.py(仓库根,未入 git,Plan 03-02 Task 4 删除)
|
||||||
|
modified:
|
||||||
|
- aiapp/views.py(末尾追加 64 行:1 块 schema + 1 个 APIView 类)
|
||||||
|
- qy_lty/urls.py(imports 段 +1 行 / api_urlpatterns +2 行含注释)
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "[Plan 03-01] CredentialSlotClientView 完全独立 APIView 类,不继承 / mixin admin view,避免 Phase 2 admin view 演进时意外波及客户端语义"
|
||||||
|
- "[Plan 03-01] 不调 _ensure_admin / _build_response_data / mask_token,仅调用 success_response(data=serializer.data):明文返回是 CONTEXT 锁定决策,admin user 是手机用户超集,对客户端 view 不做 is_staff 二次校验"
|
||||||
|
- "[Plan 03-01] 客户端响应 schema 独立命名 _credential_slot_client_data_schema,access_token description 显式写「明文 Access Token,供手机/设备端实际调用第三方服务(管理端同接口会脱敏返回末 4 位)」,与 admin 端 description 形成对照"
|
||||||
|
- "[Plan 03-01] 路由放顶层 qy_lty/urls.py:api_urlpatterns(紧邻 common/upload/ 后),与 Phase 2 admin 路由(v1/admin/) 视觉分组隔离,最终 URL = /api/credential-slot/"
|
||||||
|
- "[Plan 03-01] 验收脚本 _phase3_01_verify.py 不入 git:与 Phase 2 _phase2_verify.py 同模式,是一次性证据生成器,证据落地本 SUMMARY 后由 Plan 03-02 Task 4 统一删除"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "客户端 / 管理端同 model 的双 view 反向行为模式(admin 脱敏 + 写 / client 明文 + 只读)"
|
||||||
|
- "顶层 api_urlpatterns 直挂客户端散点路径模式(参考 common/upload/,避免 sub-include 命名污染)"
|
||||||
|
|
||||||
|
requirements-completed:
|
||||||
|
- CRED-05
|
||||||
|
|
||||||
|
# Metrics
|
||||||
|
duration: 4min30s
|
||||||
|
completed: 2026-05-08
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 3 Plan 03-01:客户端通用凭据槽位 GET 接口 Summary
|
||||||
|
|
||||||
|
**CredentialSlotClientView 客户端只读 APIView 落地,/api/credential-slot/ 顶层路由注册,user / admin token 双兼容明文返回 access_token,端到端 6 条 truth 全 PASS(15 项独立断言)**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** ~4.5 min(auto 模式纯顺序执行)
|
||||||
|
- **Started:** 2026-05-08T02:11:32Z
|
||||||
|
- **Completed:** 2026-05-08T02:16:02Z
|
||||||
|
- **Tasks:** 3(2 个文件落地 + 1 个端到端验收)
|
||||||
|
- **Files modified:** 2(aiapp/views.py + qy_lty/urls.py)
|
||||||
|
- **Files created:** 1(_phase3_01_verify.py,仓库根,未入 git)
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- **CRED-05 落地完成**:`/api/credential-slot/` GET 接口已注册到 Django URLConf,明文返回 `{app_id, access_token, updated_at}` 标准壳层
|
||||||
|
- **6 条 truth 全 PASS**(15 项独立断言):
|
||||||
|
- T1 user token GET → 200 + 明文 + success=true(5 项断言)
|
||||||
|
- T2 admin token GET → 200 + 明文(2 项断言)
|
||||||
|
- T3 无 token → 401 + success=false(2 项断言)
|
||||||
|
- T4 伪造 token → 401(1 项断言)
|
||||||
|
- T5 /swagger.json/ 含 /credential-slot/ + GET 方法(3 项断言)
|
||||||
|
- T6 DB 探针态保持 probe_app / probe_secret_xxxx(2 项断言)
|
||||||
|
- **DB 探针态保持稳定**:脚本前后 `pk=1, app_id='probe_app', access_token='probe_secret_xxxx'`,给 Plan 03-02 留下与 Phase 2 一致的起点
|
||||||
|
- **Phase 2 既有代码 0 改动**:`CredentialSlotAdminView` / `CredentialSlotPutRequestSchema` / `_credential_slot_data_schema` 完全未动;imports 段未变
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
每个 task 原子提交(中文 commit message):
|
||||||
|
|
||||||
|
1. **Task 1:在 aiapp/views.py 末尾追加 CredentialSlotClientView 类** — `5269a08` (feat) — 新增 64 行(schema + view 类)
|
||||||
|
2. **Task 2:在 qy_lty/urls.py 注册 /api/credential-slot/ 路由** — `50dcf1c` (feat) — imports 段 +1 行 + api_urlpatterns +2 行
|
||||||
|
3. **Task 3:端到端验收(CRED-05 6 条 truth)** — 无 commit(验收脚本 `_phase3_01_verify.py` 留在仓库根未入 git,由 Plan 03-02 Task 4 统一删除)
|
||||||
|
|
||||||
|
**Plan metadata:** 待 final commit(本 SUMMARY + STATE.md / ROADMAP.md / REQUIREMENTS.md)
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- **`aiapp/views.py`**(行 688-748,新增 60 行):末尾追加 `_credential_slot_client_data_schema` 客户端响应 schema + `CredentialSlotClientView(APIView)` 类
|
||||||
|
- **`qy_lty/urls.py`**(行 27 + 行 58-59,新增 3 行):imports 段 `from aiapp.views import CredentialSlotClientView`;`api_urlpatterns` 列表新增 `path('credential-slot/', CredentialSlotClientView.as_view(), name='client_credential_slot')`
|
||||||
|
- **`_phase3_01_verify.py`**(仓库根,未入 git):端到端验收脚本,6 条 truth × 15 项断言;Plan 03-02 Task 4 删除
|
||||||
|
|
||||||
|
## 与 Phase 2 admin view 的对照差异
|
||||||
|
|
||||||
|
| 项 | CredentialSlotAdminView (Phase 2) | CredentialSlotClientView (Phase 3 Plan 01) |
|
||||||
|
|---|---|---|
|
||||||
|
| 类体内 `_ensure_admin` | 含(is_staff 二次校验,非 admin 返 403) | 不含(admin / user 都允许) |
|
||||||
|
| 类体内 `_build_response_data` | 含(调 mask_token 脱敏 access_token) | 不含(直接 serializer.data 明文) |
|
||||||
|
| 类体内 `mask_token` 调用 | 1 次(_build_response_data 内) | 0 次 |
|
||||||
|
| HTTP 方法 | GET + PUT(双方法) | 仅 GET(只读) |
|
||||||
|
| 响应行为 | access_token 末 4 位脱敏 `*************xxxx` | 明文 `probe_secret_xxxx` |
|
||||||
|
| swagger response data schema | `_credential_slot_data_schema`(脱敏掩码语义) | `_credential_slot_client_data_schema`(明文语义) |
|
||||||
|
| 路由命名空间 | `/api/v1/admin/credential-slot/`(admin sub-include) | `/api/credential-slot/`(顶层 api_urlpatterns) |
|
||||||
|
| URL name | `admin_credential_slot` | `client_credential_slot` |
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
见 frontmatter `key-decisions` 字段,已 5 条决策全部归档。
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Rule 1 - Bug] 客户端 view docstring 字面量触发自动化 verify 误报**
|
||||||
|
- **Found during:** Task 1(首次跑 verify regex check 时)
|
||||||
|
- **Issue:** PLAN.md 自动化校验脚本用 `re.search(r'^class CredentialSlotClientView.*?(?=^class |\Z)', src, re.S | re.M)` 切类体后 grep `_ensure_admin / _build_response_data / def put / mask_token` 是否出现;但首版 docstring 内含「删 _ensure_admin / 删 _build_response_data / 删 PUT 方法」字面引用,被 regex 误判为客户端类体含禁词,验收 FAIL
|
||||||
|
- **Fix:** 把 docstring 中的禁词替换为语义等价但不触发字面量匹配的描述(「不做 is_staff 二次校验」/「不脱敏:直接返回 serializer.data」/「仅 GET:客户端只读」),保留对照管理端 view 的差异说明
|
||||||
|
- **Files modified:** aiapp/views.py
|
||||||
|
- **Verification:** verify regex check 复跑全 PASS;class body 字面量不再含 `_ensure_admin` / `_build_response_data` / `def put` / `mask_token`
|
||||||
|
- **Committed in:** 5269a08(与 Task 1 主体一并提交)
|
||||||
|
|
||||||
|
**2. [Rule 3 - Blocking] python manage.py shell < 在 Windows 下行级 REPL 执行**
|
||||||
|
- **Found during:** Task 3(首次跑 `python manage.py shell < _phase3_01_verify.py` 时)
|
||||||
|
- **Issue:** Windows PowerShell + Django shell 把脚本内容当 REPL 输入逐行送入,所有缩进块(if/for/函数体等)触发 IndentationError;脚本完全无法执行
|
||||||
|
- **Fix:** 改用 `python manage.py shell -c "exec(open('_phase3_01_verify.py', encoding='utf-8').read())"` —— Django shell 的 `-c` 参数把字符串作为 Python 源码完整 exec,保留缩进语义;与 Linux/macOS 下 `<` 重定向行为等价
|
||||||
|
- **Files modified:** 无(仅调整执行命令)
|
||||||
|
- **Verification:** 复跑成功,15 PASSes / 0 FAILs
|
||||||
|
- **Committed in:** 不需要 commit(执行方式调整,不触动代码)
|
||||||
|
|
||||||
|
**3. [Rule 3 - Blocking] Windows GBK 控制台无法编码 Unicode 字符 ✓**
|
||||||
|
- **Found during:** Task 3(exec 执行成功收尾时)
|
||||||
|
- **Issue:** 脚本 print 循环用 `✓` 标记 PASS 项;Windows 默认 stdout 编码 cp936/gbk,UnicodeEncodeError 中断输出(且 PASS 标记中的中文「客户端响应未脱敏」也触发);脚本运行成功但 print 阶段 crash
|
||||||
|
- **Fix:** 把 `✓` 替换为 ASCII 字符串 `[PASS]`;把 PASS list 中的中文标签替换为英文短标签(保持验收语义);其余日志保留中文(不进 print 循环)
|
||||||
|
- **Files modified:** _phase3_01_verify.py(未入 git)
|
||||||
|
- **Verification:** 复跑全部 15 项 PASS 完整 print 输出,无编码异常
|
||||||
|
- **Committed in:** 不需要 commit(脚本本身不入 git)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total deviations:** 3 auto-fixed(1 Bug + 2 Blocking)
|
||||||
|
**Impact on plan:** 三处偏差均为执行环境兼容性问题(Windows shell + verify regex 假阳性),不涉及业务逻辑 / 安全语义 / 架构变更;plan acceptance criteria 全部达成,CRED-05 6 条 truth 端到端 PASS
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
无业务 / 架构问题。仅遇到上述 3 处 Windows 环境兼容性问题,已自动修复。
|
||||||
|
|
||||||
|
## Stub Status
|
||||||
|
|
||||||
|
无。本 plan 落地的 view + 路由是直连 DB 的真实数据通路(CredentialSlot.get_solo() → Postgres pk=1 单例),不含任何 placeholder / 硬编码 / mock 数据。
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
|
||||||
|
无 —— 不引入新依赖、不要求新环境变量、不需要外部服务配置。
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
- **Phase 3 Plan 02(CRED-06 阿里云日志脱敏)准备就绪**:本 plan 已确认 `CredentialSlotClientView` 直接 `success_response(data=serializer.data)` 不调 logger.info / logger.debug,**未引入新泄露源**;Plan 02 的 `AccessTokenMaskFilter` 是兜底防御
|
||||||
|
- **DB 探针态保持**:`pk=1, app_id='probe_app', access_token='probe_secret_xxxx'`,与 Phase 2 完全一致,Plan 02 验收时直接复用
|
||||||
|
- **临时验收脚本**:`_phase3_01_verify.py` 留在仓库根(未入 git),Plan 03-02 Task 4 末尾统一删除(本 plan 不写 docs/修改记录.md,由 Plan 03-02 Task 4 一并写)
|
||||||
|
- **Hand-off to Plan 03-02**:本 plan 不修改 `qy_lty/settings.py:LOGGING`,Plan 02 即可直接 patch;本 plan 不创建 `common/logging/` 目录,Plan 02 创建
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
- [x] aiapp/views.py 含 `class CredentialSlotClientView(APIView):` (FOUND)
|
||||||
|
- [x] aiapp/views.py 含 `_credential_slot_client_data_schema` (FOUND, 2 occurrences)
|
||||||
|
- [x] qy_lty/urls.py 含 `from aiapp.views import CredentialSlotClientView` (FOUND)
|
||||||
|
- [x] qy_lty/urls.py 含 `path('credential-slot/', CredentialSlotClientView.as_view(), name='client_credential_slot')` (FOUND)
|
||||||
|
- [x] commit 5269a08 in git log (FOUND)
|
||||||
|
- [x] commit 50dcf1c in git log (FOUND)
|
||||||
|
- [x] _phase3_01_verify.py 输出 ALL PASS (FOUND, 15 PASSes / 0 FAILs)
|
||||||
|
- [x] DB 探针态 pk=1/probe_app/probe_secret_xxxx 保持 (FOUND)
|
||||||
|
- [x] python manage.py check 通过(仅遗留 staticfiles.W004 与本 plan 无关)
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 03-client-and-log-mask*
|
||||||
|
*Plan: 01*
|
||||||
|
*Completed: 2026-05-08*
|
||||||
Loading…
x
Reference in New Issue
Block a user