> ## Documentation Index
> Fetch the complete documentation index at: https://docs.buildwithtrace.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Platform Architecture

> The thin-client proxy model shared by Trace Symbols and Trace Footprints — Next.js route handlers, the FastAPI backend, the shared Supabase table, and static catalog indexes.

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

<CardGroup cols={2}>
  <Card title="Catalog (read)" icon="magnifying-glass">
    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.
  </Card>

  <Card title="Mutations (proxy)" icon="arrows-rotate">
    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`.
  </Card>
</CardGroup>

## Request lifecycle — generate & save

<Steps>
  <Step title="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.
  </Step>

  <Step title="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.
  </Step>

  <Step title="Backend → AI">
    The backend runs the AI agent and returns a component (`name`, `kicad_sym`/`kicad_mod`,
    `pin_count`/`pad_count`, `trace_json`, …).
  </Step>

  <Step title="Transform & return">
    The route maps `snake_case → camelCase` and returns it. The client renders a preview and
    offers copy / download.
  </Step>

  <Step title="Save (optional)">
    `POST /api/generate/save` forwards a `SaveComponentPayload` (with `type`) to
    `POST /api/v3/components/generated`, which inserts a row into `generated_components`.
  </Step>
</Steps>

## 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](/platforms/authentication) for how RLS
scopes rows to the owner.

<Info>
  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`.
</Info>

## Snake\_case → camelCase transforms

Proxy routes normalize the backend response so the React layer is camelCase:

| Backend (snake)           | Client (camel) — symbols | Client (camel) — footprints |
| ------------------------- | ------------------------ | --------------------------- |
| `name`                    | `symbolName`             | `footprintName`             |
| `kicad_sym` / `kicad_mod` | `kicadSym`               | `kicadMod`                  |
| `pin_count` / `pad_count` | `pinCount`               | `padCount`                  |
| `reference_prefix`        | `reference`              | —                           |
| `components: [...]`       | `symbols: [...]`         | `footprints: [...]`         |

Some fields (`description`, `keywords`, `datasheet`, `footprint_filters`, `trace_json`)
pass through unchanged.
