Skip to main content

Scheduling Tables

The scheduling system supports dual-mode booking: client-owned booking links (for candidate scheduling) and user-owned booking links (for internal sales meetings). Both modes share the same booking_links table but use separate calendar connection and meeting tables.

Public booking URLs. Each link generates a page at /book/:slug where someone can self-schedule a meeting.

ColumnTypeNullableDefaultDescription
iduuidNOgen_random_uuid()Primary key
slugtextNOURL slug (unique) -- forms the booking URL /book/:slug
titletextYESDisplayed on the booking page
duration_minutesintegerYES30Meeting duration
client_iduuidYESFK to clients.id (nullable)
user_iduuidYESFK to auth.users.id (nullable)
market_iduuidYESFK to markets.id (optional)
campaign_iduuidYESFK to campaigns.id (optional)
is_activebooleanYEStrueWhether the link is accepting bookings
custom_questionsjsonbYESAdditional form questions on booking page
created_attimestamptzYESnow()
updated_attimestamptzYESnow()

Ownership Constraint

CHECK (client_id IS NOT NULL OR user_id IS NOT NULL)

A booking link must be owned by either a client or a user (or both, though in practice it is one or the other).

Dual-Mode Detection

The booking page determines the mode based on the ownership:

const isInternalLink = !bookingLink?.client_id && !!bookingLink?.user_id;
ModeOwnershipCalendar TableMeeting TableContact Table
Clientclient_id setcalendar_connectionsmeetingscontacts
Internal (User)user_id set, client_id nulluser_calendar_connectionssales_meetingssales_prospects

calendar_connections

OAuth tokens for client-owned calendar integrations. Used to check availability and create events in the client's calendar.

ColumnTypeNullableDefaultDescription
iduuidNOgen_random_uuid()Primary key
client_iduuidNOFK to clients.id
providertextNOCalendar provider: google or outlook
access_tokentextYESOAuth access token (encrypted at rest)
refresh_tokentextYESOAuth refresh token
token_expires_attimestamptzYESToken expiration time
calendar_idtextYESSelected calendar ID (e.g., primary)
connected_emailtextYESEmail associated with the calendar
is_activebooleanYEStrueWhether connection is active
created_attimestamptzYESnow()
updated_attimestamptzYESnow()

user_calendar_connections

OAuth tokens for internal user-owned calendar integrations. Same schema as calendar_connections but keyed by user_id instead of client_id.

ColumnTypeNullableDefaultDescription
iduuidNOgen_random_uuid()Primary key
user_iduuidNOFK to auth.users.id
providertextNOCalendar provider: google or outlook
access_tokentextYESOAuth access token
refresh_tokentextYESOAuth refresh token
token_expires_attimestamptzYESToken expiration time
calendar_idtextYESSelected calendar ID
connected_emailtextYESEmail associated with the calendar
is_activebooleanYEStrueWhether connection is active
created_attimestamptzYESnow()
updated_attimestamptzYESnow()

Unique constraint: (user_id, provider) -- a user can only have one connection per provider.

OAuth State Format

The OAuth callback functions distinguish between client and user mode using the state parameter:

ModeState FormatExample
Client{clientId}:{provider}abc123:google
Internal (User)user:{userId}:{provider}user:def456:google

The callback function parses the state to determine which table to upsert into:

const parts = state.split(':');
if (parts[0] === 'user') {
// Internal mode: upsert into user_calendar_connections
const userId = parts[1];
const provider = parts[2];
} else {
// Client mode: upsert into calendar_connections
const clientId = parts[0];
const provider = parts[1];
}

Scheduling Architecture