Skip to main content

Database Schema

Database tables and relationships for BFFless.

Overview

BFFless uses two PostgreSQL databases:

  • assethost - Main application data (all tables documented below)
  • supertokens - Authentication data (managed by SuperTokens, separate database)

All schema definitions are in TypeScript at apps/backend/src/db/schema/.

Schema-First Approach

This project uses a schema-first approach. Never write manual SQL migrations - always modify TypeScript schema files and generate migrations.

Table Reference

Core Tables

TableDescription
usersUser accounts
projectsRepository projects containing deployments
assetsUploaded file metadata
deployment_aliasesNamed aliases pointing to specific deployments
api_keysAPI keys for CI/CD authentication
system_configSystem-wide configuration (singleton)

Permissions Tables

TableDescription
user_groupsGroups of users for batch permissions
user_group_membersUser membership in groups
project_permissionsPer-user project access
project_group_permissionsPer-group project access
workspace_invitationsPending user invitations

Domain & Routing Tables

TableDescription
domain_mappingsCustom domain configurations
domain_redirectsDomain-level redirects
domain_traffic_weightsA/B testing traffic splits
domain_traffic_rulesConditional routing rules
primary_contentPrimary domain content settings
path_redirectsPath-level redirects within domains
path_preferencesPer-path settings (e.g., SPA mode)

Proxy Tables

TableDescription
proxy_rule_setsReusable groups of proxy rules
proxy_rulesIndividual reverse proxy configurations

SSL Tables

TableDescription
ssl_challengesACME challenge data for certificate issuance
ssl_settingsSSL configuration key-value pairs
ssl_renewal_historyCertificate renewal audit log

Content Management Tables

TableDescription
cache_rulesHTTP caching behavior per path pattern
retention_rulesAutomatic cleanup policies for old commits
retention_logsAudit log of deleted content
share_linksTemporary access links for private content

Configuration Tables

TableDescription
feature_flagsRuntime feature flag overrides

Core Tables

users

User accounts for authentication and authorization.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
emailVARCHAR(255)No-Unique email address
roleVARCHAR(50)No'member'User role (admin, user, member)
disabledBOOLEANNofalseWhether account is disabled
disabledAtTIMESTAMPYes-When account was disabled
disabledByUUIDYes-Who disabled the account
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

projects

Repository projects that contain deployments.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
ownerVARCHAR(255)No-Repository owner (e.g., "acme-corp")
nameVARCHAR(255)No-Repository name (e.g., "web-app")
displayNameVARCHAR(255)Yes-Optional friendly display name
descriptionTEXTYes-Project description
isPublicBOOLEANNofalseWhether assets are publicly accessible
unauthorizedBehaviorVARCHAR(20)No'not_found''not_found' or 'redirect_login'
requiredRoleVARCHAR(20)No'authenticated'Minimum role for access
settingsJSONBYes-Extensible settings object
defaultProxyRuleSetIdUUIDYes-Default proxy rules for this project
createdByUUIDNo-FK to users.id
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

assets

Uploaded file metadata.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
fileNameVARCHAR(255)No-Original filename
originalPathTEXTYes-Original file path
storageKeyTEXTNo-Storage location key
mimeTypeVARCHAR(100)No-File MIME type
sizeINTEGERNo-File size in bytes
projectIdUUIDNo-FK to projects.id
branchVARCHAR(255)Yes-Git branch name
commitShaVARCHAR(40)Yes-Git commit SHA
assetTypeVARCHAR(20)No'commits''commits', 'uploads', 'static'
deploymentIdUUIDYes-Groups files from same deployment
publicPathTEXTYes-Path within deployment
contentHashTEXTYes-MD5 hash for ETag optimization
committedAtTIMESTAMPYes-Git commit timestamp
createdAtTIMESTAMPNonow()Upload timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

deployment_aliases

