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

# Core Concepts

> Mental models for understanding Terra's architecture

# Core Concepts

> Before diving into code, understand the mental models that shape Terra's design.

Terra is a forms platform for government benefit programs. But it's not just a form builder—it's an intake infrastructure that handles identity, file storage, multi-language support, and downstream integrations. To work effectively with the codebase, internalize these five core concepts.

***

## 1. Forms Are Trees, Not Tables

Traditional form builders store fields in database tables. Terra stores entire forms as **recursive JSON trees**.

```mermaid theme={null}
flowchart TD
    Form[Form Schema] --> Page1[Page: Personal Info]
    Form --> Page2[Page: Household]
    Page1 --> Name[Text: Full Name]
    Page1 --> DOB[Date: Date of Birth]
    Page2 --> Members[Repeated: Household Members]
    Members --> MemberName[Text: Member Name]
    Members --> Relationship[Choice: Relationship]
```

This design emerged from a specific problem: government forms have deeply nested conditional logic. "If you have dependents, list them. If any dependent has a disability, show the accommodation questions." Relational tables require complex joins for this; JSON trees handle it naturally.

**What this means for you:**

* Form definitions live in a single JSONB column
* Adding new field types doesn't require migrations
* The `FormElement` type is recursive—groups contain elements that can themselves be groups
* Export/import works by serializing the entire tree

See [Schema Design](/core-systems/forms/schema-design) for the full implementation.

***

## 2. Identity Is Decoupled

Terra separates **authentication** (who are you?) from **authorization** (what can you do?).

```mermaid theme={null}
flowchart LR
    User[User] --> WorkOS[WorkOS AuthKit]
    WorkOS --> Session[Encrypted Session]
    Session --> ServerAction[Server Action]
    ServerAction --> PermCheck[Permission Check]
    PermCheck --> Supabase[Supabase + Service Role]
```

**WorkOS** handles authentication—login flows, SSO with enterprise identity providers, session tokens. But WorkOS doesn't know about your forms or permissions.

**Supabase** stores your data, but we don't use Supabase Auth. Instead, server actions use a `service_role` client that bypasses Row Level Security, then manually enforce permissions.

Why this split? Government agencies often require SAML/OIDC integration with Azure AD or Okta. WorkOS makes this trivial. Meanwhile, keeping authorization in application code (not RLS) makes permission logic explicit and auditable.

**What this means for you:**

* The `getSession()` helper returns WorkOS user data
* All Supabase queries use `supabaseAdmin` (service role)
* Permission checks happen in server actions, not database policies
* Roles are stored in a local `user_profiles` table, not WorkOS

See [Authentication](/core-systems/identity/authentication) and [Authorization](/core-systems/identity/authorization) for details.

***

## 3. Submissions Succeed, Integrations Retry

When an applicant submits a form, many things need to happen: save to database, sync to Airtable, send confirmation email, fire webhooks. If the Airtable sync fails, should the submission fail?

**No.** The applicant's data is sacred. We save it first, then process everything else asynchronously.

```mermaid theme={null}
sequenceDiagram
    participant A as Applicant
    participant S as Server
    participant DB as Database
    participant Q as Async Queue
    participant I as Integrations

    A->>S: Submit form
    S->>DB: Save submission
    S->>A: "Thank you" page
    S->>Q: Enqueue jobs
    Q->>I: Sync to Airtable
    Q->>I: Send email
    Q->>I: Fire webhooks
    I-->>Q: Retry on failure
```

The `async_operations` table is a persistent queue. Jobs have states (pending, processing, completed, failed), retry with exponential backoff, and eventually land in a dead-letter state for manual review.

**What this means for you:**

* Submission success is independent of integration success
* Look at `async_operations` to debug webhook failures
* Background jobs run via `/api/queue/process` (cron-triggered)
* Never block submission on external API calls

See [Queue Architecture](/core-systems/async/queue-architecture) for the full system.

***

