Subversion Repositories SmartDukaan

Rev

Blame | Last modification | View Log | RSS feed

package com.spice.profitmandi.dao.entity.user;

import com.spice.profitmandi.dao.enumuration.dtr.LeadCallProvider;
import com.spice.profitmandi.dao.enumuration.dtr.LeadCallStatus;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import java.time.LocalDateTime;

/**
 * One dial attempt against an LMS lead (SOP §12) — the call history {@code Lead} cannot hold.
 *
 * <p>{@code Lead} keeps a single last-write-wins {@code disposition} and {@code recording_url} and has
 * no call id, duration or direction at all; {@code lead_activity} is an append-only human trail whose
 * {@code remark} is rendered prose. Neither can answer "how many calls, how long, which recording".
 * This table can, and {@code lead_activity.lead_call_id} points back at it — the same shape
 * {@code auth.partner_collection_remark.agent_call_log_id} already uses for collection remarks.
 *
 * <p>Rows are created by the answer webhook (not by the browser), keyed on the provider's
 * {@code conversation_uuid}, and then advanced by the event and recording webhooks. Deliberately
 * separate from {@code cs.agent_call_log}: that table is Knowlarity-shaped, keyed off
 * {@code sip_master.caller_id}, and shared with the ticket/upsell flows this feature must not disturb.
 */
@Entity
@Table(name = "user.lead_call",
        uniqueConstraints = {@UniqueConstraint(columnNames = "provider_call_uuid")})
public class LeadCall {

    @Id
    @Column(name = "id", unique = true, updatable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "lead_id")
    private int leadId;

    /** The agent who placed the call — {@code auth.auth_user.id}. */
    @Column(name = "auth_id")
    private int authId;

    @Column(name = "provider")
    @Enumerated(EnumType.STRING)
    private LeadCallProvider provider;

    /**
     * The provider's own id for the agent leg. Null until the provider tells us — the row is created
     * on the answer webhook, which is the first moment we have a durable handle.
     */
    @Column(name = "provider_call_uuid")
    private String providerCallUuid;

    /** Groups both legs of the bridged call; this is the correlation key across webhooks. */
    @Column(name = "conversation_uuid")
    private String conversationUuid;

    /** OUTBOUND for everything today; INBOUND reserved for a future retailer-callback flow. */
    @Column(name = "direction")
    private String direction;

    /** Outbound CLI actually presented to the retailer. */
    @Column(name = "from_number")
    private String fromNumber;

    @Column(name = "to_number")
    private String toNumber;

    @Column(name = "started_at")
    private LocalDateTime startedAt;

    /** When the retailer picked up. Null on an unanswered call — this is what proves contact. */
    @Column(name = "answered_at")
    private LocalDateTime answeredAt;

    @Column(name = "ended_at")
    private LocalDateTime endedAt;

    /** Billed/talk seconds as reported by the provider, not {@code ended - started}. */
    @Column(name = "duration_seconds")
    private Integer durationSeconds;

    @Column(name = "status")
    @Enumerated(EnumType.STRING)
    private LeadCallStatus status;

    /** Provider's recording handle, kept as provenance even after we archive our own copy. */
    @Column(name = "recording_uuid")
    private String recordingUuid;

    /**
     * Key of our own archived copy in the object store. Null until the archival sweep has stored it.
     *
     * <p>Deliberately not {@code dtr.document}: that table's {@code path} is VARCHAR(30) and a
     * recording key is ~58 characters, so routing recordings through it made every upload fail on a
     * STRICT-mode truncation error.
     */
    @Column(name = "recording_object_key")
    private String recordingObjectKey;

    /**
     * Failed fetch attempts. A call whose audio has expired at the provider can never succeed, and
     * without a ceiling it would occupy a slot in every batch forever and starve newer recordings.
     */
    @Column(name = "recording_archive_attempts")
    private int recordingArchiveAttempts;

    @Column(name = "recording_duration")
    private Integer recordingDuration;

    /**
     * Our archived copy — {@code dtr.document.id}. Null until the archival worker has fetched it;
     * a null here with a non-null {@code recording_uuid} means "recording exists, not yet pulled".
     */
    @Column(name = "recording_document_id")
    private Integer recordingDocumentId;

