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-apidata plane — the Figma plugin's read/write surface for wf2des. This overview centers on thewf2des-apigroup.
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.
- The plugin writes the detail sub-doc to
wf2des-api(a DocumentDB write into thedesign_generation_resultdoc — the reject / placement / feedback sub-block). - Only then does the plugin call the corresponding backend flag endpoint, which flips the
wf2desPostgreSQL 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.