Skip to main content
Both platforms are thin clients. They render the catalog and proxy every authenticated or write operation to the Trace backend. No AI, model prompts, or layout logic live in these repos — if the backend is down, generation returns an error rather than falling back to anything local.

The four layers

┌──────────────────────────────────────────────────────────────┐
│ Next.js 16 App Router  (symbols. / footprints.buildwithtrace.com) │
│   Server Components + Client Components                        │
├──────────────────────────────────────────────────────────────┤
│ API route handlers  (src/app/api/**/route.ts)                 │
│   • Browse/search  → read local *_index.json (no backend)     │
│   • Generate/save/contribute/community/comments/rating        │
│       → proxy to api.buildwithtrace.com with the user's JWT   │
├──────────────────────────────────────────────────────────────┤
│ Trace backend  (FastAPI, api.buildwithtrace.com)              │
│   /api/v3/components/*  — AI generation, persistence, search  │
│   /api/v1/auth/*, /api/v1/user/*  — auth + profile            │
├──────────────────────────────────────────────────────────────┤
│ Supabase (Postgres)  — public.generated_components            │
│   one table, `type` ∈ {symbol, footprint}                     │
└──────────────────────────────────────────────────────────────┘

Two data paths

Catalog (read)

Browsing, search, library detail, suggestions, and thumbnails read a pre-built JSON index committed in the repo (symbols_index.json / footprints_index.json). These routes never call the backend, so the public catalog stays fast and works even if the backend is unavailable.

Mutations (proxy)

Generation, save, contribution, community feed, comments, and ratings are proxied to /api/v3/components/* with the caller’s Authorization: Bearer token. Proxy routes transform the backend’s snake_case into the client’s camelCase.

Request lifecycle — generate & save

1

Client → site route

The browser calls the site’s own route (/api/generate for symbols, /api/generate/footprint for footprints) with the user’s JWT.
2

Site route → backend

The route validates input (e.g. description 5–5000 chars) and forwards to POST /api/v3/components/generate/{symbol|footprint} with the token.
3

Backend → AI

The backend runs the AI agent and returns a component (name, kicad_sym/kicad_mod, pin_count/pad_count, trace_json, …).
4

Transform & return

The route maps snake_case → camelCase and returns it. The client renders a preview and offers copy / download.
5

Save (optional)

POST /api/generate/save forwards a SaveComponentPayload (with type) to POST /api/v3/components/generated, which inserts a row into generated_components.

The shared database

A single Supabase project backs both sites. The public.generated_components table holds every AI-generated component; the type column ('symbol' default, or 'footprint') keeps them separate. Symbol-only columns (kicad_sym, pin_count, footprint_filters, reference_prefix) and footprint-only columns (kicad_mod, pad_count, package_type) coexist on the same row shape. See Authentication for how RLS scopes rows to the owner.
Sibling tables component_comments, component_ratings, and component_submissions are also shared and type-agnostic — footprints and symbols use the same rows, filtered by component_type.

Snake_case → camelCase transforms

Proxy routes normalize the backend response so the React layer is camelCase:
Backend (snake)Client (camel) — symbolsClient (camel) — footprints
namesymbolNamefootprintName
kicad_sym / kicad_modkicadSymkicadMod
pin_count / pad_countpinCountpadCount
reference_prefixreference
components: [...]symbols: [...]footprints: [...]
Some fields (description, keywords, datasheet, footprint_filters, trace_json) pass through unchanged.