Coaching Schema

Source of truth: callytics-common/src/db/schema/calls.ts + coaching-reviews.ts + ai-feedback.ts (verified 2026-06-15) 物理表边界: AI coaching 内容仍在 calls 表;经理处理状态在 coaching_reviews;对 AI 内容质量/采纳的反馈在 ai_feedback(subject_type='coaching')Calls 全表: ../calls-feature/calls-schema.md


1. 表说明

Coaching 有 3 层数据,不要混在一起:

表 / 字段谁写用途
AI 内容层calls.practicalCoachingScenario, calls.practicalCoachingFeedbackai-analysis-processor Coaching prompt告诉 manager 这通电话为什么值得辅导、应该怎么教
Manager workflow 层coaching_reviewsstudio-api /v3/coaching-reviewsread/unread、active/archived/removed、manager note
AI feedback 层ai_feedback(subject_type='coaching')前端反馈入口 / studio-api记录 manager 是否觉得 AI coaching 有用、是否采纳或修正

calls 内的 4 个 coaching/review 字段拆 2 类:

  • 已接线 (AI 真在写,前端真在读): practicalCoachingScenario / practicalCoachingFeedback — 给前台看的辅导建议
  • 已定义未接线 (schema 有列 + 有 index, AI pipeline 零 write, 前端零 read): reviewCategory / reviewReason — 通话质量评估标签

写入者: ai (Coaching prompt) = ai-analysis-processor Stage 3 (Coaching) 调用 AI prompt 后直接写入 calls 表对应 4 列。

Coaching gate (shouldRunCoaching()): 必须 callState === 'human_conversation'duration > 30 秒才跑 AI;否则填占位 sentinel,详见 coaching-calculations.md

覆盖语义 + 反馈叠加:coaching 是 per-call 一次性产出,仅手动 reprocess 覆盖(罕见)。人工修改不动 calls 原行,而是走统一反应层 ai_feedbackcorrected 叠加 —— 设计见 AI 产出数据架构


2. Schema 全字段

#FieldTypeNullableEnum / ValuesWriter用途
1practicalCoachingScenariotextNULL— (自由文本 + 3 种 sentinel,见 §6)ai (Coaching prompt)一句话标签,命名 AI 识别到的具体辅导场景(如 "Cancellation save attempt missed objection")
2practicalCoachingFeedbackjsonbNULL{ timestamp, what_was_said, context, what_could_have_been_said, why_recommendation_is_better } (5 个 string 子字段,见 §7)ai (Coaching prompt)详细辅导反馈 — 哪个时刻、员工原话、上下文、建议替换话术、为什么更好
3reviewCategory ⚠️textNULLNOT_REQUIRED | EXEMPLARY | FAILURE | CHURN_RISK | MISSED_OPPORTUNITY | ESCALATION (6 值,见 §3)ai (设计意图;实际未接线)AI 对通话的质量评估标签。schema 已定义 + 有 index idx_calls_review_category,但 lambda 零 write、前端零 read
4reviewReason ⚠️textNULLai (设计意图;实际未接线)reviewCategory ≠ NOT_REQUIRED 时的说明文本(1-2 句话)

⚠️ = "schema 占位 + 未接线" — 6 个 reviewCategory 值是设计意图,不是可观察行为。


3. reviewCategory enum — 6 values

reviewCategory 列单独拉出来,每个 value 有含义说明。

Value含义
NOT_REQUIRED不需要复盘 — 设计意图 ~90-95% 的通话落在这里(常规通话,无异常无亮点)
EXEMPLARY标杆通话 — 员工处理得非常好,值得作为培训案例
FAILURE明显失败 — 员工有重大失误(冷漠、错信息、流程错误)
CHURN_RISK流失风险 — 客户表达不满 / 取消意图,需经理介入挽留
MISSED_OPPORTUNITY错失机会 — 客户给了 buying signal 但员工没接住
ESCALATION需升级 — 投诉 / 法律风险 / 安全问题,需立刻找经理

4. coaching_reviews workflow 表

coaching_reviews 是一通 coaching call 在 manager inbox 里的处理状态。它不存 AI coaching 内容,只用 (store_id, telephony_session_id) 对齐 calls

FieldTypeNullableValues用途
storeIdtextNOT NULLStore-level isolation key;复合 PK 一半
telephonySessionIdtextNOT NULL对应 calls.telephony_session_id;复合 PK 一半
tenantIduuidNULLmultitenant V1 预留
statustextNOT NULLactive | archived | removedManager inbox 状态
statusChangedAttimestamptzNULL状态最后一次变更时间
readAttimestamptzNULLNULL 表示 unread
notetextNULL经理复盘备注
updatedBytextNULL最后操作人 Cognito user id
createdAt, updatedAttimestamptzNOT NULL系统时间戳

