Skip to content

Infrastructure

Guinness is built on AWS and consists of three areas: admin, user, and AI workers. Responsibilities are split across three teams: 4D, NDVN, and Plabs.


Overall Architecture

graph TB
    Admin[Service Admin]
    User[User]

    subgraph "4D โ€” Admin side"
        AdminFrontend["Admin Frontend\nAmplify / Next.js"]
        AdminAPI["API Gateway\nAdmin endpoints"]
        AdminLambda["Lambda\napi-admin (Hono + Bun)"]
        AdminCognito["Cognito\nAdmin pool"]
        AdminRDS["RDS PostgreSQL\nAdmin DB"]
    end

    subgraph "4D โ€” User side"
        UserFrontend["User Frontend\nAmplify / Next.js"]
        UserAPI["API Gateway\nUser endpoints"]
        UserLambda["Lambda\napi-user (Hono + Bun)"]
        UserCognito["Cognito\nApp pool"]
        UserRDS["RDS PostgreSQL\nUser DB"]
        UserSQS["SQS\nJob queue"]
        S3["Amazon S3\nAsset storage"]
    end

    Plugin[Figma Plugin]

    subgraph "Plabs โ€” AI workers (guinness-ai-v2)"
        DesignImport["Lambda\ndesign-import"]
        CodeImport["Lambda\ncode-import"]
        Des2Code["Lambda\ndes2code"]
        WF2Des["Lambda\nwf2des (4 run families)"]
        WF2DesGenSQS["SQS\nwf2des generation"]
        WF2DesEventsSQS["SQS\nwf2des-events (AI-owned)"]
        WF2DesEB["EventBridge\ncomponent resync"]
        InternalAPI["internal-api\nwf2des-api (DocDB + S3)"]
        DocDB["DocumentDB\ndesign / code\n(embedding vectors)\n+ 6 wf2des collections:\nwireframe / design_rule / design_component /\nproject_figma_file / design_generation_result /\ndesign_resolution"]
    end

    subgraph "External Services"
        OpenAI["OpenAI API"]
        FigmaREST["Figma REST\n(service-account PAT)"]
    end

    Admin --> AdminFrontend
    AdminFrontend --> AdminAPI
    AdminAPI --> AdminLambda
    AdminLambda --> AdminCognito
    AdminLambda --> AdminRDS

    User --> UserFrontend
    UserFrontend --> UserAPI
    UserAPI --> UserLambda
    UserLambda --> UserCognito
    UserLambda --> UserRDS
    UserLambda --> UserSQS
    UserLambda --> S3

    UserSQS --> DesignImport
    UserSQS --> CodeImport
    UserSQS --> Des2Code

    DesignImport -->|upsert design| DocDB
    CodeImport -->|upsert code| DocDB
    Des2Code -->|read design/code| DocDB

    DesignImport --> OpenAI
    CodeImport --> OpenAI
    DesignImport --> S3
    CodeImport --> S3
    Des2Code --> S3

    DesignImport -. "Webhook (private VPC)" .-> UserLambda
    CodeImport -. "Webhook (private VPC)" .-> UserLambda
    Des2Code -. "Webhook (private VPC)" .-> UserLambda

    UserLambda -->|SendMessage generation parse/assemble| WF2DesGenSQS
    UserLambda -->|SendMessage wf2des-events send-only| WF2DesEventsSQS
    WF2DesGenSQS --> WF2Des
    WF2DesEventsSQS --> WF2Des
    WF2DesEB -->|invoke resync| WF2Des
    WF2Des -->|read/write 6 collections| DocDB
    WF2Des --> S3
    WF2Des --> FigmaREST
    WF2Des -. "ai-status webhook (generation) / component manifest (private VPC)" .-> UserLambda

    Plugin --> InternalAPI
    InternalAPI --> DocDB
    InternalAPI --> S3

Admin Infrastructure

The admin-facing area owned by 4D. 4D staff manage organizations, users, and admin accounts here.

Subsystem Service Role
Admin frontend Amplify / Next.js Admin operations UI
API Gateway API Gateway Routing for admin endpoints
Backend Lambda (Hono + Bun) api-admin โ€” business logic
Authentication Cognito admin pool Auth for 4D staff
Database RDS PostgreSQL Admin accounts, organizations, sessions

