# Admin App Access Setup

The admin app is designed to be internal-only and requires a separate privileged token flow.

## Required admin worker configuration

Set these values for `apps/admin`:

- `ADMIN_APP_ACCESS_TOKEN`
- `ADMIN_APP_SESSION_SECRET`

`ADMIN_APP_ACCESS_TOKEN` is the first-layer token required before the admin SPA will be served.
`ADMIN_APP_SESSION_SECRET` signs the worker-issued app session cookie after that token is accepted.

Production domain: `https://admin-panel.xtablo.com`

## Deploy commands

Use the root command:

```bash
pnpm deploy:admin
```

Or directly from the app package:

```bash
pnpm --filter @xtablo/admin run deploy
```

## Required API configuration

Set these values for `apps/api`:

- `ADMIN_TOKEN_SIGNING_SECRET`
- `ADMIN_TOKEN_AUDIENCE`
- `ADMIN_APP_URL`

`ADMIN_TOKEN_SIGNING_SECRET` signs short-lived admin session tokens.
`ADMIN_TOKEN_AUDIENCE` scopes privileged access to the admin app only.
`ADMIN_APP_URL` is the allowed frontend origin for the admin surface, for example `https://admin-panel.xtablo.com`.

## Access model

1. The operator reaches the private `apps/admin` deployment from the internal network boundary.
2. The admin worker presents a dedicated app-access gate before any SPA asset is served.
3. The operator submits the app access token, and the worker issues a signed session cookie.
4. Only then does the browser load the React admin shell.
5. Inside the shell, the operator pastes a separate privileged admin API token.
6. `POST /admin/auth/exchange` validates that token and returns a short-lived `admin_session`.
7. The admin app stores that session locally and attaches it as a bearer token for admin routes.
8. All privileged data and mutations go through `/admin/*` API routes guarded by admin middleware.

Normal product auth is not sufficient for admin access.

## Current guarded routes

- `GET /admin/overview`
- `GET /admin/tables`
- `GET /admin/tables/:tableId/meta`
- `GET /admin/tables/:tableId/rows`
- `PATCH /admin/tables/:tableId/rows/:rowId`
- `GET /admin/datasets`
- `GET /admin/datasets/:datasetId`
- `GET /admin/actions`
- `POST /admin/actions/:actionId/run`

All write paths emit admin audit log entries.

## Local development

- Run the API and local Supabase stack.
- Start the admin app with `pnpm dev:admin`.
- Configure worker env for `ADMIN_APP_ACCESS_TOKEN` and `ADMIN_APP_SESSION_SECRET`.
- Use the app-access token at the worker gate, then use a valid privileged API token compatible with `ADMIN_TOKEN_SIGNING_SECRET` and `ADMIN_TOKEN_AUDIENCE`.

## Initial action coverage

- `deactivate_tablo_access`
- `grant_tablo_admin`

## Initial analytics coverage

- `profile_growth`
- `plan_mix`
- `tablo_access_mix`
