# 数据库变更审计：RNS1.2 客户与助教接口

> 审计日期：2026-03-19
> 关联 SPEC：`rns1-customer-coach-api`（RNS1.2）
> 审计结论：**本次实现无 schema 变更，仅读取已有表**

---

## 1. 审计范围

RNS1.2 新增 3 个后端接口：
- **CUST-1** `GET /api/xcx/customers/{customerId}` — 客户详情
- **CUST-2** `GET /api/xcx/customers/{customerId}/records` — 客户服务记录
- **COACH-1** `GET /api/xcx/coaches/{coachId}` — 助教详情

实现文件：
- `apps/backend/app/services/customer_service.py`（新增）
- `apps/backend/app/services/coach_service.py`（新增）
- `apps/backend/app/services/fdw_queries.py`（扩展，新增查询函数）
- `apps/backend/app/routers/xcx_customers.py`（新增）
- `apps/backend/app/routers/xcx_coaches.py`（新增）

---

## 2. 业务库表引用审计（test_zqyy_app）

### 2.1 biz.coach_tasks — 仅 SELECT

| 引用位置 | 操作 | 用途 |
|---------|------|------|
| `customer_service._build_coach_tasks()` | SELECT | 查询客户关联的助教任务（`WHERE member_id = %s AND status IN ('active', 'inactive')`） |
| `coach_service.get_coach_detail()` | SELECT | 统计当月已完成任务数（`WHERE assistant_id = %s AND status = 'completed'`） |
| `coach_service._build_task_groups()` | SELECT | 查询助教任务分组（`WHERE assistant_id = %s AND status IN ('active', 'inactive', 'abandoned')`） |
| `coach_service._build_history_months()` | SELECT | 按月统计回访/召回完成数（`GROUP BY DATE_TRUNC('month', updated_at), task_type`） |

**结论：无 DDL 变更。** 表已由 P4 迁移脚本创建（`2026-02-27__p4_create_biz_tables.sql`），RNS1.2 仅新增读取路径。

### 2.2 biz.notes — 仅 SELECT

| 引用位置 | 操作 | 用途 |
|---------|------|------|
| `customer_service._build_notes()` | SELECT | 查询客户备注（`WHERE target_type = 'member' AND target_id = %s`，最多 20 条） |
| `coach_service._build_task_groups()` | SELECT | 查询任务关联备注（`WHERE task_id = ANY(%s)`） |
| `coach_service._build_notes()` | SELECT | 查询助教相关备注（`JOIN biz.coach_tasks ON task_id`，最多 20 条） |

**结论：无 DDL 变更。** 表已由 P4 迁移脚本创建。

### 2.3 biz.ai_cache — 仅 SELECT

| 引用位置 | 操作 | 用途 |
|---------|------|------|
| `customer_service._build_ai_insight()` | SELECT | 查询 AI 分析缓存（`WHERE cache_type = 'app4_analysis' AND target_id = %s`，取最新 1 条） |

**结论：无 DDL 变更。** 表已由 P5 迁移脚本创建（`2026-03-08__create_ai_tables.sql`）。

### 2.4 public.member_retention_clue — 仅 SELECT

| 引用位置 | 操作 | 用途 |
|---------|------|------|
| `customer_service._build_retention_clues()` | SELECT | 查询维客线索（`WHERE member_id = %s ORDER BY created_at DESC`） |

**结论：无 DDL 变更。** 表已由独立迁移脚本创建（`2026-02-26__refactor_birthday_to_retention_clue.sql`）。

---

## 3. FDW / ETL 视图引用审计

RNS1.2 通过 `fdw_queries.py` 直连 ETL 库（`test_etl_feiqiu`）查询 `app.v_*` RLS 视图。
**不使用** `fdw_etl.*` 外部表（原因：`postgres_fdw` 不传递自定义 GUC 参数到远端连接）。

### 引用的 ETL RLS 视图

| 视图 | 引用函数 | 用途 |
|------|---------|------|
| `app.v_dim_member` | `get_member_info()` | 会员信息（nickname, mobile），DQ-6 |
| `app.v_dim_member_card_account` | `get_member_balance()` | 会员卡余额，DQ-7 |
| `app.v_dim_assistant` | `get_assistant_info()` | 助教基本信息 |
| `app.v_dwd_assistant_service_log` | `get_consumption_60d()`, `get_last_visit_days()`, `get_consumption_records()`, `get_customer_service_records()`, `get_total_service_count()`, `get_coach_60d_stats()`, `get_coach_top_customers()`, `get_coach_service_records()`, `get_monthly_customer_count()` | 服务记录明细（废单排除 `is_delete=0`，金额 `ledger_amount`） |
| `app.v_dws_assistant_salary_calc` | `get_salary_calc()`, `get_salary_calc_multi_months()` | 助教绩效/档位/收入 |
| `app.v_dws_member_assistant_relation_index` | `get_relation_index()` | 会员-助教关系指数 |

**结论：无 FDW 配置变更。** 所有引用的视图均已存在于 ETL 库 `app` schema 中，且 `fdw_etl` schema 的外部表映射已包含这些视图（通过 `IMPORT FOREIGN SCHEMA app` 批量导入）。RNS1.2 采用直连 ETL 库方式，不依赖 `fdw_etl` 外部表。

---

## 4. DDL 变更汇总

| 变更类型 | 数量 | 说明 |
|---------|------|------|
| 新建表 | 0 | — |
| 新增字段 | 0 | — |
| 新增索引 | 0 | — |
| FDW 映射变更 | 0 | — |
| 迁移脚本 | 0 | 无需编写 |

**本次实现无 schema 变更，仅读取已有表。** 无需编写迁移脚本。

---

## 5. 风险评估

| 风险项 | 评估 | 缓解措施 |
|--------|------|---------|
| 查询性能 | 低 | 已有索引覆盖主要查询路径（`idx_coach_tasks_assistant_status`、`idx_notes_target`、`idx_ai_cache_lookup`） |
| 数据一致性 | 低 | 所有金额使用 `items_sum` 口径，废单排除使用 `is_delete=0`，会员信息通过维度表 JOIN |
| FDW 连接稳定性 | 中 | 扩展模块查询失败时优雅降级为空默认值，不影响核心响应 |

---

## 6. 关联文档

- BD 手册（biz 表）：`docs/database/BD_Manual_biz_tables.md`（已更新 §2.1 RNS1.2 引用说明）
- BD 手册（AI 表）：`docs/database/BD_Manual_ai_tables.md`
- BD 手册（维客线索）：`docs/database/BD_Manual_member_retention_clue.md`
- BD 手册（FDW）：`docs/database/BD_Manual_fdw_etl_setup.md`
- 设计文档：`.kiro/specs/rns1-customer-coach-api/design.md`
- 需求文档：`.kiro/specs/rns1-customer-coach-api/requirements.md`