Named aliases pointing to specific deployments.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
projectIdUUIDNo-FK to projects.id
repositoryVARCHAR(255)No-Repository identifier (deprecated)
aliasVARCHAR(100)No-Alias name (e.g., "production")
commitShaVARCHAR(40)No-Target commit SHA
deploymentIdUUIDNo-Target deployment ID
isPublicBOOLEANYes-Visibility override (null = inherit)
unauthorizedBehaviorVARCHAR(20)Yes-Access control override
requiredRoleVARCHAR(20)Yes-Role requirement override
isAutoPreviewBOOLEANNofalseAuto-generated preview alias
basePathVARCHAR(512)Yes-Base path for SPA preview
proxyRuleSetIdUUIDYes-Override proxy rules
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

api_keys

API keys for CI/CD authentication.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
nameVARCHAR(255)No-Human-readable key name
keyVARCHAR(255)No-Bcrypt-hashed key value
userIdUUIDNo-FK to users.id
projectIdUUIDYes-FK to projects.id (null = global)
expiresAtTIMESTAMPYes-Optional expiration
lastUsedAtTIMESTAMPYes-Last usage timestamp
createdAtTIMESTAMPNonow()Creation timestamp

system_config

System-wide configuration (singleton table).

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
isSetupCompleteBOOLEANNofalseSetup wizard completed
storageProviderVARCHAR(50)Yes-'local', 'minio', 's3', 'gcs', 'azure'
storageConfigTEXTYes-Encrypted storage credentials
emailProviderVARCHAR(50)Yes-Email provider type
emailConfigTEXTYes-Encrypted email credentials
cacheConfigTEXTYes-Encrypted cache config
jwtSecretTEXTYes-JWT signing secret
apiKeySaltTEXTYes-API key hashing salt
allowPublicSignupsBOOLEANNofalseAllow public registration
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

Permissions Tables

user_groups

Groups of users for batch permissions.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
nameVARCHAR(255)No-Group name
descriptionTEXTYes-Group description
createdByUUIDNo-FK to users.id
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

user_group_members

User membership in groups.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
groupIdUUIDNo-FK to user_groups.id
userIdUUIDNo-FK to users.id
addedByUUIDYes-FK to users.id
addedAtTIMESTAMPNonow()When user was added

project_permissions

Per-user project access.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
projectIdUUIDNo-FK to projects.id
userIdUUIDNo-FK to users.id
roleVARCHAR(50)No-'owner', 'admin', 'contributor', 'viewer'
grantedByUUIDYes-FK to users.id
grantedAtTIMESTAMPNonow()When permission was granted

project_group_permissions

Per-group project access.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
projectIdUUIDNo-FK to projects.id
groupIdUUIDNo-FK to user_groups.id
roleVARCHAR(50)No-'admin', 'contributor', 'viewer'
grantedByUUIDYes-FK to users.id
grantedAtTIMESTAMPNonow()When permission was granted

workspace_invitations

Pending user invitations.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
emailVARCHAR(255)No-Invited email address
roleVARCHAR(32)No'user'Role to assign on acceptance
tokenVARCHAR(255)No-Unique invitation token
invitedByUUIDYes-FK to users.id
expiresAtTIMESTAMPNo-When invitation expires
acceptedAtTIMESTAMPYes-When accepted (null if pending)
acceptedUserIdUUIDYes-FK to users.id (who accepted)
createdAtTIMESTAMPNonow()Creation timestamp

Domain & Routing Tables

domain_mappings

Custom domain configurations.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
projectIdUUIDYes-FK to projects.id
aliasVARCHAR(255)Yes-Target deployment alias
pathVARCHAR(500)Yes-Path within deployment
domainVARCHAR(255)No-Custom domain name (unique)
domainTypeVARCHAR(20)No-'subdomain', 'custom', 'redirect'
redirectTargetVARCHAR(255)Yes-Target for redirect type
isActiveBOOLEANNotrueWhether mapping is active
isPublicBOOLEANYes-Visibility override
sslEnabledBOOLEANNofalseSSL/HTTPS enabled
sslExpiresAtTIMESTAMPYes-Certificate expiration
dnsVerifiedBOOLEANNofalseDNS verification status
autoRenewSslBOOLEANNotrueAuto-renew SSL certificates
stickySessionsEnabledBOOLEANNotrueEnable sticky sessions
stickySessionDurationINTEGERNo86400Session duration in seconds
isSpaBOOLEANNofalseSPA mode (404 → index.html)
isPrimaryBOOLEANNofalsePrimary domain flag
wwwBehaviorVARCHAR(20)Yes-WWW redirect behavior
createdByUUIDNo-FK to users.id
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