Admin Authentication Flow

sequenceDiagram
    participant Admin as Service Admin
    participant FE as Admin Frontend
    participant API as API Gateway
    participant Lambda as Lambda (api-admin)
    participant Cognito as Cognito (admin pool)
    participant RDS as RDS PostgreSQL

    Admin->>FE: Login
    FE->>API: POST /v1/auth/login
    API->>Lambda: Forward request
    Lambda->>Cognito: initiateAuth()
    Cognito-->>Lambda: JWT access token
    Lambda->>RDS: Create session
    Lambda-->>FE: 200 { token, admin }

    Admin->>FE: Admin operation
    FE->>API: Admin API call
    API->>Lambda: Process request
    Lambda->>RDS: Data operation
    RDS-->>Lambda: Result
    Lambda-->>FE: Response

Session Lifecycle

stateDiagram-v2
    [*] --> Created: Admin login
    Created --> Active: Session stored in DB
    Active --> Expired: expires_at passed
    Active --> Revoked: Admin logout
    Active --> Revoked: Password reset
    Active --> Revoked: Global sign-out
    Expired --> CleanedUp: Scheduled cleanup job
    Revoked --> CleanedUp: Scheduled cleanup job
    CleanedUp --> [*]: Soft deleted (deleted_at set)

Sessions are retained for SESSION_RETENTION_DAYS (default: 90 days) after expiry before being soft-deleted.

Key Environment Variables (api-admin)

Variable Required Description
ADMIN_COGNITO_USER_POOL_ID Yes AWS Cognito User Pool ID
ADMIN_COGNITO_CLIENT_ID Yes AWS Cognito App Client ID
ADMIN_COGNITO_REGION No AWS region (default: ap-northeast-1)
DATABASE_NAME Yes PostgreSQL database name
DATABASE_USER Yes PostgreSQL user
DATABASE_PASSWORD Yes PostgreSQL password
DATABASE_HOST No PostgreSQL host (default: localhost)
DATABASE_PORT No PostgreSQL port (default: 5432)
SESSION_CLEANUP_API_KEY Yes API key for session cleanup endpoint
SESSION_RETENTION_DAYS No Days to retain expired sessions (default: 90)
ALLOWED_ORIGINS No Comma-separated CORS origins
PORT No Server port (default: 8081)

User Infrastructure

The end-user-facing area owned by 4D. AI processing tasks such as design import, code import, and Des2Code are executed asynchronously via SQS.

Subsystem Service Role
User frontend Amplify / Next.js End-user operations UI
API Gateway API Gateway Routing for user endpoints
Backend Lambda (Hono + Bun) api-user โ€” business logic
Authentication Cognito app pool Auth for end users
Database RDS PostgreSQL Workflow artifacts and user identity
Job queue SQS Async job delivery to AI workers
Storage Amazon S3 Asset files (screenshots, etc.)

AI Infrastructure (guinness-ai-v2)

The AI conversion worker area owned by Plabs. Workers are triggered by SQS queues and notify the backend via Webhook on completion.

Worker Queue Role Duration
design-import design-import Imports Figma designs into DocumentDB and generates embedding vectors ~2โ€“5 min
code-import code-import Imports code entries into DocumentDB and generates embedding vectors ~1โ€“3 min
des2code des2code Matches design embeddings against code entries, writes S3 result artifacts, and reports the result via backend webhook ~1โ€“5 min
page-import (planned) page-import Validates and normalizes one captured application page TBD
code2wf (planned) code2wf Converts one completed Page Import into a WF2Des-shaped result artifact containing the existing DesignSpecModel TBD
wf2des wf2des generation + wf2des-events + EventBridge Turns a Figma wireframe into a native Figma design by direct assembly (4 run families: generation parse/assemble, wf_parse, rule_process, component_sweep; no embeddings) Parse preview <~60s, confirmโ†’spec <~2 min

