Files
Neo-ZQYY/.kiro/specs/rns1-customer-coach-api/requirements.md

24 KiB
Raw Blame History

需求文档 — RNS1.2:客户与助教接口

简介

RNS1.2 是 NS1 小程序后端 API 补全项目的第三个子 spec负责实现客户详情CUST-1、客户服务记录CUST-2、助教详情COACH-13 个接口。这三个接口覆盖客户视角和助教视角的详情查看需求,是走查报告中 Gap 最集中的区域GAP-2330、GAP-3235、GAP-38~44数据结构最为复杂。

依赖

  • RNS1.0(基础设施与契约重写)已完成:全局响应包装中间件(ResponseWrapperMiddleware、camelCase 转换(CamelModel)、重写后的 API 契约
  • RNS1.1(任务与绩效接口)可并行开发,无直接依赖
  • 后端已有 fdw_queries.pyFDW 查询集中封装)、task_manager.pynote_service.py
  • 前端已有 13 个页面P5.2 交付),当前使用 mock 数据

来源文档

  • docs/prd/Neo_Specs/RNS1-split-plan.md — 拆分计划主文档RNS1.2 章节)
  • docs/miniprogram-dev/API-contract.md — API 契约CUST-1、CUST-2、COACH-1 完整定义)
  • docs/reports/storyboard-walkthrough-assistant-view.md — 助教视角走查报告GAP-2330、GAP-3235、GAP-38~44
  • docs/reports/miniprogram-storyboard-walkthrough-gaps.md — 管理层视角走查报告G4、G5
  • docs/reports/DWD-DOC/ — 金额口径与字段语义权威标杆文档
  • docs/architecture/backend-architecture.md — 后端架构文档

术语表

  • BackendFastAPI 后端应用,位于 apps/backend/
  • Miniprogram:微信小程序前端应用,位于 apps/miniprogram/
  • CUST_1_API:客户详情接口 GET /api/xcx/customers/{customerId}返回客户完整详情Banner 概览、AI 洞察、关联助教任务、最亲密助教、消费记录、备注)
  • CUST_2_API:客户服务记录接口 GET /api/xcx/customers/{customerId}/records,返回按月查询的服务记录列表
  • COACH_1_API:助教详情接口 GET /api/xcx/coaches/{coachId}返回助教完整详情绩效、收入、档位、TOP 客户、历史月份、任务分组、备注)
  • FDWPostgreSQL Foreign Data Wrapper后端通过直连 ETL 库查询 app.v_* RLS 视图
  • items_sumDWD-DOC 强制使用的消费金额口径,= table_charge_money + goods_money + assistant_pd_money + assistant_cx_money + electricity_money
  • assistant_pd_money助教陪打费用基础课DWD-DOC 强制规则 2 要求的拆分字段
  • assistant_cx_money助教超休费用激励课DWD-DOC 强制规则 2 要求的拆分字段
  • v_dim_memberETL RLS 视图提供会员基本信息nickname、mobile通过 member_id 关联,取 scd2_is_current=1
  • v_dim_member_card_accountETL RLS 视图,提供会员卡余额,通过 tenant_member_id 关联,取 scd2_is_current=1
  • v_dwd_assistant_service_logETL RLS 视图,提供助教服务记录明细(基于 dwd_assistant_service_log 基表,废单字段为 is_delete
  • v_dws_member_assistant_relation_indexETL RLS 视图,提供会员与助教的关系指数
  • v_dws_member_consumption_summaryETL RLS 视图,提供会员消费汇总
  • v_dws_assistant_salary_calcETL RLS 视图,提供助教绩效/档位/收入数据
  • v_dim_assistantETL RLS 视图,提供助教基本信息
  • v_dwd_table_fee_logETL RLS 视图,提供台费明细
  • ai_cache:业务库 biz.ai_cache 表,按 cache_type 存储不同类型的 AI 分析缓存
  • coach_tasks:业务库 biz.coach_tasks 表,存储助教任务分配与状态
  • member_retention_clue:业务库 public.member_retention_clue 表,存储维客线索
  • user_assistant_binding:认证库 auth.user_assistant_binding 表,映射小程序用户与助教身份
  • settle_type:结算类型字段,正向交易取 IN (1, 3)
  • is_deleteRLS 视图中的废单标记字段整数类型0=正常),对应 design.md 中的 is_trash

