Files
JobRadar/.craftkit/designs/engineering-baseline/interface-design.md
T

253 lines
9.1 KiB
Markdown

---
reviewStatus: pending
reviewedAt: null
replacedBy: null
---
# 第一阶段工程基线接口与页面契约设计
## 1. 设计范围
第一阶段不采用 Django REST Framework,也不提供公开 JSON API 或 OpenAPI 契约。本设计只定义浏览器访问的服务端页面 HTTP 契约,以及页面、Admin、Agent SDK 适配器调用的内部服务契约。
如果后续出现前后端分离、第三方调用或移动端需求,应重新执行正式 API 设计,不直接把本阶段内部服务暴露为外部 API。
关联设计:
- [后端落地设计](backend-design.md)
- [前端落地设计](frontend-design.md)
- [数据库设计](database-design.md)
## 2. 通用 HTTP 规则
- 用户认证使用 Django Session。
- 所有状态修改请求使用 POST 并验证 CSRF。
- GET 请求不得产生业务状态变更。
- 成功写入后使用 POST/Redirect/GET。
- 未登录访问受保护页面时跳转登录页,并携带安全的站内返回地址。
- 普通用户访问其他用户资源时返回 404,不暴露资源存在性。
- 表单输入错误返回原页面和字段错误,响应状态按 Django 页面约定实现。
- 意外异常返回通用错误页面,日志使用请求关联标识定位。
- 响应不得包含堆栈、数据库错误、密钥、Cookie 或未脱敏工具参数。
## 3. 页面端点
### 3.1 登录
`GET /accounts/login/`
- 返回登录表单。
- 已登录用户可重定向到运行列表。
`POST /accounts/login/`
- 输入:用户名、密码、可选站内 `next`。
- 成功:建立 Session,重定向到安全 `next` 或运行列表。
- 失败:返回登录页和统一认证错误,不区分用户名或密码错误。
### 3.2 退出
`POST /accounts/logout/`
- 前置条件:已登录。
- 成功:清除 Session,重定向登录页。
- 不提供 GET 退出。
### 3.3 个人资料
`GET /accounts/profile/`
- 前置条件:已登录。
- 返回当前用户的用户名、显示名和时区。
- 不接受目标用户编号参数。
`POST /accounts/profile/`
- 前置条件:已登录、CSRF 有效。
- 输入:显示名、时区。
- 成功:保存当前用户资料并重定向到资料页。
- 失败:原页显示字段错误,不保存部分数据。
### 3.4 Agent Run 列表
`GET /runs/`
- 前置条件:已登录。
- 查询参数:`page`,其他未知参数忽略或按统一规则拒绝。
- 返回当前用户拥有的 Run,按创建时间倒序分页。
- 管理员在普通站点页面仍默认只看自己的 Run;跨用户管理使用 Admin。
### 3.5 Agent Run 详情
`GET /runs/<uuid:run_id>/`
- 前置条件:已登录。
- 返回 Run 概览、有序事件、工具调用摘要和人工确认状态。
- 目标不存在或不属于当前用户时返回相同的 404。
- 页面端点不提供状态更新能力。
### 3.6 管理后台
`/admin/` 沿用 Django Admin 的认证和权限体系。
- 用户资料和 Run 主记录按配置开放管理能力。
- 事件和完成的工具调用设置为只读或限制修改。
- 人工确认处理必须调用领域服务,不能只修改单个状态字段。
### 3.7 模型服务商配置
`GET /runs/providers/`
- 返回内置服务商目录、当前用户连接状态、搜索和分类结果。
- 不返回密文 API Key,已配置密钥只显示末四位提示。
`POST /runs/providers/<provider_code>/configure/`
- 输入:API Key、可选默认模型、是否设为默认服务商。
- 服务端按固定预设端点请求模型目录;验证成功后才加密保存。
- 验证失败返回安全错误说明,不透传上游正文,不覆盖旧密钥。
`POST /runs/providers/<provider_code>/disconnect/`
- 只删除当前用户对应配置;删除默认配置后自动选择一个剩余可用配置。
- GET 请求不得删除或修改配置。
## 4. 表单契约
### 4.1 登录表单
| 字段 | 必填 | 规则 |
| --- | --- | --- |
| `username` | 是 | 使用 Django 认证表单规则 |
| `password` | 是 | 不回显、不写日志 |
| `next` | 否 | 只允许站内安全路径 |
### 4.2 用户资料表单
| 字段 | 必填 | 规则 |
| --- | --- | --- |
| `display_name` | 否 | 去除首尾空白,长度上限由模型统一定义 |
| `timezone` | 是 | 必须来自服务端受控候选 |
模型约束、表单约束和服务校验必须保持一致,不能只依赖浏览器端校验。
## 5. 内部服务契约
内部服务只接受明确的操作者和标识,不接受未经限定的 QuerySet。
### 5.1 账户服务
| 操作 | 输入 | 输出 | 失败语义 |
| --- | --- | --- | --- |
| 获取资料 | 当前用户 | `UserProfile` | 用户无效 |
| 更新资料 | 当前用户、已校验数据 | 更新后资料 | 校验失败、并发冲突 |
| 停用用户 | 管理员、目标用户 | 停用结果 | 无权限、目标不存在 |
### 5.2 Run 查询服务
| 操作 | 输入 | 输出 | 权限规则 |
| --- | --- | --- | --- |
| 查询列表 | 当前用户、分页参数 | 分页 Run | 强制用户归属过滤 |
| 查询详情 | 当前用户、Run UUID | Run 详情视图模型 | 越权与不存在统一处理 |
### 5.3 Run 命令服务
| 操作 | 关键输入 | 关键输出 |
| --- | --- | --- |
| 创建 Run | 所属用户、脱敏输入摘要、版本 | 新 Run 和创建事件 |
| 开始 Run | Run 标识、期望版本 | `running` Run 和开始事件 |
| 完成 Run | Run 标识、脱敏输出、用量 | `succeeded` Run 和完成事件 |
| 失败 Run | Run 标识、错误码、脱敏摘要 | `failed` Run 和失败事件 |
| 取消 Run | 操作者、Run 标识 | `cancelled` Run 和取消事件 |
| 请求确认 | Run、请求键、类型、摘要 | 待处理确认和暂停事件 |
| 处理确认 | 操作者、确认标识、决定 | 确认结果及 Run 状态变更 |
命令服务必须显式返回更新后的领域对象或结果对象,不依赖调用方猜测数据库状态。
## 6. SDK Gateway 契约
### 6.1 请求模型
`AgentExecutionRequest` 至少包含:
- `agent_run_id`
- `user_id`
- `agent_name`
- `agent_version`
- `instruction_version`
- `toolset_version`
- 脱敏运行输入
- 最大轮次、时间和工具调用预算
不包含 API Key、网站密码和 Cookie。
### 6.2 结果模型
`AgentExecutionResult` 至少包含:
- 结果状态。
- 脱敏结构化输出摘要。
- trace 标识。
- 输入和输出 token。
- 估算费用。
- 稳定错误码和脱敏错误摘要。
### 6.3 失败分类
- 配置缺失:调用真实 Gateway 前失败,不影响其他页面。
- 输入无效:不发起外部请求。
- 外部超时或服务失败:记录工具或 Run 失败事件。
- 输出校验失败:保留安全摘要并将 Run 标记失败。
- 取消:停止后续调用并记录取消事件。
第一阶段测试使用 Stub Gateway,禁止自动化测试发起真实付费调用。
## 7. 幂等、并发和重试
- 页面资料提交使用 POST/Redirect/GET,重复刷新不重复写入。
- Run 命令携带期望的 `lock_version` 或在服务内锁定记录。
- 工具调用使用 `(run_id, call_id)` 和幂等键防止重复记录。
- 人工确认使用 `(run_id, request_key)` 防止重复请求。
- 第一阶段不实现自动重试;失败结果保持终态。
- 外部调用开始和完成分别写入短事务,调用方可根据已有状态安全恢复记录。
## 8. 错误映射
| 领域错误 | 页面语义 | 外部 API 预留语义 |
| --- | --- | --- |
| 资源不存在或无权访问 | 404 页面 | 404 |
| 输入校验失败 | 表单错误 | 400 或 422,后续 API 设计确定 |
| 状态转换冲突 | 操作失败提示 | 409 |
| 重复或幂等冲突 | 操作失败提示 | 409 |
| SDK 配置缺失 | 功能不可用提示 | 503 |
| 外部服务失败 | 通用失败提示和关联编号 | 502 或 503,后续确定 |
表中外部 API 状态只作为未来语义预留,不代表第一阶段已经提供 JSON API。
## 9. 安全测试清单
- 登录失败信息不泄露账户存在性。
- `next` 参数不能跳转到站外地址。
- GET 退出请求不能改变 Session。
- 缺失或错误 CSRF 的写请求被拒绝。
- 用户 A 无法通过修改 URL 访问用户 B 的 Run。
- UUID 格式错误和不存在资源均安全处理。
- 表单和摘要输出经过 HTML 转义。
- 密码、Cookie、API Key 和完整敏感参数不出现在响应或日志。
- Admin 人工确认操作经过领域服务和权限检查。
## 10. 兼容与演进
- 页面 URL 使用命名空间和反向解析,避免模板硬编码路径。
- 第一阶段不承诺外部 API 兼容性。
- 后续新增 JSON API 时复用领域服务,不复用 HTML 视图作为接口层。
- 引入 DRF 或 OpenAPI 前必须确认调用方、认证方式、版本策略和错误模型。
- Celery 接入后通过同一 Run 命令服务记录状态,不改变页面查询契约。
## 11. 待确认项
- 页面表单错误是否统一使用 200 还是采用更严格的 4xx 状态,实施时按项目测试约定确定。
- 是否允许管理员在普通运行页面跨用户查询;当前设计仅允许 Admin。
- 第二阶段是否向普通用户开放人工确认处理页面。
- 是否存在未来外部调用方;确认前不创建 OpenAPI 文档。