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

# System Context

> The single high-level picture of CONA — who uses it, what runs, and which external systems it talks to

# System Context

The whole platform on one page. This is C4 Level 1: it shows **what CONA talks to**, not
what is inside each part. Every box here has a detail page linked at the bottom.

Deliberately omitted: internal module structure, the 57 `@cona/core` domains, individual
integrations (19 provider families are grouped into two boxes), and the split between
Axiom, Sentry, and PostHog.

### Who uses CONA, and what runs

```mermaid theme={null}
flowchart TB
    OrgUser["Organisation<br/>users"]
    Customer["Document<br/>recipients"]
    Superadmin["CONA staff"]

    subgraph Vercel["Vercel"]
        WebApp["@cona/webapp<br/>cona.app"]
        Portal["@cona/portal"]
        Console["@cona/console"]
    end

    TemporalCloud["Temporal Cloud<br/>33 queues"]
    Workers["temporal-workers<br/>Fly.io fra<br/>28 workers"]

    subgraph Data["Data stores"]
        Postgres["Supabase Postgres<br/>98 models"]
        Redis["Redis"]
        Storage["Supabase Storage"]
    end

    OrgUser -->|"HTTPS, Auth0"| WebApp
    Customer -->|"share token + PLZ"| Portal
    Superadmin -->|"HTTPS, Auth0"| Console

    WebApp -->|"@cona/core"| Postgres
    Portal -->|"@cona/core"| Postgres
    Console -->|"direct Prisma"| Postgres
    Workers -->|"@cona/core"| Postgres

    WebApp --> Redis
    WebApp --> Storage
    Workers --> Redis
    Workers --> Storage

    WebApp -->|"start workflow"| TemporalCloud
    TemporalCloud -->|"queue poll"| Workers

    classDef boundary fill:#f8fafc,stroke:#94a3b8,color:#334155

    classDef app fill:#dbe2fb,stroke:#3B56C5,color:#111827
    classDef data fill:#fde8e8,stroke:#c53b3b,color:#111827
    classDef async fill:#e3f7ea,stroke:#2f9e5c,color:#111827
    classDef actor fill:#eceff4,stroke:#64748b,color:#111827

    class WebApp,Portal,Console app
    class Workers,TemporalCloud async
    class Postgres,Redis,Storage data
    class OrgUser,Customer,Superadmin actor
    class Vercel,Data boundary
```

### What CONA talks to

```mermaid theme={null}
flowchart LR
    Shops["Marketplaces & shops<br/>Shopify · Amazon · TikTok<br/>Otto · Orderchamp · Xentral<br/>6× Mirakl"]
    PSPs["Payment & banking<br/>Stripe · PayPal<br/>Mollie · finAPI"]

    WebApp["@cona/webapp"]
    Workers["temporal-workers"]

    Auth0["Auth0<br/>identity"]
    Email["Resend + org SMTP<br/>customer email"]
    GoogleAPI["Google Drive & Sheets<br/>export destination"]
    AIGateway["Vercel AI Gateway<br/>Mastra agents"]
    Observability["Axiom · Sentry · PostHog"]

    Shops -->|"API sync / CSV"| Workers
    PSPs -->|"API sync"| Workers
    Shops -->|"OAuth callback · webhook"| WebApp
    PSPs -->|"OAuth callback · webhook"| WebApp

    WebApp -->|OIDC| Auth0
    WebApp -->|"document delivery"| Email
    Workers -->|"document delivery"| Email
    WebApp -->|"push export"| GoogleAPI
    WebApp -->|"agent calls"| AIGateway
    Workers -->|"agent calls"| AIGateway
    WebApp -.-> Observability
    Workers -.-> Observability

    classDef app fill:#dbe2fb,stroke:#3B56C5,color:#111827
    classDef async fill:#e3f7ea,stroke:#2f9e5c,color:#111827
    classDef external fill:#fff4dd,stroke:#c98a12,color:#111827
    classDef observability fill:#f0e8fd,stroke:#7c3bc5,color:#111827

    class WebApp app
    class Workers async
    class Shops,PSPs,Auth0,AIGateway,Email,GoogleAPI external
    class Observability observability
```

Portal and console are omitted from the second diagram — neither talks to an external
system beyond Auth0.

## The four deployed units

| Unit                     | Runs on      | Reaches the database via                                      | Detail                                                 |
| ------------------------ | ------------ | ------------------------------------------------------------- | ------------------------------------------------------ |
| `@cona/webapp`           | Vercel       | `@cona/core`, `@cona/database/tracked`, and 40 files directly | [Webapp](/architecture/webapp-architecture)            |
| `@cona/portal`           | Vercel       | `@cona/core` only                                             | [Portal](/architecture/portal-architecture)            |
| `@cona/console`          | Vercel       | **direct Prisma — no core layer**                             | [Console](/architecture/console-architecture)          |
| `@cona/temporal-workers` | Fly.io `fra` | `@cona/core` via activities                                   | [Workers](/architecture/temporal-workers-architecture) |

`@cona/internal-docs` (this site) is a fifth app but has no code edges — it is Mintlify
content only.

## Three ways in

The three entry paths have genuinely different trust properties. This is the most
important thing on the diagram.

<CardGroup cols={3}>
  <Card title="Authenticated app" icon="lock">
    `proxy.ts` enforces an Auth0 session on every request. Covers all pages and most API routes.
  </Card>

  <Card title="Self-verifying" icon="key">
    Webhooks and the Stripe App bypass the auth proxy and verify their own signatures.
  </Card>

  <Card title="Share token + PLZ" icon="link">
    Portal has no middleware, but access is two-factor: the share link plus the customer's postal
    code, then a signed session cookie.
  </Card>
</CardGroup>

See [Data Flows & Trust Boundaries](/architecture/data-flows-trust-boundaries) and
[Ingress](/architecture/ingress-oauth-webhooks).

## Notes

**Data flows in through the workers, not the webapp.** Marketplaces and payment providers
are polled by Temporal activities. The webapp only receives OAuth callbacks and webhooks —
it never pulls provider data itself.

**DATEV is a format, not a connection.** The DATEV export generates files that users
download; no CONA code calls a DATEV API. That is why no DATEV box appears above.

**Google is the one true outbound integration.** `api/export/google-sheets` pushes to
Google Drive. Every other external edge is inbound or a notification.

**File storage is mid-migration.** All new uploads go to Supabase Storage; the UploadThing
store is a read-only shim for legacy URLs
(`packages/core/src/files/composite-file-store.ts:7-11`).

**Observability coverage is uneven** — the dotted lines are not equivalent. Console has
`@axiomhq/js` only; Sentry and PostHog are webapp-only. See
[Observability](/architecture/observability).
