NNO Docs

Database Schemas

Database schema reference for all NNO services using Cloudflare D1.

Database Schemas

NNO uses Cloudflare D1 (SQLite) for persistence. Each service owns its own isolated database. Two services use Drizzle ORM with a typed schema file; the remaining services manage their schema via raw SQL migration files applied through wrangler.

ServiceDatabase NameORM
Registryregistry-dbDrizzle ORM
IAMiam-dbDrizzle ORM
Billingbilling-dbRaw D1 migrations
Provisioningprovisioning-dbRaw D1 migrations
Stack Registrymarketplace-dbRaw D1 migrations

Registry Database (Drizzle ORM)

Source: services/registry/src/db/schema.ts

The Registry is the authoritative store for all platform catalog data: platforms, their tenant entities, provisioned stacks, Cloudflare resources, feature activations, DNS routing, and audit history.

erDiagram
    platforms ||--o{ entities : "has"
    platforms ||--o{ stacks : "owns"
    platforms ||--o{ platform_build_state : "tracks"
    platforms ||--o{ provision_jobs : "spawns"
    platforms ||--o{ audit_log : "logs"
    platforms ||--o{ platform_lifecycle_events : "records"
    platforms ||--o{ onboarding_sessions : "tracks"
    entities ||--o{ stacks : "tenantId"
    entities ||--o{ resources : "assigned to"
    entities ||--o{ feature_activations : "activates"
    stacks ||--o{ resources : "contains"
    stacks ||--o{ dns_records : "routes"
    resources ||--o{ secrets : "holds"
    resources ||--o{ dns_records : "target of"
    platforms ||--o{ custom_domains : "owns"
    dns_records ||--o{ custom_domains : "backed by"

platforms

The top-level tenant record. Every platform has a unique slug and maps to a Cloudflare account.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
nameTEXTNOT NULLDisplay name
slugTEXTNOT NULL, UNIQUEURL-safe identifier
statusTEXTNOT NULL, default activeactive | suspended | cancelled | deleted
tierTEXTNOT NULL, default starterstarter | growth | scale
cf_account_idTEXTLinked Cloudflare account ID
repo_nameTEXTGitHub repository name
stripe_customer_idTEXTStripe customer reference
owner_user_idTEXTIAM user who owns the platform
cancelled_atINTEGERUnix ms timestamp of cancellation
cancellation_reasonTEXTHuman-readable cancellation reason
suspended_atINTEGERUnix ms timestamp of suspension
suspension_reasonTEXTHuman-readable suspension reason
trial_ends_atINTEGERUnix ms timestamp when trial expires
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp
deleted_atINTEGERUnix ms soft-delete timestamp

Indexes: idx_platforms_slug (slug), idx_platforms_status (status)


entities

Tenant-scoped sub-units within a platform (e.g. organisations, projects, workspaces). Entities can be hierarchical via parent_id.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULLParent platform reference
parent_idTEXTParent entity for nesting (nullable)
typeTEXTNOT NULLEntity type (e.g. tenant, workspace)
nameTEXTNOT NULLDisplay name
slugTEXTNOT NULLPlatform-scoped slug
statusTEXTNOT NULL, default activeactive | inactive | deleted
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp
deleted_atINTEGERUnix ms soft-delete timestamp

Indexes: idx_entities_platform_slug UNIQUE (platform_id, slug), idx_entities_platform (platform_id), idx_entities_parent (parent_id)


stacks

A named grouping of Cloudflare resources deployed for a tenant entity. Each platform has at most one default stack.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
tenant_idTEXTNOT NULL, FK → entities.idOwning entity
platform_idTEXTNOT NULL, FK → platforms.idOwning platform
nameTEXTNOT NULLStack display name
is_defaultINTEGERNOT NULL, default 0Boolean — 1 for the platform's default stack
template_idTEXTSource stack template ID (nullable)
repo_nameTEXTLinked GitHub repository
statusTEXTNOT NULL, default activeactive | inactive | deleted
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp

Indexes: idx_stacks_tenant (tenant_id), idx_stacks_platform (platform_id), idx_stacks_platform_tenant (platform_id, tenant_id), idx_stacks_platform_default UNIQUE (platform_id, is_default) WHERE is_default = 1


resources

Individual Cloudflare resources (Workers, D1 databases, R2 buckets, KV namespaces, etc.) provisioned for a stack.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULLOwning platform
entity_idTEXTNOT NULLOwning entity
stack_idTEXTNOT NULL, FK → stacks.idParent stack
resource_typeTEXTNOT NULLworker | d1 | r2 | kv | pages | etc.
service_nameTEXTNOT NULLLogical service name within the stack
environmentTEXTNOT NULLproduction | staging | development
cf_nameTEXTNOT NULL, UNIQUECloudflare resource name
cf_idTEXTCloudflare-assigned resource ID (nullable until provisioned)
cf_urlTEXTDeployed URL (nullable)
statusTEXTNOT NULL, default pendingpending | provisioning | active | failed | deleted
provision_job_idTEXTLinked provisioning job (nullable)
configTEXTJSON resource configuration blob (nullable)
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp
deleted_atINTEGERUnix ms soft-delete timestamp

Indexes: idx_resources_platform, idx_resources_entity, idx_resources_stack, idx_resources_cf_name, idx_resources_status, idx_resources_type_env (resource_type, environment)


feature_activations

Tracks which feature packages are active for a given entity and environment. Optionally managed by a parent stack instance.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULLOwning platform
entity_idTEXTNOT NULLTarget entity
feature_idTEXTNOT NULLFeature package identifier
feature_versionTEXTNOT NULLSemver version of the activated feature
environmentTEXTNOT NULLproduction | staging | development
statusTEXTNOT NULL, default activatingactivating | active | deactivating | inactive | failed
activated_atINTEGERUnix ms activation timestamp
deactivated_atINTEGERUnix ms deactivation timestamp
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp
stack_instance_idTEXTParent stack instance (NULL = standalone activation)

Indexes: idx_feature_activations_unique UNIQUE (entity_id, feature_id, environment), idx_feature_activations_entity, idx_feature_activations_feature, idx_feature_activations_status, idx_feature_activations_stack


secrets

Tracks the presence (not value) of secrets bound to provisioned resources.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
resource_idTEXTNOT NULLParent resource reference
secret_nameTEXTNOT NULLCloudflare secret binding name
statusTEXTNOT NULL, default missingmissing | set | rotating
last_set_atINTEGERUnix ms timestamp when last updated
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp

Indexes: idx_secrets_resource_secret UNIQUE (resource_id, secret_name), idx_secrets_resource, idx_secrets_status


platform_build_state

One row per platform per environment — tracks the latest Cloudflare Pages deployment state.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULLOwning platform
environmentTEXTNOT NULLproduction | staging
repo_nameTEXTNOT NULLGitHub repository name
last_commit_shaTEXTSHA of the last deployed commit
cf_deployment_idTEXTCloudflare Pages deployment ID
build_statusTEXTNOT NULL, default unknownunknown | queued | building | success | failed
build_urlTEXTCloudflare Pages deployment URL
triggered_byTEXTActor who triggered the build
triggered_atINTEGERUnix ms trigger timestamp
completed_atINTEGERUnix ms completion timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp

Indexes: idx_build_state_platform_env UNIQUE (platform_id, environment)


provision_jobs

Registry-side record of provisioning operations delegated to the Provisioning service.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULLTarget platform
entity_idTEXTNOT NULLTarget entity
operationTEXTNOT NULLPROVISION_PLATFORM | ACTIVATE_FEATURE | DEACTIVATE_FEATURE | DEPROVISION_PLATFORM
statusTEXTNOT NULL, default pendingpending | running | completed | failed
payloadTEXTNOT NULLJSON job input
stepsTEXTJSON array of step results
errorTEXTError message if failed
retry_countINTEGERNOT NULL, default 0Number of retry attempts
max_retriesINTEGERNOT NULL, default 3Maximum allowed retries
created_atINTEGERNOT NULLUnix ms creation timestamp
started_atINTEGERUnix ms start timestamp
completed_atINTEGERUnix ms completion timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp

Indexes: idx_provision_jobs_platform, idx_provision_jobs_status, idx_provision_jobs_created


dns_records

Cloudflare DNS routing rules that map hostnames to provisioned resources within a stack.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULL, FK → platforms.idOwning platform
stack_idTEXTNOT NULL, FK → stacks.idParent stack
hostnameTEXTNOT NULL, UNIQUEFully-qualified hostname
target_typeTEXTNOT NULLworker | pages | etc.
resource_idTEXTNOT NULL, FK → resources.idTarget resource
environmentTEXTNOT NULLproduction | staging
cf_route_idTEXTCloudflare Workers route ID (nullable)
statusTEXTNOT NULL, default pendingpending | active | failed | deleted
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp

Indexes: idx_dns_platform, idx_dns_stack, idx_dns_status


custom_domains

Custom hostnames added by platform operators, backed by a dns_records entry.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULL, FK → platforms.idOwning platform
dns_record_idTEXTNOT NULL, FK → dns_records.idBacking DNS record
hostnameTEXTNOT NULL, UNIQUECustom hostname
target_dnsTEXTNOT NULLDNS target (e.g. Workers subdomain)
cf_hostname_idTEXTCloudflare custom hostname ID
ssl_statusTEXTdefault pendingpending | active | failed
statusTEXTNOT NULL, default pendingpending | active | failed | deleted
verified_atINTEGERUnix ms timestamp of SSL verification
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp

Indexes: idx_custom_domains_platform, idx_custom_domains_status, idx_custom_domains_dns_record


audit_log

Immutable append-only log of all state-changing operations in the Registry.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULLTarget platform
actor_idTEXTNOT NULLUser or service that performed the action
actor_typeTEXTNOT NULLuser | service | system
actionTEXTNOT NULLAction verb (e.g. platform.create, resource.delete)
entity_typeTEXTNOT NULLType of affected resource
entity_idTEXTNOT NULLID of affected resource
beforeTEXTJSON snapshot before change
afterTEXTJSON snapshot after change
metadataTEXTAdditional JSON context
actor_emailTEXTResolved actor email
ip_addressTEXTRequest IP address
user_agentTEXTRequest user-agent string
created_atINTEGERNOT NULLUnix ms event timestamp

Indexes: idx_audit_log_platform, idx_audit_log_entity_id, idx_audit_log_created, idx_audit_log_action


platform_lifecycle_events

Immutable record of every platform status transition.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULLTarget platform
from_statusTEXTNOT NULLPrevious status
to_statusTEXTNOT NULLNew status
triggered_byTEXTNOT NULLActor ID who triggered the transition
trigger_typeTEXTNOT NULLuser | system | stripe
reasonTEXTHuman-readable reason
metadataTEXTAdditional JSON context
created_atINTEGERNOT NULLUnix ms event timestamp

Indexes: idx_lifecycle_platform, idx_lifecycle_created


onboarding_sessions

Tracks the multi-step onboarding flow for new platforms.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULLTarget platform
user_idTEXTNOT NULLIAM user completing onboarding
statusTEXTNOT NULL, default in_progressin_progress | completed | expired | failed
stepsTEXTNOT NULLJSON array of step completion state
stack_template_idTEXTSelected stack template (nullable)
tierTEXTNOT NULLSelected billing tier
provision_job_idTEXTLinked provisioning job (nullable)
current_stepTEXTIdentifier of the active step
metadataTEXTAdditional JSON context
started_atINTEGERNOT NULLUnix ms session start timestamp
completed_atINTEGERUnix ms completion timestamp
expires_atINTEGERUnix ms session expiry timestamp
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp

Indexes: idx_onboarding_platform, idx_onboarding_user, idx_onboarding_status, idx_onboarding_expires


IAM Database (Drizzle ORM)

Source: services/iam/src/core/schema.ts

The IAM database backs the Better Auth authentication library with extensions for the Admin, Organisation, Two-Factor, and API Key plugins. It also stores NNO-specific roles, permission grants, and auth audit logs.

erDiagram
    user ||--o{ session : "authenticates via"
    user ||--o{ account : "linked to"
    user ||--o{ two_factor : "secures with"
    user ||--o{ api_key : "issues"
    user ||--o{ member : "joins org via"
    user ||--o{ invitation : "sends"
    user ||--o{ nno_permission_grants : "granted to"
    organization ||--o{ member : "has"
    organization ||--o{ invitation : "has"
    session ||--o{ audit_authentication : "references"
    audit_authentication }o--|| user : "userId"
    audit_authorization }o--|| user : "userId"

user

Core Better Auth user record, extended with Admin plugin fields, Two-Factor status, and NNO metadata.

ColumnTypeConstraintsDescription
idTEXTPKBetter Auth user ID
nameTEXTDisplay name (nullable)
emailTEXTNOT NULL, UNIQUEUser email address
email_verifiedINTEGERNOT NULL, default falseBoolean — email verification status
imageTEXTAvatar URL (nullable)
created_atINTEGERNOT NULLCreation timestamp
updated_atINTEGERNOT NULLLast-updated timestamp
roleTEXTNOT NULL, default userAdmin plugin: user | admin | superadmin
bannedINTEGERNOT NULL, default falseAdmin plugin: account ban flag
ban_reasonTEXTAdmin plugin: reason for ban
ban_expiresINTEGERAdmin plugin: ban expiry timestamp (nullable = permanent)
two_factor_enabledINTEGERNOT NULL, default falseTwo-Factor plugin: TOTP enabled flag
metadataTEXTJSON user preferences (theme, density, notifications)

session

Active session tokens. Extended with Admin impersonation and Organisation active-org context.

ColumnTypeConstraintsDescription
idTEXTPKSession ID
expires_atINTEGERNOT NULLSession expiry timestamp
tokenTEXTNOT NULL, UNIQUEOpaque session token
created_atINTEGERNOT NULLCreation timestamp
updated_atINTEGERNOT NULLLast-updated timestamp
ip_addressTEXTClient IP address
user_agentTEXTClient user-agent string
user_idTEXTNOT NULL, FK → user.id (CASCADE)Owning user
impersonated_byTEXTAdmin plugin: actor user ID for impersonation sessions
active_organization_idTEXTOrganisation plugin: currently active org

account

OAuth provider tokens and credential storage for external identity providers.

ColumnTypeConstraintsDescription
idTEXTPKAccount ID
account_idTEXTProvider-specific account identifier
provider_idTEXTNOT NULLOAuth provider (e.g. github, google, credential)
user_idTEXTNOT NULL, FK → user.id (CASCADE)Owning user
access_tokenTEXTOAuth access token
refresh_tokenTEXTOAuth refresh token
id_tokenTEXTOpenID Connect ID token
access_token_expires_atINTEGERAccess token expiry timestamp
refresh_token_expires_atINTEGERRefresh token expiry timestamp
scopeTEXTGranted OAuth scopes
passwordTEXTHashed password for credential provider
created_atINTEGERNOT NULLCreation timestamp
updated_atINTEGERNOT NULLLast-updated timestamp

verification

Short-lived tokens used for email verification and password reset flows.

ColumnTypeConstraintsDescription
idTEXTPKVerification ID
identifierTEXTNOT NULLEmail address or other identifier
valueTEXTNOT NULLOne-time verification code or token
expires_atINTEGERNOT NULLExpiry timestamp
created_atINTEGERNOT NULLCreation timestamp
updated_atINTEGERNOT NULLLast-updated timestamp

organization

Multi-tenant workspace records. Each Better Auth organisation maps to an NNO platform.

ColumnTypeConstraintsDescription
idTEXTPKOrganisation ID
nameTEXTNOT NULLOrganisation display name
slugTEXTNOT NULL, UNIQUEURL-safe slug
logoTEXTLogo URL (nullable)
metadataTEXTJSON metadata
created_atINTEGERNOT NULLCreation timestamp
updated_atINTEGERNOT NULLLast-updated timestamp

member

Organisation membership records linking users to organisations with a role.

ColumnTypeConstraintsDescription
idTEXTPKMember ID
organization_idTEXTNOT NULL, FK → organization.id (CASCADE)Parent organisation
user_idTEXTNOT NULL, FK → user.id (CASCADE)Member user
roleTEXTNOT NULL, default memberowner | admin | member
created_atINTEGERNOT NULLCreation timestamp
updated_atINTEGERNOT NULLLast-updated timestamp

invitation

Pending invitations for users to join an organisation.

ColumnTypeConstraintsDescription
idTEXTPKInvitation ID
organization_idTEXTNOT NULL, FK → organization.id (CASCADE)Target organisation
emailTEXTNOT NULLInvitee email address
roleTEXTNOT NULL, default memberRole to assign upon acceptance
statusTEXTNOT NULL, default pendingpending | accepted | cancelled | expired
expires_atINTEGERNOT NULLInvitation expiry timestamp
inviter_idTEXTNOT NULL, FK → user.id (CASCADE)User who sent the invitation
created_atINTEGERNOT NULLCreation timestamp

two_factor

TOTP secrets and backup codes for two-factor authentication.

ColumnTypeConstraintsDescription
idTEXTPKRecord ID
secretTEXTNOT NULLEncrypted TOTP secret
backup_codesTEXTNOT NULLJSON array of hashed backup codes
user_idTEXTNOT NULL, FK → user.id (CASCADE)Owning user
created_atINTEGERNOT NULLCreation timestamp
updated_atINTEGERNOT NULLLast-updated timestamp

api_key

API keys for programmatic access, with optional rate limiting and refill policies.

ColumnTypeConstraintsDescription
idTEXTPKKey ID
nameTEXTNOT NULLHuman-readable key name
prefixTEXTDisplay prefix (e.g. nno_)
hashed_keyTEXTNOT NULLBcrypt-hashed key value
user_idTEXTNOT NULL, FK → user.id (CASCADE)Owning user
rate_limit_enabledINTEGERNOT NULL, default falseWhether rate limiting is active
rate_limit_time_windowINTEGERRate limit window in milliseconds
rate_limit_maxINTEGERMax requests per window
request_countINTEGERNOT NULL, default 0Lifetime request count
remainingINTEGERRemaining requests in current window
expires_atINTEGERKey expiry timestamp (nullable = never)
last_requestINTEGERTimestamp of last request
refill_intervalINTEGERRefill interval in milliseconds
refill_amountINTEGERRequests to add per refill interval
last_refill_atINTEGERTimestamp of last refill
metadataTEXTJSON metadata
permissionsTEXTJSON permissions array
created_atINTEGERNOT NULLCreation timestamp
updated_atINTEGERNOT NULLLast-updated timestamp

audit_authentication

Security audit log for all authentication events. Retained for 90 days.

ColumnTypeConstraintsDescription
idTEXTPKEvent ID
user_idTEXTAuthenticated user (nullable for failed logins)
organization_idTEXTActive organisation at event time
event_typeTEXTNOT NULLlogin | logout | refresh | registration | etc.
authentication_methodTEXTemail_password | api_key | sso | etc.
resultTEXTNOT NULLsuccess | failure | error
ip_addressTEXTClient IP address
user_agentTEXTClient user-agent string
device_infoTEXTJSON device context (browser, OS, device type)
failure_reasonTEXTWhy authentication failed
session_idTEXTAssociated session ID
timestampINTEGERNOT NULLEvent timestamp

audit_authorization

Security audit log for all authorisation decisions. Retained for 90 days.

ColumnTypeConstraintsDescription
idTEXTPKEvent ID
user_idTEXTNOT NULLActor user
organization_idTEXTTenant context
actionTEXTNOT NULLcreate | read | update | delete | invite | etc.
resource_typeTEXTNOT NULLorganization | member | invitation | etc.
resource_idTEXTSpecific resource ID
resultTEXTNOT NULLgranted | denied | error
reasonTEXTReason for denial or error
ip_addressTEXTClient IP address
user_agentTEXTClient user-agent string
session_idTEXTAssociated session ID
timestampINTEGERNOT NULLEvent timestamp

nno_roles

Organisation-scoped roles with associated permission arrays. Unique per (org_id, role) pair.

ColumnTypeConstraintsDescription
idTEXTPKRole ID
org_idTEXTNOT NULLScoping organisation
roleTEXTNOT NULLRole name (e.g. admin, developer, viewer)
permissionsTEXTNOT NULLJSON array of permission strings
created_atINTEGERNOT NULLCreation timestamp
updated_atINTEGERNOT NULLLast-updated timestamp

nno_permission_grants

Explicit per-user permission overrides within an organisation. Can grant or revoke a permission independently of role membership.

ColumnTypeConstraintsDescription
idTEXTPKGrant ID
user_idTEXTNOT NULL, FK → user.id (CASCADE)Target user
org_idTEXTNOT NULLScoping organisation
permissionTEXTNOT NULLPermission string being granted/revoked
grantedINTEGERNOT NULL, default true1 = grant, 0 = revoke
granted_byTEXTNOT NULL, FK → user.idActor who created the grant
expires_atINTEGERExpiry timestamp (nullable = permanent)
created_atINTEGERNOT NULLCreation timestamp

auth_failed_attempts

Tracks failed login attempts per email for progressive brute-force protection.

Policy: 5–9 failures apply exponential delay; 10+ failures lock the account for 30 minutes.

ColumnTypeConstraintsDescription
idTEXTPKRecord ID
user_emailTEXTNOT NULL, UNIQUEEmail address being tracked
attempt_countINTEGERNOT NULL, default 0Cumulative failed attempt count
last_attempt_atINTEGERNOT NULLTimestamp of the most recent failure
locked_untilINTEGERLockout expiry timestamp (nullable = not locked)

Billing Database (D1 Migrations)

Source: services/billing/migrations/

The Billing database stores Stripe subscription records, usage snapshots (per platform and optionally per entity), invoices, usage alerts, and Stripe webhook idempotency state.

subscriptions

One row per platform. Mirrors the active Stripe subscription.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULL, UNIQUEOwning platform
tierTEXTNOT NULLstarter | growth | scale
statusTEXTNOT NULLactive | trialing | past_due | canceled
stripe_customer_idTEXTNOT NULLStripe customer ID
stripe_sub_idTEXTNOT NULLStripe subscription ID
billing_emailTEXTNOT NULLEmail for billing notifications
current_period_startINTEGERNOT NULLBilling period start (Unix ms)
current_period_endINTEGERNOT NULLBilling period end (Unix ms)
cancel_at_period_endINTEGERNOT NULL, default 0Boolean — scheduled for cancellation
trial_startINTEGERTrial period start (Unix ms)
trial_endINTEGERTrial period end (Unix ms)
auto_finalizeINTEGERNOT NULL, default 1Boolean — auto-generate invoice at period end
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp

usage_snapshots

Daily Cloudflare resource consumption snapshots. A NULL entity_id represents the platform-level aggregate; a non-null value represents a per-entity (tenant) breakdown.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULLOwning platform
entity_idTEXTEntity scope (NULL = platform aggregate)
snapshot_dateTEXTNOT NULLDate in YYYY-MM-DD format
worker_invocationsINTEGERNOT NULL, default 0Cloudflare Worker invocations
worker_errorsINTEGERNOT NULL, default 0Cloudflare Worker errors
d1_read_rowsINTEGERNOT NULL, default 0D1 read row operations
d1_write_rowsINTEGERNOT NULL, default 0D1 write row operations
r2_storage_bytesINTEGERNOT NULL, default 0R2 storage in bytes
r2_class_a_opsINTEGERNOT NULL, default 0R2 Class A operations (PUT, COPY, POST)
r2_class_b_opsINTEGERNOT NULL, default 0R2 Class B operations (GET, HEAD)
kv_readsINTEGERNOT NULL, default 0KV read operations
kv_writesINTEGERNOT NULL, default 0KV write operations
collected_atINTEGERNOT NULLUnix ms collection timestamp

Indexes: idx_snapshots_platform_entity_date UNIQUE (platform_id, COALESCE(entity_id, ''), snapshot_date), idx_snapshots_entity (entity_id, snapshot_date) WHERE entity_id IS NOT NULL


invoices

Monthly invoice records generated from usage snapshots.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULLOwning platform
entity_idTEXTEntity scope (nullable)
stripe_invoice_idTEXTStripe invoice ID (nullable until synced)
period_startINTEGERNOT NULLBilling period start (Unix ms)
period_endINTEGERNOT NULLBilling period end (Unix ms)
statusTEXTNOT NULLdraft | open | paid | void | uncollectible
tierTEXTNOT NULLTier at time of invoice
base_amountINTEGERNOT NULLBase subscription amount (cents)
overage_amountINTEGERNOT NULLUsage overage amount (cents)
total_amountINTEGERNOT NULLTotal charged (cents)
line_itemsTEXTNOT NULLJSON array of line items
pdf_urlTEXTStripe PDF URL
due_dateINTEGERPayment due date (Unix ms)
paid_atINTEGERPayment timestamp (Unix ms)
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp

Indexes: idx_invoices_platform (platform_id, status), idx_invoices_entity (entity_id, status) WHERE entity_id IS NOT NULL


usage_alerts

Records when a platform crosses a usage threshold (50%, 75%, 90%, 100%) for any metered resource in a billing period.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
platform_idTEXTNOT NULLOwning platform
resourceTEXTNOT NULLResource type (e.g. worker_invocations, d1_read_rows)
threshold_pctINTEGERNOT NULLThreshold that was crossed: 50 | 75 | 90 | 100
triggered_atINTEGERNOT NULLUnix ms trigger timestamp
notified_atINTEGERUnix ms notification send timestamp (NULL = not yet sent)
periodTEXTNOT NULLBilling period in YYYY-MM format

Indexes: idx_alerts_platform (platform_id, period)


stripe_events

Idempotency log for Stripe webhook events.

ColumnTypeConstraintsDescription
stripe_event_idTEXTPKStripe event ID (used as idempotency key)
event_typeTEXTNOT NULLStripe event type (e.g. invoice.paid)
processed_atINTEGERNOT NULLUnix ms processing timestamp
payloadTEXTNOT NULLFull Stripe event JSON

Provisioning Database (D1 Migrations)

Source: services/provisioning/migrations/

The Provisioning database tracks all Cloudflare resource lifecycle jobs — creation, rollback, and the dead-letter queue for failed operations.

provisioning_jobs

One row per provisioning operation. Jobs progress through a state machine; failed jobs that exhaust retries are routed to the DLQ.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
typeTEXTNOT NULLPROVISION_PLATFORM | ACTIVATE_FEATURE | DEACTIVATE_FEATURE | DEPROVISION_PLATFORM
platform_idTEXTNOT NULLTarget platform
entity_idTEXTTarget entity (nullable for platform-scoped jobs)
feature_idTEXTTarget feature (nullable)
environmentTEXTTarget environment (nullable)
billing_emailTEXTBilling email captured at job creation
plan_tierTEXTBilling tier captured at job creation
statusTEXTNOT NULL, default PENDINGPENDING | RUNNING | COMPLETED | FAILED | TIMED_OUT | ROLLING_BACK | ROLLED_BACK
stepsTEXTNOT NULL, default []JSON array of ProvisioningStep results
errorTEXTError message on failure
stack_instance_idTEXTLinked stack instance ID (nullable)
stack_idTEXTStack template ID (nullable)
stack_versionTEXTStack template version (nullable)
shared_resourcesTEXTJSON map of shared resource IDs (nullable)
sub_jobsTEXTJSON array of child job IDs (nullable)
workspace_stack_idTEXTWorkspace-level stack reference (nullable)
rolled_back_atINTEGERUnix ms rollback completion timestamp
rollback_errorTEXTError message during rollback
dlq_entry_idTEXTDLQ entry ID for failed jobs
started_atINTEGERUnix ms job start timestamp
completed_atINTEGERUnix ms job completion timestamp
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp

Indexes: idx_jobs_platform (platform_id, status), idx_jobs_status (status, created_at), idx_provisioning_jobs_stack_instance (stack_instance_id) WHERE stack_instance_id IS NOT NULL


Stack Registry Database (D1 Migrations)

Source: services/stack-registry/migrations/

The Stack Registry stores versioned stack template definitions. Each template describes a named set of Cloudflare resources and features; versions are immutable once published.

stack_templates

A named, versioned stack blueprint available for platform provisioning.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
nameTEXTNOT NULL, UNIQUEMachine-readable template name (e.g. saas-starter)
display_nameTEXTNOT NULLHuman-readable display name
descriptionTEXTNOT NULLTemplate description
iconTEXTIcon URL or identifier (nullable)
domainTEXTTarget domain category (nullable)
latest_versionTEXTSemver of the latest published version
statusTEXTNOT NULL, default activeactive | deprecated | removed
created_atINTEGERNOT NULLUnix ms creation timestamp
updated_atINTEGERNOT NULLUnix ms last-updated timestamp

Indexes: idx_stack_templates_status (status)


stack_versions

Immutable versioned snapshots of a stack template definition.

ColumnTypeConstraintsDescription
idTEXTPKNanoID identifier
template_idTEXTNOT NULL, FK → stack_templates.idParent template
versionTEXTNOT NULLSemver version string
stack_definitionTEXTNOT NULLJSON stack definition payload
nno_sdk_versionTEXTNOT NULLMinimum NNO SDK version required
statusTEXTNOT NULL, default activeactive | deprecated
published_atINTEGERNOT NULLUnix ms publication timestamp
created_atINTEGERNOT NULLUnix ms creation timestamp

Constraints: UNIQUE (template_id, version)

Indexes: idx_stack_versions_template (template_id), idx_stack_versions_status (template_id, status)


Timestamp Conventions

All services use Unix millisecond integers for timestamps unless otherwise noted. The IAM service uses Drizzle's { mode: "timestamp" } option, which maps to Unix seconds at the SQLite layer.

ConventionServicesFormat
Unix millisecondsRegistry, Billing, Provisioning, Stack RegistryINTEGER (ms since epoch)
Unix seconds (timestamp mode)IAMINTEGER (seconds since epoch, via Drizzle)

Integer Boolean Conventions

SQLite has no native boolean type. All boolean columns use INTEGER with values 0 (false) and 1 (true). In the IAM service Drizzle schema, { mode: "boolean" } is used so the ORM handles coercion transparently.

On this page