需求

需求 1实现 CUST-1 客户详情 Banner 概览T2-1 基础部分)

用户故事: 作为管理者或助教,我希望在客户详情页顶部看到客户的基本信息和关键指标(余额、近期消费、到店间隔、距上次到店天数),以便快速评估客户价值和活跃度。

验收标准

  1. THE CUST_1_API SHALL 返回客户基础信息字段:id(客户唯一 IDname(客户姓名)、phone(脱敏手机号,如 "139****5678")、phoneFull(完整手机号)、avatar(头像 URLmemberLevel(会员等级)、relationIndex(关系指数)、tags(客户标签列表)
  2. THE CUST_1_API SHALL 通过 member_id LEFT JOIN v_dim_member(取 scd2_is_current=1)获取 namenickname 字段)和 phone/phoneFullmobile 字段),禁止使用 settlement_head.member_phoneDQ-6
  3. THE CUST_1_API SHALL 通过 member_id LEFT JOIN v_dim_member_card_accounttenant_member_id=member_id,取 scd2_is_current=1)获取 memberLevel,禁止使用 member_card_type_nameDQ-7
  4. THE CUST_1_API SHALL 返回 Banner 概览字段:balance(客户余额,元)、consumption60d(近 60 天消费金额,元)、idealInterval(理想到店间隔,天)、daysSinceVisit(距上次到店天数)
  5. THE CUST_1_API SHALL 使用 items_sum 口径计算 balanceconsumption60dDWD-DOC 强制规则 1禁止使用 consume_money
  6. THE CUST_1_API SHALL 从 v_dwd_assistant_service_log 查询客户最后到店日期(MAX(create_time),过滤 is_delete=0),计算 daysSinceVisit(当前日期与最后到店日期的天数差)
  7. IF 某个 Banner 字段的数据源查询失败或无数据THEN THE CUST_1_API SHALL 对该字段返回 null,不影响其他字段和整体响应

需求 2实现 CUST-1 AI 洞察模块T2-1 AI 部分)

用户故事: 作为管理者或助教,我希望在客户详情页看到 AI 生成的客户分析洞察和策略建议,以便制定针对性的服务策略。

验收标准

  1. THE CUST_1_API SHALL 返回 aiInsight 字段,包含 summaryAI 分析摘要文本)和 strategies(策略建议列表,每项含 colortext
  2. THE CUST_1_API SHALL 从 biz.ai_cache 查询 cache_type='app4_analysis'target_id=customerId 的缓存记录,解析 cache_value JSON 生成 aiInsight 数据
  3. IF biz.ai_cache 中无对应缓存记录THEN THE CUST_1_API SHALL 返回 aiInsight: { summary: "", strategies: [] }

需求 3实现 CUST-1 维客线索与备注T2-1 线索与备注部分)

用户故事: 作为管理者或助教,我希望在客户详情页看到维客线索和历史备注,以便了解客户的留存风险和过往沟通记录。

验收标准

  1. THE CUST_1_API SHALL 返回 retentionClues 字段(维客线索列表),从 public.member_retention_clue 查询,按 created_at 倒序排列,格式与 TASK-2 一致
  2. THE CUST_1_API SHALL 返回 notes 字段(备注列表),从 biz.notes 查询 target_type='member'target_id=customerId 的记录,每项含 idtagLabelcreatedAtcontent,按 created_at 倒序排列,最多返回 20 条

需求 4实现 CUST-1 消费记录嵌套结构T2-1 消费记录部分)

用户故事: 作为管理者或助教,我希望在客户详情页看到消费记录的完整拆分(台费、酒水、助教服务明细),以便分析客户的消费构成和偏好。