5. ai_feedback(subject_type='coaching')

ai_feedback 是产品用户对 AI 内容的反应层。对 coaching 来说,subject_id = calls.telephony_session_id

FieldValues / 用途
subjectTypecoaching
subjectIdtelephony_session_id 文本
feedbackhelpful, not_relevant, followed, corrected
reason可选原因,尤其适合 not_relevant
correctedContentcorrected 时的人工修正版
storeId, tenantId, userId, createdAt隔离、操作人、时间

6. Sentinel 占位值

practicalCoachingScenario 不只有 AI 自由文本,有 3 种 sentinel 占位,分管道路径:

Sentinel写入路径触发条件配套 practicalCoachingFeedback
No coaching — <reason> (em dash)Staged pipeline (pipeline.ts,当前活跃)Gate 没通过 (通话太短 / voicemail / no-answer)NULL
No Coaching Available - <state> (hyphen)Legacy path (models.ts,历史遗留)同上NULL
No coaching moment identified两条路径共用Gate 通过 + AI 跑了但判断"这通无值得辅导时刻"5 个子字段全填 "N/A"

⚠️ 前端 / 运营按字符串识别空 coaching 时要匹配 No coaching — (em dash) — 当前活跃路径是 staged pipeline。详细行为见 coaching-calculations.md


7. practicalCoachingFeedback jsonb 结构

对应 Coaching prompt 输出的 detailed_feedback_item:

子字段类型含义
timestampstring辅导时刻的转录时间戳(如 "01:23")
what_was_saidstring员工当时实际说的话(逐字引用或近似转述)
contextstring1-2 句话交代当时情境(客户刚说了什么、利害关系、通话主题)
what_could_have_been_saidstring建议替换话术(写成员工能直接照说的自然句子,不是抽象建议)
why_recommendation_is_betterstring1-2 句话说明为什么这个建议更好(关联销售 / 留存原则)

AI 判断无辅导时刻时,5 个子字段全填 "N/A"(详见 §6)。

V1 coaching-highlights-spec 提过的"5 个 SA 维度打分"(Booking Ask / Objection Handling / Retention Technique / Rapport Building / Information Accuracy,各 0-10 分)当前未实现 — 代码里只有 scenario + feedback(单个最有价值的辅导时刻)。V1 spec 见 ../../v1/coaching-highlights-feature/coaching-highlights-spec.md


8. Prompt Output ↔ Schema 字段对照(给 reviewer 用)

Reviewer 用本表验证 prompt 输出 JSON 字段是否落在 calls 表的 coaching 子集内。

Prompt写入字段备注
01 Triage不写 coaching
02 Classify不写 coaching(写 calls 其他字段)
03 Verify不写 coaching
04 CoachingpracticalCoachingScenario / practicalCoachingFeedback主要写入 prompt — reviewer 重点验证输出字段 ∈ §2
05 Contact Profile写 contacts 表
06 Task Decision写 tasks + task_progress_events
07 Task Playbookread-only

reviewCategory / reviewReason 没有 prompt 在产出 — 当前 7 个 prompt 中,reviewer 无需验证这两个字段。


9. Appendix A — Re-verification commands

2026-06-15 verified。文档 stale(>30 天)时重跑下方命令并比对。

# 1. 4 个 coaching 字段是否还在 calls.ts 里
grep -nE "practicalCoaching|reviewCategory|reviewReason" \
  ../../../../../callytics-common/src/db/schema/calls.ts
# 期望: 4 行 column 定义 + 1 行 idx_calls_review_category index

# 1b. manager workflow 表 + AI feedback 表
grep -nE "coachingReviews|COACHING_REVIEW_STATUS|aiFeedback|AI_FEEDBACK_SUBJECT_TYPE|AI_FEEDBACK_TYPE" \
  ../../../../../callytics-common/src/db/schema/coaching-reviews.ts \
  ../../../../../callytics-common/src/db/schema/ai-feedback.ts

# 2. Codex final design 是否动 coaching
grep -i "coaching\|practicalCoaching\|reviewCategory" \
  ../../tasks-feature/design/task-pipeline-deliverable-codex.md
# 期望: 0 行 — codex 完全不提 coaching

# 3. Unified pipeline final 是否动 coaching schema
grep -i "coaching\|practicalCoaching\|reviewCategory" \
  ../../unified-pipeline/unified-pipeline-final.md
# 期望: 只 reference Coaching 是 Stage ⑤ + 写 calls 表,不改 schema

# 4. reviewCategory 真接线了吗
grep -rnE "reviewCategory|review_category" \
  ../../../../../callytics-infrastructure/lambda/ \
  ../../../../../callytics-common/src/ 2>/dev/null | \
  grep -v schema/calls.ts
# 期望: 0 行 write/read — 仍是 schema 占位

10. Cross-References