Leave Localhost logoLeave LocalhostDocs
Architecture

Data Model

The database schema is defined in packages/backend/convex/schema.ts. Convex uses a document-oriented model — each table stores JSON documents with validated shapes.

The database schema is defined in packages/backend/convex/schema.ts. Convex uses a document-oriented model — each table stores JSON documents with validated shapes.

Tables

users

The application-level user record. Created automatically when a Better Auth user signs up (via the onCreate trigger in auth.ts).

FieldTypeDescription
authUserIdstringForeign key to the Better Auth user
namestring?Display name
emailstring?Email address
usernamestring?Chosen username (set during onboarding)
imagestring?Avatar URL
imageIdId<"_storage">?Convex storage ID for uploaded avatar
personalOrganizationIdstring?The user's default personal workspace
activeOrganizationIdstring?Currently selected workspace

Indexes: email, authUserId

organization_profiles

App-owned metadata for each Better Auth organization. Tracks lifecycle status independently of the auth layer.

FieldTypeDescription
organizationIdstringBetter Auth organization ID
ownerUserIdId<"users">Creating user
isPersonalbooleantrue for the auto-created personal workspace
status"active" | "suspended" | "deleted"Lifecycle status
createdAtnumberTimestamp
updatedAtnumberTimestamp

Indexes: by_organizationId, by_ownerUserId_and_isPersonal, by_status

billing_customers

Maps an organization to a billing provider customer.

FieldTypeDescription
organizationIdstringWorkspace identifier
provider"polar" | "stripe" | "lemon_squeezy"Billing provider
providerCustomerIdstringProvider's customer ID
emailstring?Billing email

Indexes: by_organizationId_and_provider, by_provider_and_providerCustomerId

billing_subscriptions

Tracks active and historical subscriptions per organization.

FieldTypeDescription
organizationIdstringWorkspace
providerstringBilling provider
providerSubscriptionIdstringProvider's subscription ID
planKeystringMaps to a billingPlanCatalog entry
statusstringactive, trialing, past_due, canceled, etc.
currentPeriodStart/Endnumber | nullBilling cycle timestamps
cancelAtPeriodEndbooleanWill cancel at cycle end

Indexes: by_organizationId_and_provider, by_provider_and_providerSubscriptionId, by_provider_and_providerCustomerId

billing_grants

Individual capability grants tied to billing events. This is the core of the entitlement system — the rest of the app checks grants, not subscriptions.

FieldTypeDescription
organizationIdstringWorkspace
capabilityKeyCapabilityKeye.g. "feature.pro", "billing.portal"
sourcestringEvent source identifier (e.g. "stripe:subscription:sub_123")
sourceType"subscription" | "one_time" | "manual"How the grant was created
providerstring"polar", "stripe", "lemon_squeezy", or "manual"
planKeystringAssociated billing plan
expiresAtnumber | nullnull for lifetime grants
revokedAtnumber | nullSet when revoked

Indexes: by_organizationId, by_organizationId_and_capabilityKey, by_source_and_capabilityKey

billing_event_sources

Idempotency tracking for billing webhook events.

FieldTypeDescription
sourcestringEvent source identifier
lastEventIdstringLast processed webhook event ID
lastEventTimestampnumberTimestamp of last processed event

workspace_records

Removable demo table for organization-scoped data. See Removing the Workspace Demo.

FieldTypeDescription
organizationIdstringScoping workspace
titlestringRecord title
status"open" | "in_progress" | "done"Record status
createdByUserIdId<"users">Creator

security_verification_challenges

Short-lived step-up verification challenges for sensitive actions. Stores only a salted, peppered hash of the verification code — never the raw code.

FieldTypeDescription
userIdId<"users">User being verified
actionSensitiveActionIdAction being protected
methodVerificationMethod"emailCode", "password", "totp", etc.
codeHashstringSalted+peppered hash
expiresAtnumberTTL timestamp
attemptCountnumberFailed attempts counter

security_verification_grants

Records that a user recently passed step-up verification for a specific action.

FieldTypeDescription
userIdId<"users">Verified user
actionSensitiveActionIdVerified action
expiresAtnumberGrant validity window
usedAtnumber?Set when consumed (single-use grants)

Better Auth Tables

Better Auth manages its own tables for user, session, account, organization, member, invitation, verification, and twoFactor. These are accessed through the Better Auth API, not queried directly from app code.

Relationships

users ──┬── organization_profiles (ownerUserId)
        ├── workspace_records (createdByUserId)
        ├── security_verification_challenges (userId)
        └── security_verification_grants (userId)

organization_profiles ──── billing_customers (organizationId)
                       ├── billing_subscriptions (organizationId)
                       ├── billing_grants (organizationId)
                       └── workspace_records (organizationId)

Next Reads

On this page