コンテンツにスキップ

AI Des2WF — Backend 契約

guinness-backend における Des2WF のプロダクトコントロールプレーンです。本ページは面の契約であり、 development/apps/backend/user/api-definition/des2wf/ 配下のエンドポイント別ページは凍結された形状に従います。

分担は WF2Des から不変であり、システムの主要な不変条件です。backend がプロダクト契約と PostgreSQL を所有し、AI 側が 実行を所有する。 ワーカーは PostgreSQL に書かず、PG クレデンシャルも持ちません。


エンドポイント

リリース 1 は WF2Des の 20 エンドポイント面より意図的に狭くしています。confirm を持たない one-shot フローでは、その 大半が不要です。

エンドポイント 目的 リリース 1
POST /des2wf 実行作成: 行を INSERT(edge=des2wf)、デザインスナップショット取得、投入。ボディはワイヤーフレームの mode と layout、および取得範囲を絞るためクライアントが解決した任意項目 sectionNodeId を運ぶ(下記参照) 対象
GET /des2wf/{id} 実行の status / phase / attempt / 結果参照 / フラグ数 / スコア 対象
POST /des2wf/{id}/cancel 実行中の中断とフェンス解放 対象
GET /des2wf/{id}/result 結果ドキュメント — 出力された spec、スコア、成果物参照。ワーカー自身の形状をそのまま通す 対象
POST /des2wf/{id}/render materialize 後にプラグインがデザインとワイヤーフレームの PNG を投稿。対を保存し、レンダーレビューを投入 対象
POST /des2wf/component-uploads プラグインが選択したキットボードからワイヤーフレームキットを登録 対象
POST /des2wf/component-captures 当該キットのバリアント単位キャプチャをプラグインから投入 対象
GET /des2wf/kit セットアップ画面向けのキット概況: どれだけ登録され、そのうちどれだけがインスタンス化できるか 対象
POST /des2wf/{id}/confirm — 非対象: one-shot のため確認対象が無い
POST /des2wf/{id}/feedback — 非対象: 本プロダクトに人手修正ループが存在しない
ルール系エンドポイント — 非対象: Des2WF はルールセットを取り込まない

confirm の停止点、feedback API、ルール取り込みはありません。明示的なグラフィック override は organization/project/file に限定した運用者向け CLI であり、プラグインの feedback API ではありません。 ストア を参照してください。


トリガーボディ

POST /organizations/{organization_id}/projects/{project_id}/des2wf

フィールド 必須 値 意味
figmaFileKey 必須 Figma verbatim(英数字のみ、アンダースコア不可) デザインフレームが存在するファイル
sourceNodeId 必須 Figma ノード ID デザインフレーム — 入力ノード
sectionNodeId 任意 Figma ノード ID フレームを内包するボード/SECTION。スナップショット取得の範囲を絞る(下記参照)
mode 任意 primitives(既定)/kit ワイヤーフレームを何から描くか
layout 任意 absolute(既定)/auto どんな種類のワイヤーフレームか

mode。primitives は文言と元のジオメトリを保ち、面を中立的なプリミティブにします。 両 mode は利用可能な元画像と文脈でグラフィックを分類するため、primitives は「モデル呼び出しなし」ではありません。 kit はサンプリングによるバリアント選択と決定的ガードを追加します。使えないキット選択はプリミティブへ、 不確かなグラフィックは元の図形の保持へフォールバックします。

layout。mode とは独立です。absolute は元座標を保ち、再フローしません。 auto は子が 1 つのラッパーも含む元の所有階層、itemSpacing、padding、alignment、wrap、 軸ごとの sizing、絶対配置オーバーレイを保持します。

API の既定値は mode=primitives と layout=absolute のままで、エンドポイントが解決してキューへ書きます。 現在のプラグインは layout=auto を明示送信し、レイアウト選択 UI はありません。 画像分類でモデルを使うため、どちらの mode も生成結果のバイト単位の一致は保証しません。