domain_traffic_weights

A/B testing traffic splits.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
domainIdUUIDNo-FK to domain_mappings.id
aliasVARCHAR(255)No-Target alias
weightINTEGERNo-Traffic percentage (0-100)
isActiveBOOLEANNotrueWhether weight is active
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

domain_traffic_rules

Conditional routing rules.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
domainIdUUIDNo-FK to domain_mappings.id
aliasVARCHAR(255)No-Target alias
conditionTypeVARCHAR(20)No-'query_param' or 'cookie'
conditionKeyVARCHAR(255)No-Parameter/cookie name
conditionValueVARCHAR(500)No-Value to match
priorityINTEGERNo100Evaluation order (lower first)
isActiveBOOLEANNotrueWhether rule is active
labelVARCHAR(255)Yes-Human-readable label
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

primary_content

Primary domain content settings (singleton per workspace).

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
enabledBOOLEANNofalsePrimary content routing enabled
projectIdUUIDYes-FK to projects.id
aliasVARCHAR(255)Yes-Target alias
pathVARCHAR(500)Yes-Path within deployment
wwwEnabledBOOLEANNotrueEnable www subdomain
wwwBehaviorVARCHAR(50)No'redirect-to-www'WWW redirect behavior
isSpaBOOLEANNofalseSPA mode
configuredByUUIDYes-FK to users.id
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

Proxy Tables

proxy_rule_sets

Reusable groups of proxy rules.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
projectIdUUIDNo-FK to projects.id
nameVARCHAR(255)No-Rule set name (unique per project)
descriptionTEXTYes-Description
environmentVARCHAR(50)Yes-Environment tag
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

proxy_rules

Individual reverse proxy configurations.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
ruleSetIdUUIDNo-FK to proxy_rule_sets.id
pathPatternVARCHAR(500)No-URL pattern to match
targetUrlTEXTNo-Target URL for forwarding
stripPrefixBOOLEANNotrueRemove matched prefix
orderINTEGERNo0Evaluation order
timeoutINTEGERNo30000Request timeout (ms)
preserveHostBOOLEANNofalseKeep original Host header
forwardCookiesBOOLEANNofalseForward cookies to target
headerConfigJSONBYes-Header configuration (encrypted)
authTransformJSONBYes-Auth transformation config
isEnabledBOOLEANNotrueWhether rule is active
descriptionTEXTYes-Rule description
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

SSL Tables

ssl_challenges

ACME challenge data for certificate issuance.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
baseDomainVARCHAR(255)No-Base domain (unique)
challengeTypeVARCHAR(20)No-'dns-01' or 'http-01'
recordNameVARCHAR(255)No-DNS record name
recordValueTEXTNo-TXT record value
tokenVARCHAR(255)No-ACME challenge token
orderDataTEXTNo-Serialized ACME order
authzDataTEXTNo-Serialized authorizations
statusVARCHAR(20)No'pending'Challenge status
expiresAtTIMESTAMPNo-When challenge expires
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

ssl_settings

SSL configuration key-value pairs.

ColumnTypeNullableDefaultDescription
keyVARCHAR(50)No-Setting key (PK)
valueVARCHAR(255)No-Setting value
updatedAtTIMESTAMPNonow()Last update timestamp

ssl_renewal_history

Certificate renewal audit log.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
domainIdUUIDYes-FK to domain_mappings.id
certificateTypeVARCHAR(20)No-'wildcard' or 'individual'
domainVARCHAR(255)No-Domain name (preserved if deleted)
statusVARCHAR(20)No-'success', 'failed', 'skipped'
errorMessageTEXTYes-Error details if failed
previousExpiresAtTIMESTAMPYes-Previous expiration
newExpiresAtTIMESTAMPYes-New expiration
triggeredByVARCHAR(20)No-'auto' or 'manual'
createdAtTIMESTAMPNonow()When renewal occurred

Content Management Tables

cache_rules

