Skip to main content

Campaign Tables

campaigns

SDR and CS campaign definitions. Each campaign belongs to a client and determines how calls are analyzed.

ColumnTypeDefaultNullableDescription
iduuiduuid_generate_v4()noPrimary key
agency_iduuidyesFK → agencies.id
client_iduuidnoFK → clients.id
namevarchar(255)noCampaign display name
typecampaign_typenosdr or cs — determines analysis behavior
settingsjsonb'{}'yesCampaign-specific configuration
is_activebooleantruenoWhether the campaign is active
created_attimestamptznow()noRecord creation timestamp
updated_attimestamptznow()noLast update timestamp (auto-updated)

Constraints:

ConstraintTypeDetails
campaigns_pkeyPrimary keyid
campaigns_agency_id_fkeyForeign keyagency_idagencies(id) ON DELETE CASCADE
campaigns_client_id_fkeyForeign keyclient_idclients(id) ON DELETE CASCADE
campaigns_name_not_emptyChecklength(trim(name)) > 0

Indexes:

IndexColumnsNotes
idx_campaigns_client_idclient_idClient-scoped queries
idx_campaigns_client_active(client_id, is_active)Active campaigns per client
idx_campaigns_typetypeFilter by campaign type
idx_campaigns_created_atcreated_atChronological listing
idx_campaigns_agency_idagency_idAgency-scoped queries

Triggers:

TriggerEventFunction
update_campaigns_updated_atBEFORE UPDATEupdate_updated_at_column()

campaign_contacts

Contacts within a campaign. Tracks call attempts, outcomes, and do-not-call status.

ColumnTypeDefaultNullableDescription
iduuiduuid_generate_v4()noPrimary key
campaign_iduuidnoFK → campaigns.id
phone_numbervarchar(20)noContact phone number
first_namevarchar(100)yesContact first name
last_namevarchar(100)yesContact last name
emailvarchar(255)yesContact email address
companyvarchar(255)yesCompany name
titlevarchar(255)yesJob title
timezonevarchar(50)yesContact timezone
custom_datajsonb'{}'noAdditional contact fields
statuscontact_status'pending'noProcessing status
call_iduuidyesFK → calls.id (last call)
batch_iduuidyesFK → call_batches.id (current batch)
attemptsinteger0noNumber of call attempts made
max_attemptsinteger3noMaximum attempts before failing
last_attempt_attimestamptzyesWhen the last call was attempted
next_attempt_attimestamptzyesWhen to try next
completed_attimestamptzyesWhen processing completed
outcomecontact_outcomeyesResult of the call attempt
duration_secondsintegeryesDuration of the last call
outcome_notestextyesNotes about the outcome
do_not_callbooleanfalsenoWhether the contact is on the DNC list
dnc_reasontextyesWhy the contact was marked DNC
created_attimestamptznow()noRecord creation timestamp
updated_attimestamptznow()noLast update timestamp (auto-updated)

Constraints:

ConstraintTypeDetails
campaign_contacts_pkeyPrimary keyid
campaign_contacts_campaign_id_fkeyForeign keycampaign_idcampaigns(id) ON DELETE CASCADE
campaign_contacts_call_id_fkeyForeign keycall_idcalls(id) ON DELETE SET NULL
campaign_contacts_batch_id_fkeyForeign keybatch_idcall_batches(id) ON DELETE SET NULL
campaign_contacts_phone_formatCheckphone_number ~ '^\+?[1-9][0-9]{6,14}$'
campaign_contacts_attempts_positiveCheckattempts >= 0
campaign_contacts_max_attempts_positiveCheckmax_attempts > 0

Indexes:

IndexColumnsNotes
idx_campaign_contacts_campaign_idcampaign_idCampaign-scoped queries
idx_campaign_contacts_statusstatusFilter by processing status
idx_campaign_contacts_phonephone_numberLookup by phone number
idx_campaign_contacts_call_idcall_idFiltered: WHERE call_id IS NOT NULL
idx_campaign_contacts_batch_idbatch_idFiltered: WHERE batch_id IS NOT NULL
idx_campaign_contacts_pending(campaign_id, status, next_attempt_at)Filtered: WHERE status IN ('pending', 'scheduled') — for picking next contacts to call
idx_campaign_contacts_dncphone_numberFiltered: WHERE do_not_call = true — DNC lookups

Triggers:

TriggerEventFunction
update_campaign_contacts_updated_atBEFORE UPDATEupdate_updated_at_column()