feat: batch update - gift card breakdown spec, backend APIs, miniprogram pages, ETL finance recharge, docs & migrations

This commit is contained in:
Neo
2026-03-20 01:43:48 +08:00
parent 075caf067f
commit 79f9a0e1da
437 changed files with 118603 additions and 976 deletions

View File

@@ -0,0 +1,300 @@
# RNS1 拆分计划 — NS1 小程序后端 API 补全
> 创建时间2026-03-18
> 来源NS1 原始 spec + 两份 Storyboard 走查报告(助教视角 51 Gap + 管理层视角 31 Gap
> 拆分原则:每个子 spec 控制在 5-8 个任务、可独立交付验证、依赖关系清晰
---
## 拆分总览
| 子 Spec | 名称 | 任务数 | 依赖 | 交付物 |
|---------|------|:------:|------|--------|
| RNS1.0 | 基础设施与契约重写 | 6 | 无 | 全局中间件 + 重写后的 API 契约 + 前端跨页面参数修复 |
| RNS1.1 | 任务与绩效接口 | 6 | RNS1.0 | TASK-1 扩展 + TASK-2 + PERF-1 + PERF-2 + 前端适配 |
| RNS1.2 | 客户与助教接口 | 6 | RNS1.0 | CUST-1 + CUST-2 + COACH-1 + 前端适配 |
| RNS1.3 | 三看板接口 | 7 | RNS1.0 | BOARD-1 + BOARD-2 + BOARD-3 + CONFIG-1 + 前端筛选修复 |
| RNS1.4 | CHAT 对齐与联调收尾 | 5 | RNS1.1-1.3 | CHAT 迁移 + FDW 验证 + 前后端联调 |
总计30 个任务5 个子 spec。
---
## RNS1.0:基础设施与契约重写
> 阻塞所有后续子 spec必须最先完成。
> 预估2-3 天
### 目标
1. 后端全局响应包装 + camelCase 转换R2 决策)
2. API 契约按走查报告发现完全重写BOARD-1/2/3、CUST-1、COACH-1、PERF-1、TASK-1 performance
3. 前端跨页面参数传递统一用唯一 ID
### 任务清单
| # | 任务 | 说明 | 产出 |
|---|------|------|------|
| T0-1 | 全局响应包装中间件 | `{ code: 0, data }` + 异常处理器 `{ code, message }` | `apps/backend/app/middleware/` |
| T0-2 | Pydantic schema 统一 camelCase | `alias_generator=to_camel`,所有现有 + 新增 schema | `apps/backend/app/schemas/` |
| T0-3 | 后端 TASK-4 路径 `/cancel-abandon``/restore` | 对齐契约R1-3 | `xcx_tasks.py` |
| T0-4 | 前端 `request()``.data` 解包 | 适配全局包装 | `api.ts` |
| T0-5 | **API 契约完全重写** | 按走查报告重写全部接口响应定义(详见下方) | `API-contract.md` |
| T0-6 | **前端跨页面参数修复** | 统一用唯一 ID 传参(详见下方) | 多个页面 `.ts` |
#### T0-5 契约重写范围
需要完全重写响应定义的接口:
| 接口 | 问题 | 重写要点 |
|------|------|---------|
| BOARD-3 | 扁平 metrics → 6 板块嵌套 | overview/recharge/revenue/cashflow/expense/coachAnalysis 完整字段定义,赠送卡 3×4 矩阵,收入结构表 9 行含子行,助教分析按等级分行,现金流出 4 子分组环比格式xxxCompare + isDown/isFlat |
| BOARD-1 | 10 通用字段 → 20 字段含 4 维度 | skills 改为 `Array<{text,cls}>`,补充 topCustomers4 维度专属字段perf/salary/sv/tasksort 参数改为枚举 |
| BOARD-2 | 8 通用字段 → 40+ 维度专属字段 | 8 维度各自字段集,补充 assistants 关联助教列表weeklyVisits 柱状图coachDetails 明细表potentialTags |
| CUST-1 | 缺少 5 大模块 | 补充 balance/consumption60d/idealInterval/daysSinceVisitaiInsightcoachTasksfavoriteCoaches消费记录改为嵌套结构含 coaches 子数组),备注列表 |
| COACH-1 | 缺少 6 大模块 | 补充 performance6 指标income本月/上月各 4 项tierNodeshistoryMonthstopCustomers 扩展heartEmoji/score/balance备注列表 |
| PERF-1 | 扁平数组 → DateGroup | this_month_records 改为按日期分组结构补充收入档位currentTier/nextTier/upgradeHoursNeeded/upgradeBonuslastMonthIncomeincomeItems.desc |
| TASK-1 perf | 4 字段 → 15+ 字段 | 补充 tierNodes/basicHours/bonusHours/currentTier/nextTierHours/tierCompleted/bonusMoney/incomeTrend/incomeTrendDir/prevMonth |
| CHAT-1/2 | 字段名不一致 + 缺失 | timestamp→created_at 统一,补充 titlereferenceCard 结构SSE 端点定义customerId→chatId 映射 |
#### T0-6 前端跨页面参数修复范围
用户决策:统一用唯一 ID 传参。
| 来源页面 | 目标页面 | 当前问题 | 修复方案 |
|---------|---------|---------|---------|
| task-detail | chat | 传 `detail.id`taskId当 customerId | TASK-2 响应增加 `customer_id`,跳转改为 `?customerId={detail.customerId}` |
| task-detail | customer-service-records | 同上 | 同上 |
| customer-detail | customer-service-records | 未传 customerId | 跳转加 `?customerId={detail.id}` |
| customer-detail | chat | 未传 customerId | 跳转加 `?customerId={detail.id}` |
| coach-detail | customer-detail | 任务项用 name 跳转 | 改为 `?id={customerId}`(需 TaskItem 含 customerId |
| performance | task-detail | 传 customerName | 改为 `?id={taskId}`(需记录含 taskId |
| customer-detail | — | loadDetail() 用 `__route__` 解析 id | 改为从 `onLoad(options)` 获取 |
| chat | API | 传 customerId 但 API 需 chatId | 后端支持 `?customerId=` 查询参数自动查找/创建对话 |
---
## RNS1.1:任务与绩效接口
> 助教日常使用频率最高的 4 个接口。
> 依赖RNS1.0(全局中间件 + 契约)
> 预估3-4 天
### 目标
实现任务列表扩展、任务详情、绩效概览、绩效明细 4 个接口,覆盖助教视角的核心工作流。
### 任务清单
| # | 任务 | 说明 | 涉及 Gap |
|---|------|------|---------|
| T1-1 | 扩展 TASK-1任务列表 + 绩效概览) | performance 从 4 字段扩展到 15+ 字段tierNodes/basicHours/bonusHours/currentTier/nextTierHours/tierCompleted/bonusMoney/incomeTrend/incomeTrendDir/prevMonthenrichTask 补充 lastVisitDays/balance/aiSuggestion | GAP-02, GAP-03 |
| T1-2 | 实现 TASK-2任务详情完整版 | 服务记录/备注各 20 条懒加载;响应含 `customer_id`;维客线索统一 tag 格式和 source 枚举aiAnalysis 明确 cache_type 映射 | GAP-06~11 |
| T1-3 | 实现 PERF-1绩效概览 | this_month_records 按 DateGroup 分组收入档位数据currentTier/nextTier/upgradeHoursNeeded/upgradeBonuslastMonthIncomeincomeItems 含 desc | GAP-12~16 |
| T1-4 | 实现 PERF-2绩效明细 | 20 条懒加载按日期分组courseTypeClass 枚举统一(`basic`/`vip`/`tip`,不带 `tag-` 前缀) | GAP-19~20 |
| T1-5 | 实现 pin/unpin API 端点 | `POST /tasks/{id}/pin` + `POST /tasks/{id}/unpin`;前端 api.ts 补充对应函数 | GAP-04 |
| T1-6 | 前端适配(任务+绩效页面) | createNote 补充 score 参数performance 页添加月份切换F8performance-records 月份切换重置分页F9avatarChar/avatarColor 前端自行计算GAP-19 决策) | GAP-05, F8, F9 |
### 数据源
- `dws_assistant_salary_calc` via FDW → 绩效/档位/收入
- `dwd_assistant_service_log` via FDW → 服务记录
- `biz.coach_tasks` → 任务列表
- `biz.ai_cache` → AI 分析/话术
- `public.member_retention_clue` → 维客线索
### 验收标准
- 助教登录后可看到真实任务列表 + 绩效卡片
- 点击任务可查看完整详情服务记录、维客线索、AI 分析、备注)
- 绩效概览展示真实档位进度和收入明细
- 绩效明细按日期分组展示,支持月份切换
---
## RNS1.2:客户与助教接口
> 详情页是 Gap 最集中的区域,数据结构最复杂。
> 依赖RNS1.0(全局中间件 + 契约)
> 预估3-4 天
### 目标
实现客户详情、客户服务记录、助教详情 3 个接口,覆盖两个角色视角的详情查看需求。
### 任务清单
| # | 任务 | 说明 | 涉及 Gap |
|---|------|------|---------|
| T2-1 | 实现 CUST-1客户详情 | 含 balance/consumption60d/idealInterval/daysSinceVisitBanneraiInsightbiz.ai_cache app4维客线索消费记录嵌套结构含 coaches 子数组、tableFee/foodAmount 分项);备注列表 | GAP-23~30 |
| T2-2 | 实现 CUST-1 coachTasks 模块 | 关联助教任务列表:从 biz.coach_tasks + FDW 聚合,每位助教含任务类型/状态/最后服务时间/近60天服务次数/总时长/次均时长 | GAP-25 |
| T2-3 | 实现 CUST-1 favoriteCoaches 模块 | 最亲密助教:从 `v_dws_member_assistant_relation_index` 获取关系指数,聚合基础课时/激励课时/上课次数/充值金额 | GAP-26 |
| T2-4 | 实现 CUST-2客户服务记录 | 按月查询(改掉前端全量加载本地过滤);补充 recordType/isEstimate月度统计汇总monthCount/monthHourscustomerPhoneFulltotalServiceCount | GAP-32~35 |
| T2-5 | 实现 COACH-1助教详情 | performance6 指标income本月/上月各 4 项tierNodestopCustomers 扩展heartEmoji/score/balance/consume近期服务明细含 perfHours任务分组active/inactive/abandoned 含 notes 子数组和 reason备注列表 | GAP-38~44 |
| T2-6 | 实现 COACH-1 historyMonths 模块 | 历史月份统计(最近 5+ 个月):客户数/工时/工资/回访完成数/召回完成数/是否预估 | GAP-41 |
### 数据源
- `fdw_etl.v_dim_member` → 客户基本信息DQ-6member_phone 不可靠,用 dim_member.mobile
- `fdw_etl.v_dws_member_consumption_summary` → 消费汇总/余额
- `fdw_etl.v_dws_member_assistant_relation_index` → 关系指数
- `fdw_etl.v_dwd_assistant_service_log` → 服务记录明细
- `fdw_etl.v_dwd_table_fee_log` → 台费明细
- `fdw_etl.v_dim_assistant` → 助教基本信息
- `fdw_etl.v_dws_assistant_salary_calc` → 助教绩效/收入
- `biz.coach_tasks` → 任务关联
- `biz.ai_cache` → AI 洞察
- `public.member_retention_clue` → 维客线索
### 关键约束
- 金额口径:统一使用 `items_sum`,禁用 `consume_money`DWD-DOC 强制规则 1
- 助教费用拆分:`assistant_pd_money`(陪打)+ `assistant_cx_money`(超休),禁用 `service_fee`DWD-DOC 强制规则 2
- 会员信息:通过 `member_id` JOIN `dim_member`,禁用 `settlement_head.member_phone`DQ-6
### 验收标准
- 客户详情页展示真实余额、消费、AI 洞察、关联助教、最亲密助教、消费记录(含助教明细)、备注
- 客户服务记录支持按月切换,展示真实数据
- 助教详情页展示真实绩效、收入明细、档位进度、TOP20 客户、历史月份统计、任务分组
---
## RNS1.3:三看板接口
> 看板是管理层视角的核心BOARD-3 财务看板是全项目最复杂的单个接口。
> 依赖RNS1.0(全局中间件 + 契约)
> 预估4-5 天
### 目标
实现 3 个看板接口 + 技能配置接口,修复前端看板筛选 Bug。
### 任务清单
| # | 任务 | 说明 | 涉及 Gap |
|---|------|------|---------|
| T3-1 | 实现 BOARD-1助教看板 | 4 维度专属字段perf/salary/sv/taskskills 为 `Array<{text,cls}>`topCustomerssort 枚举参数time 参数日期范围计算 | G2, 八¾ B1 |
| T3-2 | 实现 BOARD-2客户看板 | 8 维度各自字段集assistants 关联助教列表weeklyVisits 柱状图freq60coachDetails 明细表loyalpotentialTagspotential20 条懒加载 | G3, 八¾ B2 |
| T3-3 | 实现 BOARD-3 经营一览 + 预收资产 | overview8 指标 + 8 环比recharge储值卡 5 指标 + 赠送卡 3×4 矩阵 = 24 字段 + 24 环比area≠all 时预收资产隐藏 | G1, G6, G10 |
| T3-4 | 实现 BOARD-3 应计收入 + 现金流 | revenue收入结构表 9 行含子行 + 正价/优惠/渠道明细cashflow消费收款 + 充值收款 + 合计) | G7 |
| T3-5 | 实现 BOARD-3 现金流出 + 助教分析 | expense4 子分组:经营/固定/助教分成/平台服务费coachAnalysis基础课 + 激励课各按 4 等级分行) | G8, G9 |
| T3-6 | 实现 CONFIG-1技能类型列表 | 从 ETL cfg 表读取,前端 api.ts 硬编码作为 mock 回退 | R8-1 |
| T3-7 | 前端看板筛选修复 | F1-F6筛选变更触发重新请求BOARD-2 补充分页参数BOARD-3 fetchBoardFinance 签名扩展为 `{time,area,compare}` | F1~F6 |
### BOARD-3 环比计算说明
- 所有环比为月环比(与上一个相同时间周期对比)
- 后端根据 `time` 参数计算当期和上期日期范围,分别查询后计算百分比
- 返回格式:每个值旁有 `xxxCompare: string`(如 `"+12.5%"`+ `isDown: boolean` + `isFlat: boolean`
- `compare=0` 时不计算环比,减少查询开销
### 数据源
- BOARD-1`v_dws_assistant_salary_calc` + `v_dws_assistant_monthly_summary` + `v_dim_assistant`
- BOARD-28 个维度对应不同 FDW 表(详见八¾ B2 维度映射)
- BOARD-36 个 `v_dws_finance_*` 表 + `v_dws_assistant_salary_calc`(助教分析)
- CONFIG-1ETL cfg 表
### 验收标准
- 助教看板 4 维度切换正常,筛选变更触发重新请求
- 客户看板 8 维度切换正常,懒加载 20 条
- 财务看板 6 板块数据正确,环比开关工作,区域筛选隐藏预收资产
- 技能类型从 cfg 表读取
---
## RNS1.4CHAT 对齐与联调收尾
> 最后阶段,依赖前面所有子 spec 完成。
> 预估2-3 天
### 目标
CHAT 模块路径迁移和功能补全FDW 端到端验证,全量前后端联调。
### 任务清单
| # | 任务 | 说明 | 涉及 Gap |
|---|------|------|---------|
| T4-1 | CHAT 路径迁移 | `/api/ai/*``/api/xcx/chat/*`;保留 SSE 流式端点 | R3, GAP-51 |
| T4-2 | 新增 CHAT-1/2 同步端点 | 历史列表(含 title 字段)+ 消息查看timestamp→created_at 统一);支持 `?customerId=` 查询参数自动查找/创建对话 | GAP-45~50 |
| T4-3 | CHAT referenceCard 支持 | 消息中附带结构化引用卡片type/title/summary/data多入口参数路由customerId/historyId/coachId | GAP-45, GAP-50 |
| T4-4 | FDW 端到端验证 | 验证所有 FDW 查询在 test_zqyy_app → test_etl_feiqiu 链路上正常工作;检查索引和查询性能 | — |
| T4-5 | 前后端联调 + 修复 | 全量联调 13 个页面修复联调中发现的问题notes 页补充触底加载F11customer-service-records 改为按月请求 APIF10 | F10, F11 |
### 验收标准
- CHAT 模块 SSE 流式 + 同步端点均可用
- 从任意入口进入 chat 页面均能正确关联上下文
- 13 个页面全部连接真实后端运行,无 mock 数据残留
---
## 执行顺序与依赖关系
```
RNS1.0(基础设施+契约)
├── RNS1.1(任务+绩效)──┐
├── RNS1.2(客户+助教)──┼── RNS1.4CHAT+联调)
└── RNS1.3(三看板)─────┘
```
- RNS1.0 必须最先完成(阻塞所有后续)
- RNS1.1 / RNS1.2 / RNS1.3 可并行(无相互依赖)
- RNS1.4 依赖 RNS1.1-1.3 全部完成
---
## 与 NS1 原始 spec 的关系
NS1 原始 spec`NS1-xcx-backend-api.md`)保留为历史参考文档,其中:
- 一~七章:技术架构和接口设计(被 RNS1.0 T0-5 契约重写替代)
- 八½:前置审查发现 R1-R8决策仍有效分散到各子 spec 执行)
- 八¾看板筛选交叉矩阵仍为权威参考RNS1.3 直接引用)
- 九:原始任务清单(被本拆分计划替代)
两份走查报告保留在 `docs/reports/` 作为需求追溯依据:
- `storyboard-walkthrough-assistant-view.md`助教视角51 Gap
- `miniprogram-storyboard-walkthrough-gaps.md`管理层视角31 Gap
---
## Gap 追溯矩阵
### 助教视角报告 Gap → 子 Spec 映射
| Gap | 描述 | 子 Spec |
|-----|------|---------|
| GAP-01 | globalData.authUser 缺少 role/store_name/coach_level/avatar | RNS1.0 T0-6前端修复/me 已返回这些字段) |
| GAP-02 | TASK-1 performance 字段不足4→15+ | RNS1.1 T1-1 |
| GAP-03 | enrichTask 需要 lastVisitDays/balance/aiSuggestion | RNS1.1 T1-1 |
| GAP-04 | pin/unpin API 端点未定义 | RNS1.1 T1-5 |
| GAP-05 | createNote 缺少 score 参数 | RNS1.1 T1-6 |
| GAP-06~08 | 维客线索 tag/source 格式 + aiAnalysis cache_type | RNS1.1 T1-2 |
| GAP-09~10 | taskId/customerId 混淆 | RNS1.0 T0-6 |
| GAP-11 | storageLevel/relationLevel 计算逻辑 | RNS1.1 T1-6前端自行计算 |
| GAP-12~16 | PERF-1 DateGroup/档位/lastMonthIncome/incomeItems | RNS1.1 T1-3 |
| GAP-17 | performance→task-detail 传参不匹配 | RNS1.0 T0-6 |
| GAP-18 | performance 无月份切换 | RNS1.1 T1-6F8 |
| GAP-19~22 | PERF-2 avatarChar/courseTypeClass/分页重置/Banner | RNS1.1 T1-4 + T1-6 |
| GAP-23~30 | CUST-1 五大缺失模块 | RNS1.2 T2-1~T2-3 |
| GAP-31 | customer-detail 跳转未传 customerId | RNS1.0 T0-6 |
| GAP-32~35 | CUST-2 扩展字段 + 按月查询 | RNS1.2 T2-4 |
| GAP-36~37 | notes 触底加载 + tagType 语义 | RNS1.4 T4-5 |
| GAP-38~44 | COACH-1 六大缺失模块 | RNS1.2 T2-5~T2-6 |
| GAP-45~51 | CHAT 模块全部 Gap | RNS1.4 T4-1~T4-3 |
### 管理层视角报告 Gap → 子 Spec 映射
| Gap | 描述 | 子 Spec |
|-----|------|---------|
| G1 | BOARD-3 响应结构完全不匹配 | RNS1.3 T3-3~T3-5 |
| G2 | BOARD-1 字段严重不足 | RNS1.3 T3-1 |
| G3 | BOARD-2 字段严重不足 | RNS1.3 T3-2 |
| G4 | COACH-1 缺少多个核心区域 | RNS1.2 T2-5~T2-6 |
| G5 | CUST-1 缺少管理层核心数据 | RNS1.2 T2-1~T2-3 |
| G6~G10 | BOARD-3 各子模块缺失 + 环比格式 | RNS1.3 T3-3~T3-5 |
| G11 | customer-detail→customer-service-records 未传 customerId | RNS1.0 T0-6 |
| G12 | coach-detail 任务项用 name 跳转 | RNS1.0 T0-6 |
| G13~G14 | api.ts 返回类型不匹配 | RNS1.0 T0-5契约重写时同步更新类型 |
| G15~G26 | 各接口中等严重度缺陷 | 分散到对应子 Spec |
| G27~G31 | 低严重度设计决策 | 分散到对应子 Spec |
### 前端修复项 → 子 Spec 映射
| 修复项 | 描述 | 子 Spec |
|--------|------|---------|
| F1~F6 | 看板筛选变更不触发重新请求 | RNS1.3 T3-7 |
| F7 | task-list status 筛选 UI 未实现 | RNS1.1 T1-6低优先级可后续 |
| F8 | performance 无月份切换 | RNS1.1 T1-6 |
| F9 | performance-records 月份切换未重置分页 | RNS1.1 T1-6 |
| F10 | customer-service-records 本地筛选改 API 请求 | RNS1.4 T4-5 |
| F11 | notes 无触底加载 | RNS1.4 T4-5 |