コンテンツにスキップ

AI Internal API (wf2des-api) — I/O 定義

このページは apps/internal-api/(guinness-ai-v2)内の wf2des-api ルートグループの 公式 I/O 契約 です。これは Figma プラグイン(セッション発行トークン)と バックエンド / MCP(共有サービストークン)が消費する VPC 内部 HTTP データプレーンです。エンドポイント、フィールド、enum 値、ステータスコード、path/query パラメータ、エラー形状のいかなる変更も、実装の前にここへ — そして同じ internal-api アプリを共有する姉妹ドキュメント AI Read API (mcp-api) I/O 定義 へ — 反映しなければなりません。

契約の権威。 リードルートが返し、ライトルートが変更するのは、AI WF2Des ワーカー が管轄する design_generation_result ドキュメントおよび project_figma_file コレクションのブロックです。フィールドの形状 はそのワーカーの契約で定義されます。このページはそれらに対する アクセス契約 です。返却または書き込みされるブロックの形状がそちらで変わったら、このページもそれに追随します。


概要

wf2des-api はプラグインが AI プレーンに入るための唯一の入口です。DocumentDB ドキュメントと S3 アーティファクトを presign / 読み込みし、プラグインの detail-first 書き込みを受け付けます — プラグインは detail サブドキュメントをまずここに書き、その後 wf2des PostgreSQL 行を反転する対応の バックエンド フラグエンドポイントを呼び出します。wf2des-api はそれ自身では決して PG 反転を行いません。

flowchart LR
  PLUGIN["Figma plugin<br/>(session token<br/>{org_id, project_id, exp})"]
  BE["Backend / MCP<br/>(X-AI-Service-Token)"]
  API["wf2des-api<br/>(internal-api app, VPC internal)<br/>/internal/wf2des/* · /internal/projects/*"]
  DDB[("DocumentDB guinness_v2<br/>design_generation_result ·<br/>project_figma_file")]
  S3[("S3<br/>result / parse artifacts")]

  PLUGIN -->|"read: result / parse / figma-files<br/>write: reject / placement / feedback / figma-files"| API
  BE -->|"read only (X-AI-Service-Token)"| API
  API -->|"find_one / update sub-doc block"| DDB
  API -->|"presign / proxy artifact"| S3
  API -.->|"NEVER"| PG[("PostgreSQL")]
  API -.->|"NEVER"| SQS[("SQS")]
  PLUGIN -->|"detail first, flag last:<br/>after a write, call the BACKEND flag endpoint"| BE
