Telecaller & Leads
Schedulers & Crons
Database Tables

Database Tables

This document describes the core database tables supporting the telecaller module, including lead management, call logging, follow-ups, and AI interactions.

Entity Relationship Diagram

Table Descriptions

ExternalLeads

The primary table for managing lead records in the system.

CREATE TABLE ExternalLeads (
    LeadId INT PRIMARY KEY IDENTITY(1,1),
    Mobile NVARCHAR(20) NOT NULL,
    Name NVARCHAR(100),
    Email NVARCHAR(100),
    StaffId INT,
    CallSourceId INT NOT NULL,
    Status NVARCHAR(50) NOT NULL DEFAULT 'NEW',
    IsActive BIT NOT NULL DEFAULT 1,
    CreatedDate DATETIME NOT NULL DEFAULT GETDATE(),
    ModifiedDate DATETIME NOT NULL DEFAULT GETDATE(),
    AICallStatus NVARCHAR(50) NULL,
    AIPostRetryCount INT DEFAULT 0,
    AIProviderType NVARCHAR(50),
    AICallId NVARCHAR(100),
    PostedToAIDate DATETIME NULL,
    LastAIAttempt DATETIME NULL,
    AIFailureReason NVARCHAR(MAX),
 
    FOREIGN KEY (StaffId) REFERENCES Staff(StaffId),
    FOREIGN KEY (CallSourceId) REFERENCES CallSource(SourceId)
);
 
CREATE INDEX idx_ExternalLeads_Mobile ON ExternalLeads(Mobile);
CREATE INDEX idx_ExternalLeads_StaffId ON ExternalLeads(StaffId);
CREATE INDEX idx_ExternalLeads_Status ON ExternalLeads(Status);
CREATE INDEX idx_ExternalLeads_IsActive ON ExternalLeads(IsActive);
CREATE INDEX idx_ExternalLeads_CreatedDate ON ExternalLeads(CreatedDate);
CREATE INDEX idx_ExternalLeads_AIStatus ON ExternalLeads(AICallStatus);

Lead Status Values

StatusDescriptionFromToAuto-close?
NEWUncontacted leadSystemCP, Call Back, TrashedNo (< 30 days)
CP (Call Progress)Promising lead, follow-up plannedManual/AIFollow-up/SV FixedNo (protected)
SV_FIXEDSuccessful conversionManualNoneNo (protected)
TRASHEDInvalid/uninterestedManual/AutoNoneYes (immediate)
NO_RESPONSENo answer after attemptsManual/AIFollow-up/TrashedYes (30+ days)
PENDING_AI_CALLQueued for AI auto-callerSystemProcessing/AI_FAILEDNo (< 7 days)
PROCESSINGAI call in progressAI SchedulerCompleted/FailedNo
AI_FAILEDAI calling failed permanentlyAI SchedulerAssigned/Manual QueueNo
AUTO_CLOSEDClosed by auto-close jobAuto-close SchedulerArchiveYes (immediate)

CallLog

Records every call attempt (manual or AI) for audit and performance tracking.

CREATE TABLE CallLog (
    LogId INT PRIMARY KEY IDENTITY(1,1),
    LeadId INT NOT NULL,
    StaffId INT,
    Mobile NVARCHAR(20),
    CallStatus NVARCHAR(50) NOT NULL,
        -- Values: ANSWERED, NOT_ANSWERED, INVALID, BUSY, DO_NOT_CALL
    Notes NVARCHAR(MAX),
    DurationSeconds INT DEFAULT 0,
    CallDate DATETIME NOT NULL,
    CreatedDate DATETIME NOT NULL DEFAULT GETDATE(),
 
    FOREIGN KEY (LeadId) REFERENCES ExternalLeads(LeadId),
    FOREIGN KEY (StaffId) REFERENCES Staff(StaffId)
);
 
CREATE INDEX idx_CallLog_LeadId ON CallLog(LeadId);
CREATE INDEX idx_CallLog_StaffId ON CallLog(StaffId);
CREATE INDEX idx_CallLog_CallDate ON CallLog(CallDate);
CREATE INDEX idx_CallLog_CallStatus ON CallLog(CallStatus);

