阶段6:完成Issue226交接与最终门禁
补充交给Issue225的Header、tracking metadata和认证主体交接契约 新增阶段6验收记录并汇总TS、Rust、正负向及幂等回归结果 更新Issue226实施方案与分阶段计划为已完成并记录发布环境限制
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
- `#226 添加客户端特殊标识`:本方案实际实施范围
|
||||
- `#225 添加客户端埋点统计`:主站接收、落库和后台统计,本文只冻结交接契约,不在本次实施
|
||||
|
||||
状态:阶段 5 已完成,待阶段 6 实施<br>
|
||||
状态:阶段 6 已完成(客户端实现、#225 交接与最终门禁已收口)<br>
|
||||
本方案包含 #226 客户端代码修改,不包含 #225 主站接收、落库和后台统计代码
|
||||
|
||||
## 1. 一句话交付结果
|
||||
@@ -407,3 +407,37 @@ Rust 层:
|
||||
- OSS、签名 URL、Provider、搜索、loopback 和更新下载不带标记。
|
||||
- 客户端测试覆盖正向和负向边界。
|
||||
- 不修改 `#225` 所需的主站数据设计;`#225` 可直接读取 Header 并按本文约定写入 tracking metadata。
|
||||
|
||||
## 12. 阶段 6 实施记录与交接状态
|
||||
|
||||
更新时间:`2026-09-02`
|
||||
|
||||
阶段 6 已完成,`#226` 客户端侧可以交付评审;`#225` 不需要因客户端实现回改设计。固定交接材料如下:
|
||||
|
||||
- 请求 Header:`X-Genarrative-Client: agc`。
|
||||
- tracking metadata:复用现有 `metadata_json`,写入 `client: "agc"`;缺失时不写空字符串。
|
||||
- 主站记录实际收到的 method/path;不能只记录客户端账本中的 External v1 endpoint。
|
||||
- 登录账号态按真实用户维度记录;External API Key 态按 `ExternalApiPrincipal.owner_user_id` 记录,必要时保留 `key_id` 维度。
|
||||
- Header 只用于来源审计/统计,不参与鉴权、权限、计费或账号归属;不记录 token、API Key 明文或签名 URL。
|
||||
- `#225` 应同时覆盖账号态 `/api/auth/*`、`/api/profile/*`、`/api/assets/*`、`/api/editor/*`、`/api/runtime/*` 和 API Key 态 `/api/external/v1/*`。
|
||||
- Header 缺失、空值或未知值按未标记处理,不拒绝业务请求;客户端不需要为失败、重试或轮询请求更换标记。
|
||||
|
||||
最终门禁结果:
|
||||
|
||||
| 门禁 | 结果 |
|
||||
|---|---|
|
||||
| TS `clientHttp` 定向测试 | 通过,14 tests passed |
|
||||
| AGC TS 类型检查(含 skill-pack/config 检查) | 通过 |
|
||||
| Rust `http_client` factory 测试 | 通过,2 tests passed |
|
||||
| Rust OSS/签名 URL/Provider/搜索/loopback/更新下载负向测试 | 通过,`omits_agc_marker` 4 tests passed;loopback 认证边界 1 test passed |
|
||||
| Rust 账号态主站 mock 捕获 | 通过,1 test passed |
|
||||
| Rust External Key 态主站 mock 捕获 | 通过,1 test passed |
|
||||
| Rust 签名 URL 下载边界 | 通过,1 test passed |
|
||||
| Rust 提交响应丢失幂等回归 | 通过,1 test passed |
|
||||
| Rust fmt、编码、diff 空白检查 | 通过 |
|
||||
|
||||
本阶段未执行真实发布环境线上 smoke;账号态和 External Key 态证据来自本地 mock/custom `apiBaseUrl` fixture。真实发布环境 smoke 属于发布前或 `#225` 联调门禁,不改变本次 `#226` 客户端契约。
|
||||
|
||||
可直接粘贴到 `#225` 的交接评论:
|
||||
|
||||
> `#226` 客户端侧已完成并冻结交接契约:AGC 主站业务请求统一发送 `X-Genarrative-Client: agc`。账号态 `/api/auth/*`、`/api/profile/*`、`/api/assets/*`、`/api/editor/*`、`/api/runtime/*` 与 External API Key 态 `/api/external/v1/*` 均覆盖;OSS/签名下载、Provider、受控搜索、loopback、更新下载和外部网页请求不带该标记。主站可按实际 method/path 读取 Header,并在现有 tracking `metadata_json` 中写入 `client: "agc"`;Header 缺失/空值/未知值按未标记处理且不拒绝请求。登录态按真实用户维度记录,External Key 态按 `owner_user_id`(必要时 `key_id`)记录,不记录 token/API Key 明文或签名 URL。客户端正向、负向、账号态、External Key 态和幂等回归均已通过,`#225` 不需要让 `#226` 回改设计。`
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
- `#226 添加客户端特殊标识`:本计划全部实施范围
|
||||
- `#225 添加客户端埋点统计`:只接收交接契约,不在本计划实现
|
||||
|
||||
当前状态:阶段 5 已完成;阶段 6 尚未开始。阶段 0 的证据与验收记录见
|
||||
当前状态:阶段 6 已完成;阶段 0 的证据与验收记录见
|
||||
[【阶段验收】Issue226阶段0现状基线与契约冻结-2026-09-01.md](C:/projects/narrative/Genarrative/local-docs/【阶段验收】Issue226阶段0现状基线与契约冻结-2026-09-01.md)。
|
||||
|
||||
## 1. 交付目标
|
||||
@@ -375,6 +375,26 @@ tracking metadata:client = "agc"
|
||||
- `git diff --check`。
|
||||
- 检查 `git status --short`,确保没有构建产物、日志、凭据和无关文件。
|
||||
|
||||
### 10.4 阶段 6 实施记录
|
||||
|
||||
阶段 6 已完成,交给 `#225` 的固定材料已在
|
||||
[【实施方案】Issue226-AGC客户端主站请求统一标记-2026-09-01.md](C:/projects/narrative/Genarrative/local-docs/【实施方案】Issue226-AGC客户端主站请求统一标记-2026-09-01.md)
|
||||
第 12 节集中确认:Header 为 `X-Genarrative-Client: agc`,tracking metadata 使用 `client: "agc"`,主站按实际 method/path 和真实认证主体记录;缺失/空值/未知 Header 不拒绝请求。该交接不要求 `#226` 再回改客户端,也不要求本阶段实现 `#225` 的主站 tracking、数据库或后台代码。
|
||||
|
||||
最终门禁已通过:
|
||||
|
||||
- TS `clientHttp` 定向测试:14 tests passed。
|
||||
- AGC TS 类型检查:通过。
|
||||
- Rust `http_client` factory:2 tests passed。
|
||||
- Rust `omits_agc_marker`:4 tests passed;loopback 认证边界:1 test passed。
|
||||
- 账号态主站 mock 捕获:1 test passed。
|
||||
- External Key 态主站 mock 捕获:1 test passed。
|
||||
- 签名 URL 下载边界:1 test passed。
|
||||
- 提交响应丢失幂等回归:1 test passed。
|
||||
- Rust fmt、`npm run check:encoding`、`git diff --check`:通过。
|
||||
|
||||
发布环境说明:本阶段没有执行真实发布环境线上 smoke;账号态/External Key 态使用本地 mock 和自定义 `apiBaseUrl` fixture 验证。真实发布环境 smoke 留给发布前或 `#225` 联调门禁,不影响 `#226` 客户端实现完成判定。
|
||||
|
||||
## 11. 建议提交/评审节奏
|
||||
|
||||
为方便阶段验收,建议在同一个 `#226` PR 内按以下逻辑组织提交或至少按阶段分组:
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
# Issue #226 阶段 6:#225 交接与最终门禁验收记录
|
||||
|
||||
更新时间:`2026-09-02`
|
||||
实施范围:`#226 添加客户端特殊标识`
|
||||
交接范围:`#225 添加客户端埋点统计`
|
||||
执行结论:阶段 6 通过;#226 客户端实现、边界回归、交接材料和最终门禁已收口。未修改 #225 主站代码、数据库、OpenAPI 或后台实现。
|
||||
|
||||
## 1. 阶段边界
|
||||
|
||||
本阶段只完成:
|
||||
|
||||
1. 复核并固定交给 `#225` 的 Header、tracking metadata、认证主体和路径边界。
|
||||
2. 汇总阶段 1~5 的正向、负向和语义回归证据。
|
||||
3. 执行最终定向测试、编码/格式/空白检查和工作树检查。
|
||||
4. 更新实施方案与分阶段计划的完成状态。
|
||||
|
||||
本阶段明确不做:
|
||||
|
||||
- 不修改 `server-rs`、主站 tracking middleware、route tracking 或后台。
|
||||
- 不修改 SpacetimeDB `tracking_event` schema、migration、bindings 或索引。
|
||||
- 不修改 External v1 OpenAPI、DTO 或请求响应语义。
|
||||
- 不执行真实发布环境线上写入或埋点验证。
|
||||
|
||||
## 2. 当前仓库状态
|
||||
|
||||
阶段 6 开始时:
|
||||
|
||||
| 项目 | 结果 |
|
||||
|---|---|
|
||||
| 分支 | `feat/agc_call_header` |
|
||||
| HEAD | `8059bbcb5`(已合并最新 `origin/master`) |
|
||||
| 工作树 | 干净 |
|
||||
| `origin/master` | `4a2f5be6c`,同步 AGC 更新下载域名门禁 |
|
||||
|
||||
阶段 0~5 的提交保持不变,本阶段只补充交接/验收文档。
|
||||
|
||||
## 3. 给 #225 的固定交接契约
|
||||
|
||||
### 3.1 客户端请求标记
|
||||
|
||||
```http
|
||||
X-Genarrative-Client: agc
|
||||
```
|
||||
|
||||
- Header 名大小写不敏感;值精确为小写 `agc` 时识别为 AGC。
|
||||
- 缺失、空值或未知值按未标记处理,不拒绝请求,也不改变业务行为。
|
||||
- Header 只用于来源审计和统计,不参与鉴权、权限、计费或账号归属。
|
||||
- 不记录 access token、API Key 明文、签名 URL、项目绝对路径、用户隐私或客户端版本号。
|
||||
|
||||
### 3.2 tracking metadata
|
||||
|
||||
第一阶段复用现有 tracking `metadata_json`,固定 JSON key/value:
|
||||
|
||||
```json
|
||||
{
|
||||
"route": "/api/editor/images/generations",
|
||||
"method": "POST",
|
||||
"status": 202,
|
||||
"operation": "generateExternalEditorImage",
|
||||
"client": "agc"
|
||||
}
|
||||
```
|
||||
|
||||
约定:
|
||||
|
||||
- `client` key 固定;AGC 值固定为 `agc`。
|
||||
- Header 缺失时不写 `client` 空字符串。
|
||||
- 记录主站实际收到的 method/path,不只记录客户端账本中的 External v1 endpoint。
|
||||
- `/api/external/v1/*` 不能因为缺少完整 route spec 而漏记。
|
||||
|
||||
### 3.3 认证主体
|
||||
|
||||
- 登录账号态:沿用主站现有 access token 解析出的用户维度。
|
||||
- External API Key 态:使用 `ExternalApiPrincipal.owner_user_id`,必要时保留 `key_id` 维度。
|
||||
- Header 与认证主体独立处理;不能用 Header 代替认证,也不能从 `generationInputs.source` 推导客户端标记。
|
||||
|
||||
### 3.4 路由和边界
|
||||
|
||||
应识别的主站请求:
|
||||
|
||||
- 账号态 `/api/auth/*`、`/api/profile/*`、`/api/assets/*`、`/api/editor/*`、`/api/runtime/*`。
|
||||
- External API Key 态 `/api/external/v1/*`。
|
||||
- 生成提交、异步轮询、项目/素材/资源登记和 `/api/assets/read-url` 换签。
|
||||
|
||||
明确不应识别为 AGC 主站业务请求:
|
||||
|
||||
- OSS multipart 上传。
|
||||
- 签名 URL/OSS 媒体下载。
|
||||
- LLM/Codex Provider。
|
||||
- AGC 受控搜索。
|
||||
- loopback 工具桥。
|
||||
- 更新清单、更新包下载和任意外部网页请求。
|
||||
|
||||
## 4. 最终门禁结果
|
||||
|
||||
| 验收项 | 命令/证据 | 结果 |
|
||||
|---|---|---|
|
||||
| TS 统一出口正向测试 | `npm exec vitest run apps/ai-game-creator-shell/tests/clientHttp.test.ts` | 通过,14 tests passed |
|
||||
| AGC TS 类型和配置检查 | `npm run ai-game-creator-shell:typecheck` | 通过;skill-pack/config 检查通过 |
|
||||
| Rust 主站 Client factory | `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml http_client -- --nocapture` | 通过,2 tests passed |
|
||||
| 第三方请求负向矩阵 | `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml omits_agc_marker -- --nocapture` | 通过,4 tests passed |
|
||||
| loopback 认证/请求边界 | `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml loopback_proxy_strips_false_codex_limit_headers_and_requires_bearer -- --nocapture` | 通过,1 test passed |
|
||||
| 账号态主站请求捕获 | `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml background_agent_runtime_can_generate_platform_art_asset -- --nocapture` | 通过,1 test passed |
|
||||
| External Key 态和自定义 origin | `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml sync_canvas_project_assets_with_developer_key_uses_external_route_and_marker -- --nocapture` | 通过,1 test passed |
|
||||
| `read-url` 与签名下载边界 | `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml sync_canvas_project_assets_downloads_external_resources -- --nocapture` | 通过,1 test passed |
|
||||
| 结果未知/幂等语义 | `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml generation_submit_response_loss_is_not_retried -- --nocapture` | 通过,1 test passed |
|
||||
| Rust 格式 | `cargo fmt --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml -- --check` | 通过 |
|
||||
| 中文编码 | `npm run check:encoding` | 通过,5653 个文件 |
|
||||
| Diff 空白 | `git diff --check` | 通过 |
|
||||
|
||||
Rust 测试输出包含仓库既有的 unused/dead-code warning;本任务相关测试均无 error 或 failure。
|
||||
|
||||
## 5. 发布环境限制与后续交接
|
||||
|
||||
本阶段没有执行真实发布环境线上 smoke。账号态和 External Key 态的路径、Header、认证/幂等语义来自本地 mock/custom `apiBaseUrl` fixture;OSS/签名 URL/Provider/搜索/loopback/更新下载边界来自本地请求捕获。发布前或 `#225` 联调时,应由主站侧补做真实环境 Header 接收、tracking metadata 写入和后台查询验证,不要求客户端回改本次设计。
|
||||
|
||||
## 6. 可直接粘贴到 #225 的评论
|
||||
|
||||
> `#226` 客户端侧已完成并冻结交接契约:AGC 主站业务请求统一发送 `X-Genarrative-Client: agc`。账号态 `/api/auth/*`、`/api/profile/*`、`/api/assets/*`、`/api/editor/*`、`/api/runtime/*` 与 External API Key 态 `/api/external/v1/*` 均覆盖;OSS/签名下载、Provider、受控搜索、loopback、更新下载和外部网页请求不带该标记。主站可按实际 method/path 读取 Header,并在现有 tracking `metadata_json` 中写入 `client: "agc"`;Header 缺失/空值/未知值按未标记处理且不拒绝请求。登录态按真实用户维度记录,External Key 态按 `owner_user_id`(必要时 `key_id`)记录,不记录 token/API Key 明文或签名 URL。客户端正向、负向、账号态、External Key 态和幂等回归均已通过,`#225` 不需要让 `#226` 回改设计。`
|
||||
Reference in New Issue
Block a user