Tenancy and identity models

Subscription

Table Subscription. The tenant boundary — a workspace.

Field Type Notes

id

String @id @db.Uuid

name

String

Display name; created as "<user>'s Organization" on first signup

createdAt, updatedAt

DateTime

callCycleBudgetUsd

Float?

Call-spend cap in USD for the Eastern billing cycle, the calendar month (1st 00:00 through the last day 23:59). Null means the workspace is not checked. A twice-daily Inngest cron pauses running call campaigns when cycle spend is over this cap.

It is the parent of essentially every domain model: users, campaigns, phoneNumbers, calls, campaignTargets, aiAgents, aiAgentVersions, callAiAgentAnalysisResults, configs, agentTestCases, activities, sellers, contacts, emailCampaignTargets, emailVariations, emailSendingDomains, domains, targetPhoneNumbers, targetEmails, emails, salesReps, followUpTasks, contactSequences, sequenceTemplates, blockedPhoneNumbers.

SubscriptionUser

Table SubscriptionUser. The bridge between a Profile and a Subscription.

Field Type Notes

subscriptionId

String @db.Uuid

profileId

String @db.Uuid

onDelete: Cascade — deleting a profile removes its memberships

role

SubscriptionUserRole

owner, admin, member; default member

Unique: (subscriptionId, profileId) — the constraint resolveSubscription() queries to verify membership. Index: profileId, for "which workspaces does this user belong to".

Roles are enforced in the /api/subscriptions/members routes; see Authorization.

Profile

Table Profile. The application record of a Supabase user. Global, not workspace-scoped.

Field Type Notes

supabaseUserId

String @unique @db.Uuid

Link to Supabase Auth

name

String

email

String? @unique

phoneNumber

String? @unique

justcallUserId

String? @unique

Legacy JustCall agent link

isAvailable

Boolean

Availability for human calling; default false

maxConcurrentCalls

Int

Default 1

activeCalls

Int

Default 0

Index: (isAvailable, activeCalls) — finding an available agent.

Relations: calls, subscriptionUsers, salesReps.

isAvailable, activeCalls and justcallUserId are the remains of the JustCall-era human agent model, still maintained by the handle_justcall_call_initiated() database trigger. Current rep identity lives on SalesRep, which is workspace-scoped and carries CRM ids — see SalesRep.

Signup

createProfileAndSubscriptionForUser({ supabaseUserId, name, email }) in lib/auth/subscription.ts:

  1. Upsert the Profile on supabaseUserId.

  2. If the profile has no membership at all, create a Subscription named "<name>'s Organization" and a SubscriptionUser with role owner.

The membership check means the function is idempotent — calling it again for an existing user does not create a second workspace.