Skip to main content

Reporting DB Changes


CREATE TABLE IF NOT EXISTS public.calls (
call_id BIGSERIAL PRIMARY KEY,
direction VARCHAR(20) NOT NULL,
from_number VARCHAR(50),
to_number VARCHAR(50),
primary_agent_id BIGINT,
group_id BIGINT,
campaign_id BIGINT,
start_time TIMESTAMP,
answer_time TIMESTAMP,
end_time TIMESTAMP,
duration_seconds INT,
talk_time_seconds INT,
hold_time_seconds INT,
acw_time_seconds INT,
wait_time_seconds INT,
ivr_language VARCHAR(50),
ivr_input VARCHAR(255),
was_transferred BOOLEAN DEFAULT FALSE,
abandoned BOOLEAN DEFAULT FALSE,
resolved BOOLEAN DEFAULT FALSE,
sentiment VARCHAR(20),
call_recording_url TEXT,
disposition_id BIGINT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT fk_primary_agent FOREIGN KEY (primary_agent_id) REFERENCES public.users(id),
CONSTRAINT fk_group FOREIGN KEY (group_id) REFERENCES public.groups(id),
CONSTRAINT fk_campaign FOREIGN KEY (campaign_id) REFERENCES public.campaigns(id),
CONSTRAINT fk_disposition FOREIGN KEY (disposition_id) REFERENCES public.dispositions(id)
);

CREATE TABLE IF NOT EXISTS public.call_segments (
segment_id BIGSERIAL PRIMARY KEY,
call_id BIGINT NOT NULL,
sequence_number INT NOT NULL,
event_type VARCHAR(50) NOT NULL,
start_time TIMESTAMP,
end_time TIMESTAMP,
duration_seconds INT,
agent_id BIGINT,
group_id BIGINT,
transferred_to_agent_id BIGINT,
from_number VARCHAR(50),
to_number VARCHAR(50),
prompt_played VARCHAR(255),
dtmf_input VARCHAR(50),
talk_time_seconds INT,
hold_time_seconds INT,
acw_time_seconds INT,
sentiment VARCHAR(20),
recording_url TEXT,
resolution_status VARCHAR(50),
notes TEXT,

CONSTRAINT fk_call FOREIGN KEY (call_id) REFERENCES public.calls(call_id) ON DELETE CASCADE,
CONSTRAINT fk_agent FOREIGN KEY (agent_id) REFERENCES public.users(id),
CONSTRAINT fk_group FOREIGN KEY (group_id) REFERENCES public.groups(id),
CONSTRAINT fk_transferred_agent FOREIGN KEY (transferred_to_agent_id) REFERENCES public.users(id)
);

CREATE TABLE IF NOT EXISTS public.call_crm_links (
id BIGSERIAL PRIMARY KEY,
call_id BIGINT NOT NULL,
module_name TEXT NOT NULL,
record_id BIGINT NOT NULL,
relation_type TEXT,
created_after BOOLEAN DEFAULT FALSE,

CONSTRAINT fk_call FOREIGN KEY (call_id) REFERENCES public.calls(call_id) ON DELETE CASCADE
);


Group Hierachy View

-- PostgreSQL Example
CREATE VIEW group_hierarchy AS
WITH RECURSIVE hierarchy AS (
SELECT
id,
name,
parent_group_id,
id AS root_group_id,
name AS root_group_name,
0 AS depth
FROM groups
WHERE parent_group_id IS NULL

UNION ALL

SELECT
g.id,
g.name,
g.parent_group_id,
h.root_group_id,
h.root_group_name,
h.depth + 1
FROM groups g
INNER JOIN hierarchy h ON g.parent_group_id = h.id
)
SELECT * FROM hierarchy;


Call triggers

Event NameDescription
CALL_STARTEDCall initiated (by customer or agent)
RINGINGDestination phone is ringing
CALL_ANSWEREDSomeone answers the call
HOLD_STARTEDAgent puts customer on hold
HOLD_ENDEDAgent resumes from hold
TRANSFER_INITIATEDAgent starts a transfer
TRANSFER_COMPLETEDAnother agent picks up
CONFERENCE_JOINEDA 3rd party joins the call
CALL_ENDEDCall disconnected
ACW_STARTEDAfter Call Work begins
ACW_ENDEDAgent returns to idle/ready
SURVEY_STARTEDPost-call survey starts
SURVEY_COMPLETEDSurvey response logged

Call segments

Segment TypeStart Event(s)End Event(s)Notes
RINGINGCALL_STARTEDCALL_ANSWEREDBefore agent answers
ON_CALLCALL_ANSWEREDHOLD_STARTED, TRANSFER_INITIATED, or CALL_ENDEDMay repeat per agent
HOLDHOLD_STARTEDHOLD_ENDEDCaptures hold durations
TRANSFERTRANSFER_INITIATEDTRANSFER_COMPLETEDOptional for traceability
ACWACW_STARTEDACW_ENDEDAfter call wrap-up
SURVEYSURVEY_STARTEDSURVEY_COMPLETEDCan include CSAT/NPS
BOT_HANDLINGe.g., IVR/Bot connectedAgent connectedOptional in hybrid flows