Task 字段设计
本文档定义 Task 表的字段结构,供开发者实现时参考。任务的业务规则详见 Tasks Overview。
写入者说明
| 写入者 |
含义 |
| 系统 |
任务生成时由系统自动写入 |
| 计算 |
由其他字段计算得出,非直接写入 |
| ai |
AI 分析写入(Per-Call Analysis / Contact Analysis) |
| 员工 |
员工通过 UI 操作写入 |
一、字段定义
| # |
分组 |
字段 |
类型 |
写入者 |
说明 |
| 1 |
系统标识 |
taskId |
uuid (PK) |
系统 |
任务唯一标识,客户端预生成 crypto.randomUUID() 或 DB defaultRandom() |
| 2 |
系统标识 |
contactPhone |
text |
系统 |
关联客户的电话(匹配 Contacts 复合 PK 三元组),卡片上同时作为显示号码 |
| 3 |
系统标识 |
franchiseId |
text |
系统 |
所属品牌(franchise 级多租户隔离,与 Contacts 三元组对齐) |
| 4 |
系统标识 |
siteId |
text |
系统 |
所属门店 |
| 5 |
系统标识 |
sourceLeadId |
text |
系统 |
关联的 Lead ID(指向 leads 表 PK)。仅 sourceType='lead' 时写入,partial unique index 防止同一 Lead 创建重复 Task |
| 6 |
系统标识 |
contactAnalysisRunId |
uuid |
系统 |
Contact Analysis 运行批次 ID(= sqsRecord.messageId)。同一次 run 创建的所有 tasks 共享同一个 UUID。用于 idempotency(uq_tasks_analysis_run_category unique index) |
| 7 |
系统标识 |
createdAt |
timestamp with tz |
系统 |
任务创建时间,defaultNow() |
| 8 |
系统标识 |
updatedAt |
timestamp with tz |
系统 |
最后更新时间(Drizzle $onUpdate 自动刷新。⚠️ transaction 内需显式传 NOW()) |
| 9 |
任务类型 |
taskType |
text (enum) |
系统 |
lead_outreach / follow_up |
| 10 |
任务类型 |
sourceType |
text (enum) |
系统 |
任务创建入口:lead(新 Lead 到达时由 lead-tracking Lambda 创建)/ contact_analysis(Cross-Call AI 分析后创建)/ manual(员工通过 UI 手动创建) |
| 11 |
任务类型 |
typeCategory |
text (enum) |
系统/ai |
任务业务场景标签(见 §二)。Lead Outreach 固定为 lead_outreach;Follow-up 由 Cross-Call AI 判定 |
| 12 |
任务状态 |
status |
text (enum) |
系统 |
只持久化 ongoing / closed。due_soon 和 overdue 由 API 查询时根据 dueAt 实时计算,不存库(Lead Outreach: dueAt - NOW() < 2min → duesoon;Follow-up: dueAt - NOW() < 1h → duesoon;dueAt < NOW() → overdue) |
| 13 |
行动建议 |
actionNeeded |
boolean |
ai |
Cross-Call AI 判定是否需要跟进。true 时才生成 Follow-up Task;lifecycleState=terminal 时必须为 false |
| 14 |
行动建议 |
actionNeededReason |
text |
ai |
为什么需要行动(1-2 句话)。仅 actionNeeded=true 时有值 |
| 15 |
行动建议 |
suggestedActions |
jsonb |
系统/ai |
行动建议列表(SuggestedAction[])。Lead Outreach 由系统模板生成;Follow-up 由 Contact Analysis AI 直接输出。每个元素含 action(建议操作)、reason(为什么建议)、priority(high/medium/low)、priorityReason(为什么是这个优先级) |
| 16 |
行动建议 |
priority |
text (enum) |
系统/ai |
Task 级优先级,取 suggestedActions[].priority 最高值。Lead Outreach 固定 high |
| 17 |
行动建议 |
dueAt |
timestamp with tz |
计算/员工 |
截止时间。初始值由系统计算:Lead Outreach = 进入时间 + SLA;Follow-up = 生成时间 + 优先级对应窗口。员工可手动修改(如客户要求改天联系),修改记录写入 contact_timeline 表(task.due_at_changed 事件) |
| 18 |
关闭信息 |
closedAt |
timestamp with tz |
系统 |
任务关闭时间(Open 状态时为空) |
| 19 |
关闭信息 |
closedByStaffName |
text |
系统/员工 |
执行员工的姓名。manual_closed:员工在 Close Task 弹窗的 "Who are you?" 下拉选择;auto_closed(Contact Analysis AI 关闭):固定为 'system' |
| 20 |
关闭信息 |
closedByStaffId |
uuid (FK) |
系统 |
执行员工的账号 ID(指向 staff 表 PK)。系统根据 closedByStaffName 匹配 staff 表自动带出。V1.5 阶段为 NULL |
| 21 |
关闭信息 |
closeType |
text (enum) |
系统/员工 |
auto_closed / manual_closed(Open 时为空) |
| 22 |
关闭信息 |
closeResult |
text (enum) |
员工/ai |
关闭的业务结果(见 §三)。manual_closed:员工在 Close Task 弹窗选择;auto_closed:Contact Analysis AI 从 11-value closeResult 枚举中智能选择(基于通话/SMS 历史分析) |
| 23 |
关闭信息 |
closeNote |
text |
员工/ai |
关闭备注。manual_closed:当 closeResult = other 时必填(说明原因),其他结果时可选。auto_closed:AI 固定写入 decision.reason 作为关闭原因 |
Schema 对齐说明(2026-03-25):
- phone → contactPhone:与 schema contact_phone 列名对齐
- dueAtChangelog 已移除:改用 contact_timeline 表记录 task.due_at_changed 事件。Postpone UI 读 API computed field postponeCount(COUNT(*) from timeline)
- 新增 contactAnalysisRunId:P2 idempotency 用,spec 详见 .claude/specs/2026-03-25-task-pipeline-write-flow.md
- 类型标注更精确:uuid、text (enum)、jsonb、timestamp with tz(与 Drizzle schema 一致)
二、typeCategory 枚举
typeCategory 标识任务的业务场景,帮助员工一眼识别任务性质。Lead Outreach 固定为 lead_outreach;Follow-up 由 Cross-Call AI 综合多通通话分析后判定。
2.1 typeCategory 定义
| # |
typeCategory |
显示文字 |
业务目标 |
营收类型 |
| 1 |
lead_outreach |
LEAD OUTREACH |
促进成交 |
Conversion MRR |
| 2 |
lead_follow_up |
LEAD FOLLOW-UP |
促进成交 |
Conversion MRR |
| 3 |
booked_not_converted |
BOOKED NOT CONVERTED |
促进成交 |
Conversion MRR |
| 4 |
cancellation_risk |
CANCELLATION RISK |
避免流失 |
Cancel Save MRR |
| 5 |
retention |
RETENTION |
投诉挽留 |
Complaint Retention MRR |
| 6 |
win_back |
WIN-BACK |
挽回客户 |
Win-back MRR |
| 7 |
upgrade |
UPGRADE |
促进升级 |
Upgrade MRR |
| 8 |
freeze_recovery |
FREEZE RECOVERY |
冻结恢复 |
Freeze Recovery MRR |
| 9 |
payment_recovery |
PAYMENT RECOVERY |
支付恢复 |
Payment Recovery MRR |
| 10 |
event_promotion |
EVENT PROMOTION |
活动推广 |
Event Revenue |
| 11 |
special_promotion |
SPECIAL PROMOTION |
特别推广 |
Promotion Revenue |
2.2 数据来源与前置条件
Follow-up 任务由 Contact Analysis(Cross-Call AI)每日批量分析客户的完整通话 + SMS 历史后直接创建。当 AI 判定客户需要跟进时,直接 INSERT 一条 Task 记录,写入:
typeCategory:任务业务场景(见 §2.1)
suggestedActions:具体建议的行动列表(含 action + reason)
priority:任务优先级(high / medium / low)
注:actionNeeded、actionNeededReason、suggestedActions 同时存在于 Contacts 和 Tasks 两张表——Contact Analysis 写 contacts(客户状态留存),同时写 tasks(驱动员工行动)。Tasks 表还有 task-only 字段(priority、dueAt 等)。Contact Analysis 也负责 AI-driven task decisions(close/create/update ongoing tasks)。
2.3 典型的 Task 创建原因
以下是 Task 创建的典型原因,按 typeCategory 归类:
2.3.1 新 Lead 首次联系(LEAD OUTREACH)
新 Lead 到达系统,需要在 SLA 窗口内首次联系。由 lead-tracking Lambda 在 Lead 到达时直接创建,不经过 Contact Analysis。
| 原因 |
示例 reason |
| 新 Lead 到达(网页表单) |
"New lead inquired about membership via web form. Contact within 5-min SLA window." |
| 新 Lead 到达(电话咨询) |
"New lead called asking about group fitness classes. Schedule tour and introduce options." |
| 新 Lead 到达(walk-in 推荐) |
"New lead arrived via walk-in referral. Contact within SLA window." |
2.3.2 Lead 持续跟进(LEAD FOLLOW-UP)
分两种情况:
未接通(leadStatus = new / attempted):前提是 Lead 尚未进入 terminal 状态(unreachable 或 neglected)。Contact Analysis 综合通话历史和时间衰减判定是否仍需跟进。
| 原因 |
示例 reason |
| 上一通电话未接通,需继续尝试 |
"First outreach attempt on Mar 18 was not answered. Temperature is still warm — continue outreach before it decays to cold." |
| 多次未接通,仍在规定 outreach 次数内 |
"2 of 3 required outreach attempts completed, both unanswered. Temperature warm, final attempt needed before decay." |
| 留了 voicemail 但未回拨 |
"Left voicemail on Mar 19, no callback yet. Temperature still hot — follow up with another attempt or SMS." |
已接通但未预约(leadStatus = connected):
| 原因 |
示例 reason |
| 已接通但未预约 |
"Lead connected on Mar 18, discussed class options but didn't book. Follow up to push for booking." |
| 接通后表达兴趣但需要时间考虑 |
"Lead connected and showed interest in group classes, said needs to check schedule. Follow up in 2 days." |
2.3.3 预约后促进成交(BOOKED NOT CONVERTED)
条件:leadStatus 为 booked / showed / trialed(已预约),且已过预约时间,且 lifecycleState 不是 terminal 或 paused,且未 converted。
| 原因 |
示例 reason |
| Lead 已预约试课但未到店(no-show) |
"Lead booked intro class on Mar 18 but was a no-show. Needs rescheduling." |
| Lead 完成试课但未签约 |
"Lead completed trial class but didn't sign up. Pricing concern mentioned." |
| Lead 已预约,需确认到店 |
"Intro class booked for tomorrow. Confirm attendance and prepare for conversion." |
2.3.4 促进升级(UPGRADE)
| 原因 |
示例 reason |
| 会员询问更高级套餐 |
"Member asked about upgrading from Basic to Premier during last call." |
| 会员对附加服务感兴趣 |
"Member interested in adding personal training package to current membership." |
2.3.5 投诉挽留(COMPLAINT RETENTION)
| 原因 |
示例 reason |
| 未解决的客户投诉 |
"Member has open complaint about equipment quality, unresolved for 3 days." |
| 账单/扣费争议 |
"Member reports being charged twice this month, needs billing correction." |
| 服务质量问题 |
"Member complained about trainer attitude, requested different instructor." |
| 设施问题反馈 |
"Member reported broken equipment in weight room, awaiting facility response." |
| 需要经理介入处理 |
"Billing dispute escalated — member requested manager callback." |
2.3.6 支付恢复(PAYMENT RECOVERY)
| 原因 |
示例 reason |
| 信用卡过期 |
"Member's card on file expired. Payment failed on March billing cycle. Contact to update payment method." |
| 扣款失败 |
"Member's auto-draft declined — insufficient funds. Second retry also failed. Phone outreach needed." |
2.3.7 避免流失(CANCELLATION RISK)
| 原因 |
示例 reason |
| 会员表达取消意向 |
"Member expressed intent to cancel membership due to schedule conflicts." |
| 会员申请冻结账户 |
"Member requested membership freeze, citing financial concerns." |
| 会员要求降级套餐 |
"Member wants to downgrade from Premier to Basic plan." |
| 取消费争议 |
"Member disputing cancellation fee, threatening to escalate." |
| 需要经理介入挽留 |
"Member insists on cancellation, staff unable to resolve — manager callback needed." |
2.3.8 冻结恢复(FREEZE RECOVERY)
| 原因 |
示例 reason |
| 冻结即将到期 |
"Member's freeze expires in 14 days. Proactive outreach to confirm return and schedule first class." |
| 冻结已到期未出勤 |
"Member's freeze ended 5 days ago, billing resumed but no class attendance yet. Follow up to re-engage." |
2.3.9 挽回客户(WIN-BACK)
| 原因 |
示例 reason |
| 前会员主动联系咨询回归 |
"Former member called asking about re-joining. Left 6 months ago, now back in the area." |
| 前会员回复 SMS 表达兴趣 |
"Former member responded to re-engagement SMS, interested in current promotions." |
| 原因 |
示例 reason |
| 挑战赛报名推广 |
"Dri-Tri registration opens next week. Member attended last year — follow up to encourage sign-up." |
| 活动参与邀请 |
"Transformation Challenge starts Jan 15. Member expressed interest during last class — confirm registration." |
| 原因 |
示例 reason |
| 企业合作洽谈 |
"Local company HR inquired about corporate wellness program. Schedule meeting to discuss group rates." |
| 推广活动跟进 |
"Corporate partnership with ABC Corp — 5 employees signed up, HR mentioned 10 more interested. Follow up." |
2.4 typeCategory 判定逻辑
Lead Outreach 固定为 lead_outreach(由 SLA 规则触发)。Follow-up 由 Contact Analysis AI 根据客户状态判定:
| # |
typeCategory |
触发条件 |
说明 |
| 1 |
LEAD OUTREACH |
新 Lead 到达,sourceType=lead,由 SLA 规则触发 |
新 Lead 首次联系,5 分钟 SLA 黄金窗口 |
| 2 |
LEAD FOLLOW-UP |
lifecycleStage=lead 且 leadStatus 为 new / attempted / connected,AI 综合通话历史判定仍需跟进 |
Lead 未接通需继续 outreach,或已接通但未预约需推动 booking。Lead 进入 terminal(unreachable / neglected)后不再生成 Task |
| 3 |
BOOKED NOT CONVERTED |
lifecycleStage=lead 且 leadStatus 为 booked / showed / trialed,已过预约时间,且 lifecycleState 不是 terminal 或 paused,未 converted |
Lead 已预约但未成交,需跟进推动签约 |
| 4 |
UPGRADE |
lifecycleStage=member 且 suggestedActions 中包含升级建议 |
会员有升级意向 |
| 5 |
COMPLAINT RETENTION |
lifecycleStage=member 且 hasOpenComplaint=true 或 AI 检测到投诉/账务争议 |
会员投诉需解决,防止升级为流失风险 |
| 6 |
PAYMENT RECOVERY |
lifecycleStage=member 且支付失败(卡过期/扣款失败),自动重试未成功 |
支付失败需人工催回更新支付方式 |
| 7 |
CANCELLATION RISK |
lifecycleStage=member 且 AI 检测到取消/冻结/降级意向或需要经理挽留 |
会员有流失风险,需及时挽留 |
| 8 |
FREEZE RECOVERY |
lifecycleStage=member 且会员处于冻结状态,冻结到期日临近 |
冻结即将到期,主动联系确认回归 |
| 9 |
WIN-BACK |
lifecycleStage=churned 且 lifecycleState=active(客户主动发起回归意向) |
前会员有回归意向,需推动重新签约 |
| 10 |
EVENT PROMOTION |
lifecycleStage=member 且有活动/挑战赛报名窗口,AI 判定会员适合参加 |
推动会员报名挑战赛或活动 |
| 11 |
SPECIAL PROMOTION |
推广客户咨询或已有推广合作需跟进扩展 |
特别推广洽谈或扩展 |
typeCategory 与 Per-Call Analysis 没有直接关联。Per-Call Analysis 分析单通通话,Contact Analysis 综合所有通话后写入 Contacts 结构化字段并直接创建/关闭/更新 Tasks。
三、关闭结果枚举
closeResult 枚举
任务关闭时写入。manual_closed:员工在 Close Task 弹窗中选择;auto_closed:Contact Analysis AI 从枚举中智能选择(基于通话/SMS 历史分析)。用于营收归因(见 任务与营收归因)。
| # |
值 |
显示文案 |
说明 |
归因 |
| 1 |
lead_outreached |
Lead Outreached |
已尝试联系但未接通。Lead Outreach 任务选此项即可关闭(一次 outreach 完成),系统根据 Lead 状态决定是否生成下一个 LEAD FOLLOW-UP Task |
不归因(阶段性) |
| 2 |
converted |
Converted |
客户完成了目标动作(签约、预约成功等) |
Conversion MRR |
| 3 |
win_back |
Win-back |
前会员重新签约 |
Win-back MRR |
| 4 |
complaint_resolved |
Complaint Resolved |
投诉已解决,客户满意 |
Complaint Retention MRR |
| 5 |
cancel_saved |
Cancel Saved |
挽留成功,客户取消了流失意向 |
Cancel Save MRR |
| 6 |
upgraded |
Upgraded |
客户完成升级 |
Upgrade MRR |
| 7 |
freeze_recovered |
Freeze Recovered |
冻结会员恢复活跃 |
Freeze Recovery MRR |
| 8 |
payment_recovered |
Payment Recovered |
会员更新支付方式,扣款成功 |
Payment Recovery MRR |
| 9 |
event_signed_up |
Event Signed Up |
会员报名挑战赛/活动 |
Event Revenue |
| 10 |
promotion_converted |
Promotion Converted |
推广协议签约 |
Promotion Revenue |
| 11 |
wrong_number |
Wrong Number |
号码错误或已不属于该客户 |
不归因(Leakage) |
| 12 |
do_not_contact |
Do Not Contact |
客户明确要求不再联系,同时标记 Contacts doNotContact=true |
不归因(Leakage) |
| 13 |
other |
Other |
无明确业务结果,需填写 closeNote |
不归因(Leakage) |
四、与其他文档的关系