验收标准

  1. THE CUST_1_API SHALL 返回 consumptionRecords 字段(消费记录列表),每条记录包含嵌套结构:idtypetable/shop/recharge)、datetableNamestartTimeendTimedurationtableFeetableOrigPricecoaches(助教服务子数组)、foodAmountfoodOrigPricetotalAmounttotalOrigPricepayMethodrechargeAmount
  2. THE CUST_1_API SHALL 为每条消费记录的 coaches 子数组返回助教服务明细,每项含 namelevellevelColorcourseType"基础课""激励课")、hours(服务时长)、perfHours(折算工时,可选)、fee(服务费用)
  3. THE CUST_1_API SHALL 对 coaches 子数组中的 fee 字段使用 assistant_pd_money(基础课)和 assistant_cx_money激励课拆分DWD-DOC 强制规则 2禁止使用 service_fee
  4. THE CUST_1_API SHALL 对 totalAmount 使用 items_sum 口径DWD-DOC 强制规则 1tableFee 使用 table_charge_money,对 foodAmount 使用 goods_money
  5. THE CUST_1_API SHALL 仅查询正向交易记录(settle_type IN (1, 3)
  6. THE CUST_1_API SHALL 使用 v_dwd_assistant_service_logis_delete=0 排除废单记录

需求 5实现 CUST-1 coachTasks 模块T2-2

用户故事: 作为管理者或助教,我希望在客户详情页看到所有关联助教的任务信息和近期服务统计,以便了解该客户被哪些助教跟进、服务频率和质量如何。

验收标准

  1. THE CUST_1_API SHALL 返回 coachTasks 字段(关联助教任务列表),从 biz.coach_tasks 查询该客户(member_id=customerId)的所有任务记录
  2. THE CUST_1_API SHALL 为每位关联助教返回以下字段:name(助教姓名)、level(助教等级:star/senior/middle/junior)、levelColor(等级对应颜色)、taskType(任务类型,如 "回访""召回")、taskColor(任务类型对应颜色)、bgClass(背景样式类)、status(任务状态)、lastService(最后服务日期)、metrics(指标列表)
  3. THE CUST_1_API SHALL 为每位助教的 metrics 返回近 60 天统计:服务次数、总时长、次均时长,从 v_dwd_assistant_service_log 按助教+客户聚合近 60 天数据(过滤 is_delete=0
  4. THE CUST_1_API SHALL 从 v_dws_assistant_salary_calc 获取助教等级(assistant_level_name),从 v_dim_member 获取助教姓名DQ-6

需求 6实现 CUST-1 favoriteCoaches 模块T2-3

用户故事: 作为管理者或助教,我希望在客户详情页看到该客户最亲密的助教排名和详细服务统计,以便了解客户的助教偏好和关系深度。

验收标准

  1. THE CUST_1_API SHALL 返回 favoriteCoaches 字段(最亲密助教列表),从 v_dws_member_assistant_relation_index 获取关系指数,按关系指数降序排列
  2. THE CUST_1_API SHALL 为每位亲密助教返回:emoji(亲密度 emojiname(助教姓名)、relationIndex(关系指数,如 "0.92")、indexColor(关系指数对应颜色)、bgClass(背景样式类)、stats(统计指标列表)
  3. THE CUST_1_API SHALL 为 stats 返回 4 项指标:基础课时(对应 assistant_pd_money)、激励课时(对应 assistant_cx_money)、上课次数、充值金额,使用 DWD-DOC 强制规则 2 拆分助教费用
  4. THE CUST_1_API SHALL 根据关系指数(rs_display0-10 范围)阈值映射 emojiP6 AC3 四级映射):> 8.5"💖"> 7"🧡"> 5"💛"≤ 5"💙",复用后端 compute_heart_icon() 函数

需求 7实现 CUST-2 客户服务记录T2-4

用户故事: 作为管理者或助教,我希望按月查看客户的服务记录(替代前端全量加载本地过滤),以便高效浏览大量历史数据并查看月度统计汇总。

验收标准

  1. THE CUST_2_API SHALL 接受 yearmonthtable(可选,台桌筛选)查询参数,返回指定月份的客户服务记录
  2. THE CUST_2_API SHALL 返回客户基础信息:customerName(客户姓名)、customerPhone(脱敏手机号)、customerPhoneFull(完整手机号)、relationIndex(关系指数)、tables(可选台桌列表)
  3. THE CUST_2_API SHALL 通过 member_id LEFT JOIN v_dim_member(取 scd2_is_current=1)获取 customerNamecustomerPhone/customerPhoneFullDQ-6
  4. THE CUST_2_API SHALL 返回 totalServiceCount(累计服务总次数,跨所有月份)
  5. THE CUST_2_API SHALL 为每条服务记录返回 recordTypecourserecharge)和 isEstimate是否预估数据boolean字段
  6. THE CUST_2_API SHALL 返回月度统计汇总:monthCount(当月服务次数)和 monthHours(当月总工时)
  7. THE CUST_2_API SHALL 使用 items_sum 口径计算服务记录中的 income 字段DWD-DOC 强制规则 1
  8. THE CUST_2_API SHALL 使用 is_delete=0 排除废单记录
  9. THE CUST_2_API SHALL 按 create_time 倒序排列服务记录,返回 hasMore 标记指示是否有更多数据

需求 8实现 COACH-1 助教详情基础信息与绩效T2-5 基础部分)

