160 lines
7.0 KiB
Markdown
160 lines
7.0 KiB
Markdown
# BD 手册:维客线索表(member_retention_clue)
|
||
|
||
## 概述
|
||
|
||
在 `zqyy_app` / `test_zqyy_app` 业务库中新建 `member_retention_clue` 表,替代原 `member_birthday_manual` 表。维客线索是助教为会员记录的销售/维护线索,采用"大类 + 摘要 + 详情"三层结构,覆盖客户基础、消费习惯、玩法偏好、促销偏好、社交关系、重要反馈六个维度。
|
||
|
||
生日信息不再单独建表,作为"客户基础"大类下的一条线索记录。
|
||
|
||
## 变更说明
|
||
|
||
| 库 | Schema | 表 | 变更类型 | 说明 |
|
||
|----|--------|---|---------|------|
|
||
| zqyy_app / test_zqyy_app | public | member_birthday_manual | 删除 | 旧表,生日单独记录方案废弃 |
|
||
| zqyy_app / test_zqyy_app | public | member_retention_clue | 新建 | 维客线索表 |
|
||
| zqyy_app / test_zqyy_app | public | member_retention_clue.source | 新增列 | 2026-02-27 补齐线索来源字段 |
|
||
| zqyy_app / test_zqyy_app | public | member_retention_clue.category | 约束变更 | 2026-03-08 枚举对齐:`客户基础信息` → `客户基础` |
|
||
|
||
### 表结构
|
||
|
||
| 列名 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| id | BIGSERIAL | PRIMARY KEY | 自增主键 |
|
||
| member_id | BIGINT | NOT NULL | 会员 ID |
|
||
| category | VARCHAR(20) | NOT NULL, CHECK | 线索大类枚举(6 值,见下方枚举表) |
|
||
| summary | VARCHAR(200) | NOT NULL | 摘要:重点信息 |
|
||
| detail | TEXT | 可为空 | 详情:分析及扩展说明 |
|
||
| recorded_by_assistant_id | BIGINT | — | 记录助教 ID |
|
||
| recorded_by_name | VARCHAR(50) | — | 记录助教姓名 |
|
||
| recorded_at | TIMESTAMPTZ | NOT NULL DEFAULT NOW() | 记录时间 |
|
||
| site_id | BIGINT | NOT NULL | 门店 ID(多门店隔离) |
|
||
| source | VARCHAR(20) | NOT NULL DEFAULT 'manual' | 线索来源(2026-02-27 新增) |
|
||
|
||
### category 枚举值
|
||
|
||
> 2026-03-08 枚举对齐:`客户基础信息` → `客户基础`(P5 spec 评审决定,与 AI 应用 Prompt 统一)
|
||
|
||
| 值 | 说明 |
|
||
|----|------|
|
||
| 客户基础 | 生日、职业、偏好时段等基础画像 |
|
||
| 消费习惯 | 消费频次、客单价、消费时段等 |
|
||
| 玩法偏好 | 中式/斯诺克/美式偏好、技术水平等 |
|
||
| 促销偏好 | 对储值活动、套餐、折扣的敏感度 |
|
||
| 社交关系 | 常带朋友、固定球搭子、社交圈等 |
|
||
| 重要反馈 | 客户提出的需求、投诉、建议等 |
|
||
|
||
### source 枚举值(2026-02-27 新增)
|
||
|
||
| 值 | 说明 |
|
||
|----|------|
|
||
| manual | 助教手动录入(默认值) |
|
||
| ai_consumption | 应用 3:消费分析自动生成 |
|
||
| ai_note | 应用 6:备注分析自动提取 |
|
||
|
||
### 约束与索引
|
||
|
||
| 名称 | 类型 | 列 | 说明 |
|
||
|------|------|---|------|
|
||
| member_retention_clue_pkey | PRIMARY KEY | id | 主键 |
|
||
| chk_retention_clue_category | CHECK | category | 限制大类枚举值 |
|
||
| idx_retention_clue_member | INDEX (btree) | member_id | 按会员查询 |
|
||
| idx_retention_clue_site | INDEX (btree) | site_id | 按门店查询 |
|
||
| idx_retention_clue_category | INDEX (btree) | (member_id, category) | 按会员+大类查询 |
|
||
|
||
## 兼容性
|
||
|
||
- **后端 API**:`POST /api/member-birthday` 废弃,替换为 `POST /api/retention-clue`、`GET /api/retention-clue/{member_id}`、`DELETE /api/retention-clue/{clue_id}`
|
||
- **source 字段**(2026-02-27):`POST /api/retention-clue` 接受可选 `source` 参数,默认 `manual`;`GET` 返回中包含 `source` 字段。已有数据自动填充 `DEFAULT 'manual'`,向后兼容
|
||
- **ETL Connector**:DWS 任务移除 FDW 读取 `member_birthday_manual` 的逻辑,生日仅从 `dim_member.birthday`(API 来源)读取
|
||
- **FDW**:`fdw_app.member_birthday_manual` 外部表需在 ETL 库侧同步更新为 `fdw_app.member_retention_clue`(含 `source` 列)
|
||
- **小程序**:助教端调用新 API 提交维客线索
|
||
- **H5 原型**:customer-detail 和 task-detail 页面"消费习惯"板块改为"维客线索"
|
||
|
||
## 回滚策略
|
||
|
||
### 仅回滚 source 列(2026-02-27 变更)
|
||
|
||
```sql
|
||
BEGIN;
|
||
ALTER TABLE member_retention_clue DROP COLUMN IF EXISTS source;
|
||
COMMIT;
|
||
```
|
||
|
||
### 完整回滚(整表)
|
||
|
||
```sql
|
||
BEGIN;
|
||
DROP TABLE IF EXISTS member_retention_clue CASCADE;
|
||
-- 如需恢复旧表,执行归档的 2026-02-22__C2_member_birthday_manual.sql
|
||
COMMIT;
|
||
```
|
||
|
||
## 验证步骤
|
||
|
||
```sql
|
||
-- 1. 确认旧表已删除
|
||
SELECT table_name FROM information_schema.tables
|
||
WHERE table_schema = 'public' AND table_name = 'member_birthday_manual';
|
||
-- 预期:0 行
|
||
|
||
-- 2. 确认新表存在
|
||
SELECT table_name FROM information_schema.tables
|
||
WHERE table_schema = 'public' AND table_name = 'member_retention_clue';
|
||
-- 预期:1 行
|
||
|
||
-- 3. 确认列结构完整(10 列)
|
||
SELECT column_name, data_type, is_nullable
|
||
FROM information_schema.columns
|
||
WHERE table_schema = 'public' AND table_name = 'member_retention_clue'
|
||
ORDER BY ordinal_position;
|
||
-- 预期:id, member_id, category, summary, detail,
|
||
-- recorded_by_assistant_id, recorded_by_name, recorded_at, site_id, source
|
||
|
||
-- 4. 确认 CHECK 约束
|
||
SELECT conname FROM pg_constraint
|
||
WHERE conrelid = 'member_retention_clue'::regclass AND contype = 'c';
|
||
-- 预期:chk_retention_clue_category
|
||
|
||
-- 5. 确认索引(3 + 主键)
|
||
SELECT indexname FROM pg_indexes
|
||
WHERE tablename = 'member_retention_clue';
|
||
-- 预期:4 行
|
||
|
||
-- 6. 确认表注释
|
||
SELECT obj_description('member_retention_clue'::regclass, 'pg_class');
|
||
-- 预期:包含"维客线索"
|
||
|
||
-- 7. 确认 source 列存在且默认值正确(2026-02-27)
|
||
SELECT column_name, data_type, column_default, is_nullable
|
||
FROM information_schema.columns
|
||
WHERE table_schema = 'public'
|
||
AND table_name = 'member_retention_clue'
|
||
AND column_name = 'source';
|
||
-- 预期:1 行,varchar, 'manual'::character varying, NO
|
||
|
||
-- 8. 确认 source 列注释
|
||
SELECT col_description(
|
||
(SELECT oid FROM pg_class WHERE relname = 'member_retention_clue'),
|
||
(SELECT ordinal_position FROM information_schema.columns
|
||
WHERE table_name = 'member_retention_clue' AND column_name = 'source')
|
||
);
|
||
-- 预期:包含 'manual' / 'ai_consumption' / 'ai_note'
|
||
|
||
-- 9. 确认已有数据的 source 分布
|
||
SELECT source, COUNT(*) FROM member_retention_clue GROUP BY source;
|
||
-- 预期:全部为 'manual'(或空表)
|
||
```
|
||
|
||
## 关联文件
|
||
|
||
- 迁移脚本(建表):`db/zqyy_app/migrations/2026-02-26__refactor_birthday_to_retention_clue.sql`
|
||
- 迁移脚本(source 列):`db/zqyy_app/migrations/2026-02-27__add_source_to_retention_clue.sql`
|
||
- 迁移脚本(category 枚举对齐):`db/zqyy_app/migrations/2026-03-08__align_retention_clue_category_enum.sql`
|
||
- FDW 反向映射(生产):`db/fdw/setup_fdw_reverse.sql`
|
||
- FDW 反向映射(测试):`db/fdw/setup_fdw_reverse_test.sql`
|
||
- 后端路由:`apps/backend/app/routers/member_retention_clue.py`
|
||
- 后端模型:`apps/backend/app/schemas/member_retention_clue.py`
|
||
- H5 原型:`docs/h5_ui/pages/customer-detail.html`、`docs/h5_ui/pages/task-detail.html`
|
||
- 旧表文档(已归档):`docs/database/_archived/BD_Manual_member_birthday_manual.md`
|
||
- 旧 FDW 文档(已归档):`docs/database/_archived/BD_Manual_fdw_reverse_member_birthday.md`
|