Lead Tracker Schema

Source of truth: callytics-common/src/db/schema/leads.ts (verified 2026-06-15) 表名: leads主键: id varchar(512) — composite dedup key Lead 页面主体提醒: 当前 leads-v3 页面列表和 pipeline status 主要读 contacts.lifecycle_stage='lead'leads 表是 email intake / dedup / cadence 的原始来源表。 Lead 漏斗状态: leadStatus 不在 leads 表,存在 contacts.leadStatus。见 lead-funnel-status.md


1. 表说明

leads 表存从 email 来源摄取的 lead:Google Apps Script HTTP handler 或 Lark Suite IMAP Poller 收到邮件后解析、去重、写入。原始存储曾是 DynamoDB LeadTracking-v2,现在双写到 Neon,供 studio-api 和分析 pipeline 查询。

事实说明
写入者只有 code:lead-tracking 管道
AI 写入无 AI 写入字段
主要用途intake audit、dedup、malformed/duplicated 统计、speed-to-lead cadence
与当前 Lead 页面关系Received list 不是直接按 leads 行展示,而是展示 contacts 中的 lead contact
ID 格式{customerEmail}#{customerPhone}#{dateOnly};正文解析失败时兜底 {leadEmail}#{receivedAt}

2. Schema 全字段

#FieldTypeNullableValuesWriter用途
1idvarchar(512)NOT NULLPKcodeComposite dedup key,防 Lambda retry / IMAP 重复轮询
2leadEmailvarchar(255)NOT NULLcodeLead 收件邮箱,也是 store 解析输入
3leadTypevarchar(50)NOT NULL无 DB enumcodeLead 类型,合法值由 lead-tracking 代码约束
4firstNamevarchar(255)NULLcode
5lastNamevarchar(255)NULLcode
6phonetextNULLcode归一化电话号码;部分 lead 无电话
7bookedDatevarchar(50)NULLcode预约日期
8bookedTimevarchar(50)NULLcode预约时间
9emailSubjecttextNULLcode邮件主题
10emailFromvarchar(255)NULLcode发件人
11emailRecipientvarchar(512)NULLcode收件人
12extractedTrackingIdvarchar(255)NULLcodelead-tracking+{ID}@... 提取的 tracking id
13isForwardedbooleanNULLdefault falsecode是否为转发邮件
14forwardedOriginalFromvarchar(255)NULLcode原始发件人
15forwardedOriginalTotextNULLcode原始收件人
16forwardedOriginalDatetextNULLcode原始日期
17rawBodytextNULLcode完整邮件正文,用于调试和重新解析
18processedByvarchar(50)NULLhttp-handler, imap-pollercode摄取路径
19franchiseIdtextNULLcode品牌审计字段
20accountIdtextNULLcodeaccount / site 审计字段
21storeIdtextNULLcodeStore UUID;由 leadEmail 映射 StoresV2 写入
22tenantIduuidNULLcodecontrol-plane tenant UUID,multi-tenant V1 铺路
23receivedAttimestamptzNOT NULLcode邮件接收时间
24syncedAttimestamptzNOT NULLdefault now()code首次同步到 Neon 的时间

isForwarded=false 时,forwardedOriginalFrom / forwardedOriginalTo / forwardedOriginalDate 通常为 NULL。


3. 索引

IndexColumn(s)用途
idx_leads_phonephone按客户电话查 lead
idx_leads_email_timelead_email, received_at按 lead 邮箱时序查询
idx_leads_tracking_idextracted_tracking_id按 tracking id 反查来源
idx_leads_received_atreceived_at全局时序扫描
idx_leads_franchise_sitefranchise_id, account_id历史 account-level 查询
idx_leads_store_idstore_id where not NULLstore-level filter
idx_leads_tenant_received_attenant_id, received_at where not NULLtenant-level reporting 预留

4. 当前 API 读法

Endpoint主数据源用途
GET /v3/leadscontacts + callsReceived tab list:展示 contacts.lifecycle_stage='lead' 的 contact
GET /v3/leads/pipelinecontacts + leadsstatusCounts 来自 contacts;incoming/malformed/duplicated 来自 leads
GET /v3/leads/funnelcontacts + calls7-day funnel:received / contacted / booked
GET /v3/leads/cadenceleads + callsspeed-to-lead bucket:从 leads.received_at 到首个 outbound call

重点边界:leads 表回答“系统收到了什么 lead email”;contacts 表回答“现在这个人作为 lead 处在什么状态、需要怎么跟进”。


5. Prompt Output ↔ Schema

Lead intake 没有 AI prompt 写 leads 表。leads 只是后续 AI / Task pipeline 的 read-only evidence。

Promptleads 表关系
01 Triage不读不写
02 Classify不读不写
03 Verify不读不写
04 Coaching不读不写
05 Contact Profile可作为 recent activity evidence 输入,不写 leads
06 Task DecisionsourceType='lead' task 可引用 sourceLeadId
07 Task Playbook不读不写

6. Re-verification Commands

2026-06-15 verified。文档 stale 时重跑下方命令并比对。

# leads 表所有 column + index
grep -nE "varchar\\(|text\\(|timestamp\\(|boolean\\(|uuid\\(|index\\(" \
  ../../../../../callytics-common/src/db/schema/leads.ts

# 当前 Lead API 数据源
grep -nE "FROM contacts|FROM leads|JOIN calls|l\\.received_at|c\\.lifecycle_stage = 'lead'" \
  ../../../../../studio-website-monorepo/apps/api/src/routes/v3/leads.ts \
  ../../../../../studio-website-monorepo/apps/api/src/routes/v3/lead-funnel.ts \
  ../../../../../studio-website-monorepo/apps/api/src/routes/v3/lead-cadence.ts

7. Cross-References