{
  "figmaFileKey": "9kQzR4TmVb2NxPy7LcWd1s",
  "sourceNodeId": "2199:40144",
  "sectionNodeId": "2199:39877",
  "mode": "primitives",
  "layout": "absolute"
}

スコープ付きスナップショット取得 — sectionNodeId

sectionNodeId は REST 取得を内包サブツリーに絞ります。スコープが欠落・削除済み・不正なら ファイル全体の検索へフォールバックしますが、保存するのは選択フレームだけです。 components/componentSets/styles のマップも参照分だけに絞り、source_hash は 内包ボードや隣の注記ではなくフレームのサブツリーをハッシュします。

backend は実際にフレームを取得したレスポンスのトップレベル Figma version を保持します。 要求ユーザーの PAT で、同じバージョンかつ absolute bounds の PNG を best-effort で取得し、 source hash と render hash を含むキーへ保存します。version がなければ未固定の export は行いません。 export/upload が失敗しても、有効な JSON スナップショットを返し、存在しない画像 URL は付けません。

生成キューの任意フィールド design_png_url は取得処理が設定し、公開トリガーボディでは受け取りません。 この元画像の根拠と、後からプラグインが送るレンダーレビュー用ペアは別物です。


Generation 行

1 つの共有テーブル、1 つの識別子。カラムレベルの定義は ストア を参照。API 境界で重要な点:

  • 行はメッセージ投入 前 に書かれるため、存在しない行を参照するジョブは起こり得ない;
  • edge はエンドポイントが設定し、ペイロードから推論しない;
  • open-generation フェンスは edge を含む部分ユニークインデックスなので、実行中は同一ノードの同一 edge の 2 本目を ブロックし、他方の edge はブロックしない;
  • フェンスは終端状態または明示的な cancel で解放される(取得が失敗した場合は行を open のまま残さず failed にする)。 実行中の run と衝突したトリガーには 409 と、既に走っている run の id を返す。

Webhook の効果

POST /v1/webhooks/ai-status(X-API-Key)に、タグ付きユニオンの識別子として type: "des2wf" を載せます。 完了時点で PG に書く唯一の主体 です。

イベント 効果(単一トランザクション、attempt ガード)
parse_done フェーズ進行 — リリース 1 が one-shot の間は no-op。契約変更なしで 2 フェーズ化できるように残す
succeeded status → completed、結果参照、スコア
failed status → failed、型付きエラーコード

古い attempt の Webhook は適用せず無視し、終端イベントの重複は no-op です。


データプレーン

プラグインが AI 側を直接叩くことはありません。backend がサーバー間(X-AI-Service-Token)で、internal-api アプリに置かれた des2wf-api ルート群へプロキシします。触るのは DocumentDB と S3 のみ で、PostgreSQL には 触れません。提供するのは、プラグインが materialize に使う結果ドキュメントと、セットアップ画面が読むワイヤーフレーム キットの概況です。


レンダーレビューの検証

POST /des2wf/{id}/render はプロジェクトへの書き込み権限と、tenant/project に限定した DES2WF 行を 必要とします。ボディの jobId はルートから取得した行 ID と一致しなければならず (不一致は validation error、HTTP 400)、行は COMPLETED でなければなりません(それ以外は HTTP 409)。 検証は PNG upload とキュー投入より前 に行います。

プラグインは生成開始時の元フレームと backend client/project にペアを紐づけ、 構築結果がそのジョブのものか確認します。出力ノードの選択や、実行中のプロジェクト切り替えで送信先を変えません。

ワーカーは画像の download、モデル呼び出し、レビュー更新より前に、既存結果の organization/project を検証します。 存在しない結果や別スコープの結果から新規ドキュメントを作りません。 skipped の finding count は null であり、レビュー失敗によって生成済み結果を未完了へ戻しません。


デプロイ順序

マイグレーション → ワーカー → backend → プラグイン。ルートは投入時点で ack するため、edge=des2wf を消費できない ワーカーより先に backend を出すと、プラグインが成功を表示しながらエンベロープが DLQ へ落ちます。この順序がその 緩和策です。