Skip to content

AI Internal API — Overview

The internal-api app is a VPC-internal HTTP service in guinness-ai-v2 that gives in-VPC callers a controlled door into DocumentDB + S3 only — it never touches PostgreSQL and never touches SQS. It is the evolved successor to the standalone MCP read API (mcp-api), and hosts two route groups under one Lambda Function URL:

  • the MCP read API for design / code — the internal read surface consumed by the MCP Server. It is documented separately in the MCP Read API overview; this page cross-references it, it does not re-document it.
  • the wf2des-api data plane — the Figma plugin's read/write surface for wf2des. This overview centers on the wf2des-api group.

This app exists because the Figma plugin needs first-class access to the wf2des DocumentDB collections and S3 artifacts — to preview a parse, materialize a spec, and write back placement/feedback — but it must not touch PostgreSQL. The backend owns the wf2des PostgreSQL row and every product-facing flag on it. So the plugin's DocDB/S3 traffic lands here (in the AI side's own datastores), while every PG effect is applied backend-side. wf2des-api is the data plane; the backend's create / confirm / cancel / placement / feedback endpoints are the control plane. The two never overlap — this app holds no PG credentials.

Queue: None — HTTP only (Lambda Function URL; no SQS, no EventBridge)
Auth: plugin session token {org_id, project_id, exp} (read + write, project-scoped) for the Figma plugin; shared X-AI-Service-Token (read) for the backend / MCP
Stores: the 6 wf2des DocumentDB collections + S3 — never PostgreSQL, never SQS
Source: guinness-ai-v2/apps/internal-api/ (the evolved mcp-api; reused, not a new app)


Tech Stack

Layer Technology
Runtime Python 3.12 on AWS Lambda
AI framework None — pure data-plane read/write, no LLM calls
Database Amazon DocumentDB (guinness_v2) — the 6 wf2des collections (plus design / code for the MCP route group)
Object storage Amazon S3 — spec artifacts and parse.json (presigned or proxied)
Queue None — HTTP only
Authentication Plugin session token {org_id, project_id, exp} (read + write) or shared X-AI-Service-Token header (read); both scoped by org / project
Deployment Lambda Function URL, VPC-internal only; security group allows inbound from in-VPC callers only
RDB No access — never writes or reads PostgreSQL; database isolation is respected (backend owns Postgres, AI owns DocumentDB)
SQS No access — this app never enqueues; job triggering stays on the backend / worker path

Why This App Exists

The Figma plugin is a client of the AI side, not of PostgreSQL. It needs the wf2des DocDB documents and S3 artifacts to do its job on the canvas, and it needs to write back a few sub-documents (reject reason, placement report, feedback). But the wf2des PostgreSQL row is backend-owned — status, phase, materialized_at, feedback_status, and every product flag are the backend's to flip. Letting the plugin write PG directly would break that ownership line.

wf2des-api resolves this cleanly: the plugin writes the detail sub-doc to DocumentDB through this app, then calls the backend flag endpoint to flip the row. The AI-owned data lives in AI-owned stores; the backend stays the sole PG writer. This is the same isolation stance as the MCP read API — backend owns Postgres, AI owns DocumentDB — extended from read-only to a controlled read/write data plane.


Auth Model

Two authentication paths, both org / project-scoped, share the same routes:

Caller Credential Scope Access
Figma plugin session token {org_id, project_id, exp} project-scoped, expiring read + write
Backend / MCP shared X-AI-Service-Token header service-to-service read

The plugin's session token carries {org_id, project_id, exp} and is the only credential that can write — and only within its own project. The backend and MCP use the shared X-AI-Service-Token for read access (same service-token shape as the MCP read API's X-AI-Service-Token). Every route is org / project-scoped: a token can only see and touch its own tenant's documents and assets.


The Detail-First Pattern