用户故事: 作为管理者,我希望在助教详情页看到助教的基本信息和 6 项绩效指标,以便快速评估助教的工作表现和产出。

验收标准

  1. THE COACH_1_API SHALL 返回助教基础信息字段:idnameavatarlevel(初级/中级/高级/星级)、skills(技能标签列表)、workYears(工龄,年)、customerCount(客户数)、hireDate(入职日期)
  2. THE COACH_1_API SHALL 从 v_dim_assistant 获取助教基本信息,从 v_dws_assistant_salary_calc 获取等级(assistant_level_name
  3. THE COACH_1_API SHALL 返回 performance 字段,包含 6 项绩效指标:monthlyHours(本月定档工时)、monthlySalary(本月工资预估)、customerBalance(客源储值余额合计)、tasksCompleted(本月任务完成数)、perfCurrent(当前绩效值)、perfTarget(绩效目标值)
  4. THE COACH_1_API SHALL 从 v_dws_assistant_salary_calc 查询 monthlyHourseffective_hours)和 monthlySalarygross_salary),使用 items_sum 口径DWD-DOC 强制规则 1
  5. THE COACH_1_API SHALL 从 biz.coach_tasks 查询 tasksCompleted(当月 status='completed' 的任务数)

需求 9实现 COACH-1 收入明细与档位节点T2-5 收入部分)

用户故事: 作为管理者,我希望在助教详情页看到本月和上月的收入明细拆分(基础课时费、激励课时费、充值提成、酒水提成)以及档位进度节点,以便了解助教的收入构成和升档进度。

