Files
fangke/docs/superpowers/specs/2026-09-15-customer-behavior-platform-design.md
T

18 KiB
Raw Blame History

客户行为采集平台 · 设计文档

  • 日期:2026-09-15
  • 状态:已确认
  • 关联文档:docs/客户行为数据采集平台完整项目实施方案.docx、docs/客户行为数据采集平台方案实施报告.docx(需求基线,本设计在其基础上按实际约束裁剪落地);docs/客户画像与销售转化实施方案.md(M4+ 路线图,本平台即其"跨天轨迹底座")

1. 项目目标

构建一个第一方客户行为数据采集平台:网站引入自研 JS SDK,采集访客行为轨迹与环境信息,写入独立后台数据库;后台基于 Art Design Pro 构建管理控制台,提供访客/客户的跨天行为时间线、来源归因、有效停留统计和客户档案管理。

核心业务问题:"这个客户从哪来、看过什么、哪天来过、每次停多久、在哪儿流失、什么时候变成了线索"。

2. 已确认的决策

维度 决策
形态 通用 JS SDK(网站引入)+ 独立后台
后端 Python · Django + DRF
数据库 MySQL 8(复用 1Panel 现有容器),事件表按月分区
前端 Art Design Pro(Vue3 + TypeScript + Element Plus + Pinia + ECharts)
部署 阿里云 ECS · 1Panel · Docker Compose(Nginx 静态 + 反代 Django)
规模策略 先小后大;单组织多站点,表结构带 site_id 留多站点扩展位
实时性 准实时(事件分钟内可见,最近 5 分钟活跃作为"在线"口径)
客户识别 表单提交(询盘/留言)为主;邮件专属链接识别(M2);登录绑定(P2)
缓存 M1 不引入 Redis;M2 起可选(限流/缓存加固)

2.1 与原方案文档的差异

原文档建议 本设计 理由
Node.js 后端 Django + DRF 团队技术选型
PostgreSQL MySQL 8 现有 1Panel 环境;JSON 类型 + 按月分区满足当前量级
React/Next.js 后台 Art Design Pro 指定模板,自带权限/菜单/主题体系
多租户 SaaS 就绪 单组织多站点 先自用,不为 SaaS 付复杂度
Redis 起步必备 M2 可选 先小后大

明确砍掉/推迟(首期不做):多租户组织管理、ClickHouse、同意管理平台(CMP)、Webhook、会话回放、浏览器指纹身份追踪、营销自动化、机器学习评分。

保留的治理底线(不可裁剪):敏感字段黑名单双重拦截、确定性合并原则、数据保留期限与清理、客户删除流程、隐私告知。

3. 系统架构

┌─────────────────────────────────────────────┐
│  网站浏览器                                   │
│  JS SDK(自研 ≤15KB gzip,异步加载,不阻塞页面) │
└──────────────────┬──────────────────────────┘
                   │ HTTPS 批量 JSON 上报
                   ▼