CallStatus Values

StatusMeaningDurationNext Action
ANSWEREDLead picked upVariableLog conversation outcome
NOT_ANSWEREDNo answer/ring0-60 secSchedule follow-up
INVALIDBad number/disconnected0 secMark as Trashed
BUSYLine busy0 secRetry later
DO_NOT_CALLLead opted out0 secImmediate Trashed
VOICEMAILMessage leftVariableSchedule follow-up
SWITCHEDTransferred to another partyVariableFollow conversation

FollowupCalls

Tracks all follow-up calls scheduled and their completion status.

CREATE TABLE FollowupCalls (
    FollowupId INT PRIMARY KEY IDENTITY(1,1),
    LeadId INT NOT NULL,
    StaffId INT NOT NULL,
    ReviewDateTime DATETIME NOT NULL,
        -- When this follow-up should be reviewed
    IsCompleted BIT NOT NULL DEFAULT 0,
    CompletedDate DATETIME NULL,
    Notes NVARCHAR(MAX),
    CreatedDate DATETIME NOT NULL DEFAULT GETDATE(),
    ModifiedDate DATETIME NOT NULL DEFAULT GETDATE(),
 
    FOREIGN KEY (LeadId) REFERENCES ExternalLeads(LeadId),
    FOREIGN KEY (StaffId) REFERENCES Staff(StaffId)
);
 
CREATE INDEX idx_FollowupCalls_StaffId ON FollowupCalls(StaffId);
CREATE INDEX idx_FollowupCalls_ReviewDateTime ON FollowupCalls(ReviewDateTime);
CREATE INDEX idx_FollowupCalls_IsCompleted ON FollowupCalls(IsCompleted);
CREATE INDEX idx_FollowupCalls_StaffReview ON FollowupCalls(StaffId, ReviewDateTime)
    WHERE IsCompleted = 0;

CallSource

Defines the sources/channels from which leads originate (e.g., website form, purchased list, referral).

CREATE TABLE CallSource (
    SourceId INT PRIMARY KEY IDENTITY(1,1),
    SourceName NVARCHAR(100) NOT NULL,
        -- Values: Website, PurchasedList, Referral, Inbound, etc.
    DIDNumber NVARCHAR(20),
        -- Direct Inbound Dialing number if applicable
    IsActive BIT NOT NULL DEFAULT 1,
    ProjectId INT,
    CreatedDate DATETIME NOT NULL DEFAULT GETDATE(),
    ModifiedDate DATETIME NOT NULL DEFAULT GETDATE()
);
 
CREATE INDEX idx_CallSource_SourceName ON CallSource(SourceName);

Source Types

SourceChannelLead VolumeQuality
WebsiteInbound web formHighHigh
PurchasedListThird-party providerVery HighMedium
ReferralExisting customer referenceLowVery High
InboundDirect phone callsMediumHigh
CampaignMarketing campaign responseHighMedium-High
PartnerBusiness partnerLowVariable

WeeklyLeadHistory

Aggregated historical metrics at each hierarchy level, generated weekly.

CREATE TABLE WeeklyLeadHistory (
    HistoryId INT PRIMARY KEY IDENTITY(1,1),
    WeekStartDate DATETIME NOT NULL,
    StaffId INT NOT NULL,
    ManagerId INT,
    HierarchyLevel NVARCHAR(50) NOT NULL,
        -- Values: Telecaller, BDO, SeniorManager, GM, AVP
    NewLeadsAssigned INT NOT NULL DEFAULT 0,
    SVFixed INT NOT NULL DEFAULT 0,
    CallProgress INT NOT NULL DEFAULT 0,
    Trashed INT NOT NULL DEFAULT 0,
    NoResponse INT NOT NULL DEFAULT 0,
    FollowupCreated INT NOT NULL DEFAULT 0,
    FollowupCompleted INT NOT NULL DEFAULT 0,
    ConversionRate DECIMAL(5,2) NOT NULL DEFAULT 0,
    FollowupCompletionRate DECIMAL(5,2) NOT NULL DEFAULT 0,
    AvgResponseHours DECIMAL(8,2) NOT NULL DEFAULT 0,
    ActivityRate DECIMAL(5,2) NOT NULL DEFAULT 0,
    WasteRate DECIMAL(5,2) NOT NULL DEFAULT 0,
    CreatedDate DATETIME NOT NULL DEFAULT GETDATE(),
 
    FOREIGN KEY (StaffId) REFERENCES Staff(StaffId),
    FOREIGN KEY (ManagerId) REFERENCES Staff(StaffId)
);
 