验收标准

  1. THE COACH_1_API SHALL 返回 income 字段,包含 thisMonthlastMonth 两个子数组,各含 4 项收入分类:基础课时费(assistant_pd_money)、激励课时费(assistant_cx_money)、充值提成、酒水提成
  2. THE COACH_1_API SHALL 使用 assistant_pd_money(基础课/陪打)和 assistant_cx_money(激励课/超休拆分助教费用DWD-DOC 强制规则 2禁止使用 service_fee
  3. THE COACH_1_API SHALL 从 v_dws_assistant_salary_calc 分别查询当月和上月的收入数据(salary_month 字段为 date 类型,存储为 YYYY-MM-01
  4. THE COACH_1_API SHALL 返回 tierNodes 字段(档位节点数组,如 [0, 100, 130, 160, 190, 220]),供前端绩效进度条组件使用

需求 10实现 COACH-1 TOP 客户与近期服务记录T2-5 客户部分)

用户故事: 作为管理者,我希望在助教详情页看到该助教的 TOP 客户排名(含关系指数、余额、消费)和近期服务明细(含折算工时),以便评估助教的客户关系质量和服务产出。

验收标准

  1. THE COACH_1_API SHALL 返回 topCustomers 字段TOP 客户列表,最多 20 条),每项含扩展字段:idnameinitial(姓氏首字)、avatarGradient(头像渐变色)、heartEmoji(关系 emojiP6 AC3 四级映射:💖/🧡/💛/💙)、relationScore关系指数0-10scoreColor(分数颜色)、serviceCount(服务次数)、balance(余额,格式化)、consume(消费总额,格式化)
  2. THE COACH_1_API SHALL 对 topCustomers[].consume 使用 items_sum 口径DWD-DOC 强制规则 1
  3. THE COACH_1_API SHALL 对 topCustomers[].balance 通过 member_id LEFT JOIN v_dim_member_card_account(取 scd2_is_current=1获取DQ-7
  4. THE COACH_1_API SHALL 通过 member_id LEFT JOIN v_dim_member(取 scd2_is_current=1获取客户姓名DQ-6
  5. THE COACH_1_API SHALL 返回 serviceRecords 字段(近期服务记录列表),每项含 customerIdcustomerNameinitialavatarGradienttype(课程类型)、typeClass(样式类)、table(台桌名)、duration(时长)、income(收入)、date(日期时间)、perfHours(折算工时,可选)
  6. THE COACH_1_API SHALL 对 serviceRecords[].income 使用 ledger_amount(对应 items_sum 口径DWD-DOC 强制规则 1
  7. THE COACH_1_API SHALL 使用 is_delete=0 排除废单记录

需求 11实现 COACH-1 任务分组与备注T2-5 任务部分)

用户故事: 作为管理者,我希望在助教详情页看到该助教的任务按状态分组展示(进行中/已过期/已放弃),每个任务含关联备注和放弃原因,以便全面了解助教的任务执行情况。

验收标准

  1. THE COACH_1_API SHALL 返回任务分为三组:visibleTasksactive 状态任务)、hiddenTasksinactive 状态任务)、abandonedTasksabandoned 状态任务),从 biz.coach_tasks 查询该助教的所有任务
  2. THE COACH_1_API SHALL 为 visibleTaskshiddenTasks 每项返回:typeLabel(任务类型标签)、typeClass(样式类)、customerName(客户姓名)、customerId(客户 ID用于跳转noteCount(备注数量)、pinned(是否置顶)、notes(备注列表,可选,每项含 pinnedtextdate
  3. THE COACH_1_API SHALL 为 abandonedTasks 每项返回:customerName(客户姓名)、reason(放弃原因,来自 coach_tasks.abandon_reason
  4. THE COACH_1_API SHALL 从 biz.notes 查询每个任务关联的备注(task_id 关联),按 created_at 倒序排列
  5. THE COACH_1_API SHALL 返回 notes 字段(助教相关备注列表),每项含 idcontenttimestampscorecustomerNametagLabelcreatedAt,按 created_at 倒序排列,最多返回 20 条

需求 12实现 COACH-1 historyMonths 模块T2-6

用户故事: 作为管理者,我希望在助教详情页看到该助教最近 5 个以上月份的历史统计(客户数、工时、工资、回访/召回完成数),以便追踪助教的长期表现趋势。

验收标准

  1. THE COACH_1_API SHALL 返回 historyMonths 字段(历史月份统计列表),包含最近 5 个以上月份的汇总数据,第一条为本月
  2. THE COACH_1_API SHALL 为每个月份返回:month(月份标签,如 "本月""上月""4月")、estimated是否为预估数据booleancustomers(客户数,格式化,如 "22人")、hours(工时,格式化,如 "87.5h")、salary(工资,格式化,如 "¥6,950")、callbackDone(回访任务完成数)、recallDone(召回任务完成数)
  3. THE COACH_1_API SHALL 从 v_dws_assistant_salary_calc 查询各月的工时(effective_hours)和工资(gross_salary)数据
  4. THE COACH_1_API SHALL 从 biz.coach_tasks 查询各月的回访完成数(task_type='follow_up_visit' AND status='completed')和召回完成数(task_type IN ('high_priority_recall', 'priority_recall') AND status='completed'
  5. THE COACH_1_API SHALL 将本月标记为 estimated: true(预估数据),历史月份标记为 estimated: false
  6. THE COACH_1_API SHALL 从 v_dwd_assistant_service_log 按月统计不重复的 tenant_member_id 数量作为客户数(过滤 is_delete=0

需求 13全局约束与数据隔离

用户故事: 作为系统管理员,我希望所有客户和助教接口都遵循统一的权限控制、数据隔离和数据质量规则,以确保数据安全和口径一致。

验收标准

13.1 权限与认证

  1. THE Backend SHALL 对所有 RNS1.2 接口CUST_1_API、CUST_2_API、COACH_1_API执行 require_approved() 权限检查,确保用户状态为 approved
  2. THE Backend SHALL 对所有 RNS1.2 接口通过 SET LOCAL app.current_site_id 实现门店级数据隔离FDW 查询通过 _fdw_context 上下文管理器统一执行)

13.2 DWD-DOC 强制规则

  1. THE Backend SHALL 对所有涉及金额的字段统一使用 items_sum 口径DWD-DOC 强制规则 1禁止使用 consume_money
  2. THE Backend SHALL 对所有涉及助教费用的字段使用 assistant_pd_money(陪打/基础课)+ assistant_cx_money(超休/激励课拆分DWD-DOC 强制规则 2禁止使用 service_fee
  3. THE Backend SHALL 对所有涉及会员信息的查询通过 member_id LEFT JOIN v_dim_member(取 scd2_is_current=1获取姓名和手机号DWD-DOC 强制规则 DQ-6禁止直接使用 settlement_head.member_phonemember_name
  4. THE Backend SHALL 对所有涉及会员卡信息的查询通过 member_id LEFT JOIN v_dim_member_card_accounttenant_member_id=member_id,取 scd2_is_current=1获取DWD-DOC 强制规则 DQ-7禁止使用 member_card_type_name
  5. THE Backend SHALL 使用 v_dwd_assistant_service_logis_delete=0 排除废单记录,禁止使用已废弃的 dwd_assistant_trash_event

13.3 优雅降级

  1. IF 某个扩展模块(aiInsight/coachTasks/favoriteCoaches/historyMonths的数据源查询失败THEN THE Backend SHALL 对该模块返回空默认值(空数组或空对象),不影响其他模块和整体响应
  2. THE Backend SHALL 对所有 FDW 查询异常进行捕获和日志记录,返回降级响应而非 HTTP 500

13.4 列名映射

  1. THE Backend SHALL 在 SQL 中使用 AS 别名将 RLS 视图原始列名转换为代码语义名(如 site_assistant_id AS assistant_idtenant_member_id AS member_idcreate_time AS settle_timeledger_amount AS incomeincome_seconds / 3600.0 AS service_hours),统一在 fdw_queries.py 中封装

需求 14正确性属性Property-Based Testing

用户故事: 作为开发者,我希望通过属性测试验证接口的数据一致性和业务规则正确性,以便在开发阶段发现口径错误和数据异常。

验收标准

14.1 金额口径不变量

  1. FOR ALL 消费记录THE CUST_1_API 返回的 totalAmount SHALL 等于 tableFee + foodAmount + SUM(coaches[].fee)(在浮点精度范围内),验证 items_sum 口径拆分的一致性
  2. FOR ALL 助教费用拆分,coaches[].fee 中基础课记录 SHALL 对应 assistant_pd_money,激励课记录 SHALL 对应 assistant_cx_money,两者之和 SHALL 等于该结算单的助教费用总额

14.2 数据隔离不变量

  1. FOR ALL CUST_1_API 响应中的 coachTasks,每条任务的 member_id SHALL 等于请求路径中的 customerId,验证客户-任务关联的正确性
  2. FOR ALL COACH_1_API 响应中的 serviceRecords,每条记录的 assistant_id SHALL 等于请求路径中的 coachId,验证助教数据隔离

14.3 排序与分组不变量

  1. FOR ALL CUST_1_API 响应中的 favoriteCoaches,列表 SHALL 按 relationIndex 降序排列(前一项的 relationIndex ≥ 后一项的 relationIndex
  2. FOR ALL COACH_1_API 响应中的 historyMonths,列表 SHALL 按月份降序排列(最近月份在前),且第一条的 estimated SHALL 为 true

14.4 幂等性

  1. FOR ALL 相同参数的 CUST_2_API 请求(相同 customerIdyearmonth),在数据未变更的情况下,两次请求 SHALL 返回相同的 monthCountmonthHours

14.5 废单排除一致性

  1. FOR ALL 服务记录查询,返回的记录集合中 SHALL 不包含 is_delete != 0 的记录,验证废单排除规则在所有接口中一致执行