HTTP caching behavior per path pattern.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
projectIdUUIDNo-FK to projects.id
pathPatternVARCHAR(500)No-Glob pattern to match
browserMaxAgeINTEGERNo300Browser cache max-age (seconds)
cdnMaxAgeINTEGERYes-CDN s-maxage (seconds)
staleWhileRevalidateINTEGERYes-SWR duration (seconds)
immutableBOOLEANNofalseContent is immutable
cacheabilityVARCHAR(10)Yes-'public' or 'private'
priorityINTEGERNo100Rule priority (lower first)
isEnabledBOOLEANNotrueWhether rule is enabled
nameVARCHAR(100)Yes-Human-readable name
descriptionVARCHAR(500)Yes-Rule description
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

retention_rules

Automatic cleanup policies for old commits.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
projectIdUUIDNo-FK to projects.id
nameVARCHAR(100)No-Rule name
branchPatternVARCHAR(255)No-Glob pattern for branches
excludeBranchesJSONBNo[]Branches to exclude
retentionDaysINTEGERNo-Delete after N days
keepWithAliasBOOLEANNotrueKeep commits with aliases
keepMinimumINTEGERNo0Keep N most recent
pathPatternsJSONBYes-File patterns for partial deletion
pathModeVARCHAR(10)Yes-'include' or 'exclude'
enabledBOOLEANNotrueWhether rule is enabled
lastRunAtTIMESTAMPYes-Last execution time
nextRunAtTIMESTAMPYes-Next scheduled run
lastRunSummaryJSONBYes-Summary of last execution
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

retention_logs

Audit log of deleted content.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
projectIdUUIDNo-FK to projects.id
ruleIdUUIDYes-FK to retention_rules.id
commitShaVARCHAR(40)No-Deleted commit SHA
branchVARCHAR(255)Yes-Branch name
assetCountINTEGERNo-Number of assets deleted
freedBytesBIGINTNo-Bytes freed
isPartialBOOLEANNofalsePartial deletion
deletedAtTIMESTAMPNonow()When deletion occurred

Temporary access links for private content.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
projectIdUUIDYes-FK to projects.id
domainMappingIdUUIDYes-FK to domain_mappings.id
tokenVARCHAR(64)No-Unique share token
labelVARCHAR(255)Yes-Human-readable label
isActiveBOOLEANNotrueWhether link is active
expiresAtTIMESTAMPYes-Optional expiration
lastUsedAtTIMESTAMPYes-Last usage time
useCountINTEGERNo0Number of uses
createdByUUIDNo-FK to users.id
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

Configuration Tables

feature_flags

Runtime feature flag overrides.

ColumnTypeNullableDefaultDescription
idUUIDNorandomPrimary key
keyVARCHAR(100)No-Flag identifier (unique)
valueTEXTNo-Flag value (JSON-encoded)
valueTypeVARCHAR(20)No'boolean''boolean', 'string', 'number', 'json'
descriptionTEXTYes-Human-readable description
enabledBOOLEANNotrueWhether flag is active
createdAtTIMESTAMPNonow()Creation timestamp
updatedAtTIMESTAMPNonow()Last update timestamp

Working with the Schema

Generate Migrations

After modifying schema files:

cd apps/backend
pnpm db:generate

Apply Migrations

pnpm db:migrate

View Database

# Local development
pnpm db:studio

# Docker database
pnpm db:studio:docker

Schema Location

All schema files are in apps/backend/src/db/schema/:

schema/
├── index.ts
├── users.schema.ts
├── projects.schema.ts
├── assets.schema.ts
├── api-keys.schema.ts
├── deployment-aliases.schema.ts
├── system-config.schema.ts
├── user-groups.schema.ts
├── project-permissions.schema.ts
├── workspace-invitations.schema.ts
├── domain-mappings.schema.ts
├── domain-redirects.schema.ts
├── domain-traffic-weights.schema.ts
├── domain-traffic-rules.schema.ts
├── primary-content.schema.ts
├── path-redirects.schema.ts
├── path-preferences.schema.ts
├── proxy-rule-sets.schema.ts
├── proxy-rules.schema.ts
├── ssl-challenges.schema.ts
├── ssl-settings.schema.ts
├── ssl-renewal-history.schema.ts
├── cache-rules.schema.ts
├── retention-rules.schema.ts
├── share-links.schema.ts
└── feature-flags.schema.ts