┌─────────────────────────────────────────────┐
│  阿里云 ECS · 1Panel · Docker                │
│  Nginx                                       │
│   ├─ 静态:Art Design Pro 打包产物             │
│   └─ /api/* ──► Django + DRF                 │
│                  ├─ 采集接口(公开、域名白名单、限流)│
│                  ├─ 管理接口(JWT 登录)          │
│                  └─ 后台任务(会话化/聚合/清理)   │
│                        │                     │
│                        ▼                     │
│              MySQL 8(events 按月分区)          │
└─────────────────────────────────────────────┘
  • 开发期:Vite 代理解决跨域;部署期同域无跨域问题。
  • 响应格式适配 Art Design Pro 的 {code, data, message} 约定。
  • 升级路径:事件量到瓶颈时把采集接口拆为独立 FastAPI 服务,SDK 协议不变。

4. JS SDK 设计

4.1 接入方式(两行)

<script>
window.ctk = window.ctk || function(){(ctk.q = ctk.q || []).push(arguments)};
ctk('init', { siteId: 'site_xxx', endpoint: 'https://track.example.com' });
</script>
<script async src="https://track.example.com/sdk/v1.js"></script>

4.2 身份模型

  • visitor_id:加密安全随机数,存 localStorage(第一方存储,不用 Cookie+localStorage 双恢复对抗用户清除)。
  • session_id:30 分钟无活动切新会话;跨天访问 = 新会话、同一 visitor。会话权威在 SDK;服务端按同一 30 分钟规则做兜底校验(超长/跨天异常时切分修正),不产生第二套会话口径。
  • 首次落地时保存首触来源(referrer + UTM + 落地页)到访客档案;每次会话各自记录来源。

4.3 事件清单

事件 优先级 字段要点
page_view P0 path、title、referrer、UTM;SPA 路由变化触发(P1)
page_stay P0 active_ms 有效停留:页面可见 + 有鼠标/键盘/滚动活动才累计;visibilitychange 停止;sendBeacon 兜底上报
scroll_depth P1 25/50/75/100% 四档
click P1 可配置范围(按钮/导航/外链/下载),data-track-id 优先标识
form_start / form_submit P1 表单标识、字段名清单、成功/失败;字段值白名单制(白名单在后台按站点配置,SDK init 可覆盖)
copy / download / print P1 意图事件:复制了邮箱/电话、下载报价单 PDF、打印页面
rage_click / dead_click P2 反复点无反应区域
first_interaction P1 进页面后首次互动耗时
form_field_drop P1 表单在哪个字段放弃、是否粘贴、是否自动填充
identify_hit P1 邮件专属链接 token 命中(见 5.3)
sdk_loaded P0 诊断事件:SDK 版本、初始化耗时

4.4 环境信息(首次访问携带)

设备类型、OS + 版本、浏览器 + 版本、屏幕分辨率、语言、时区、触屏、CPU 核心数、设备内存(可选开)、Client Hints(设备型号)、网络类型/下行/RTT(navigator.connection)、页面性能(Navigation Timing)。

4.5 传输可靠性

  • 内存队列 → 批量发送(10 条或 15 秒触发);页面隐藏 sendBeacon,需自定义头时 fetch keepalive。
  • 每事件 UUID event_id,服务端按 site_id + event_id 幂等去重。
  • 失败指数退避重试(上限 3 次);4xx 不重试;离线队列超限按最旧丢弃并记本地丢弃计数。
  • 客户端时间仅作排序参考,服务端另存 received_at 并标记时钟偏差。
  • SDK 全部逻辑 try/catch 包裹,任何异常不影响宿主网站。

4.6 隐私与安全红线(SDK 端)

  • 不采集:password/hidden/file/autocomplete 敏感字段值、验证码、银行卡、身份证。
  • URL 清洗:含邮箱/手机号/令牌类查询参数在入库前删除或哈希。
  • 不做:键盘逐键记录、剪贴板读取、摄像头/麦克风、浏览器指纹身份追踪(弱指纹仅用于爬虫识别,不参与身份关联)。
  • 免费文本默认不采集,需逐项白名单。

5. 身份识别与客户合并

5.1 身份层级

visitor_id(匿名浏览器)
   └─ session_id(每次访问)
        └─ events
contact(客户档案)── identity 关联表 ── visitor_id / 邮箱哈希 / 手机号哈希

5.2 表单识别(M2 主路径)

匿名访客逛了 3 天 → 第 4 天提交询盘表单
→ 白名单字段值(姓名/邮箱/电话)创建客户档案
→ 同邮箱/手机号已存在则归并,不建重复档案
→ 该 visitor_id 全部历史轨迹自动归入客户名下
→ 后续访问持续追加到同一档案
  • 表单字段值浏览器端采集(询盘线索场景够用 + 垃圾过滤:粘贴检测/Honeypot/频率)。
  • 订单、支付、注册成功等业务事实必须走服务端签名 API(P2),浏览器事件不作事实依据。

5.3 邮件专属链接识别(M2)

开发信/WhatsApp/社媒发 https://site/?ctk_token=<专属token> 链接;对方点开即触发 identify_hit,立即把匿名轨迹归到对应客户档案——比等表单提交更早识别。

5.4 合并规则

  • 只做确定性合并:邮箱/手机号/token/user_id。IP、城市、设备相似绝不自动合并,仅作线索提示。
  • 手动认领:后台把匿名访客轨迹认领给客户,支持解除;操作记审计。
  • 多个 visitor_id 绑定同一邮箱 → 汇入同一 contact(跨设备视图)。
  • 每次 merge/认领/解除记录操作者、时间、规则版本。

6. 来源归因(四层)

  1. 自动 referrer:提取来路域名(google.com / 合作伙伴站 / 微信内置浏览器 / 直接访问)。
  2. UTM 参数:utm_source / medium / campaign / term / content,外投链接统一带参。
  3. 首触 + 会话来源:访客/客户档案永久记录首触来源;每次会话各自记录(时间线可见"第 N 次访问来自 X")。
  4. 渠道规则映射 + 手动标记:后台配置 域名 → 渠道名 规则表(google.com → 自然搜索等);支持手动改/手动标(线下展会、referrer 丢失场景)。

已知边界:referrer 被剥(部分隐私工具/HTTPS→HTTP/微信)记为"直接访问";要 100% 可靠归因用 UTM 链接。

7. 匿名访客可采集信息全景

类别 内容
身份标识 visitor_id、session_id、新/回访、访问次数、首末次访问、活跃天数
行为轨迹 页面浏览及路径、每页有效停留、滚动深度、点击、表单行为(开始/放弃字段/提交)、意图事件(复制/下载/打印)
来源 referrer 域名、UTM、落地页、部分搜索词
设备环境 设备类型、OS/浏览器及版本、分辨率、语言、时区、触屏、硬件(可选)、Client Hints、网络质量、页面性能
网络地理(服务端) IP(保留期限见 9.2)、国家/省/市(ip2region 离线库)、运营商、爬虫识别
跨站关联 自有域名间经站间跳转传 token 串联(M3,首方合法做法);或经客户识别后归并到同一档案

拿不到(诚实边界):匿名阶段真实身份(姓名/邮箱/电话);跨设备同一人(直到提交表单/登录/token 命中);清存储/无痕后重新开始(不对抗)。

8. 管理控制台(Art Design Pro 页面)

# 页面 优先级 内容
C1 登录/权限 P0 JWT;管理员/普通成员两角色起步(复用模板权限体系)
C2 总览 Dashboard P0 今日/7日/30日 PV、UV、会话数、新访客比;最近 5 分钟活跃(准实时在线);趋势图
C3 访客列表(匿名) P0 访客 ID、首末次访问、会话数、来源、位置、设备
C4 访客/会话详情 P0 单访客跨天时间线 + 单会话页面路径(M1 验收核心)
C5 站点管理 P0 站点 CRUD、site_id 签发、域名白名单
C6 客户列表 P1 姓名/邮箱/手机号脱敏、首末次访问、访问次数、总停留、最近来源、标签筛选、搜索
C7 客户详情 P1 跨天时间线(日期分组)+ 会话列表 + 设备/地理位置 + 首触来源 + 标签备注
C8 事件调试流 P1 原始事件流(含拒绝原因、时延),开发调试用
C9 标签/备注 P1 客户打标签、跟进备注
C10 渠道规则 P1 域名→渠道映射配置
C11 专属链接生成 P1 给客户/活动生成带 token 的识别链接
C12 数据导出 P2 客户列表/时间线 CSV
C13 事件字典 P2 事件 schema 登记

客户时间线样式(原样采用文档 8.2):

09-01 10:20  首次访问产品 A 页面  来源 Google Ads
09-01 10:24  查看价格页  有效停留 2 分 18 秒
09-02 16:10  再次访问案例页面
09-02 16:15  询盘提交成功  身份识别为 customer@example.com

9. 数据治理

9.1 敏感字段黑名单

SDK 端 + 服务端双重拦截:password/验证码/银行卡/身份证等永不入库;服务端对 properties 做体积/数量/长度/深度校验,未知字段拒绝或隔离并记原因。

9.2 数据保留(默认值,站点可配)

数据 保留期
原始事件(events 分区) 180 天,分区清理
原始 IP 180 天,到期后台任务截断(IPv4 → /24,IPv6 → /64 前缀);地理/运营商解析结果长期保留
客户档案、标签、备注 长期(直至客户删除)
审计日志 1 年

9.3 客户删除

删除客户档案 + 关联事件(标记删除 + 异步物理清理),记录审计;导出留档。

9.4 隐私告知

提供隐私政策/Cookie 告知文案模板;SDK 预留 consent 开关接口(同意管理模式 P2 完善化);第三方脚本不可绕过同意状态。

10. 数据库核心表(MySQL 8)

表 要点
site 站点、site_id、域名白名单、采样配置
visitor visitor_id、首触来源、首次/最近访问、环境摘要
session session_id、visitor、开始/结束、来源、落地页、会话时长
events(按月分区) event_id(site 内唯一幂等键)、visitor、session、contact(可空)、event_type、occurred_at、received_at、path、properties JSON
contact 客户档案:姓名、邮箱(规范化+加盐哈希列)、电话(同)、公司(可由邮箱域名推导,预留 account 关联,M4+ 客户画像阶段扩展 Account/Person 体系)、标签、备注、负责人
identity_map visitor_id / 邮箱哈希 / 电话哈希 / token ↔ contact 关联 + 合并审计字段
track_token 专属链接 token ↔ contact
daily_stats / session_rollup 聚合派生表(日指标、会话摘要),避免报表扫 events
admin_user / audit_log 后台账号、审计

索引原则:时间线 (site_id, visitor_id/contact_id, occurred_at DESC);会话 (site_id, visitor_id, started_at DESC);高频筛选字段独立列,长尾属性进 JSON。

11. API 概览

接口 说明
POST /api/collect/batch 浏览器批量上报:校验站点状态/域名白名单/体积/限流/幂等去重/黑名单 → 入库
POST /api/collect/identify token 命中识别(M2)
管理接口 /api/admin/* JWT;站点、访客、客户、事件调试、标签、渠道规则、导出、Dashboard 聚合

采集接口返回最小响应(成功/失败 + 稳定错误码),不向匿名调用方泄露配置或客户数据。site_id 是公开标识,只用于归属,不赋予任何读取权限。

12. 非功能需求

  • SDK 体积 ≤ 15KB(gzip),初始化不阻塞首屏;加载失败对网站零影响。
  • 采集接口:日均 10 万事件内单 Django 实例 + MySQL 从容承载;监控接受率、去重率、拒绝原因分布。
  • 准实时:事件从发生到后台可见 ≤ 60 秒(列表刷新即得,无长连接)。
  • 部署:1Panel Docker Compose(Nginx + Django + gunicorn + 复用 MySQL 容器);.env 管理密钥;数据库迁移向前兼容。
  • 备份:MySQL 自动备份 + 恢复演练(复用 1Panel 能力)。

13. 里程碑

M1 · 最小闭环(端到端技术验证)

  • SDK:接入两行代码、visitor/session 身份、page_view、page_stay、批量传输、幂等去重、UTM/referrer 首触记录、环境信息、sdk_loaded 诊断事件。
  • 后端:采集 API(域名白名单/限流/黑名单校验)、核心表、会话化与日聚合任务。
  • 后台:C1 登录权限、C2 总览、C3 访客列表、C4 访客/会话详情、C5 站点管理。
  • 验收:一个真实网站接入,后台能看到"某访客今天看了 3 页、每页停多久、昨天来过、首触来源是 Google"。

M2 · 完整产品(客户识别 + 完整后台)

  • SDK:click、scroll、SPA 路由、表单事件(含字段放弃/粘贴/自动填充)、意图事件(复制/下载/打印)、first_interaction、URL 清洗、track/identify/reset API。
  • 身份:表单→客户档案创建与归并、邮箱/手机号去重、邮件专属链接识别、手动认领/解除、合并审计。
  • 后台:C6 客户列表、C7 客户详情、C8 事件调试流、C9 标签备注、C10 渠道规则、C11 专属链接生成。
  • 治理:IP 保留期任务、客户删除流程、隐私告知模板。
  • 验收:询盘表单提交后客户档案自动生成并归并全部历史轨迹;专属链接点开即识别。

M3 · 增强与扩展

  • rage/dead click、远程配置(采样/开关,ETag)、npm 包发布。
  • 登录绑定 identify(user_id)(含服务端签名令牌机制)、同意管理模式完善(consent 分目的开关)。
  • 服务端签名事件 API(订单/注册事实)、WordPress 连接器插件(注入 SDK + CF7/WPForms 钩子)。
  • IP 企业反查(Leadfeeder 式 B2B 线索提示,可选付费库,只提示不自动合并)、邮箱后缀→公司名补全。
  • 跨自有域名访客串联(站间跳转传 token)。
  • 数据导出、事件字典、Redis 限流加固、(独立评估)会话回放。
  • 上线门禁:跨境/隐私合规专项确认(按原方案文档第十二章执行)。

M4+ · 客户画像与销售转化(独立立项,见 docs/客户画像与销售转化实施方案.md)

不在本设计范围内。本平台为其提供的数据基础保障:

  • 原始事件全量保存 path/title/properties——画像评分规则可基于历史数据回放重算;
  • contact 模型对齐其 Person 概念,预留 account 关联;
  • 站内搜索词、下载/复制/打印等意图事件、表单字段级数据从 M2 起持续积累,正是其 Intent/Engagement 评分的原料。

14. 风险与开放项

项 状态
表单字段值浏览器端先行、签名机制 P2 已决策
原始 IP 默认保留 180 天后截断(站点可配) 已决策(默认值)
微信内置浏览器 referrer 常缺失 已知边界,用 UTM 专属链接兜底
主要访客区域与跨境合规 上线前按原方案文档第十章做一次专项确认
事件量超预期 升级路径已定:FastAPI 采集拆分 → 分区细化 → 聚合下沉