Files
Neo 6f8f12314f feat: 累积功能变更 — 聊天集成、租户管理、小程序更新、ETL 增强、迁移脚本
包含多个会话的累积代码变更:
- backend: AI 聊天服务、触发器调度、认证增强、WebSocket、调度器最小间隔
- admin-web: ETL 状态页、任务管理、调度配置、登录优化
- miniprogram: 看板页面、聊天集成、UI 组件、导航更新
- etl: DWS 新任务(finance_area_daily/board_cache)、连接器增强
- tenant-admin: 项目初始化
- db: 19 个迁移脚本(etl_feiqiu 11 + zqyy_app 8)
- packages/shared: 枚举和工具函数更新
- tools: 数据库工具、报表生成、健康检查
- docs: PRD/架构/部署/合约文档更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 00:03:48 +08:00

82 lines
3.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# P7→NS1/RNS1 缺失项 #4"我的新客"筛选逻辑的完整定义
## 简要结论
- 状态:⚠️ 部分解决
- 风险等级:🟠 中
- 后端已实现新客筛选逻辑,但采用的是"本月有服务 + 历史无记录"的简化定义,与 P7 AC3 定义的"首次服务 + 2月内 + 服务次数≤2"条件不完全一致。未使用 `dws_assistant_customer_stats` 表(该表已在 ETL 层建好),而是直接查询 DWD 层视图。
## 详细审查
### 审查范围
- `apps/backend/app/services/performance_service.py``_build_customer_lists()` 函数
- `apps/backend/app/services/fdw_queries.py` — FDW 查询
- `apps/etl/connectors/feiqiu/tasks/dws/assistant_customer_task.py` — DWS 客户统计 ETL
- `docs/database/ddl/etl_feiqiu__dws.sql``dws_assistant_customer_stats` 表结构
- `apps/miniprogram/miniprogram/pages/performance/performance.wxml` — 新客列表展示
### 发现
1. **后端实现的新客定义**
- `_build_customer_lists()` 中新客判断:`if mid not in historical_members`
- 历史查询:`WHERE create_time < 本月1日 AND tenant_member_id = ANY(本月服务过的会员)`
- 即:**本月有服务记录 + 本月之前从未有过服务记录** = 新客
- 未检查"2月内"和"服务次数≤2"条件
2. **P7 AC3 的完整定义**
- 首次服务first_service_date 在本月)
- 2月内首次服务距今不超过 2 个月)
- 服务次数 ≤ 2
3. **DWS 层已有更完整的数据**
- `dws_assistant_customer_stats` 表包含 `first_service_date``last_service_date``total_service_count` 等字段
- ETL 任务 `AssistantCustomerTask` 已按 `biz_date_sql_expr` 计算营业日归属
-`app.v_dws_assistant_customer_stats` RLS 视图可供后端查询
- 但后端 `fdw_queries.py` 中未使用此视图
4. **前端展示已到位**
- 新客列表展示:姓名、头像、最近服务日期、服务次数
- `<text class="customer-detail">最近服务: {{item.lastService}} · {{item.count}}次</text>`
### 证据
```python
# performance_service.py — 新客判断逻辑
# 查询历史记录(本月之前是否有服务记录)
try:
start_date = f"{year}-{month:02d}-01"
with fdw_queries._fdw_context(conn, site_id) as cur:
cur.execute("""
SELECT DISTINCT tenant_member_id
FROM app.v_dwd_assistant_service_log
WHERE site_assistant_id = %s
AND is_delete = 0
AND create_time < %s::timestamptz
AND tenant_member_id = ANY(%s)
""", (assistant_id, start_date, member_ids))
for row in cur.fetchall():
historical_members.add(row[0])
# 新客:历史无记录
if mid not in historical_members:
new_customers.append({...})
```
```sql
-- dws_assistant_customer_stats 表结构(已存在但未被后端使用)
CREATE TABLE dws.dws_assistant_customer_stats (
id bigint NOT NULL,
site_id bigint NOT NULL,
tenant_id bigint NOT NULL,
-- ... 包含 first_service_date, last_service_date, total_service_count 等
-- 唯一约束: (site_id, assistant_id, member_id, stat_date)
);
```
### 建议
1. **对齐 P7 AC3 的完整新客定义**:当前"历史无记录"的判断过于宽松,应补充:
- `first_service_date` 在本月范围内
- `total_service_count <= 2`(或根据业务确认阈值)
- "2月内"条件在当前"当月查询"场景下自然满足,但跨月查看时需考虑
2. **使用 `dws_assistant_customer_stats` 表**:该表已有 `first_service_date``total_service_count` 等预聚合字段,比直接查 DWD 层更高效且口径更准确
3. **确认新客定义的业务边界**:与产品确认"首次服务"是指该助教的首次服务还是全店首次服务