> ## 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.

# Design Philosophy

> The thinking behind Terra's architectural choices

# Design Philosophy

> Every technical decision encodes a belief. Here's what we believe.

Terra isn't just a forms platform—it's an opinionated take on how government intake infrastructure should work. This page explains the principles that guide our technical decisions.

***

## Principle 1: Applicant Data Is Sacred

Government benefit applications contain the most sensitive information people share: Social Security numbers, income documentation, disability status, immigration records. A data breach doesn't just expose information—it can result in identity theft, benefit denial, or deportation.

**This principle shapes everything:**

| Decision                          | Rationale                                             |
| --------------------------------- | ----------------------------------------------------- |
| Private storage buckets           | Files are never publicly accessible, even by accident |
| Signed URLs with 60s expiry       | Leaked URLs become useless within a minute            |
| Submissions succeed independently | External service failures don't lose applicant data   |
| Defense-in-depth security         | Multiple layers mean single bugs don't cause breaches |

When we face a tradeoff between convenience and data protection, data protection wins. Every time.

***

## Principle 2: Fail Secure, Not Fail Open

Security bugs are inevitable. The question is: when something goes wrong, what happens?

**Fail open** means errors grant access. A crashed permission check lets the user through.

**Fail secure** means errors deny access. A crashed permission check redirects to login.

We chose fail secure:

```typescript theme={null}
// Every permission check follows this pattern
export async function requireAdmin() {
  try {
    const session = await getSession();
    const user = await getUserWithRole(session.user.id);

    if (user?.role !== 'admin' && user?.role !== 'super_admin') {
      throw new Error('Forbidden');
    }

    return user;
  } catch (error) {
    // ANY error = no access
    throw new Error('Unauthorized');
  }
}
```

This extends to every security decision:

* Unknown role? Treat as `applicant` (lowest privilege)
* Can't parse redirect URL? Go to home page
* File path looks suspicious? Reject the upload
* Session decryption fails? Redirect to login

***

## Principle 3: Explicit Over Magic

Frameworks love magic. Automatic code splitting, implicit data fetching, hidden configuration. Magic is convenient until it breaks—then you're debugging something you don't understand.

Terra prefers explicit patterns:

**Server actions, not API routes**

```typescript theme={null}
// Explicit: you see exactly what's happening
"use server";

export async function updateFormStatus(formId: string, status: FormStatus) {
  const user = await requireAdmin();

  await supabaseAdmin
    .from('forms')
    .update({ status })
    .eq('id', formId);

  await logAudit(user.id, 'form.status.updated', { formId, status });

  return { success: true };
}
```

**Manual permission checks, not middleware magic**

```typescript theme={null}
// We check permissions in every action, explicitly
export async function getSubmissions(formId: string) {
  const user = await requireFormAccess(formId); // Explicit check

  // Now we know the user has access
  const submissions = await fetchSubmissions(formId);
  return submissions;
}
```

**Zustand stores, not Context gymnastics**

```typescript theme={null}
// State management is explicit and inspectable
const useFormBuilder = create((set) => ({
  schema: initialSchema,
  selectedFieldId: null,

  addField: (field) => set((state) => ({
    schema: { ...state.schema, elements: [...state.schema.elements, field] }
  })),
}));
```

When you read Terra code, you should understand what's happening without knowing framework internals.

***

## Principle 4: JSON for Flexibility, Zod for Safety

Government forms are weird. Conditional sections, repeatable groups, custom validation rules, translated labels. A normalized database schema would require migrations for every new form feature.

We use JSONB for flexibility:

```typescript theme={null}
// The entire form definition is one JSON tree
const form = {
  id: "rental-assistance",
  schema: {
    elements: [
      { type: "text", id: "name", label: { en: "Full Name" } },
      { type: "group", id: "household", elements: [...] },
      { type: "repeated", id: "income-sources", min: 1, max: 5, template: {...} }
    ]
  }
};
```

But JSON is stringly-typed. You can put anything in there. So we validate with Zod:

```typescript theme={null}
// Runtime validation catches schema errors
export const FormElementSchema = z.discriminatedUnion("type", [
  TextFieldSchema,
  ChoiceFieldSchema,
  GroupFieldSchema,
  RepeatedFieldSchema,
  // ... 20+ field types
]);

// This runs on every schema load
const validated = FormElementSchema.parse(element);
```

The combination gives us:

* **Flexibility**: Add new field types without migrations
* **Safety**: Invalid schemas fail fast with clear errors
* **Portability**: Export/import forms as JSON files
* **Versioning**: Store draft and published schemas side by side

***

## Principle 5: Async by Default

External services fail. Airtable rate limits. Twilio has outages. Webhook endpoints timeout. If form submission depends on external services, applicants suffer for infrastructure problems.

Our solution: **submissions are synchronous, everything else is async**.

```mermaid theme={null}
flowchart LR
    subgraph Sync["Synchronous (blocking)"]
        Submit[Validate + Save]
    end

    subgraph Async["Asynchronous (non-blocking)"]
        Airtable[Airtable Sync]
        Email[Send Email]
        Webhook[Fire Webhook]
    end

    Submit --> Queue[(Queue)]
    Queue --> Airtable
    Queue --> Email
    Queue --> Webhook
```

Benefits:

* Applicants see success in \~300ms regardless of integration health
* Failed operations retry automatically with exponential backoff
* Dead-letter queue captures persistent failures for manual review
* Integration outages don't create support tickets