Writes follow one strict ordering: detail first, flag last.

  1. The plugin writes the detail sub-doc to wf2des-api (a DocumentDB write into the design_generation_result doc — the reject / placement / feedback sub-block).
  2. Only then does the plugin call the corresponding backend flag endpoint, which flips the wf2des PostgreSQL row (status / materialized_at / feedback_status).

The invariant: wf2des-api itself never writes PostgreSQL. The detail always lands in DocumentDB before the backend flag flips, so the PG flag is never set without its backing detail present. If the flag call fails or is retried, the detail is already durable and idempotent. The one exception to the two-step shape is file registration (POST/PUT .../figma-files), which is a direct wf2des-api write — project_figma_file is a DocumentDB collection, not a PG-flag surface, so there is no backend flag step at all.


Route Summary

The wf2des-api route group — VPC-internal HTTP, DocumentDB + S3 only, all routes org / project-scoped. Reads are open to the plugin session token and X-AI-Service-Token; writes require the plugin session token.

# Method + Path Kind What it does Backend flag step
1 GET /internal/wf2des/{wf2des_id}/result read Returns the design_generation_result DesignSpec (spec block; if spilled to S3 via artifact_urls.spec, presign / return it). The plugin materializes native Figma from this —
2 GET /internal/wf2des/{wf2des_id}/parse read Returns the result-doc parse block + the immutable parse.json artifact for the awaiting_confirm preview (roles / intent / memo_influences). The plugin previews from this —
3 GET /internal/projects/{project_id}/figma-files read Lists the project's registered Figma files from project_figma_file (role working | library, config_url, components_synced_at). Plugin org / project + file resolution —
4 POST /internal/wf2des/{wf2des_id}/reject write Writes the result-doc parse.rejected = {reason_code, note} (reason_code: wrong_roles | wrong_memos | wrong_sections | other) → backend confirm endpoint flips the row to status '3' rejected
5 POST /internal/wf2des/{wf2des_id}/placement write Writes the result-doc placement = {placed_node_id, materialized_at, revision, spec_hash, review_id, materializer_report:[{layer_path, event, detail}]} (event: name_fallback | ordinal_fallback | build_error | font_fallback | prop_rejected | unmatched | preserved) → backend placement endpoint flips materialized_at on the row
6 POST /internal/wf2des/{wf2des_id}/feedback write Writes the result-doc feedback = {status, changed_nodes:[layer_path], diff_url, at, by} (status: fixed | adopted) → backend feedback endpoint flips feedback_status on the row
7 POST/PUT /internal/projects/{project_id}/figma-files write Registers / updates a project_figma_file (role, config_url); UNIQUE(organization_id, project_id, figma_file_key). A direct wf2des-api write — (no PG-flag surface)

Routes 1–3 are the read surface; 4–6 are the detail-first writes (each paired with a backend flag endpoint, per detail first, flag last); 7 is the one direct write.


Stores

wf2des-api is configured against the 6 wf2des DocumentDB collections and S3 — and nothing else. It never reads or writes the wf2des PostgreSQL row (backend-owned), and it never enqueues to SQS.

Store How wf2des-api uses it
DocumentDB design_generation_result Read the parse / spec blocks (routes 1–2); write the parse.rejected / placement / feedback detail sub-docs (routes 4–6)
DocumentDB project_figma_file Read the project's registered files (route 3); register / update a file directly (route 7)
DocumentDB wireframe Backing parse context for the preview (route 2)
DocumentDB design_rule Rule context surfaced alongside the parse / spec reads
DocumentDB design_component Component instancing context surfaced alongside the spec reads (route 1)
DocumentDB design_resolution Worker-owned section-resolution ledger; part of the shared wf2des data model but not directly exposed by a plugin route
S3 Presign / return spec artifacts (artifact_urls.spec) and the immutable parse.json

The MCP read route group additionally touches the design / code collections; those belong to the MCP Read API overview and are not re-documented here.


Official field-level contract: I/O Definition.