Skip to main content

Configuration

Environment Variables

VariableRequiredDescription
DATABASE_URLPostgreSQL connection string
DASHBOARD_BOOTSTRAP_SECRETFirst-time admin setup secret
GOOGLE_CLIENT_IDGoogle OAuth Client ID (dashboard login)
GOOGLE_CLIENT_SECRETGoogle OAuth Client Secret
GOOGLE_REDIRECT_URLGoogle OAuth redirect URL
GOOGLE_ALLOWED_DOMAINSComma-separated allowed email domains
BRAND_THEMEDefault theme (azure, emerald, ruby, amber, orange)
BRAND_COMPANY_NAMECompany name for white-label
LOG_LEVELSet debug for development output

App Names

App names support lowercase letters, numbers, hyphens (-), and underscores (_). Hyphens in the app name are automatically converted to underscores for the PostgreSQL schema (e.g. my-app → schema my_app, URL /my-app/todos).

Apps and Tables

Apps, tables, columns, references, and indexes are created and edited entirely through the Dashboard (/dashboard) — there is no YAML file to author. Each app's JWT secret is generated automatically and stored in the database; each app's schema lives in its own PostgreSQL schema, isolated from every other app.

Column Types

TypePostgreSQL
textTEXT
integerINTEGER
bigintBIGINT
decimalDECIMAL
booleanBOOLEAN
uuidUUID
timestamptzTIMESTAMPTZ
jsonbJSONB

Column Options

FieldDescription
requiredNOT NULL constraint
uniqueUNIQUE constraint
defaultDEFAULT value (SQL expression)
rename_fromRename column on next provision
referencesForeign key to another table in the same app — see below

References (Foreign Keys)

A column can declare a foreign key to another table in the same app:

FieldDescription
tableTarget table name (must exist in the same app)
columnTarget column — must be id or a column declared unique
on_deletecascade, restrict, set_null, or no_action (default)

Cross-app references are not supported — each app's schema is isolated. Circular foreign key dependencies between tables are rejected before any schema change is applied.

Indexes

A table can declare any number of indexes, each with one or more columns:

FieldDescription
nameIndex name, unique across the app
columnsOne or more column names, in the order the index should use
uniqueCreates a UNIQUE INDEX instead of a regular one

Indexes are created idempotently. Removing an index from a table's definition does not drop it from the database — dropping an index is a manual operation.