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 へ落ちます。この順序がその
緩和策です。