# 审计记录：维客线索重构（member_birthday_manual → member_retention_clue）

- 日期：2026-02-26 13:09:41
- Prompt-ID：`P20260226-130447`（追加审计，前序 Prompt：`P20260226-120858`）
- 风险标签：`root-file`, `dir:backend`, `dir:etl`, `dir:db`, `db-schema-change`
- 变更统计：139 files changed, 6211 insertions(+), 216484 deletions(-)

## 变更概述

将原"助教手动补录会员生日"单一功能表 `member_birthday_manual` 重构为通用"维客线索"表 `member_retention_clue`，采用"大类 + 摘要 + 详情"三层结构，覆盖六个维度（客户基础信息、消费习惯、玩法偏好、促销偏好、社交关系、重要反馈）。生日信息不再单独建表，作为"客户基础信息"大类下的一条线索记录。

本次 Prompt（P20260226-130447）需求：在租户管理后台列出每个客户的所有维客线索（标签、摘要、提供人、备注原文），支持修改、删除、隐藏操作。

### 影响范围

| 子系统 | 影响 |
|--------|------|
| 后端 API | `member_birthday` 路由替换为 `member_retention_clue`，新增 POST/GET/DELETE 三个端点 |
| ETL DWS | `member_consumption_task` 和 `member_visit_task` 移除 FDW 生日补录读取及 fallback 逻辑 |
| FDW | 外部表从 `fdw_app.member_birthday_manual` 重构为 `fdw_app.member_retention_clue` |
| DB 迁移 | 删除 `member_birthday_manual`，新建 `member_retention_clue`（含 CHECK 约束 + 3 索引） |
| DDL 基线 | `zqyy_app__public.sql` 和 `fdw.sql` 已同步更新 |

## 本次对话文件变更（session_diff）

### 新增文件
- `docs/audit/prompt_logs/prompt_log_20260226_130447.md`

### 修改文件
- `NeoZQYY.code-workspace`
- `docs/h5_ui/pages/customer-detail.html`

## DDL / 迁移检查

- 迁移脚本：`db/zqyy_app/migrations/2026-02-26__refactor_birthday_to_retention_clue.sql`
- `compliance.new_migration_sql`：空（迁移已在变更文件列表中但未被 compliance prescan 标记为待执行）
- ⚠️ DDL 基线待合并（`has_ddl_baseline: false`）
- BD 手册已创建：`docs/database/BD_Manual_member_retention_clue.md`

## DB 文档对账

`reasons` 含 `db-schema-change`，需执行全量对账。

- ⚠️ 无法自动连接测试库（TEST_DB_DSN）执行 `information_schema` 全量查询（当前环境无 pg power MCP 可用）
- 已有文档 `docs/database/BD_Manual_member_retention_clue.md` 内容与迁移脚本一致，表结构、约束、索引均已记录
- 待手动对账：用户需在测试库执行验证 SQL 确认表结构与文档一致，或在 pg power 可用时重新触发审计

## 改动注解

### `apps/backend/app/main.py`
- 变更类型：修改
- 原始原因：维客线索重构，需将后端路由注册从 `member_birthday` 切换到 `member_retention_clue`
- 思路分析：仅修改 import 和 `include_router` 调用，最小化入口文件改动；同步更新 CHANGE 注释标记
- 修改结果：后端启动时加载新的维客线索路由模块，旧生日路由不再注册

### `apps/backend/app/routers/member_retention_clue.py`
- 变更类型：新增
- 原始原因：替代原 `member_birthday` 路由，提供维客线索的 CRUD 接口
- 思路分析：提供三个端点：POST 提交线索（INSERT）、GET 按会员查询（倒序）、DELETE 删除单条。使用 `get_connection()` 直连业务库，事务手动管理
- 修改结果：新增 `/api/retention-clue` 系列接口，支持多大类线索的增删查

### `apps/backend/app/schemas/member_retention_clue.py`
- 变更类型：新增
- 原始原因：为维客线索接口定义请求/响应 Pydantic 模型
- 思路分析：定义 `ClueCategory` 枚举（6 个大类）、`RetentionClueSubmit`（提交请求）、`RetentionClueOut`（返回模型），字段约束与数据库 CHECK 一致
- 修改结果：后端接口具备完整的输入校验和输出序列化能力

### `apps/etl/connectors/feiqiu/tasks/dws/member_consumption_task.py`
- 变更类型：修改
- 原始原因：维客线索重构后，生日不再通过 FDW 从业务库补录，ETL 侧需移除相关逻辑
- 思路分析：删除 `sql_with_fdw`（含 COALESCE 子查询）和 `sql_fallback`（降级查询），合并为单一 `sql` 直接读取 `dim_member.birthday`；移除 try/except FDW 降级逻辑和 rollback 处理
- 修改结果：会员消费汇总任务的会员信息提取简化为单次查询，消除 FDW 依赖和降级复杂度（-51 行）

### `apps/etl/connectors/feiqiu/tasks/dws/member_visit_task.py`
- 变更类型：修改
- 原始原因：同 member_consumption_task，移除 FDW 生日补录读取
- 思路分析：同样删除双 SQL + try/except 降级模式，简化为单一查询
- 修改结果：会员到店汇总任务的会员信息提取简化，消除 FDW 依赖（-49 行）

### `db/fdw/setup_fdw_reverse.sql`
- 变更类型：修改
- 原始原因：FDW 外部表需从 `member_birthday_manual` 重构为 `member_retention_clue`
- 思路分析：更新外部表列定义（移除 `birthday_value`/`source`，新增 `category`/`summary`/`detail`），更新 OPTIONS 指向新表名，精简注释和验证 SQL
- 修改结果：生产环境 FDW 反向映射指向新的维客线索表

### `db/fdw/setup_fdw_reverse_test.sql`
- 变更类型：修改
- 原始原因：测试环境 FDW 配置需与生产环境同步
- 思路分析：与 `setup_fdw_reverse.sql` 保持一致，仅目标库为 `test_zqyy_app`
- 修改结果：测试环境 FDW 反向映射同步更新

### `db/zqyy_app/migrations/2026-02-26__refactor_birthday_to_retention_clue.sql`
- 变更类型：新增
- 原始原因：需要数据库迁移脚本完成表结构重构
- 思路分析：事务内先 DROP 旧表再 CREATE 新表，幂等设计（IF EXISTS / IF NOT EXISTS）；新表含 CHECK 约束限制 category 枚举值，3 个索引覆盖常用查询模式
- 修改结果：执行后 `member_birthday_manual` 被删除，`member_retention_clue` 就绪

### `docs/h5_ui/pages/customer-detail.html`
- 变更类型：修改（session_diff.modified）
- 简要注解：H5 客户详情页面调整，配合维客线索功能的前端展示

### `NeoZQYY.code-workspace`
- 变更类型：修改（session_diff.modified）
- 简要注解：工作区配置文件更新

## Prompt 溯源

```
- [P20260226-130447] 2026-02-26 13:04:47 +0800
  - summary: 依旧保留回访任务完成的判定新增：租户管理后台，列出每个客户的所有维客线索，标签 摘要 提供人 备注原文等字段。支持修改，删除，隐藏的操作。
```

> 本次 prompt 在维客线索重构基础上，进一步要求管理后台支持线索的列表展示与管理操作。