design-import and code-import use PydanticAI for agent orchestration and the OpenAI API for model inference and embedding generation. des2code consumes existing embeddings, writes timestamped S3 result artifacts, does not call OpenAI, and does not generate source code. wf2des also uses PydanticAI for its bounded LLM steps (parse roles/intent, assemble section selection, asset-process vision labeling) but does no retrieval, no embeddings, and no vector search โ€” it assembles directly from the project's own component registry and rule set.

The planned Page Import capture runs in a trusted local/CI CLI; its Lambda only validates uploaded evidence. Code2WF consumes the completed import, while the Figma plugin materializes the wireframe immediately or after reopen.

AI Processing Flow (des2code)

sequenceDiagram
    participant User as User
    participant API as API Gateway
    participant Lambda as Lambda (api-user)
    participant PG as RDS PostgreSQL
    participant SQS as SQS
    participant Worker as des2code Lambda
    participant DocDB as DocumentDB
    participant S3 as Amazon S3

    User->>API: Des2Code request
    API->>Lambda: Process request
    Lambda->>PG: INSERT (status: pending)
    Lambda->>SQS: Enqueue job
    Lambda-->>User: 202 Accepted

    SQS->>Worker: Consume message
    Worker->>DocDB: Fetch design embeddings
    Worker->>DocDB: Vector search against code collection
    Worker->>S3: PutObject result artifact

    Worker-)Lambda: POST /v1/webhooks/ai-status (success + matched codes + artifact ref)
    Lambda->>PG: UPDATE latest Des2Code result/status/artifact ref

    User->>API: Poll status
    API-->>User: success + matched codes

AI Processing Flow (wf2des generation)

The generation happy path. The backend writes the wf2des row first (status '0', phase parse) and captures the wireframe snapshot before enqueuing. Completion flows back through the generation-only ai-status webhook, which the backend applies to the row.

sequenceDiagram
    participant Designer as Designer
    participant Plugin as Figma Plugin
    participant WFAPI as internal-api (wf2des-api)
    participant Lambda as Lambda (api-user)
    participant PG as RDS PostgreSQL
    participant GenSQS as SQS (wf2des generation)
    participant Worker as wf2des Lambda
    participant DocDB as DocumentDB
    participant S3 as Amazon S3

    Lambda->>PG: INSERT wf2des row (status '0', phase parse)
    Lambda->>S3: Capture WF snapshot
    Lambda->>GenSQS: Enqueue parse job

    GenSQS->>Worker: Consume parse message
    Worker->>DocDB: Deterministic extract + LLM roles/intent โ†’ wireframe cache + result doc
    Worker->>S3: PutObject parse.json
    Worker-)Lambda: POST /v1/webhooks/ai-status (parse_done)
    Lambda->>PG: Set phase awaiting_confirm

    Plugin->>WFAPI: Preview parse (session token)
    WFAPI->>DocDB: Read parse artifacts
    Designer->>Plugin: Confirm
    Plugin->>Lambda: Confirm endpoint (CAS awaiting_confirm + attempt)
    Lambda->>GenSQS: Enqueue assemble job

    GenSQS->>Worker: Consume assemble message
    Worker->>DocDB: Rehydrate pins โ†’ candidate filter โ†’ LLM section selection โ†’ validator โ†’ computed confidence โ†’ result doc
    Worker->>S3: PutObject result artifact + manifest
    Worker-)Lambda: POST /v1/webhooks/ai-status (succeeded + manifest key)
    Lambda->>PG: Flip row to '1' completed + result refs + flag_count (one PG txn)

    Plugin->>WFAPI: Read spec โ†’ materialize native Figma

The three internal runs (wf_parse, rule_process, component_sweep) are driven by the wf2des-events intake queue and the EventBridge schedule and are webhook-free โ€” each run's output document is its own record of completion. component_sweep is the one exception with a backend-side PG effect: instead of the ai-status webhook it emits a discovered-component sweep manifest the backend applies as platform design (type=component) registry upserts.

Webhook Contract

All workers report status to POST /v1/webhooks/ai-status on the private VPC with the shared service X-API-Key.

