| 1 | telephonySessionId | text (PK) | NOT NULL | — | code | RC telephony session ID(每通通话唯一,主键) |
| 2 | id | text | NULL | — | code | RC 内部 call log record ID |
| 3 | sessionId | text | NULL | — | code | RC session ID |
| 4 | startTime | timestamptz | NOT NULL | — | code | 通话开始时间 |
| 5 | duration | integer | NULL | — | code | 通话时长(秒) |
| 6 | type | text | NULL | Voice | Fax | code | 通话类型 |
| 7 | transport | text | NULL | PSTN | VoIP | code | 传输方式 |
| 8 | direction | text | NOT NULL | Inbound | Outbound | code | 通话方向 |
| 9 | result | text | NULL | Accepted | Missed | No Answer | Busy | Voicemail | Hang Up | ... | code | RC 通话结果 |
| 10 | action | text | NULL | Phone Call | VoIP Call | Incoming Fax | ... | code | RC 动作类型 |
| 11 | reason | text | NULL | Accepted | Connected | Busy | BlindTransfer | ... | code | 挂断原因 |
| 12 | reasonDescription | text | NULL | — | code | 原因的自由文本描述 |
| 13 | shortRecording | boolean | NULL | true / false | code | 录音过短(< 30s)无法存储时为 true |
| 14 | deleted | boolean | NULL | true / false | code | 软删除标记(ISync 用) |
| 15 | lastModifiedTime | timestamptz | NULL | — | code | RC 最后修改此记录的时间 |
| 16 | fromPhoneNumber | text | NULL | — | code | 主叫号码(from RC from 对象拍平) |
| 17 | fromName | text | NULL | — | code | 主叫名 |
| 18 | fromExtensionId | text | NULL | — | code | 主叫分机 ID |
| 19 | fromExtensionNumber | text | NULL | — | code | 主叫分机号 |
| 20 | fromLocation | text | NULL | — | code | 主叫位置 |
| 21 | fromDeviceId | text | NULL | — | code | 主叫设备 ID |
| 22 | toPhoneNumber | text | NULL | — | code | 被叫号码(from RC to 对象拍平) |
| 23 | toName | text | NULL | — | code | 被叫名 |
| 24 | toExtensionId | text | NULL | — | code | 被叫分机 ID |
| 25 | toExtensionNumber | text | NULL | — | code | 被叫分机号 |
| 26 | toLocation | text | NULL | — | code | 被叫位置 |
| 27 | toDeviceId | text | NULL | — | code | 被叫设备 ID |
| 28 | extensionId | text | NULL | — | code | call record 所属分机(owner) |
| 29 | recordingId | text | NULL | — | code | 录音 ID(from RC recording 对象) |
| 30 | recordingType | text | NULL | — | code | 录音类型 |
| 31 | recordingContentUri | text | NULL | — | code | 录音内容 URI |
| 32 | billingCostIncluded | numeric | NULL | — | code | 套餐内话费(from RC billing 对象) |
| 33 | billingCostPurchased | numeric | NULL | — | code | 额外购买话费 |
| 34 | messageId | text | NULL | — | code | 关联的语音留言/传真消息 ID(from RC message 对象) |
| 35 | messageType | text | NULL | — | code | 消息类型 |
| 36 | delegateId | text | NULL | — | code | 代理(秘书)ID(from RC delegate 对象) |
| 37 | delegateName | text | NULL | — | code | 代理名 |
| 38 | legs | jsonb | NULL | — | code | RC Detailed view 的完整 legs 数组 |
| 39 | rawCallLog | jsonb | NULL | — | code | 完整 Call Log API 响应(不截断) |
| 40 | accountId | text | NOT NULL | — | code | RC account ID(多租户隔离审计字段) |
| 41 | legacySiteId | text (SQL site_id) | NOT NULL | — | code | @deprecated — 与 account_id 冗余,保留向后兼容。注意 TS 名 legacySiteId ↔ SQL 列 site_id |
| 42 | franchiseId | text | NOT NULL | — | code | 品牌标识 |
| 43 | storeId | text | NULL | — | code | DynamoDB StoresV2 store UUID,终态隔离键。由 ai-analysis-processor + transcribe-processor 经 resolvePhoneIdentity() 写入。Phase 3 rollout 前为 NULL |
| 44 | clientId | text | NULL | — | code | 我们的复合键 {franchise}-{siteId} |
| 45 | durationMs | integer | NULL | — | code | 时长(毫秒,高精度) |
| 46 | internalType | text | NULL | — | code | 内部通话类型分类(TollFreeNumber / Local 等) |
| 47 | partyExtensionId | text | NULL | — | code | Webhook party 分机 ID |
| 48 | callState | text | NULL | 6 值,见 §3 | ai | 通话状态(驱动下游 gate 决策) |
| 49 | staffName | text | NULL | — | ai | 员工姓名(AI 从对话识别) |
| 50 | staffConfidence | numeric | NULL | 0-1 | ai | 员工识别置信度 |
| 51 | originalStaffName | text | NULL | — | ai | 首次修订前的原始员工名(审计) |
| 52 | amendmentHistory | jsonb | NULL | [{from, to, amendedBy, amendedAt, reason}] | ai | 修订历史 |
| 53 | customerType | text | NULL | 5 值,见 §3 | ai | 客户类型 |
| 54 | customerConfidence | numeric | NULL | 0-1 | ai | 客户类型置信度 |
| 55 | customerEvidence | text | NULL | — | ai | 判断客户类型的证据 |
| 56 | primaryTopicType | text | NULL | — | ai | 主题类型分类 |
| 57 | primaryCategory | text | NULL | 4 值,见 §3 | ai | 主题大类 |
| 58 | primarySubcategory | text | NULL | — | ai | 主题子分类 |
| 59 | primaryOutcomeResult | text | NULL | 6 值,见 §3 | ai | 主结果 |
| 60 | primaryOutcomeReasoning | text | NULL | — | ai | 结果判断的推理过程 |
| 61 | creditCardCaptured | text | NULL | yes | no | na | ai | 是否采集到信用卡 |
| 62 | primaryEvidence | text | NULL | — | ai | 支持主题判断的转录证据 |
| 63 | secondaryTopics | jsonb (string[]) | NULL | — | ai | 二级主题子分类列表 |
| 64 | revenuePriority | text | NULL | 4 值,见 §3 | ai | 收入优先级 |
| 65 | revenuePriorityEvidence | text | NULL | — | ai | 收入优先级判断的证据 |
| 66 | executiveSummary | text | NULL | — | ai | AI 生成的通话摘要 |
| 67 | followUpNeeded | text | NULL | yes | no | ai | 是否需要跟进 |
| 68 | followUpReasons | jsonb (string[]) | NULL | — | ai | 需要跟进的原因列表 |
| 69 | practicalCoachingScenario ↗ | text | NULL | — | ai | AI 识别的辅导场景 — 详见 coaching-schema.md |
| 70 | practicalCoachingFeedback ↗ | jsonb | NULL | {timestamp, what_was_said, context, ...} | ai | AI 详细辅导反馈 — 详见 coaching-schema.md |
| 71 | reviewCategory ↗ | text | NULL | 6 值,见 coaching-schema.md | ai | AI 通话质量评估 — 详见 coaching-schema.md |
| 72 | reviewReason ↗ | text | NULL | — | ai | reviewCategory ≠ NOT_REQUIRED 时的说明(1-2 句话)— 详见 coaching-schema.md |
| 73 | inputTokens | integer | NULL | — | ai | 输入 token 数 |
| 74 | outputTokens | integer | NULL | — | ai | 输出 token 数 |
| 75 | reasoningTokens | integer | NULL | — | ai | 推理 token 数(部分模型支持) |
| 76 | totalTokens | integer | NULL | — | ai | 总 token 数 |
| 77 | estimatedCostUsd | numeric | NULL | — | ai | 预估成本(USD) |
| 78 | aiModelUsed | text | NULL | — | ai | 实际使用的 AI 模型 ID |
| 79 | s3AnalysisPath | text | NULL | — | ai | AI 分析结果在 S3 的完整路径 |
| 80 | callLogFetchedAt | timestamptz | NULL | — | transcribe-processor | RC call log 已拉取存储(Disconnected 事件的首步)。Pipeline 进度时间戳:NULL=未到达,NOT NULL=到达时间 |
| 81 | recordingAvailableAt | timestamptz | NULL | — | transcribe-processor | 确认 RC 录音可下载 |
| 82 | transcribeStartedAt | timestamptz | NULL | — | transcribe-processor | 开始下载 + 转录 |
| 83 | transcribeCompletedAt | timestamptz | NULL | — | transcribe-processor | 转录完成 |
| 84 | aiAnalysisStartedAt | timestamptz | NULL | — | ai-analysis-processor | 开始 AI 分析 |
| 85 | aiAnalysisCompletedAt | timestamptz | NULL | — | ai-analysis-processor | AI 分析完成 |
| 86 | contactsCompletedAt | timestamptz | NULL | — | contacts-analyzer / ai-analysis-processor | task 已生成;或 AI 分析跳过(voicemail / no-answer) |
| 87 | leadId | text | NULL | — | code | Lead ID(用于关联 contacts 表) |
| 88 | contactPhone | text | NULL | — | code | 客户电话号码(用于关联 contacts 表) |
| 89 | syncedAt | timestamptz | NOT NULL | DEFAULT NOW() | code | 首次同步此记录的时间 |
| 90 | updatedAt | timestamptz | NOT NULL | DEFAULT NOW(), $onUpdate | code | 最后更新时间(Drizzle db.update() 自动刷新) |