diff --git a/qy-lty-admin/docs/修改记录.md b/qy-lty-admin/docs/修改记录.md index 6332015..e628705 100644 --- a/qy-lty-admin/docs/修改记录.md +++ b/qy-lty-admin/docs/修改记录.md @@ -25,6 +25,27 @@ +### [2026-05-07] Phase 2 — 锁定后端通用凭据槽位 REST 接口契约(消费方文档化) + +配套服务端 Phase:[../qy_lty/.planning/phases/02-admin-rest/](../../qy_lty/.planning/phases/02-admin-rest/) +覆盖服务端需求:CRED-03 + CRED-04(本仓库消费方) + +- **文件路径**: `docs/修改记录.md`(仅文档新增条目;本仓库代码未改) +- **修改类型**: 新增(文档) +- **修改内容**: + - 文档化服务端在本日落地的 `/api/v1/admin/credential-slot/` REST 接口契约(GET 脱敏读取 + PUT 全字段覆写 + admin token 鉴权),为后续 Web 管理后台前端(本仓库)的 CRED-FE-* phase 写 API client 与表单 UI 留下契约锚点 + - 接口契约要点(消费方视角): + - URL:`{NEXT_PUBLIC_API_BASE_URL}/v1/admin/credential-slot/` + - 鉴权:`Authorization: Bearer `(来源于 `/api/v1/admin/login/` 的现有 admin 登录返回值) + - GET 响应:`{ success: boolean, code: number, message: string, data: { app_id: string, access_token: string /* 末 4 位脱敏掩码,前缀 * */, updated_at: string /* ISO 8601 */ } }` + - PUT 请求体:`{ app_id?: string, access_token?: string }`(任一字段缺省时由后端兜底保留原值;写入是全字段覆写语义,建议前端 UI 始终提交两字段全集以避免歧义) + - PUT 响应同 GET 形态(access_token 同样脱敏返回,前端**不应**用响应值回填明文输入框) + - 错误矩阵:401(无 token / token 失效)、403(持非 admin token,message 含"需要管理员权限")、400(参数无效) +- **修改原因**: + - 服务端首次为本管理后台暴露受控的凭据读写接口;本仓库即将启动 CRED-FE-01(API client) + CRED-FE-02(表单录入页面)等 phase,先把后端契约固化进本仓库修改记录便于反查 + - 文档化"GET 与 PUT 响应均脱敏 access_token"避免前端工程师误以为可以从响应回填明文表单(实际明文仅存于 DB;任何回填只能保留掩码或要求运营重新输入) +- **服务端联动**: 后端联动条目 [../qy_lty/docs/修改记录.md](../../qy_lty/docs/修改记录.md) 同期 `[2026-05-07] Phase 2 — 管理端通用凭据槽位 REST 接口(GET 脱敏 / PUT 覆写)`。本仓库代码未改,仅文档侧做契约固化;待本仓库 CRED-FE-01 phase 启动落地 API client + Hook 时再补一条独立条目并互引 + ### [2026-05-07] 修复 NEXT_PUBLIC_API_BASE_URL 注入时机错误(线上登录 Network Error) - **文件路径**: diff --git a/qy_lty/docs/修改记录.md b/qy_lty/docs/修改记录.md index c848a8c..66921aa 100644 --- a/qy_lty/docs/修改记录.md +++ b/qy_lty/docs/修改记录.md @@ -23,6 +23,26 @@ +### [2026-05-07] Phase 2 — 管理端通用凭据槽位 REST 接口(GET 脱敏 / PUT 覆写) + +配套 Phase:[.planning/phases/02-admin-rest/](.planning/phases/02-admin-rest/) +覆盖需求:CRED-03 + CRED-04 +设计参考:1:1 复刻 `aiapp.views.RTCChatHistoryAPIView`(`aiapp/views.py:434-555`)的单 URL 多方法 APIView 风格 + +- **文件路径**: + - `aiapp/serializers.py`(修改 — 顶部 import 追加 `CredentialSlot`,文件末尾追加 `CredentialSlotSerializer` ModelSerializer 类) + - `aiapp/views.py`(修改 — 顶部 import 追加 `CredentialSlot` / `CredentialSlotSerializer` / `mask_token` / `get_standardized_response_schema`;文件末尾追加 `CredentialSlotPutRequestSchema` swagger 请求体 + `_credential_slot_data_schema` 响应 data schema + `CredentialSlotAdminView` APIView 类) + - `userapp/admin_urls.py`(修改 — 追加 `from aiapp.views import CredentialSlotAdminView` 与 `path('credential-slot/', CredentialSlotAdminView.as_view(), name='admin_credential_slot')`) +- **修改类型**: 新增 +- **修改内容**: + - 暴露 `GET /api/v1/admin/credential-slot/`:admin token 鉴权(`RedisTokenAuthentication` + 视图内 `is_staff` 二次校验,不发明 admin-only permission 类);返回 `{ success, code, message, data: { app_id, access_token: <末 4 位脱敏掩码>, updated_at } }`,脱敏由 view 层调 `common.utils.mask_token` 完成(serializer 不参与脱敏,避免双重责任) + - 暴露 `PUT /api/v1/admin/credential-slot/`:admin token 鉴权;接受 `{ app_id, access_token }` 全字段覆写;空记录场景自动走 `CredentialSlot.get_solo()` 的 `get_or_create(pk=1)`;写入后 `updated_at` 由 `auto_now=True` 自动刷新;响应同样脱敏 access_token(避免运营在 admin UI 看到自己刚提交的明文回显) + - 鉴权拒绝矩阵:无 token → 401(DRF NotAuthenticated → middleware 兜底标准壳层);持普通 user token(非 staff)→ 403 + `message="需要管理员权限"` + - Swagger / ReDoc 自动暴露:method-level `@swagger_auto_schema` 装饰器;响应 schema 配 `common.swagger_utils.get_standardized_response_schema()`;access_token 字段 description 显式标注「Access Token 末 4 位脱敏掩码(如 "*********1234")」,避免前端误解为明文 + - 不引入新依赖(沿用 Django 4.2.13 + DRF + drf-yasg + Phase 1 落地的 `CredentialSlot.get_solo` / `mask_token`) +- **修改原因**: Milestone v1.0「通用凭据槽位(APP ID + Access Token)」Phase 2 — 给管理后台前端(qy-lty-admin)暴露受控的凭据读写入口,让运营无需进 Django Admin 也能管理凭据;GET 与 PUT 响应均脱敏,避免明文经管理端 UI / 浏览器 devtools / 阿里云日志(GET 响应体路径)泄露;为 Phase 3 客户端明文 GET 接口 + 阿里云日志 formatter 提供"接口已上线、凭据可写入"的稳定起点 +- **跨项目联动**: 前端联动条目 [qy-lty-admin/docs/修改记录.md](../../qy-lty-admin/docs/修改记录.md) 同期 `[2026-05-07] Phase 2 — 锁定后端通用凭据槽位 REST 接口契约(消费方文档化)`。本 phase 是 Milestone v1.0 首次跨项目接口契约落地:本仓库(服务端)暴露 `/api/v1/admin/credential-slot/` GET/PUT,前端 `qy-lty-admin` 后续 phase 将基于该契约写 API client(含 React Hooks 调用 + 表单录入 UI)。前后端各自维护独立修改记录,本条与对方条目互相引用,便于未来回查接口的双向上下游 + ### [2026-05-07] Phase 1 — Django Admin 注册凭据槽位(脱敏 + 单例约束 + 禁删) 配套 Phase:[.planning/phases/01-credential-data-layer/](.planning/phases/01-credential-data-layer/)