項目 値
ルートグループ wf2des-api — internal-api アプリ内の /internal/wf2des/* + /internal/projects/*(Lambda Function URL / private HTTP integration、VPC 内部のみ)
呼び出し元 Figma プラグイン(セッショントークン、read + write、プロジェクトスコープ)· バックエンド / MCP(共有 X-AI-Service-Token、read のみ)
読み込み DocumentDB design_generation_result、project_figma_file + S3(result / spec / parse アーティファクト)
書き込み DocumentDB サブドキュメントブロック(parse.rejected、placement、feedback)+ project_figma_file ドキュメント。S3 書き込みなし — メディア/アーティファクトはワーカーが生成し、この API は presign / プロキシするだけ
RDB アクセス なし — wf2des-api は決して PostgreSQL に接続しません。あらゆる wf2des 行のフラグ反転は、detail 書き込みの後にプラグインが呼び出す 別個の バックエンドエンドポイントです
キューアクセス なし — wf2des-api は決して SQS を送信しません。これは同期的なデータプレーンであり、ジョブプロデューサではありません
テナンシー あらゆるルートが org/project スコープ。あらゆる読み込みと書き込みが organization_id + project_id でフィルタリングされます

プラットフォームの厳格ルール。 wf2des-api は DocumentDB + S3 のみ に触れます — PostgreSQL には決して触れず、SQS にも決して触れません。純粋なデータプレーンサーフェスです。wf2des PostgreSQL 行はバックエンドのみが進めます(ai-status Webhook ハンドラと confirm / placement / feedback / placement エンドポイント)。AI 管轄の wf2des-events SQS キューはバックエンドの送信専用権限によってのみ供給されます。wf2des-api はそのいずれにも関与しません。


ルートサマリー

# ルート 種別 認証(最小) DocDB / S3 効果
1 GET /internal/wf2des/{wf2des_id}/result read セッショントークン または X-AI-Service-Token design_generation_result.spec(スピル時は artifact_urls.spec を presign)
2 GET /internal/wf2des/{wf2des_id}/parse read セッショントークン または X-AI-Service-Token design_generation_result.parse + イミュータブルな parse.json を presign
3 GET /internal/projects/{project_id}/figma-files read セッショントークン または X-AI-Service-Token project_figma_file.find(プロジェクトスコープ)
4 POST /internal/wf2des/{wf2des_id}/reject write セッショントークン のみ design_generation_result.parse.rejected を書き込む
5 POST /internal/wf2des/{wf2des_id}/placement write セッショントークン のみ design_generation_result.placement を書き込む
6 POST /internal/wf2des/{wf2des_id}/feedback write セッショントークン のみ design_generation_result.feedback を書き込む
7 POST / PUT /internal/projects/{project_id}/figma-files write セッショントークン のみ project_figma_file ドキュメントを upsert — UNIQUE(organization_id, project_id, figma_file_key)

認証の分岐。 リードルートはプラグインセッショントークン または 共有 X-AI-Service-Token(バックエンド / MCP 解決)のいずれかを受け付けます。ライトルートはプラグインセッショントークン のみ を受け付けます — バックエンド/MCP のサービストークンは read スコープであり、書き込んではなりません。認証 を参照。

Detail-first(ライトルート 4〜6)。 プラグインは detail サブドキュメントをまずここに書き、その後 wf2des PG 行を反転する対応の バックエンド フラグエンドポイントを呼び出します — detail が先、flag が後。ルート 7 は異なります: これはバックエンドのフラグパートナーを持たない wf2des-api への 直接 書き込みです(project_figma_file は DocumentDB コレクションであって PG フラグサーフェスではありません)。


リードルート

1. GET /internal/wf2des/{wf2des_id}/result

design_generation_result の DesignSpec — assemble フェーズが書き込んだ spec ブロック — を返します。プラグインはこの spec からネイティブ Figma ノードをマテリアライズします。

プロパティ 値
Method / Path GET /internal/wf2des/{wf2des_id}/result
認証 セッショントークン または X-AI-Service-Token(read)
Path params wf2des_id — 実行 id = wf2des PG 行 id(design_generation_result._id)
Query params なし
Request body なし
DocDB read design_generation_result.find_one({_id: wf2des_id, organization_id, project_id}) → spec ブロック
S3 効果 spec がスピルした場合(spec > ~1MB)、spec はインラインに存在せず artifact_urls.spec に置かれる。API はその S3 オブジェクトを presign し、ドキュメントと共に URL を返す
PG / SQS なし
GET /internal/wf2des/8f14e4.../result HTTP/1.1
Authorization: Bearer <plugin-session-token>

Response body — DesignSpec(spec ブロック。形状は ワーカー契約 の通り。parse_confirmed はミラー。5 つのノードタイプ layout_frame / instance / compose / text / unmatched):

{
  "ok": true,
  "data": {
    "wf2des_id": "8f14e4...",
    "spec": {
      "spec_version": "…",
      "parse_confirmed": true,
      "style_bindings": { "token/name": "figma-style-or-variable-id" },
      "root": { "…": "layout_frame / instance / compose / text / unmatched tree" }
    },
    "confidence": { "min": 0.71, "avg": 0.88, "flag_count": 3, "formula_version": "cf@0.2" },
    "artifact_urls": {
      "result": "s3://…-result.json",
      "spec": "https://…presigned…-spec.json"   // spec が S3 にスピルした場合にのみ存在(presign 済み)
    }
  },
  "error": null
}

spec スピル時、data.spec はインラインで省略されることがあり、data.artifact_urls.spec がプラグインの辿る presign 済み URL を運びます。結果アーティファクトはこの presign 経路(またはバックエンド自身のロール)を介してのみ読み込み可能です。

2. GET /internal/wf2des/{wf2des_id}/parse

結果ドキュメントの parse ブロックとイミュータブルな parse.json アーティファクト — awaiting_confirm の プレビュー サーフェス — を返します。プラグインはデザイナーが confirm または reject する前に、これから roles / intent / memo influences をプレビューします。

プロパティ 値
Method / Path GET /internal/wf2des/{wf2des_id}/parse
認証 セッショントークン または X-AI-Service-Token(read)
Path params wf2des_id — 実行 id(design_generation_result._id)
Query params なし
Request body なし
DocDB read design_generation_result.find_one({_id, organization_id, project_id}) → parse ブロック + artifact_urls.parse
S3 効果 イミュータブルな parse.json(artifact_urls.parse)を presign する — この実行が使った正式な parse。プレビューは この アーティファクトを読み、上書き可能な wireframe キャッシュドキュメントは決して読まない
PG / SQS なし

Response body — parse ブロック + presign 済みアーティファクトポインタ:

{
  "ok": true,
  "data": {
    "wf2des_id": "8f14e4...",
    "parse": {
      "confirmed": false,
      "confirmed_by": null,
      "confirmed_at": null,
      "rejected": null,                       // reject が書き込まれると構造化 {reason_code, note} になる(ルート 4)
      "memo_influences": [
        { "memo_node_id": "…", "text": "…" }  // TEXT スナップショット済み — wireframe 再 parse を生き延びる
      ]
    },
    "artifact_urls": {
      "parse": "https://…presigned…-parse.json"  // 使用されたイミュータブルな完全 WFNode ツリー + memo(roles / intent)
    }
  },
  "error": null
}

プラグインは presign 済みの parse.json を取得し、プレビュー用に完全な parse 済み WFNode ツリー(roles、ノードごとの intent)をレンダリングします。

3. GET /internal/projects/{project_id}/figma-files

project_figma_file からプロジェクトの登録済み Figma ファイルをリストします。プラグインが org/project + ファイル解決に、また component_sweep が(バックエンド/サービストークン経由で)巡回をスコープするために使います。

プロパティ 値
Method / Path GET /internal/projects/{project_id}/figma-files
認証 セッショントークン または X-AI-Service-Token(read)
Path params project_id — integer、> 0
Query params なし(path でプロジェクトスコープ)
Request body なし
DocDB read project_figma_file.find({organization_id, project_id})
S3 効果 なし
PG / SQS なし

Response body — 登録済みファイル(role、config_url、components_synced_at):

{
  "ok": true,
  "data": {
    "project_id": 3,
    "items": [
      {
        "figma_file_key": "hDDA9BNori9OTXSClduXqR",
        "role": "working",                    // working | library
        "config_url": "s3://…/1/3/wf2des/config.json",
        "components_synced_at": "2026-07-06T09:30:00Z"
      }
    ]
  },
  "error": null
}

role は working | library のいずれかです。sweep 管轄のフィールド(style_captures、sweep_marker、sweep_error)はワーカー内部のものであり、プラグイン向けのリスト形状には含まれません。


ライトルート

detail が先、flag が後。 ルート 4〜6 は design_generation_result の detail サブドキュメントをまずここに書き、その後プラグインは wf2des PG 行を反転する対応の バックエンド フラグエンドポイントを呼び出します。wf2des-api は決して PostgreSQL に書き込みません。ルート 7 はバックエンドパートナーを持たない直接書き込みです。

4. POST /internal/wf2des/{wf2des_id}/reject

結果ドキュメントの parse.rejected — awaiting_confirm チェックポイントにおけるデザイナーの構造化された parse 却下 — を書き込みます。reject は失敗では ありません(wf2des status '3' rejected にマップされ、'2' failed ではありません)。

プロパティ 値
Method / Path POST /internal/wf2des/{wf2des_id}/reject
認証 セッショントークン のみ(write、プロジェクトスコープ)
Path params wf2des_id — 実行 id(design_generation_result._id)
Request body { reason_code, note }
DocDB write design_generation_result.parse.rejected = { reason_code, note } をセット(organization_id + project_id でスコープ)
S3 / PG / SQS S3 なし、PG なし、SQS なし
Detail-first パートナー この書き込みの後、プラグインは バックエンドの confirm エンドポイント を呼び出し、wf2des 行を status '3' rejected に反転する

Request body — reason_code は wrong_roles | wrong_memos | wrong_sections | other のいずれか:

{
  "reason_code": "wrong_roles",   // wrong_roles | wrong_memos | wrong_sections | other
  "note": "The CTA row was parsed as a header."
}

書き込まれた parse.rejected は、ルート 2 が返す rejected 値になります。wf2des の status '3' 反転は 別個の バックエンド呼び出しです。wf2des-api は detail を記録するだけです。

5. POST /internal/wf2des/{wf2des_id}/placement

結果ドキュメントの placement — プラグインが spec からネイティブ Figma ノードを縫合した後のマテリアライズ記録 — を書き込みます。配置されたノードと、materializer のレイヤーごとの fallback/error レポートを記録します。

プロパティ 値
Method / Path POST /internal/wf2des/{wf2des_id}/placement
認証 セッショントークン のみ(write、プロジェクトスコープ)
Path params wf2des_id — 実行 id(design_generation_result._id)
Request body { placed_node_id, materialized_at, materializer_report[] }
DocDB write design_generation_result.placement をセット(プラグインが書き込むフィールド。ワーカーは assemble 時にすでに placement.design_area を書き込み済み)
S3 / PG / SQS S3 なし、PG なし、SQS なし
Detail-first パートナー この書き込みの後、プラグインは バックエンドの placement エンドポイント を呼び出し、wf2des 行の materialized_at を反転する

Request body — materializer_report[].event は name_fallback | ordinal_fallback | build_error | font_fallback | prop_rejected | unmatched | preserved のいずれか:

{
  "placed_node_id": "40002029:37050",
  "materialized_at": "2026-07-06T09:41:12Z",
  "materializer_report": [
    {
      "layer_path": "root/section-1/cta",
      "event": "name_fallback",     // 上記 7 値のいずれか
      "detail": "component_key not found; matched by name"
    }
  ]
}

placement ブロックは、ワーカーが書き込んだ placement.design_area(解決された DESIGN エリアの矩形)と共存します。行の materialized_at 反転は 別個の バックエンド呼び出しです。

6. POST /internal/wf2des/{wf2des_id}/feedback

結果ドキュメントの feedback — マテリアライズ後のデザイナーのシグナル(採用された結果、または修正された結果)— を、変更されたノードと diff ポインタと共に書き込みます。

プロパティ 値
Method / Path POST /internal/wf2des/{wf2des_id}/feedback
認証 セッショントークン のみ(write、プロジェクトスコープ)
Path params wf2des_id — 実行 id(design_generation_result._id)
Request body { status, changed_nodes[], diff_url, at, by }
DocDB write design_generation_result.feedback をセット
S3 / PG / SQS S3 なし、PG なし、SQS なし — diff_url はワーカー/プラグインが生成した diff アーティファクトへのポインタであり、ここでは書き込まれない
Detail-first パートナー この書き込みの後、プラグインは バックエンドの feedback エンドポイント を呼び出し、wf2des 行の feedback_status を反転する

Request body — status は fixed | adopted のいずれか:

{
  "status": "adopted",             // fixed | adopted
  "changed_nodes": ["root/section-1/cta", "root/section-2/hero"],
  "diff_url": "s3://…/1/3/wf2des/8f14e4…-…-feedback.json",
  "at": "2026-07-06T10:05:00Z",
  "by": "designer@example.com"
}

changed_nodes は layer_path 値です(spec の layer_path アドレッシングと一致)。行の feedback_status 反転は 別個の バックエンド呼び出しです。

7. POST / PUT /internal/projects/{project_id}/figma-files

project_figma_file エントリ — ファイルの role と config_url — を登録(POST)または更新(PUT)します。これは バックエンドのフラグパートナーを持たない wf2des-api への 直接 書き込みです: project_figma_file は DocumentDB コレクションであって PG フラグサーフェスではありません。

プロパティ 値
Method / Path POST / PUT /internal/projects/{project_id}/figma-files
認証 セッショントークン のみ(write、プロジェクトスコープ)
Path params project_id — integer、> 0
Request body { figma_file_key, role, config_url }
DocDB write project_figma_file ドキュメントを upsert — UNIQUE(organization_id, project_id, figma_file_key)。POST は insert(既存キーでは 409)。PUT は既存ドキュメントの role / config_url を更新
S3 / PG / SQS S3 なし、PG なし、SQS なし
Detail-first パートナー なし — これは直接書き込みであり、detail-then-flag のペアではない

Request body — role は working | library のいずれか:

{
  "figma_file_key": "hDDA9BNori9OTXSClduXqR",
  "role": "working",               // working | library
  "config_url": "s3://…/1/3/wf2des/config.json"
}

プラグインの role / config_url 書き込みは、component_sweep がスタンプする sweep 管轄のフィールド(style_captures、components_synced_at、sweep_marker、sweep_error)とフィールドレベルで分離しています — 決して衝突しません。UNIQUE(organization_id, project_id, figma_file_key) で衝突する POST は 409 を返します。既存の登録を更新するには PUT を使ってください。


エラーハンドリング

エラーは姉妹リード API と同じエンベロープ({ ok, data, error }、error: { code, message })を使います。

シナリオ HTTP ステータス エラーコード
X-AI-Service-Token の欠落 / 不正 かつ 有効なセッショントークンなし 401 UNAUTHORIZED
未知の wf2des_id または project_id(該当ドキュメントなし) 404 NOT_FOUND
誤ったプロジェクトスコープ — トークンの {org_id, project_id} が path のスコープと一致しない、または不正/期限切れのセッショントークン 403 FORBIDDEN
ライトルートで使われたサービストークン(read スコープのトークンによる書き込み試行) 403 FORBIDDEN
UNIQUE(organization_id, project_id, figma_file_key) で衝突する POST figma-file 409 CONFLICT
不正な path/query/body(不正な reason_code / event / status / role enum、不正な形式の body) 400 BAD_REQUEST
DocumentDB / S3 の接続またはクエリエラー 500 INTERNAL_ERROR

補足:

  • 404(未知の id)。 欠落した design_generation_result(wf2des_id)、または特定のファイルがアドレスされたのに project_figma_file ドキュメントを持たないプロジェクトは、いずれも NOT_FOUND を返します。空の figma-files LIST(ルート 3)は 404 では ありません — { items: [] } を返します。
  • 403(誤ったプロジェクトスコープ / 不正なセッショントークン)。 あらゆるルートが org/project スコープです。{org_id, project_id} が要求された project_id / ドキュメントのテナンシーと一致しないセッショントークン、期限切れトークン(exp 経過)、またはライトルートで使われた read スコープの X-AI-Service-Token → FORBIDDEN。プロジェクト横断アクセスは決してデフォルトではありません。
  • 409(figma-file の一意衝突)。 既存の UNIQUE(organization_id, project_id, figma_file_key) にヒットするルート 7 への POST → CONFLICT。PUT が冪等な更新経路です。

エラー body:

{
  "ok": false,
  "data": null,
  "error": { "code": "NOT_FOUND", "message": "design_generation_result not found" }
}

認証

2 つの認証情報が wf2des-api に到達します。ルートの種別がどちらを受け付けるかを決めます(ルートサマリー を参照)。

プラグインセッショントークン(read + write、プロジェクトスコープ)

Figma プラグインは {org_id, project_id, exp} を運ぶ セッション発行のデータプレーントークン を提示します:

  • スコープ。 トークンは 1 つの org_id + project_id に固定されます。あらゆるリクエストがそのスコープに対して検証されます。トークンのスコープ外の path project_id(またはドキュメントのテナンシー)→ 403。
  • 期限。 exp が強制されます。経過した exp → 403(不正/期限切れのセッショントークン)。
  • 権限。 read + write。これがライトルート(4〜7)で受け付けられる 唯一の 認証情報です。

バックエンド / MCP サービストークン(read のみ)

バックエンドと MCP は共有 X-AI-Service-Token ヘッダーを提示し、定数時間比較で設定済みシークレットと照合されます(姉妹の mcp-api と同じ):

  • 権限。 read のみ。org/project + ファイル解決と result/parse 取得のため、リードルート(1〜3)で受け付けられます。ライトルートでは 拒否 されます — サービストークンによる書き込み試行 → 403(FORBIDDEN)。
  • それを必要とするルートでの欠落 / 不一致トークンで、有効なセッショントークンも存在しない場合 → 401(UNAUTHORIZED)。

wf2des-api が決して保持しないもの。 PostgreSQL 認証情報も SQS 送信権限も持ちません。wf2des 行のフラグは、各 detail 書き込みの後にプラグインが呼び出すバックエンドエンドポイントによって反転されます。AI 管轄の wf2des-events キューはバックエンドの送信専用権限によってのみ供給されます。wf2des-api は DocumentDB + S3 のみです。


関連

  • AI Read API (mcp-api) I/O 定義 — 同じ internal-api アプリ内の姉妹となる内部 HTTP リード API(バックエンド MCP v2 → DocumentDB design / code)。
  • AI WF2Des I/O 定義 — これらのルートが読み(一部は書き込む)design_generation_result、project_figma_file ドキュメントを 生成する ワーカー。正確なブロック形状の出所。