Persistence and environments
MAIL-72 stands up the PostgreSQL migration runner and fail-closed environment validation. Domain tables are added by later tickets.
Host
| Item | Value |
|---|---|
| Project | Supabase Sandbox |
| Ref | hijznwisiirxdknbnvyz |
| Host | db.hijznwisiirxdknbnvyz.supabase.co |
| Schema | inbox_agent |
This is a shared database. Never drop unrelated schemas or tables. See ADR 0002.
Required environment
Process start (loadRequiredEnv in @inbox-agent/config) refuses to boot unless all of the following are present and valid:
| Variable | Rule |
|---|---|
APP_ENV | local, preview, production, or test |
DATABASE_URL | postgres:// or postgresql:// URL |
TOKEN_ENCRYPTION_KEY | secret, at least 32 characters |
SESSION_SECRET | secret, at least 32 characters |
Copy .env.example to a local .env that is never committed. Do not put secrets in Git, fixtures, docs, or Jira.
ENABLE_SEND and ENABLE_DELETE remain default-off feature flags (MAIL-70). They are not substitutes for the secrets above.
Migrations
SQL files live in database/migrations/ as NNNN_name.sql. The runner:
- Applies pending files in version order inside a transaction
- Records version, name, and SHA-256 checksum in
inbox_agent.schema_migrations - Refuses checksum drift for an already-applied version
Current head (MAIL-96): 0011_conversation_states.sql — conversation-level attention keyed by thread_id (ADR 0009). Sprint 02 added connected_accounts through conversation_states (0004–0011). MAIL-74 0003_encrypted_provider_tokens.sql remains ciphertext-only. MAIL-73 0002_users.sql and MAIL-72 0001_inbox_agent_bootstrap.sql are unchanged. See canonical schema.
# Real Postgres (local service, CI service, or Supabase). Fails closed without DATABASE_URL.
npm run db:migrate
# CI gate: DATABASE_URL when set, otherwise ephemeral PGlite.
npm run migrate:ci
migrate:ci is the hook reserved by MAIL-70. This ticket supplies the runner that applies SQL.
Queue (Sprint 01)
PostgreSQL transactional outbox only. Do not add Redis or SQS. The outbox table is a later migration.
RLS
inbox_agent.schema_migrations, inbox_agent.users, and inbox_agent.provider_tokens have row-level security enabled. anon and authenticated are revoked when those roles exist. Keep inbox_agent off the Supabase Data API until a later ticket defines an access model.
Provider token ciphertext is not readable from the database alone. Decrypt requires TOKEN_ENCRYPTION_KEY via TokenSecretStore. See provider token encryption and ADR 0004.