CREATE INDEX idx_WeeklyLeadHistory_StaffId ON WeeklyLeadHistory(StaffId);
CREATE INDEX idx_WeeklyLeadHistory_WeekStart ON WeeklyLeadHistory(WeekStartDate);
CREATE INDEX idx_WeeklyLeadHistory_HierarchyLevel ON WeeklyLeadHistory(HierarchyLevel);
CREATE INDEX idx_WeeklyLeadHistory_StaffWeek ON WeeklyLeadHistory(StaffId, WeekStartDate);

AICallLog

Complete record of all AI auto-calling interactions.

CREATE TABLE AICallLog (
    AILogId INT PRIMARY KEY IDENTITY(1,1),
    LeadId INT NOT NULL,
    ProviderId NVARCHAR(50) NOT NULL,
        -- AI provider: VoiceAPI, Twilio, CustomProvider
    CallId NVARCHAR(100) NOT NULL UNIQUE,
        -- Provider's call identifier
    Status NVARCHAR(50) NOT NULL,
        -- Values: INITIATED, IN_PROGRESS, COMPLETED, FAILED
    DurationSeconds INT DEFAULT 0,
    RecordingUrl NVARCHAR(MAX),
    TranscriptText NVARCHAR(MAX),
    CallResult NVARCHAR(50),
        -- Values: INTERESTED, NOT_INTERESTED, CALLBACK, ERROR
    CreatedDate DATETIME NOT NULL DEFAULT GETDATE(),
    CompletedDate DATETIME NULL,
 
    FOREIGN KEY (LeadId) REFERENCES ExternalLeads(LeadId)
);
 
CREATE INDEX idx_AICallLog_LeadId ON AICallLog(LeadId);
CREATE INDEX idx_AICallLog_ProviderId ON AICallLog(ProviderId);
CREATE INDEX idx_AICallLog_Status ON AICallLog(Status);
CREATE INDEX idx_AICallLog_CreatedDate ON AICallLog(CreatedDate);

TeleLeaderMapping

Maps managers to their assigned team members with periodic cache refresh.

CREATE TABLE TeleLeaderMapping (
    MappingId INT PRIMARY KEY IDENTITY(1,1),
    LeaderId INT NOT NULL,
        -- Manager (BDO, Senior Manager, GM, AVP)
    StaffId INT NOT NULL,
        -- Direct report (TC or BDO)
    IsActive BIT NOT NULL DEFAULT 1,
    CreatedDate DATETIME NOT NULL DEFAULT GETDATE(),
    ModifiedDate DATETIME NOT NULL DEFAULT GETDATE(),
 
    FOREIGN KEY (LeaderId) REFERENCES Staff(StaffId),
    FOREIGN KEY (StaffId) REFERENCES Staff(StaffId),
 
    CONSTRAINT chk_SelfMapping CHECK (LeaderId <> StaffId)
);
 
CREATE INDEX idx_TeleLeaderMapping_LeaderId ON TeleLeaderMapping(LeaderId);
CREATE INDEX idx_TeleLeaderMapping_StaffId ON TeleLeaderMapping(StaffId);
CREATE INDEX idx_TeleLeaderMapping_Active ON TeleLeaderMapping(IsActive);

Staff (Reference)

Core staff/user table (simplified view for context).

CREATE TABLE Staff (
    StaffId INT PRIMARY KEY IDENTITY(1,1),
    StaffName NVARCHAR(100) NOT NULL,
    Email NVARCHAR(100) UNIQUE,
    Phone NVARCHAR(20),
    Role NVARCHAR(50),
        -- Values: Telecaller, BDO, SeniorManager, GM, AVP
    IsActive BIT NOT NULL DEFAULT 1,
    CreatedDate DATETIME NOT NULL DEFAULT GETDATE(),
    ModifiedDate DATETIME NOT NULL DEFAULT GETDATE()
);
 