Worker PostgreSQL table updated DocumentDB write
design-import design Yes (upsert into design)
code-import code Yes (upsert into code)
des2code backend-owned latest Des2Code result/status/artifact reference No
page-import (planned) page_import No
code2wf (planned) code2wf No
wf2des wf2des (generation, via ai-status) + platform design type=component upserts (from component_sweep's manifest) Yes (6 collections)
Status PG value Meaning
pending 0 Enqueued
success 1 Completed
failed 2 Failed (SQS retry possible)

wf2des extends this platform 3-state status to five states for its generation row โ€” adding '3' rejected (designer declined the parse; not a failure) and '4' cancelled โ€” plus a phase field ('0' parse / '1' awaiting_confirm / '2' assemble) namespaced inside status '0'. Only the generation run family emits the ai-status webhook; the three internal runs are webhook-free, and internal runs carry no wf2des row.

Database Isolation

AI workers and the backend do not share a database. They communicate only via Webhook.

Service Owns Communication
guinness-backend (4D) RDS PostgreSQL Receives Webhooks
guinness-ai-v2 (Plabs) DocumentDB Sends Webhooks

wf2des owns 6 DocumentDB collections (wireframe, design_rule, design_component, project_figma_file, design_generation_result, design_resolution) plus the wf2des-api data plane โ€” a route group in the internal-api app that reads/writes DocumentDB + S3 only and is used by the Figma plugin for previews, placement, and file registration. As with the other workers, wf2des workers never write PostgreSQL; every generation PG effect is applied backend-side by the ai-status webhook handler (the sole completion-time PG writer).

The planned Page Import and Code2WF workers use S3 artifacts and do not connect to DocumentDB or PostgreSQL; the backend owns their PostgreSQL rows.

Credential Isolation

Service Holds Does not hold
guinness-backend PostgreSQL credentials, SQS queue URLs, Webhook endpoint (inbound) DocumentDB access
guinness-ai-v2 DocumentDB connection string, S3 artifact write permission, OPENAI_API_KEY for import workers, Webhook URL (outbound). For wf2des additionally: the service-account Figma PAT in wf2design's own secret store (never the platform figma_token table or ENCRYPTION_KEY), consume access on the wf2des generation + wf2des-events queues, the AI-owned EventBridge schedule, and the plugin session token issued by wf2des-api PostgreSQL access

Target V2 Wiring (genai-infrastructure)

genai-infrastructure/aws/envs/dev/guinness-backend is the reference layout for the target wiring. Each environment must expose the same logical resources and permissions.

Resource Terraform logical name Requirement
design-import queue + DLQ guinness_ai_v2_design_import_queue, guinness_ai_v2_design_import_dlq Backend sends design-import payloads; Lambda event source mapping uses ReportBatchItemFailures
code-import queue + DLQ guinness_ai_v2_code_import_queue, guinness_ai_v2_code_import_dlq Backend sends code-import payloads; Lambda event source mapping uses ReportBatchItemFailures
des2code queue + DLQ guinness_ai_v2_des2code_queue, guinness_ai_v2_des2code_dlq Backend REST API and MCP v2 send des2code payloads; Lambda event source mapping uses ReportBatchItemFailures
page-import queue + DLQ (planned) guinness_ai_v2_page_import_queue, guinness_ai_v2_page_import_dlq Backend sends Page Import validation jobs; Lambda event source mapping uses ReportBatchItemFailures
code2wf queue + DLQ (planned) guinness_ai_v2_code2wf_queue, guinness_ai_v2_code2wf_dlq Backend sends completed Page Import conversion jobs; Lambda event source mapping uses ReportBatchItemFailures
Page Import / Code2WF S3 prefixes (planned) existing guinness_backend_ai_v2 bucket Store immutable import and generation artifacts under tenant/project-scoped prefixes
Page Import orphan-upload lifecycle (planned) lifecycle rule on existing guinness_backend_ai_v2 bucket; Terraform label TBD Expire only objects tagged page_import_state=orphan after the configured incomplete-upload window; objects retagged page_import_state=retained after row creation are excluded
backend AI bucket lifecycle guinness_backend_ai_v2_des2code_results Objects tagged des2code_result=true expire after the configured retention window
wf2des generation queue + DLQ guinness_ai_v2_wf2des_generation_queue, guinness_ai_v2_wf2des_generation_dlq Backend-owned; backend sends parse / assemble payloads; Lambda event source mapping uses ReportBatchItemFailures
wf2des-events queue + DLQ guinness_ai_v2_wf2des_events_queue, guinness_ai_v2_wf2des_events_dlq AI-owned intake queue (rule / asset / plugin events); backend holds SendMessage only; Lambda event source mapping uses ReportBatchItemFailures
wf2des component-resync schedule guinness_ai_v2_wf2des_component_sweep_schedule AI-owned EventBridge schedule invoking component_sweep resync sweeps; cron / rate per deployment
backend AI bucket wf2des prefix + lifecycle guinness_backend_ai_v2_wf2des_results Result + manifest artifacts under {org}/{proj}/wf2des/; objects expire after the configured retention window
wf2des PostgreSQL table wf2des (backend RDS) Backend-owned generation run row (status / phase / attempt + result refs + flag_count); no AI-side access

Backend runtime variables:

Variable Used by Requirement
DATABASE_* / RDS Proxy variables backend app, MCP v2 PostgreSQL only for user/backend state and MCP API-key auth
SQS_DESIGN_IMPORT_QUEUE_URL, SQS_DESIGN_IMPORT_QUEUE_ARN backend design API SendMessage to design-import
SQS_CODE_IMPORT_QUEUE_URL, SQS_CODE_IMPORT_QUEUE_ARN backend code API SendMessage to code-import
SQS_DES2CODE_QUEUE_URL, SQS_DES2CODE_QUEUE_ARN backend Des2Code API, MCP v2 SendMessage to des2code
SQS_PAGE_IMPORT_QUEUE_URL, SQS_PAGE_IMPORT_QUEUE_ARN backend Page Import API (planned) SendMessage to page-import
SQS_CODE2WF_QUEUE_URL, SQS_CODE2WF_QUEUE_ARN backend Code2WF API (planned) SendMessage to code2wf
SQS_WF2DES_GENERATION_QUEUE_URL, SQS_WF2DES_GENERATION_QUEUE_ARN backend wf2des API (create / confirm) SendMessage to the backend-owned wf2des generation queue (parse / assemble)
SQS_WF2DES_EVENTS_QUEUE_URL, SQS_WF2DES_EVENTS_QUEUE_ARN backend wf2des rule / asset / frame-registration paths SendMessage only to the AI-owned wf2des-events intake queue (the backend's only send right on AI-owned infra)
WEBHOOK_API_KEY backend webhook Shared service key expected in X-API-Key (used by the generation ai-status flip for wf2des too)
AI_V2_INTERNAL_URL, AI_SERVICE_TOKEN MCP v2 or backend proxy Service-token reads from guinness-ai-v2 design/code internal API; also cover wf2des-api read routes (X-AI-Service-Token)
CLOUDFRONT_SECRET_HEADER MCP v2 Secret value checked against X-MCP-Token outside local

AI worker runtime variables:

Variable Used by Requirement
DOCUMENTDB_CONNECTION_STRING, DOCUMENTDB_NAME all AI workers DocumentDB access for design and code; backend does not receive these
DESIGN_TABLE_NAME, CODE_TABLE_NAME import workers, des2code Collection names; target values are design and code
WEBHOOK_BASE_URL, WEBHOOK_API_KEY all AI workers POST completion/failure to backend POST /v1/webhooks/ai-status
RESULT_BUCKET, DES2CODE_RESULT_TTL_DAYS des2code Timestamped result/failed artifacts; tag objects with des2code_result=true
OPENAI_API_KEY, DESC_MODEL, EMBEDDING_MODEL, EMBEDDING_DIMENSIONS design-import, code-import Import analysis and embedding generation
Per-collection names for the 6 wf2des collections (+ DOCUMENTDB_NAME=guinness_v2) wf2des Env-overridable collection names: wireframe, design_rule, design_component, project_figma_file, design_generation_result, design_resolution
wf2des generation queue + wf2des-events queue URLs / ARNs wf2des Event source mappings consumed by the worker (backend-owned generation + AI-owned intake)
EventBridge schedule (component_sweep resync) wf2des AI-owned schedule invoking the worker directly; cron / rate per deployment
WEBHOOK_BASE_URL, WEBHOOK_API_KEY wf2des (generation only) POST POST /v1/webhooks/ai-status on completion (X-API-Key)
RESULT_BUCKET + the {org}/{proj}/wf2des/ prefix wf2des Client-facing result + manifest artifacts; internal parse / spec / feedback artifacts under the same prefix
Figma service-account PAT secret ARN wf2des (component_sweep + snapshot / memo fallback) wf2design's own secret store; never the platform figma_token table or ENCRYPTION_KEY; per deployment
Model tiers (fast / strong / vision) + PROMPT_VERSION wf2des Parse roles/intent (fast), assemble selection (strong), asset vision labeling; pinned per run; concrete ids per deployment
DEFAULT_ORGANIZATION_ID wf2des Single-tenant default 1; organization_id on every doc
S3_BUCKET_NAME + Page Import schema/size limits page-import (planned) Read scoped capture artifacts and write normalized artifacts
RESULT_BUCKET code2wf (planned) Write WF2Des-shaped result artifacts to the existing AI bucket

IAM boundaries:

Principal Must allow Must not require
backend app sqs:SendMessage to the three import/des2code v2 queues plus the backend-owned wf2des generation queue and (send-only) the AI-owned wf2des-events queue, S3 asset read/write as needed, PostgreSQL access DocumentDB access
MCP v2 PostgreSQL read/update for MCP auth, sqs:SendMessage to des2code, internal AI/backend HTTP access DocumentDB access in deployed environments
design-import/code-import Lambdas consume their SQS queues, read S3 input assets, write DocumentDB, call backend webhook PostgreSQL access
des2code Lambda consume des2code queue, read DocumentDB design/code, write/tag S3 artifacts, call backend webhook PostgreSQL access
backend app (planned additions) send to page-import/code2wf queues and read/write their tenant/project-scoped S3 prefixes DocumentDB access
page-import Lambda (planned) consume page-import queue, read capture objects, write normalized objects, call backend webhook PostgreSQL, DocumentDB, browser execution
code2wf Lambda (planned) consume code2wf queue, read completed Page Import objects, write result objects, and call the backend webhook PostgreSQL, DocumentDB, OpenAI API, Figma PAT/write access
wf2des Lambda consume the wf2des generation + wf2des-events queues, EventBridge invoke, read/write the 6 DocumentDB collections, read/write S3 artifacts + snapshots, Figma REST via the service-account PAT secret, call the backend ai-status webhook PostgreSQL access
wf2des-api (in internal-api) read/write DocumentDB + S3, issue/verify the plugin session token, accept X-AI-Service-Token PostgreSQL access, SQS access

V1 โ†’ V2 Worker Migration Mapping

V1 worker V2 worker Key changes
design design-import Dual embeddings (visual + semantic), no MySQL access
legacy code import predecessor code-import legacy code data โ†’ code collection, dual embeddings, CSS support
legacy Des2Code/code-generation predecessor des2code Des2Code worker; result written to S3, delivered by webhook, and persisted by backend PostgreSQL as latest result/artifact reference
wireframe (V1 continues) The wireframe โ†’ design path is now served by the net-new wf2des worker (see below); not a 1:1 port of a V1 worker
(net-new โ€” no V1 predecessor) wf2des New direct-assembly engine: turns a Figma wireframe into a native Figma design under the project's design rules (4 run families; no embeddings / retrieval). Backend owns the wf2des row + endpoints; the Figma plugin reads/writes via wf2des-api (in internal-api)
(net-new โ€” no V1 predecessor) page-import (planned) One-page repository capture followed by deterministic validation and normalization
(net-new โ€” no V1 predecessor) code2wf (planned) Completed Page Import to a WF2Des-shaped result artifact; the Figma plugin materializes its existing DesignSpecModel

Team Responsibilities

Area Owner Key services
Admin frontend, backend, and infrastructure 4D AdminFrontend, api-admin, RDS PostgreSQL
User frontend, backend, and infrastructure 4D UserFrontend, api-user, RDS PostgreSQL, SQS, S3
AI conversion engines Plabs design-import, code-import, des2code, wf2des (+ its Figma plugin and wf2des-api in internal-api), DocumentDB