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>
This commit is contained in:
@@ -4,6 +4,9 @@
|
||||
> 预估工作量:中等
|
||||
> 前置条件:P5-A 已完成(AI 骨架就绪)、NS1 已完成(后端 API 数据结构确定)
|
||||
> 参考基准:`docs/prd/specs/P5-miniapp-ai-integration.md`(P5-B 阶段定义)
|
||||
> SPEC 状态:✅ 三件套已完成(requirements.md → design.md → tasks.md)
|
||||
> SPEC 路径:`.kiro/specs/ai-prompt-refinement/`
|
||||
> 实施状态:⏳ 未开始(代码实施待启动)
|
||||
|
||||
---
|
||||
|
||||
@@ -17,7 +20,7 @@ P5-A 阶段已交付 AI 集成管道:百炼封装、缓存 API、SSE 框架、
|
||||
|
||||
| 应用 | 文件 | 骨架状态 | 待细化字段 |
|
||||
|------|------|---------|-----------|
|
||||
| 应用 1 | `app1_chat.py` | 页面上下文文本化工具留接口 | `page_context`、`screen_content` 各页面文本化 |
|
||||
| 应用 1 | `app1_chat.py` | 页面上下文文本化工具留接口 | `page_context` + `screen_content` 合并为 `build_page_text()` 输出(详见 3.7 设计决策) |
|
||||
| 应用 3 | `app3_clue.py` | `build_prompt()` 占位 | `consumption_records`(DWD+DWS 订单明细全维度) |
|
||||
| 应用 4 | `app4_analysis.py` | `build_prompt()` 占位 | `service_history`、`assistant_info` |
|
||||
| 应用 5 | `app5_tactics.py` | `build_prompt()` 占位 | `service_history`、`assistant_info`(同应用 4) |
|
||||
@@ -316,30 +319,50 @@ NS2 需确认事项:
|
||||
|
||||
### 3.7 应用 1:页面上下文传递与文本化
|
||||
|
||||
#### 当前问题(P5 PRD 与 RNS1.4 实现的差异)
|
||||
#### P5 原始设计 vs NS2 实际方案
|
||||
|
||||
P5 PRD 原始设计:
|
||||
```
|
||||
前端跳转 chat.html 时传入 source_page + page_context + screen_content
|
||||
→ 后端接收后文本化 → 拼接为首条 user message
|
||||
```
|
||||
P5 PRD 定义应用 1 首条 Prompt 包含三个字段:
|
||||
|
||||
RNS1.4 当前实现:
|
||||
```
|
||||
前端跳转 chat 页面时仅传入 contextType + contextId(如 task/12345)
|
||||
→ 后端 _build_page_context() 为占位实现,page_context 和 screen_content 为空
|
||||
→ AI 无法获得页面上下文
|
||||
```
|
||||
| 字段 | P5 定义 | 含义 |
|
||||
|------|---------|------|
|
||||
| `source_page` | 来源页面标识 | 如 `task-detail`、`board-finance` |
|
||||
| `page_context` | 页面上下文摘要 | 结构化数据,后端可从 DB 获取 |
|
||||
| `screen_content` | 用户当前屏幕可见内容的文本化描述 | 需前端传入当前视口内容 |
|
||||
|
||||
#### 解决方案:后端根据 contextType 自动获取页面上下文
|
||||
AI需求2.md 原文对应:
|
||||
- `page_context` → "用户正在查看页面内容:页面上下文(来源页面+内容摘要)"
|
||||
- `screen_content` → "用户页面视野内容:当前屏幕内容"
|
||||
|
||||
采用方案 B(简化前端,后端自动查询),与 RNS1.4 已有的 `contextType`/`contextId` 参数兼容:
|
||||
#### `screen_content` 的设计决策
|
||||
|
||||
> ⚠️ **设计决策(NS2 与 P5 的差异点)**:NS2 不要求前端传入 `screen_content`,改由后端根据 `contextType` + `contextId` + 筛选参数自动查询数据库,生成等效的页面上下文文本。
|
||||
|
||||
**决策理由:**
|
||||
1. 微信小程序前端难以将当前屏幕 DOM 序列化为结构化文本(无 `innerText` 等 Web API)
|
||||
2. RNS1.4 已实现 `contextType`/`contextId` 参数机制,后端可据此精确获取页面数据
|
||||
3. 后端自动查询可获取比前端视口更完整的上下文(如关联的 AI 分析、历史备注等)
|
||||
4. 看板类页面通过额外传入筛选参数(`timeDimension`、`dimension` 等),后端可还原用户当前视图的数据范围
|
||||
|
||||
**等效覆盖说明:**
|
||||
- P5 的 `page_context`(结构化数据摘要)→ NS2 通过 `build_page_text()` 从 DB 获取,完全覆盖
|
||||
- P5 的 `screen_content`(屏幕可见内容)→ NS2 通过 `contextType` + 筛选参数推断用户当前视图,近似覆盖
|
||||
- 对于详情类页面(task-detail、customer-detail 等),后端获取的数据与用户屏幕内容高度一致
|
||||
- 对于看板类页面,通过筛选参数还原当前视图的数据维度和范围
|
||||
|
||||
**局限性:**
|
||||
- 无法获取用户滚动位置(如长列表中用户正在看第几条)
|
||||
- 无法获取用户输入中但未提交的内容
|
||||
- 看板页面若前端未传筛选参数,使用默认值可能与用户实际视图不一致
|
||||
|
||||
#### 实际方案:后端根据 contextType 自动获取页面上下文
|
||||
|
||||
与 RNS1.4 已有的 `contextType`/`contextId` 参数兼容:
|
||||
|
||||
```
|
||||
前端传入 contextType="task-detail" + contextId="12345"
|
||||
→ 后端 build_page_text("task-detail", 12345, site_id)
|
||||
前端传入 contextType="task-detail" + contextId="12345"(+ 看板类页面的筛选参数)
|
||||
→ 后端 build_page_text("task-detail", 12345, site_id, filters?)
|
||||
→ 后端从数据库获取任务详情、客户信息、备注、AI 分析等
|
||||
→ 格式化为结构化中文文本
|
||||
→ 格式化为结构化中文文本(同时覆盖 page_context 和 screen_content 的信息需求)
|
||||
→ 拼接为首条 user message 的 page_context 字段
|
||||
```
|
||||
|
||||
@@ -435,17 +458,19 @@ RNS1.4 当前实现:
|
||||
|
||||
```
|
||||
用户点击 AI 入口
|
||||
→ 前端传入 contextType + contextId(+ 可选筛选参数)
|
||||
→ 前端传入 contextType + contextId(+ 看板类页面的筛选参数)
|
||||
→ 后端 build_page_text(contextType, contextId, site_id, filters?)
|
||||
→ 从数据库获取对应页面数据,格式化为结构化中文文本
|
||||
→ 文本同时覆盖 P5 定义的 page_context(数据摘要)和 screen_content(屏幕内容)
|
||||
→ 拼接为首条 user message 的 page_context 字段
|
||||
→ 注入 biz_params(User_ID/Role/Nickname)到 system prompt
|
||||
→ SSE 流式调用百炼 API
|
||||
```
|
||||
|
||||
> ⚠️ 与 P5 PRD 原始设计的差异:P5 设计为前端传入 `source_page` + `page_context` + `screen_content`,
|
||||
> RNS1.4 实际实现为前端传入 `contextType` + `contextId`,后端自动查询数据库获取上下文。
|
||||
> NS2 沿用 RNS1.4 方案(后端自动获取),不要求前端传入原始页面数据。
|
||||
> ⚠️ 与 P5 PRD 原始设计的差异(详见 3.7 设计决策):
|
||||
> P5 设计为前端传入 `source_page` + `page_context` + `screen_content` 三个独立字段,
|
||||
> NS2 采用后端自动查询方案,前端仅传入 `contextType` + `contextId` + 筛选参数,
|
||||
> 后端通过 `build_page_text()` 生成合并的页面上下文文本,等效覆盖 `page_context` 和 `screen_content` 的信息需求。
|
||||
|
||||
---
|
||||
|
||||
@@ -467,55 +492,67 @@ RNS1.4 当前实现:
|
||||
|
||||
---
|
||||
|
||||
## 七、预审查清单(SPEC 启动前确认)
|
||||
## 七、预审查清单(已确认)
|
||||
|
||||
> 以下问题已在 SPEC 细化阶段(requirements.md / design.md)中逐一确认。
|
||||
|
||||
### 7.1 数据结构
|
||||
|
||||
1. **消费记录字段范围**:`consumption_records` 中每条记录需要包含哪些字段?是否需要包含折扣信息(discount_manual/discount_other)?是否需要包含支付方式明细(balance_pay/cash_pay/online_pay)?
|
||||
2. **服务记录字段范围**:`service_history` 中每条记录需要包含哪些字段?是否需要包含台桌类型(room_category)和客户评价?
|
||||
3. **备注内容截断**:`all_notes` 中每条备注是否需要全文传入?长备注是否截断?截断长度?
|
||||
4. **会员卡明细粒度**:`member_cards` 是否需要包含卡号、开卡日期、有效期等详细信息,还是只需要卡类型和余额?
|
||||
1. **消费记录字段范围**:每条记录包含 `settle_date`、`settle_type`、`items_sum`、`table_charge_money`、`assistant_pd_money`、`assistant_cx_money`、`goods_money`、`room_name`、`duration_minutes`、`assistant_names` 共 10 个字段。不包含折扣明细和支付方式明细(token 预算有限,这些字段对 AI 分析价值低)。
|
||||
2. **服务记录字段范围**:每条记录包含 `service_date`、`duration_minutes`、`items_sum`、`room_name`、`is_pd`(是否陪打)。不包含台桌类型和客户评价。
|
||||
3. **备注内容截断**:单条备注最大 500 字符,超出截断并附加"…(已截断)"标记。备注总数最多 50 条(按 `created_at DESC`)。
|
||||
4. **会员卡明细粒度**:仅包含 `card_type`(卡类型)、`balance`(余额)、`gift_balance`(赠送余额),不含卡号、开卡日期、有效期。
|
||||
|
||||
### 7.2 Prompt 优化
|
||||
|
||||
5. **Token 预算**:每个应用的首条 Prompt 的 token 上限是多少?百炼 API 的单次请求 token 限制?
|
||||
6. **数据时间窗口**:消费记录默认取近 3 个月,是否需要可配置?不同应用是否需要不同时间窗口?
|
||||
7. **空数据处理**:当客户无消费记录/无备注/无服务历史时,Prompt 如何处理?是否需要特殊提示词?
|
||||
5. **Token 预算**:应用 3/4/5/6/7 的 system message content ≤ 8000 字符(约 4000 token);应用 1 的 system prompt(含页面上下文)≤ 4000 字符(约 2000 token)。
|
||||
6. **数据时间窗口**:默认近 3 个月,通过 `months` 参数可配置。各应用统一使用 3 个月窗口。
|
||||
7. **空数据处理**:使用明确的空状态提示词(如"该客户暂无消费记录,请基于已有信息分析"),不传入空数据不做说明。`reference` 无历史数据时设为空对象并标注"暂无历史线索"。
|
||||
|
||||
### 7.3 页面文本化(应用 1)
|
||||
|
||||
8. **文本化格式**:页面上下文是输出为结构化中文文本还是 JSON?AI 对哪种格式理解更好?
|
||||
9. **数据量控制**:每个页面上下文的字符上限?是否需要根据页面类型动态调整?
|
||||
10. **实时性要求**:应用 1 的页面上下文是否需要实时获取最新数据?还是可以使用缓存(如 task_detail_cache)?
|
||||
8. **文本化格式**:输出为结构化中文描述文本(分段标题 + 缩进),非 JSON。中文描述更便于 AI 理解上下文语义。
|
||||
9. **数据量控制**:每个页面上下文统一 ≤ 2000 字符,不按页面类型动态调整。超出截断并标注。
|
||||
10. **实时性要求**:实时获取最新数据(不使用缓存),设置 5 秒 FDW 查询超时。数据获取失败时返回降级文本,不阻断对话。
|
||||
|
||||
### 7.4 性能与安全
|
||||
|
||||
11. **FDW 查询并发**:多个数据获取函数是否可以并发执行(asyncio.gather)?FDW 连接池是否支持?
|
||||
12. **数据脱敏**:传入百炼 API 的数据中,哪些字段需要脱敏?member_phone 已断档不传,还有其他敏感字段吗?
|
||||
13. **错误降级**:某个数据获取函数失败时(如 FDW 超时),是否跳过该部分继续生成 Prompt?还是整体失败?
|
||||
11. **FDW 查询并发**:支持。使用 `asyncio.gather(return_exceptions=True)` 并发执行多个数据获取函数,部分失败不阻断。同一连接上的多个 FDW 查询串行执行(共享 RLS 设置)。
|
||||
12. **数据脱敏**:`member_phone` 已断档不传。会员信息通过 `member_id JOIN v_dim_member (scd2_is_current=1)` 获取昵称,不传入手机号等敏感字段。`build_page_text()` 输出中不包含 `member_phone`。
|
||||
13. **错误降级**:部分失败继续。失败部分使用默认空值(空数组/空对象),在 Prompt 中标注"该部分数据获取失败",继续生成 Prompt 并调用百炼 API。确保 Prompt JSON 不含 `null`。
|
||||
|
||||
---
|
||||
|
||||
## 八、任务清单(草案,SPEC 细化后调整)
|
||||
## 八、任务清单(已细化,详见 SPEC tasks.md)
|
||||
|
||||
### Batch A:共享数据获取层
|
||||
- [ ] T1:创建 `data_fetchers/member_data.py`(客户消费数据获取,应用 3/6/7 共用)
|
||||
- [ ] T2:创建 `data_fetchers/assistant_data.py`(助教信息 + 服务历史获取,应用 4/5 共用)
|
||||
- [ ] T3:创建 `data_fetchers/page_context.py`(页面上下文文本化框架,应用 1 专用)
|
||||
> SPEC 三件套已完成:`requirements.md`(14 条需求)→ `design.md`(17 个正确性属性)→ `tasks.md`(17 个顶层任务)。
|
||||
> 以下为 PRD 级任务概览,详细实施步骤见 `.kiro/specs/ai-prompt-refinement/tasks.md`。
|
||||
|
||||
### Batch B:Prompt 拼接实现
|
||||
- [ ] T4:完善 `app3_clue.py` 的 `build_prompt()`(客户消费数据 → 维客线索分析)
|
||||
- [ ] T5:完善 `app4_analysis.py` 的 `build_prompt()`(助教+客户数据 → 关系分析)
|
||||
- [ ] T6:完善 `app5_tactics.py` 的 `build_prompt()`(复用应用 4 数据 + task_suggestion)
|
||||
- [ ] T7:完善 `app6_note.py` 的 `build_prompt()`(备注+客户数据 → 备注分析)
|
||||
- [ ] T8:完善 `app7_customer.py` 的 `build_prompt()`(客户全量数据 → 运营策略)
|
||||
### Batch A:共享数据获取层(tasks 1-4)
|
||||
- [ ] T1:创建 `data_fetchers/` 模块骨架(`__init__.py` + 3 个子模块)
|
||||
- [ ] T2:实现 `member_data.py`(`fetch_member_consumption_data` + `fetch_member_notes`)
|
||||
- [ ] T3:实现 `assistant_data.py`(`fetch_assistant_info` + `fetch_service_history`)
|
||||
- [ ] T4:检查点 — 数据获取层完成
|
||||
|
||||
### Batch C:应用 1 页面文本化 + 前端配合
|
||||
- [ ] T9:实现各页面类型的文本化函数(task-detail/customer-detail/board-*/performance 等)
|
||||
- [ ] T10:补充 `app1_chat.py` 的 `_build_page_context()` 调用文本化函数,根据 `contextType` 路由到对应文本化函数
|
||||
- [ ] T11:前端补充看板类页面的筛选参数传递(board-finance/board-customer/board-coach 跳转 chat 时传入当前筛选条件)
|
||||
- [ ] T12:确认 biz_params 端到端正确性(前端 JWT → 后端提取 user_id/role/nickname → system prompt 注入 → 百炼权限隔离生效)
|
||||
### Batch B:Prompt 拼接实现(tasks 5-11)
|
||||
- [ ] T5:完善 `app3_clue.py` 的 `build_prompt()`(async + 真实数据)
|
||||
- [ ] T6:完善 `app4_analysis.py` 的 `build_prompt()`(asyncio.gather 并发获取)
|
||||
- [ ] T7:完善 `app5_tactics.py` 的 `build_prompt()`(复用 App4 + task_suggestion)
|
||||
- [ ] T8:完善 `app6_note.py` 的 `build_prompt()`(消费数据 + 全部备注)
|
||||
- [ ] T9:完善 `app7_customer.py` 的 `build_prompt()`(客观+主观数据,标注来源)
|
||||
- [ ] T10:检查点 — 应用 3-7 完成
|
||||
- [ ] T11:实现错误降级与 Token 预算控制
|
||||
|
||||
### Batch D:联调与验证
|
||||
- [ ] T13:端到端联调(触发事件 → Prompt 拼接 → 百炼调用 → 缓存写入 → 前端展示)
|
||||
- [ ] T14:应用 1 页面上下文联调(各入口页面 → contextType/contextId → 后端文本化 → AI 对话验证上下文感知)
|
||||
### Batch C:应用 1 页面文本化 + 前端配合(tasks 12-15)
|
||||
- [ ] T12:实现 `page_context.py`(10 种页面类型文本化)
|
||||
- [ ] T13:集成 `app1_chat.py` 的 `_build_page_context()` 调用 `build_page_text()`
|
||||
- [ ] T14:检查点 — 页面上下文完成
|
||||
- [ ] T15:前端看板筛选参数传递(小程序 ai-float-button + chat 页面参数解析)
|
||||
|
||||
### Batch D:集成联调(tasks 16-17)
|
||||
- [ ] T16:集成连线(dispatcher await 正确性 + 端到端验证)
|
||||
- [ ] T17:最终检查点
|
||||
|
||||
### 属性测试(可选,标记 * 的子任务)
|
||||
- 17 个正确性属性(P1-P17)对应 Hypothesis 属性测试
|
||||
- 测试文件:`tests/test_data_fetchers/`、`tests/test_ai_apps/`
|
||||
|
||||
Reference in New Issue
Block a user