CREATE INDEX idx_Staff_StaffName ON Staff(StaffName);
CREATE INDEX idx_Staff_Role ON Staff(Role);

Data Size & Retention

Estimated data volumes and retention policies:

TableAnnual RowsGB/YearRetention
ExternalLeads4K-18K0.1-0.52 years
CallLog4K-55K0.2-1.53 years
FollowupCalls1K-6K0.05-0.21 year
AICallLog2K-9K0.2-0.82 years
WeeklyLeadHistory5K-26K0.1-0.37 years
Total Estimated16K-114K0.65-3.3

Query Performance Indexes

All critical queries have indexes defined:

TableQuery PatternIndexImpact
ExternalLeadsPending AI leadsStatus, IsActive, CreatedDateCritical
ExternalLeadsTC's active leadsStaffId, Status, IsActiveCritical
CallLogLead historyLeadId, CallDateHigh
FollowupCallsTC's due follow-upsStaffId, ReviewDateTime, IsCompletedCritical
FollowupCallsManager's overdueStaffId, ReviewDateTime, IsCompletedHigh
WeeklyLeadHistoryManager dashboardStaffId, WeekStartDate, HierarchyLevelHigh
AICallLogAI success rateProviderId, Status, CreatedDateMedium

Archival Strategy

To maintain performance as data grows:

-- Archive old data to separate table
CREATE TABLE ExternalLeads_Archive (
    -- Same schema as ExternalLeads
);
 
-- Monthly job to archive leads older than 2 years
INSERT INTO ExternalLeads_Archive
SELECT * FROM ExternalLeads
WHERE DATEDIFF(YEAR, CreatedDate, GETDATE()) > 2
AND IsActive = 0;
 
DELETE FROM ExternalLeads
WHERE DATEDIFF(YEAR, CreatedDate, GETDATE()) > 2
AND IsActive = 0;

Data Integrity Rules

Critical constraints and business rules:

RuleEnforcementConsequence
LeadId uniquenessPRIMARY KEYCannot create duplicate leads
Mobile formatCHECK constraint (20 chars)Invalid numbers rejected
ReviewDateTime > NowApplication logicCannot schedule past follow-ups
Status enumCHECK constraintOnly valid statuses allowed
AI retry limitApplication logicFailed leads moved to manual queue
Follow-up completionCannot be null date if IsCompleted = 1Ensures audit trail
Manager-Staff mappingNo self-mappingCannot assign person as own manager

Performance Considerations

Clustered Indexes

-- Optimize for most common queries
ALTER TABLE ExternalLeads
    ADD CONSTRAINT pk_ExternalLeads PRIMARY KEY CLUSTERED (LeadId);
 
ALTER TABLE CallLog
    ADD CONSTRAINT pk_CallLog PRIMARY KEY CLUSTERED (LeadId, CallDate);
 
ALTER TABLE FollowupCalls
    ADD CONSTRAINT pk_FollowupCalls PRIMARY KEY CLUSTERED (StaffId, ReviewDateTime);

Non-Clustered Covering Indexes

-- For "due soon" follow-up query
CREATE NONCLUSTERED INDEX idx_FollowupDueSoon
ON FollowupCalls (StaffId, IsCompleted)
INCLUDE (ReviewDateTime, FollowupId, LeadId)
WHERE IsCompleted = 0;

Backup & Disaster Recovery

  • Backup Frequency: Daily full, hourly transaction log
  • Retention: 30 days on-site, 90 days off-site
  • Recovery Time: < 1 hour (RTO)
  • Recovery Point: < 5 minutes (RPO)

Monitoring & Alerts

Database health monitoring:

  • Table fragmentation > 30% → Auto-rebuild indexes
  • Query execution time > 5 sec → Log and investigate
  • Backup failures → Immediate alert
  • Replication lag > 1 min → Monitoring escalation