    /** The trail entry this call produced, once the agent dispositions it. */
    @Column(name = "lead_activity_id")
    private Integer leadActivityId;

    @Column(name = "created_timestamp")
    private LocalDateTime createdTimestamp;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getLeadId() {
        return leadId;
    }

    public void setLeadId(int leadId) {
        this.leadId = leadId;
    }

    public int getAuthId() {
        return authId;
    }

    public void setAuthId(int authId) {
        this.authId = authId;
    }

    public LeadCallProvider getProvider() {
        return provider;
    }

    public void setProvider(LeadCallProvider provider) {
        this.provider = provider;
    }

    public String getProviderCallUuid() {
        return providerCallUuid;
    }

    public void setProviderCallUuid(String providerCallUuid) {
        this.providerCallUuid = providerCallUuid;
    }

    public String getConversationUuid() {
        return conversationUuid;
    }

    public void setConversationUuid(String conversationUuid) {
        this.conversationUuid = conversationUuid;
    }

    public String getDirection() {
        return direction;
    }

    public void setDirection(String direction) {
        this.direction = direction;
    }

    public String getFromNumber() {
        return fromNumber;
    }

    public void setFromNumber(String fromNumber) {
        this.fromNumber = fromNumber;
    }

    public String getToNumber() {
        return toNumber;
    }

    public void setToNumber(String toNumber) {
        this.toNumber = toNumber;
    }

    public LocalDateTime getStartedAt() {
        return startedAt;
    }

    public void setStartedAt(LocalDateTime startedAt) {
        this.startedAt = startedAt;
    }

    public LocalDateTime getAnsweredAt() {
        return answeredAt;
    }

    public void setAnsweredAt(LocalDateTime answeredAt) {
        this.answeredAt = answeredAt;
    }

    public LocalDateTime getEndedAt() {
        return endedAt;
    }

    public void setEndedAt(LocalDateTime endedAt) {
        this.endedAt = endedAt;
    }

    public Integer getDurationSeconds() {
        return durationSeconds;
    }

    public void setDurationSeconds(Integer durationSeconds) {
        this.durationSeconds = durationSeconds;
    }

    public LeadCallStatus getStatus() {
        return status;
    }

    public void setStatus(LeadCallStatus status) {
        this.status = status;
    }

    public String getRecordingUuid() {
        return recordingUuid;
    }

    public void setRecordingUuid(String recordingUuid) {
        this.recordingUuid = recordingUuid;
    }

    public Integer getRecordingDuration() {
        return recordingDuration;
    }

    public void setRecordingDuration(Integer recordingDuration) {
        this.recordingDuration = recordingDuration;
    }

    public String getRecordingObjectKey() {
        return recordingObjectKey;
    }

    public void setRecordingObjectKey(String recordingObjectKey) {
        this.recordingObjectKey = recordingObjectKey;
    }

    public int getRecordingArchiveAttempts() {
        return recordingArchiveAttempts;
    }

    public void setRecordingArchiveAttempts(int recordingArchiveAttempts) {
        this.recordingArchiveAttempts = recordingArchiveAttempts;
    }

    public Integer getRecordingDocumentId() {
        return recordingDocumentId;
    }

    public void setRecordingDocumentId(Integer recordingDocumentId) {
        this.recordingDocumentId = recordingDocumentId;
    }

    public Integer getLeadActivityId() {
        return leadActivityId;
    }

    public void setLeadActivityId(Integer leadActivityId) {
        this.leadActivityId = leadActivityId;
    }

    public LocalDateTime getCreatedTimestamp() {
        return createdTimestamp;
    }

    public void setCreatedTimestamp(LocalDateTime createdTimestamp) {
        this.createdTimestamp = createdTimestamp;
    }

    @Override
    public String toString() {
        return "LeadCall [id=" + id + ", leadId=" + leadId + ", authId=" + authId + ", provider=" + provider
                + ", conversationUuid=" + conversationUuid + ", status=" + status
                + ", durationSeconds=" + durationSeconds + "]";
    }
}