## 4. Multi-Tenancy Through Folders

Terra supports multiple organizations, but not through a traditional tenant model. Instead, **folders** (internally called workspaces) provide logical grouping.

```mermaid theme={null}
flowchart TD
    Org[Organization] --> F1[Folder: Housing Programs]
    Org --> F2[Folder: Food Assistance]
    F1 --> Form1[Form: Rental Assistance]
    F1 --> Form2[Form: Emergency Housing]
    F2 --> Form3[Form: SNAP Application]

    F1 --> D1[Custom Domain: housing.example.gov]
    F2 --> D2[Custom Domain: food.example.gov]
```

Each folder can have:

* Its own custom domain
* Shared branding (logo, colors)
* Team members with folder-scoped access

Agencies are a layer above folders—an agency can have multiple folders across different programs. This enables a single organization to run many benefit programs under different brands.

**What this means for you:**

* Forms belong to folders (nullable—some are "uncategorized")
* Custom domains are resolved in middleware
* Team permissions cascade: org admins see all, folder members see their folder
* The `agencies` system is for external partners managing multiple clients

See [Multi-Tenancy](/core-systems/identity/multi-tenancy) for the full model.

***

## 5. Security Is Layered

Government platforms handle SSNs, bank accounts, medical records. A single security bug could expose thousands of applicants. Terra uses **defense-in-depth**: every security-sensitive operation has multiple independent checks.

```mermaid theme={null}
flowchart TD
    Input[User Input] --> L1[Layer 1: Client Validation]
    L1 --> L2[Layer 2: Server Validation]
    L2 --> L3[Layer 3: Storage Validation]
    L3 --> DB[Database]

    L1 -.->|Fails| Reject1[Reject]
    L2 -.->|Fails| Reject2[Reject]
    L3 -.->|Fails| Reject3[Reject]
```

For file uploads:

1. **Client**: `cleanFileName()` removes path traversal attempts
2. **Server**: `buildSafeStoragePath()` constructs validated paths
3. **Storage**: `sanitizeStoragePath()` validates before saving

For redirects:

1. **Input**: Parse URL and check protocol
2. **Validation**: Ensure same-origin or allowed list
3. **Default**: Fail-secure to home page if anything is suspicious

**What this means for you:**

* Use centralized security utilities in `src/lib/security.ts`
* Never trust user input, even after client validation
* When in doubt, fail secure (deny access, redirect home)
* XSS: Always sanitize with DOMPurify before rendering HTML

See [Security](/operations/security) for implementation details.

***

## How These Concepts Connect

```mermaid theme={null}
flowchart TD
    subgraph Identity
        Auth[WorkOS Auth]
        Perms[Permission Checks]
    end

    subgraph Forms
        Schema[JSON Schema]
        Builder[Form Builder]
        Renderer[Form Renderer]
    end

    subgraph Data
        DB[(Supabase)]
        Storage[(Private Files)]
        Queue[(Async Queue)]
    end

    subgraph Integrations
        Airtable[Airtable]
        Email[Resend]
        Webhooks[Webhooks]
    end

    Auth --> Perms
    Perms --> Builder
    Perms --> DB
    Schema --> Renderer
    Renderer --> DB
    Renderer --> Storage
    DB --> Queue
    Queue --> Airtable
    Queue --> Email
    Queue --> Webhooks
```

A typical flow:

1. User authenticates via WorkOS
2. Permission check determines what they can do
3. Form builder modifies the JSON schema
4. Schema renders into a public form
5. Applicant submits → data saved to Supabase
6. Queue picks up async jobs
7. Integrations sync to external systems

***

## Next Steps

<CardGroup cols={2}>
  <Card title="System Map" icon="diagram-project" href="/foundation/system-map">
    Visual overview of all Terra components
  </Card>

  <Card title="Design Philosophy" icon="lightbulb" href="/foundation/design-philosophy">
    Why we built it this way
  </Card>
</CardGroup>
