Files
Genarrative/docs/【后端架构】外部OpenAPI与APIKey接入方案-2026-06-19.md
T
lhk229 aecabdacfd 新抠图算法 (#85)
Co-authored-by: 段舒康 <kdletters@qq.com>
Reviewed-on: https://git.genarrative.world/git/GenarrativeAI/Genarrative/pulls/85
Co-authored-by: Linghong <ink29535@proton.me>
Co-committed-by: Linghong <ink29535@proton.me>
2026-07-16 18:33:06 +08:00

10 KiB
Raw Blame History

外部 OpenAPI 与 API Key 接入方案

背景

外部调用方需要通过稳定 HTTP 契约使用图片画布编辑器内的素材生成、编辑和管理能力,并能创建项目、保存画板布局和管理账号级素材库。该能力必须走 server-rs + Axum + SpacetimeDB 正式链路,不能把 API Key、画板状态、素材状态或生成结果放到前端临时状态中。

v1 范围

本期新增外部 API 命名空间:

/api/external/v1

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/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。可选传入 projectIdassetFolderId,生成后按站内编辑器规则写入 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。

角色图生成、图标 spritesheet 和 UI 素材提取的 2xx 成功响应可携带可选结构化 warning { code, reason },当前稳定 codepostprocess-failed-source-preserved。provider 原图已保存但透明背景处理最终失败时,接口返回原图,不返回不存在的透明处理图,图标和 UI 也不继续拆分;有 projectId + canvasCompletion 时由原图完成画布写回,无画布上下文时只返回原图及实际存在的资源 / 素材快照。调用方应展示 warning,但不得把任务改判为失败。该降级只覆盖透明背景处理的最终失败,phase 上报、原图或透明处理图持久化、画布写回失败仍返回错误。图标 / UI 已成功生成透明图、只有自动拆分失败时继续使用既有 sliceWarning;服务端保证通用 warningsliceWarning 互斥,防御性客户端若收到异常双字段响应仍以通用 warning 为准。

管理 API Key 的登录态接口保留在站内个人中心链路,但不写入外部 OpenAPI JSON

GET    /api/profile/api-keys
POST   /api/profile/api-keys
DELETE /api/profile/api-keys/{keyId}

前端入口位于登录后个人中心的 我的 → 开发者 API Key,用于查看当前 Key、创建新 Key、复制一次性明文和撤销已创建 Key。外部 OpenAPI 只描述 /api/external/v1 下可由 API Key 调用的接口,不混入登录态 API Key 管理接口。

鉴权

外部调用使用 Bearer API Key

Authorization: Bearer tnr_sk_xxx

规则:

  • API Key 归属于 owner_user_id,外部接口只能访问该账号自己的项目、画布和生成素材。
  • 明文 Key 只在创建接口返回一次,后端只保存 key_hashkey_prefix
  • API Key 被撤销后立即不可再用于外部接口。
  • 外部 API 鉴权不复用登录态 JWT,不检查 refresh session;它是独立开发者凭据。
  • OpenAPI JSON 公共可读,不需要鉴权。

数据模型

新增 SpacetimeDB private 表:

external_api_key

字段:

  • key_id:主键。
  • owner_user_id:所属账号。
  • name:用户可识别名称。
  • key_prefix:前缀片段,用于列表展示和排障。
  • key_hash:完整 Key 的 SHA-256 十六进制摘要,唯一。
  • scopes_json:作用域 JSONv1 固定包含 editor:projecteditor:canvaseditor:image-generateeditor:asset。其中 editor:image-generate 覆盖图片生成、重绘、规范图、宣发图、图标拆分、UI 素材拆分、角色动画、视频、音效和音乐生成。
  • created_at / last_used_at / revoked_at / updated_at

SpacetimeDB procedure

  • create_external_api_key_and_return
  • list_external_api_keys_and_return
  • revoke_external_api_key_and_return
  • authenticate_external_api_key_and_return

素材生成与落库

外部生成接口复用站内编辑器已有 handler 和 DTO,不维护第二套生成语义:

  • 图片生成 / 重绘 / 规范图 / 宣发图 / UI 设计图复用 /api/editor/images/generations/api/editor/images/edits 的校验、模型归一、计费和持久化规则。
  • 图标 spritesheet 和 UI 设计图素材提取复用站内拆分逻辑,生成图集后按连通域切片,并把图集与切片都按请求写入项目资源和素材库。
  • 角色动画、视频、音效和背景音乐复用站内编辑器生成链路;请求携带 assetFolderId 时按站内规则写入素材库,音频类外部调用使用 API Key 所属账号作为 asset owner。
  • API Key 管理接口仍只属于登录态个人中心,不进入外部 OpenAPI JSON。

素材外部生成成功后,后端拿到素材后:

  1. 通过 OSS / asset object adapter 持久化媒体文件。
  2. 写入 editor_asset,让生成素材进入账号级素材库。
  3. 如果请求带 projectId,写入 editor_project_resource
  4. 返回图片读取地址、素材 ID、资源 ID、尺寸、prompt、model、provider 和 taskId。

如果请求未带 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 固定落在:

docs/openapi/genarrative-external-v1.openapi.json

服务端 GET /api/external/v1/openapi.json 使用同一份 JSON,通过 include_str! 导出,避免运行时生成结果与仓库文档漂移。

验收

  • API Key 创建只返回一次明文,列表不返回明文。
  • 撤销后的 API Key 调用外部接口返回 401
  • 外部图片生成、重绘、图标拆分、UI 素材拆分、视频、音效和音乐生成成功后,生成结果按请求同时出现在画布资源和账号级素材库。
  • 角色图、图标 spritesheet 和 UI 素材提取的 2xx 成功响应允许携带 EditorGenerationWarning;provider 原图保留降级与自动拆分降级必须保持成功状态,并分别使用通用 warning 与兼容 sliceWarning 表达。
  • 外部视频、角色动画、音效和音乐接口使用站内编辑器相同的请求校验、模型限制和价格校验。
  • OpenAPI JSON 能被 serde_json 解析,且 security scheme 为 Bearer API Key。
  • OpenAPI JSON 不包含 /api/profile/api-keysUserAccessToken 或 API Key 管理 schema。
  • 外部素材库接口覆盖当前已有素材操作:直传凭证、素材对象确认、签名读取、读取素材库、创建 / 更新 / 删除文件夹、创建 / 更新 / 删除素材、创建项目画布资源。
  • 外部项目接口覆盖当前已有项目管理操作:项目列表、最近项目、创建、读取、重命名、删除和默认画布保存。
  • 外部素材生成接口覆盖当前已有编辑器素材操作:生图、重绘 / 调整、规范图生成、宣发素材生成、图标素材生成与拆分、UI 设计图生成与拆分、角色动画、视频、音效和背景音乐。
  • 修改 SpacetimeDB schema 后运行 npm run spacetime:generatenpm run check:spacetime-schema