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

# Architecture Overview

> Components, certificate flow, persistence, configuration, and deployment for DelegatedSSL.

# Architecture Overview

## Workspaces

The repository is a pnpm monorepo with three deployable surfaces:

| Workspace | Purpose | Deployed route |
| - | - | - |
| `apps/marketing` | Public-facing `delegatedssl.com` website (React 19, Vite) | `delegatedssl.com` |
| `apps/portal` | Authenticated agency operations console (React 19, Vite) | `app.delegatedssl.com` |
| `apps/api-worker` | Cloudflare Worker API (Hono) | `api.delegatedssl.com` |

Additional directories: `database/supabase/` (PostgreSQL schema and migrations), `database/azure/` (runtime roles, RLS, billing/email schemas).

## Domain and certificate flow

1. A domain create request normalizes the hostname and rejects an invalid or duplicate apex within the organization.
2. The API obtains the Cloudflare delegated-DCV UUID and builds a CNAME at `_acme-challenge.<domain>`.
3. It creates a Cloudflare for SaaS custom hostname with `ssl.method` set to `txt` and `ssl.type` set to `dv`.
4. The domain row stores the custom-hostname identifier, delegation record, validation state, certificate state, client link, tags, and notes.
5. Verify and recheck operations retrieve the custom hostname from Cloudflare and map Cloudflare hostname and SSL states into DelegatedSSL's validation, certificate, and operational states.

Certificate issuance is per hostname. `POST /v1/domains/:id/certificates/issue` rejects `wildcard: true`.

The API sends the smallest supported Custom Hostname create payload: `hostname` plus `ssl.method = "txt"` and `ssl.type = "dv"`. No `custom_origin_server`, wildcard settings, minimum TLS overrides, or other optional fields. The SaaS zone fallback hostname is `fallback.delegatedssl.com`, configured in Cloudflare.

## Persistence model

The PostgreSQL schema centers on organizations, users, organization memberships, clients, domains, certificates, and verification links. Supporting tables store audit events, API keys, idempotency records, outbound webhooks, white-label settings, support tickets, webhook delivery records, and email delivery state. Stripe customer and subscription fields are stored on organization rows.

Organization memberships use `owner`, `admin`, `operator`, and `read_only` roles. Tenant-owned records carry an organization identifier, and Azure migrations enable row-level-security policies for the Worker database role.

Database migrations live in `database/supabase/migrations/` (ordered upgrades), `database/supabase/schema.sql` (greenfield schema), and `database/azure/` (runtime roles and RLS policies).

## Authentication and request controls

The API accepts Auth0 JWT access tokens and `dssl_` API keys as bearer tokens. Auth0 JWTs are verified against the configured issuer and audience. API keys are hashed for lookup, assigned explicit scopes, and downgraded to organization-scoped database access before route handling.

The Worker applies a Durable Object rate limiter to `/v1/*` (240 req/60s) and tighter namespaces to public verification (30 req/60s), auth, and webhook routes. Authenticated non-read requests can use the PostgreSQL-backed idempotency middleware (24-hour replay ledger).

## Entitlement and plan limits

Organization plan limits are enforced at the API layer on single domain creation, bulk domain creation, and team invitations:

| Plan | Domain limit | Seat limit |
| - | - | - |
| Agency | 250 | 10 |
| Enterprise | 2,000+ | Unlimited |

Subscriptions in `past_due` status maintain full limits while Stripe retries card payment. An org with no subscription and no started trial has its Agency trial started on its first gated action. Only terminal non-payment (`unpaid`, `canceled`, `incomplete_expired`) downgrades to 0 domains and 1 seat.

## Deployment

* `pnpm run deploy:marketing` — deploys the marketing site to Cloudflare Pages.
* `pnpm run deploy:portal` — deploys the portal to Cloudflare Workers.
* `pnpm run deploy:api` — deploys the API Worker.
* CI validates every affected component, applies selected database migrations before the API, and requires API health before publishing affected frontends.

## Configuration contract

Production startup validation requires the database connection, rate limiting, HTTPS URLs, and core identity settings. Configuration is supplied by the deployment environment; no credential values or setting names are published here.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.