***

## Principle 6: Server-First, Client-Lite

React traditionally runs in the browser. The server sends HTML, then JavaScript hydrates it into an interactive app. This creates security risks: secrets can leak into client bundles, API keys can be extracted, business logic can be reverse-engineered.

Terra uses React Server Components (RSC) to keep sensitive logic on the server:

```typescript theme={null}
// This component runs ONLY on the server
export default async function SubmissionsPage({ params }) {
  // Database query happens server-side
  const submissions = await getSubmissions(params.formId);

  // Only the rendered HTML goes to the client
  return <SubmissionsTable data={submissions} />;
}
```

Client components exist for interactivity (form inputs, drag-drop, modals) but they receive pre-fetched data rather than making their own API calls.

**What stays on the server:**

* Database credentials and queries
* Permission checks
* File signed URL generation
* Integration API keys
* Encryption/decryption

**What runs on the client:**

* Form input handling (react-hook-form)
* Drag-and-drop (dnd-kit)
* UI state (modals, tabs, accordions)
* File uploads (after receiving signed URL)

***

## Principle 7: White-Label as a Feature

Government agencies have strong brand requirements. Their forms should look like "their" forms, not a third-party service. Terra is designed to be invisible.

**Branding is configurable at every level:**

* Organization: Logo, colors, fonts
* Folder (workspace): Override logo, custom domain
* Form: Override any setting, form-specific domain

**Custom domains are first-class:**

```
housing.example.gov → routes to Housing folder
benefits.example.gov → routes to Benefits folder
apply.example.gov/rental → routes to specific form
```

**Email templates are brandable:**

```tsx theme={null}
<SubmissionReceipt
  logo={organization.branding.logo}
  primaryColor={organization.branding.primaryColor}
  supportUrl={form.supportUrl}
/>
```

The applicant never sees "Terra" or "Unify"—just their agency's brand.

***

## Principle 8: Multi-Language by Design

Government forms serve diverse populations. Language support isn't a plugin—it's baked into the data model.

Every user-facing string is an `I18nString`:

```typescript theme={null}
type I18nString = {
  en: string;
  es?: string;
  zh?: string;
  // ... any language code
};

// Field labels, placeholders, error messages, help text
const field = {
  type: "text",
  label: { en: "Full Name", es: "Nombre Completo" },
  placeholder: { en: "Enter your name", es: "Ingrese su nombre" },
};
```

Translation workflow:

1. Create form in English
2. Add languages to form settings
3. Auto-translate with DeepL (or translate manually)
4. Applicants switch languages at runtime

The form builder shows all languages simultaneously—no switching modes to edit translations.

***

## Principle 9: Audit Everything

When something goes wrong (and it will), you need to know what happened. Terra logs every significant action:

```typescript theme={null}
// Audit log entry structure
{
  user_id: "usr_123",
  action: "form.schema.updated",
  resource_type: "form",
  resource_id: "form_456",
  changes: {
    before: { status: "draft" },
    after: { status: "published" }
  },
  ip_address: "192.168.1.1",
  user_agent: "Mozilla/5.0...",
  created_at: "2025-01-02T10:30:00Z"
}
```

Every form edit, status change, permission grant, and file access is recorded. Audit logs are immutable (append-only table) and retained indefinitely.

This enables:

* Debugging: "Who changed this field label?"
* Compliance: "Show all accesses to this applicant's data"
* Security: "What did this user do before we revoked access?"

***

## Principle 10: Boring Technology (Mostly)

Innovation is expensive. Every new technology requires learning, debugging, and maintenance. Terra uses boring, proven technologies wherever possible:

| Layer      | Technology  | Why                                  |
| ---------- | ----------- | ------------------------------------ |
| Framework  | Next.js     | Massive ecosystem, Vercel support    |
| Database   | PostgreSQL  | 30 years of battle-testing           |
| Validation | Zod         | Simple, composable, TypeScript-first |
| Styling    | Tailwind    | Utility-first, no CSS debugging      |
| State      | Zustand     | Minimal API, great DevTools          |
| Email      | React Email | Just React, render to HTML           |

We reserve complexity for problems that need it:

* Form schema (novel problem → custom solution)
* Async queue (specific requirements → custom table)
* AI form import (genuinely complex → novel approach)

But auth? We use WorkOS. Storage? Supabase. Email delivery? Resend. These are solved problems—we don't need to re-solve them.

***

## Summary

| Principle                | One-liner                                           |
| ------------------------ | --------------------------------------------------- |
| Applicant Data Is Sacred | Protect data above all else                         |
| Fail Secure              | Errors deny access, never grant it                  |
| Explicit Over Magic      | Code should be readable without framework knowledge |
| JSON + Zod               | Flexibility with safety                             |
| Async by Default         | Submissions succeed, integrations retry             |
| Server-First             | Keep secrets and logic on the server                |
| White-Label              | Agencies own their brand                            |
| Multi-Language by Design | I18n isn't an afterthought                          |
| Audit Everything         | Know what happened                                  |
| Boring Technology        | Innovate only where necessary                       |

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Forms Engine" icon="file-lines" href="/core-systems/forms/schema-design">
    How the form schema works
  </Card>

  <Card title="Local Development" icon="laptop-code" href="/operations/local-development">
    Get Terra running on your machine
  </Card>
</CardGroup>
