补齐外部OpenAPI编辑器素材能力

移除外部OpenAPI中的API Key管理接口暴露
补齐编辑器项目列表、最近项目、重命名和删除外部接口
补齐素材直传凭证、素材对象确认和签名读取外部接口
复用站内编辑器生成、素材库和项目资源链路并按API Key账号归属
更新外部OpenAPI、后端契约和项目共享记忆文档
This commit is contained in:
2026-06-21 13:40:09 +08:00
parent 98545d74d1
commit d8dd2f1857
16 changed files with 4075 additions and 583 deletions
File diff suppressed because it is too large Load Diff
@@ -19,7 +19,7 @@
## 2026-06-19 外部 OpenAPI 与 API Key 管理走 server-rs 正式链路
- 背景:外部调用方需要稳定调用图片画布项目创建、画布布局保存和编辑器美术生图能力,同时需要可撤销的开发者凭据,不能依赖前端临时状态或人工分发密钥。
- 决策:外部 API 固定放在 `/api/external/v1` 命名空间,v1 暴露项目创建 / 读取、默认画布保存、编辑器美术生图和 `/api/external/v1/openapi.json`。API Key 管理走登录态 `/api/profile/api-keys`,外部调用使用 `Authorization: Bearer tnr_sk_xxx`;后端只保存 `key_hash` 和 `key_prefix`,明文只在创建响应返回一次。外部 API 鉴权、项目 / 画布 / 素材写回全部经 `api-server -> spacetime-client -> spacetime-module`,生成图片成功后同时写入账号级 `editor_asset`,带 `projectId` 时写入 `editor_project_resource`。
- 决策:外部 API 固定放在 `/api/external/v1` 命名空间,v1 暴露素材直传凭证 / asset object 确认 / 签名读取、项目列表 / 最近 / 创建 / 读取 / 重命名 / 删除、默认画布保存、账号级素材库、项目资源记录、编辑器图片 / 视频 / 音频生成和 `/api/external/v1/openapi.json`。API Key 管理走登录态 `/api/profile/api-keys`,外部调用使用 `Authorization: Bearer tnr_sk_xxx`;后端只保存 `key_hash` 和 `key_prefix`,明文只在创建响应返回一次。外部 API 鉴权、项目 / 画布 / 素材写回全部经 `api-server -> spacetime-client -> spacetime-module`,生成素材成功后按请求写入账号级 `editor_asset`,带 `projectId` 时写入 `editor_project_resource`;外部确认 asset object 时 owner 固定为 API Key 所属账号。API Key 管理接口不进入外部 OpenAPI JSON。
- 影响范围:`server-rs/crates/api-server/src/external_*`、`server-rs/crates/api-server/src/modules/external_api.rs`、`server-rs/crates/spacetime-module/src/external_api_key_storage.rs`、`server-rs/crates/spacetime-client/src/external_api_key.rs`、`docs/openapi/genarrative-external-v1.openapi.json` 和后端数据契约文档。
- 验证方式:`cargo test -p api-server external_api --manifest-path server-rs/Cargo.toml`、`cargo test -p api-server external_editor_api --manifest-path server-rs/Cargo.toml`、`cargo check -p api-server --manifest-path server-rs/Cargo.toml`、`npm run check:spacetime-schema`、`npm run check:encoding`、`git diff --check`。
- 关联文档:`docs/【后端架构】外部OpenAPI与APIKey接入方案-2026-06-19.md`。
@@ -59,6 +59,7 @@ npm run check:server-rs-ddd
- 个人中心:`/api/profile/*`,包括钱包流水、任务、领奖、充值、反馈、邀请和兑换等账号侧能力。
- 平台基础能力:`/api/llm/*`、`/api/speech/volcengine/*`,只保留通用 LLM 和语音代理。
- 资产基础能力:`/api/assets/direct-upload-tickets`、`/api/assets/sts-upload-credentials`、`/api/assets/objects/*`、`/api/assets/read-*`,负责直传、确认、绑定和读取。
- 外部 OpenAPI:`/api/external/v1/openapi.json`、`/api/external/v1/assets/direct-upload-tickets`、`/api/external/v1/assets/objects/confirm`、`/api/external/v1/assets/read-url`、`/api/external/v1/editor/*`,使用 Bearer API Key 鉴权;API Key 管理仍在登录态 `/api/profile/api-keys`,不进入外部 OpenAPI JSON。
- 创作 / 游玩支撑能力:`/api/creation-entry/config`、`/api/ai/tasks*`、`/api/runtime/chat/*`、`/api/runtime/settings`、`/api/runtime/save/snapshot`、`/api/profile/browse-history`、`/api/profile/save-archives*`、`/api/profile/play-stats`、`/api/assets/history`、`/api/assets/character-visual/*`、`/api/assets/character-animation/*`、`/api/assets/character-workflow-cache*`、`/api/assets/hyper3d/*`、`/api/runtime/custom-world/asset-studio/*`、`/api/editor/projects*`。
- 后台入口配置:`/admin/api/creation-entry/config`、`/admin/api/creation-entry/config/banners` 和 `/admin/api/creation-entry/config/interactions`。
- 自定义世界 / RPG:`/api/runtime/custom-world*`、`/api/story/*`、`/api/runtime/chat/*`。
@@ -433,7 +434,7 @@ npm run check:server-rs-ddd
- Rust 结构体:`ExternalApiKey`
- 源码:`server-rs/crates/spacetime-module/src/external_api_key_storage.rs`
- 说明:外部 OpenAPI 调用使用的账号级 API Key 凭据表,只保存 key prefix、SHA-256 hash、作用域、撤销状态和使用时间;明文 Key 只在 `/api/profile/api-keys` 创建接口返回一次,不进入 SpacetimeDB。
- 说明:外部 OpenAPI 调用使用的账号级 API Key 凭据表,只保存 key prefix、SHA-256 hash、作用域、撤销状态和使用时间;明文 Key 只在 `/api/profile/api-keys` 创建接口返回一次,不进入 SpacetimeDB,且 API Key 管理接口不写入外部 OpenAPI JSON。v1 默认作用域为 `editor:project`、`editor:canvas`、`editor:image-generate`、`editor:asset`;其中 `editor:project` 覆盖项目列表、最近项目、创建、读取、重命名和删除,`editor:canvas` 覆盖默认画布布局保存,`editor:image-generate` 覆盖编辑器现有图片生成、重绘 / 调整、规范图、宣发素材、图标 spritesheet 生成 / 拆分、UI 设计图素材拆分、角色动画、视频、音效和背景音乐生成,`editor:asset` 覆盖素材直传凭证、素材对象确认、签名读取、账号级素材库和项目画布资源记录操作。
- 索引:`by_external_api_key_owner_user_id` 用于登录态 API Key 列表;`key_hash` 唯一索引用于外部 API 鉴权。
### `editor_project`
@@ -2,7 +2,7 @@
## 背景
外部调用方需要通过稳定 HTTP 契约使用图片画布编辑器内的美术生图能力,并能创建项目、保存画板布局。该能力必须走 `server-rs + Axum + SpacetimeDB` 正式链路,不能把 API Key、画板状态或生成结果放到前端临时状态中。
外部调用方需要通过稳定 HTTP 契约使用图片画布编辑器内的素材生成、编辑和管理能力,并能创建项目、保存画板布局和管理账号级素材库。该能力必须走 `server-rs + Axum + SpacetimeDB` 正式链路,不能把 API Key、画板状态、素材状态或生成结果放到前端临时状态中。
## v1 范围
@@ -14,13 +14,35 @@
v1 只开放以下能力:
- `POST /api/external/v1/assets/direct-upload-tickets`:创建素材直传 OSS 凭证。
- `POST /api/external/v1/assets/objects/confirm`:确认已上传素材对象,`ownerUserId` 固定为 API Key 所属账号。
- `GET /api/external/v1/assets/read-url`:获取私有素材读取签名 URL。
- `GET /api/external/v1/editor/projects`:列出当前 API Key 所属账号的图片画布项目。
- `POST /api/external/v1/editor/projects`:创建图片画布项目。
- `GET /api/external/v1/editor/projects/recent`:读取当前账号最近图片画布项目。
- `GET /api/external/v1/editor/projects/{projectId}`:读取项目与默认画布。
- `PATCH /api/external/v1/editor/projects/{projectId}/metadata`:更新图片画布项目标题。
- `DELETE /api/external/v1/editor/projects/{projectId}`:删除图片画布项目,并级联清理默认画布和项目资源元数据。
- `PATCH /api/external/v1/editor/projects/{projectId}/canvas`:保存默认画布的 viewport 和 layers。
- `POST /api/external/v1/editor/images/generations`:调用编辑器美术生图能力;可选传入 `projectId`,生成后自动写入 `editor_project_resource`,同时写入账号级 `editor_asset` 素材库。
- `POST /api/external/v1/editor/projects/{projectId}/resources`:创建项目画布资源记录。
- `GET /api/external/v1/editor/assets/library`:读取账号级编辑器素材库。
- `POST /api/external/v1/editor/assets/folders`:创建素材文件夹。
- `PATCH /api/external/v1/editor/assets/folders/{folderId}`:更新素材文件夹名称或折叠状态。
- `DELETE /api/external/v1/editor/assets/folders/{folderId}`:删除素材文件夹并返回最新素材库。
- `POST /api/external/v1/editor/assets`:创建素材记录。
- `PATCH /api/external/v1/editor/assets/{assetId}`:更新素材名称或所在文件夹。
- `DELETE /api/external/v1/editor/assets/{assetId}`:删除素材记录。
- `POST /api/external/v1/editor/images/generations`:调用编辑器图片素材生成能力;通过 `kind` 支持普通图、规范图 `spec`、角色图 `character`、快速编辑参考图 `quick-edit`、UI 设计图 `ui-design` 和宣发素材 `publication-material`。可选传入 `projectId` 和 `assetFolderId`,生成后按站内编辑器规则写入 `editor_project_resource` 和账号级 `editor_asset`。
- `POST /api/external/v1/editor/images/edits`:重绘 / 调整已有图片,结果可写入项目资源和素材库。
- `POST /api/external/v1/editor/icon-spritesheets/generations`:按规范图生成图标 spritesheet,并拆分为独立图标素材。
- `POST /api/external/v1/editor/ui-designs/assets/extractions`:从 UI 设计图中提取 / 拆分素材。
- `POST /api/external/v1/editor/character-animations/generations`:基于角色图片生成角色动画预览和帧序列。
- `POST /api/external/v1/editor/videos/generations`:生成编辑器视频素材,支持现有 Seedance / Kling / Veo 模型参数和参考媒体限制。
- `POST /api/external/v1/editor/audios/sound-effects/generations`:生成编辑器音效素材。
- `POST /api/external/v1/editor/audios/background-music/generations`:生成编辑器背景音乐素材。
- `GET /api/external/v1/openapi.json`:导出本版本 OpenAPI 3.1 JSON。
管理 API Key 的登录态接口:
管理 API Key 的登录态接口保留在站内个人中心链路,但不写入外部 OpenAPI JSON:
```text
GET /api/profile/api-keys
@@ -28,7 +50,7 @@ POST /api/profile/api-keys
DELETE /api/profile/api-keys/{keyId}
```
前端入口位于登录后个人中心的 `我的 → 开发者 API Key`,用于查看当前 Key、创建新 Key、复制一次性明文和撤销已创建 Key。
前端入口位于登录后个人中心的 `我的 → 开发者 API Key`,用于查看当前 Key、创建新 Key、复制一次性明文和撤销已创建 Key。外部 OpenAPI 只描述 `/api/external/v1` 下可由 API Key 调用的接口,不混入登录态 API Key 管理接口。
## 鉴权
@@ -61,7 +83,7 @@ external_api_key
- `name`:用户可识别名称。
- `key_prefix`:前缀片段,用于列表展示和排障。
- `key_hash`:完整 Key 的 SHA-256 十六进制摘要,唯一。
- `scopes_json`:作用域 JSON,v1 固定包含 `editor:project`、`editor:canvas`、`editor:image-generate`。
- `scopes_json`:作用域 JSON,v1 固定包含 `editor:project`、`editor:canvas`、`editor:image-generate`、`editor:asset`。其中 `editor:image-generate` 覆盖图片生成、重绘、规范图、宣发图、图标拆分、UI 素材拆分、角色动画、视频、音效和音乐生成。
- `created_at` / `last_used_at` / `revoked_at` / `updated_at`。
SpacetimeDB procedure:
@@ -71,9 +93,16 @@ SpacetimeDB procedure:
- `revoke_external_api_key_and_return`
- `authenticate_external_api_key_and_return`
## 生成图落库
## 素材生成与落库
外部生图接口复用编辑器内 `VectorEngine` / `gpt-image-2` 生成链路,后端拿到图片后:
外部生成接口复用站内编辑器已有 handler 和 DTO,不维护第二套生成语义:
- 图片生成 / 重绘 / 规范图 / 宣发图 / UI 设计图复用 `/api/editor/images/generations` 与 `/api/editor/images/edits` 的校验、模型归一、计费和持久化规则。
- 图标 spritesheet 和 UI 设计图素材提取复用站内拆分逻辑,生成图集后按连通域切片,并把图集与切片都按请求写入项目资源和素材库。
- 角色动画、视频、音效和背景音乐复用站内编辑器生成链路;音频类外部调用使用 API Key 所属账号作为 asset owner。
- API Key 管理接口仍只属于登录态个人中心,不进入外部 OpenAPI JSON。
图片类外部生成成功后,后端拿到素材后:
1. 通过 OSS / asset object adapter 持久化图片。
2. 写入 `editor_asset`,让生成图进入账号级素材库。
@@ -82,6 +111,17 @@ SpacetimeDB procedure:
如果请求未带 `projectId`,只生成并写入素材库;调用方可随后创建项目或自行保存画板布局。
## 素材与项目资源操作
外部素材操作复用站内图片画布素材库和项目资源的后端事实源:
- 外部上传素材时先调用 `POST /api/external/v1/assets/direct-upload-tickets` 获取 OSS 表单直传参数,上传完成后调用 `POST /api/external/v1/assets/objects/confirm` 写入 `asset_object`,再用 `assetObjectId` / `objectKey` 创建账号级素材或项目资源记录。
- 外部读取私有 generated / uploaded 素材预览时调用 `GET /api/external/v1/assets/read-url` 获取短期签名 URL;不开放浏览器 STS 写权限。
- 素材库读取、文件夹创建 / 更新 / 删除、素材创建 / 更新 / 删除、项目画布资源创建全部通过 `api-server -> spacetime-client -> spacetime-module`。
- 所有外部素材接口使用 API Key 所属的 `owner_user_id`,不能由请求体传入 owner。
- 素材库仍是账号级事实源,不归属于单个项目;项目画布内资源继续使用 `editor_project_resource`。
- 素材创建和项目资源创建接口只保存记录和元数据;图片二进制上传、签名读取和生成图持久化继续复用已有资产 / 生成链路。
## OpenAPI 导出
OpenAPI 3.1 JSON 固定落在:
@@ -96,6 +136,11 @@ docs/openapi/genarrative-external-v1.openapi.json
- API Key 创建只返回一次明文,列表不返回明文。
- 撤销后的 API Key 调用外部接口返回 `401`。
- 外部生图成功后,生成结果同时出现在画布资源和账号级素材库。
- 外部图片生成、重绘、图标拆分和 UI 素材拆分成功后,生成结果按请求同时出现在画布资源和账号级素材库。
- 外部视频、角色动画、音效和音乐接口使用站内编辑器相同的请求校验、模型限制和价格校验。
- OpenAPI JSON 能被 `serde_json` 解析,且 security scheme 为 Bearer API Key。
- OpenAPI JSON 不包含 `/api/profile/api-keys`、`UserAccessToken` 或 API Key 管理 schema。
- 外部素材库接口覆盖当前已有素材操作:直传凭证、素材对象确认、签名读取、读取素材库、创建 / 更新 / 删除文件夹、创建 / 更新 / 删除素材、创建项目画布资源。
- 外部项目接口覆盖当前已有项目管理操作:项目列表、最近项目、创建、读取、重命名、删除和默认画布保存。
- 外部素材生成接口覆盖当前已有编辑器素材操作:生图、重绘 / 调整、规范图生成、宣发素材生成、图标素材生成与拆分、UI 设计图生成与拆分、角色动画、视频、音效和背景音乐。
- 修改 SpacetimeDB schema 后运行 `npm run spacetime:generate` 与 `npm run check:spacetime-schema`。