Files
Neo-ZQYY/.kiro/specs/rns1-infra-contract-rewrite/requirements.md

24 KiB
Raw Blame History

需求文档 — RNS1.0:基础设施与契约重写

简介

RNS1.0 是 NS1 小程序后端 API 补全项目的第一个子 spec负责建立全局基础设施响应包装、camelCase 转换)、修正路由路径、适配前端解包逻辑、完全重写 API 契约响应定义、以及修复前端跨页面参数传递问题。本 spec 阻塞所有后续子 specRNS1.1-1.4),必须最先完成。

来源文档

  • docs/prd/Neo_Specs/RNS1-split-plan.md — 拆分计划主文档
  • docs/prd/Neo_Specs/NS1-xcx-backend-api.md — NS1 原始 spec含八½前置审查决策 R1-R8
  • docs/prd/Neo_Specs/storyboard-walkthrough-assistant-view.md — 助教视角走查报告51 Gap
  • docs/prd/Neo_Specs/miniprogram-storyboard-walkthrough-gaps.md — 管理层视角走查报告31 Gap

术语表

  • Response_Wrapper:全局响应包装中间件,将 FastAPI 路由返回值统一封装为 { code: 0, data: ... } 格式
  • Exception_Handler:全局异常处理器,将 HTTPException 和未捕获异常统一封装为 { code: <status_code>, message: <detail> } 格式
  • CamelCase_ConverterPydantic schema 的 alias_generator=to_camel 配置,使 JSON 响应字段名从 snake_case 转为 camelCase
  • API_Contractdocs/miniprogram-dev/API-contract.md,定义前后端接口的请求/响应格式基准文档
  • Frontend_Unpacker:前端 services/api.tsrequest() 工具函数的 .data 解包逻辑,从全局包装中提取业务数据
  • BackendFastAPI 后端应用,位于 apps/backend/
  • Miniprogram:微信小程序前端应用,位于 apps/miniprogram/
  • FDWPostgreSQL Foreign Data Wrapper用于从业务库 zqyy_app 访问 ETL 库 etl_feiqiu 的数据
  • DateGroup:按日期分组的数据结构,包含日期标签、当日汇总、记录列表
  • DWD-DOCdocs/reports/DWD-DOC/ 标杆文档,金额口径和字段语义的权威参考
  • items_sumDWD-DOC 强制使用的消费金额口径,= table_charge_money + goods_money + assistant_pd_money + assistant_cx_money + electricity_money
  • 环比:月环比,当期值与上一个相同时间周期的对比百分比

需求

需求 1全局响应包装中间件T0-1

用户故事: 作为后端开发者,我希望所有 API 响应自动包装为统一格式,以便前端可以用一致的方式解析成功和错误响应。

验收标准

  1. THE Response_Wrapper SHALL 将所有成功响应HTTP 2xx封装为 { "code": 0, "data": <原始响应体> } 格式
  2. THE Exception_Handler SHALL 将 HTTPException 封装为 { "code": <HTTP状态码>, "message": <错误详情> } 格式
  3. THE Exception_Handler SHALL 将未捕获的服务端异常封装为 { "code": 500, "message": "Internal Server Error" } 格式,同时将完整异常堆栈写入服务端日志
  4. WHEN 已有接口Auth、Tasks、Notes、AI Chat 共 16 个端点返回响应时THE Response_Wrapper SHALL 对这些接口同样生效,保持向后兼容
  5. WHEN 响应内容类型为 text/event-streamSSE 流式端点THE Response_Wrapper SHALL 跳过包装,直接透传原始响应
  6. WHEN 响应内容类型为非 JSON 格式如文件下载THE Response_Wrapper SHALL 跳过包装,直接透传原始响应

需求 2Pydantic Schema 统一 camelCase 输出T0-2

用户故事: 作为前端开发者,我希望后端 API 响应的 JSON 字段名统一为 camelCase 格式,以便前端无需手动转换 snake_case 字段。

验收标准

  1. THE CamelCase_Converter SHALL 为所有 Pydantic 响应 schema 配置 alias_generator=to_camelpopulate_by_name=True
  2. WHEN Backend 返回 JSON 响应时THE CamelCase_Converter SHALL 将所有字段名从 snake_case 转换为 camelCase例如 user_iduserIdstore_namestoreName
  3. THE CamelCase_Converter SHALL 同时应用于所有现有 schemaAuth、Tasks、Notes、AI Chat 模块)和所有新增 schema
  4. WHEN Backend 接收请求体时THE CamelCase_Converter SHALL 同时接受 camelCase 和 snake_case 格式的字段名(通过 populate_by_name=True 实现)

需求 3后端路由路径修正T0-3

用户故事: 作为前端开发者,我希望后端任务恢复端点的路径与 API 契约和前端调用一致,以便联调时不会因路径不匹配而失败。

验收标准

  1. THE Backend SHALL 将 POST /api/xcx/tasks/{taskId}/cancel-abandon 端点的路径修改为 POST /api/xcx/tasks/{taskId}/restore
  2. WHEN 前端调用 POST /api/xcx/tasks/{taskId}/restoreTHE Backend SHALL 执行与原 /cancel-abandon 端点相同的业务逻辑(将任务状态从 abandoned 恢复为 pending
  3. THE Backend SHALL 移除原 /cancel-abandon 路径,不保留旧路径的兼容映射

需求 4前端请求工具函数适配全局包装T0-4

用户故事: 作为前端开发者,我希望 request() 工具函数自动从全局包装中提取业务数据,以便各页面调用 API 后无需手动解包。

验收标准

  1. THE Frontend_Unpacker SHALL 在 services/api.tsrequest() 函数中,对成功响应自动提取 .data 字段并返回给调用方
  2. WHEN 响应的 code 字段不为 0 时THE Frontend_Unpacker SHALL 抛出包含 codemessage 的错误对象,供调用方的 catch 块处理
  3. WHEN 响应不包含 code 字段(非标准格式,如 SSE 流式响应THE Frontend_Unpacker SHALL 直接返回原始响应体,不做解包处理
  4. THE Frontend_Unpacker SHALL 确保所有现有 API 调用Auth、Tasks、Notes、AI Chat在解包后行为不变

需求 5API 契约完全重写T0-5

用户故事: 作为前后端开发者,我希望 API 契约文档准确反映前端实际需要的响应结构,以便后续子 specRNS1.1-1.4)的后端实现有明确的、与前端一致的接口定义作为基准。

5.1 BOARD-3 财务看板契约重写

验收标准
  1. THE API_Contract SHALL 将 BOARD-3 响应从扁平 metrics 数组重写为 6 个独立板块的嵌套结构:overview(经营一览)、recharge(预收资产)、revenue(应计收入确认)、cashflow(现金流入)、expense(现金流出)、coachAnalysis(助教分析)
  2. THE API_Contract SHALL 为 overview 板块定义 8 个指标字段(occurrence/discount/discountRate/confirmedRevenue/cashIn/cashOut/cashBalance/balanceRate),每个指标附带对应的环比字段(xxxCompare: string)和方向标记(isDown: booleanisFlat: boolean
  3. THE API_Contract SHALL 为 recharge 板块定义储值卡 5 个指标(actualIncome/firstCharge/renewCharge/consumed/cardBalance)及各自环比字段,以及赠送卡 3×4 矩阵(行:新增/消费/余额,列:合计/酒水卡/台费卡/抵用券),每个单元格含值和环比字段,以及全类别会员卡余额合计(allCardBalance)及环比
  4. THE API_Contract SHALL 为 revenue 板块定义收入结构表(structureRows9 行含子行标记 isSub,每行含 name/desc/amount/discount/booked/bookedCompare)、正价明细(priceItems4 项)、优惠明细(discountItems4 项)、渠道明细(channelItems3 项),以及确认收入合计及环比
  5. THE API_Contract SHALL 为 cashflow 板块定义消费收款(consumeItems3 项)、充值收款(rechargeItems1 项)、合计及环比,每项含 name/desc/value/compare/isDown
  6. THE API_Contract SHALL 为 expense 板块定义 4 个子分组:经营支出(operationItems3 项)、固定支出(fixedItems4 项)、助教分成(coachItems4 项)、平台服务费(platformItems3 项),以及合计及环比
  7. THE API_Contract SHALL 为 coachAnalysis 板块定义基础课(basic)和激励课(incentive)两个子表,每个子表含汇总行(totalPay/totalShare/avgHourly 及各自环比)和按等级分行的数组(rows:初级/中级/高级/星级,每行含 level/pay/payCompare/share/shareCompare/hourly/hourlyComparepayDown/shareDown/hourlyFlat 布尔标记)
  8. THE API_Contract SHALL 为 BOARD-3 定义请求参数:time8 种时间范围枚举:month/lastMonth/week/lastWeek/quarter3/quarter/lastQuarter/half6)、area7 种区域枚举:all/hall/hallA/hallB/hallC/mahjong/teamBuilding)、compare0/1,控制是否返回环比数据)
  9. WHEN area 不为 allTHE API_Contract SHALL 标注 recharge(预收资产)板块不返回数据(储值卡数据不按区域拆分)
  10. THE API_Contract SHALL 标注所有金额字段使用 items_sum 口径DWD-DOC 强制规则 1助教费用使用 assistant_pd_money + assistant_cx_money 拆分DWD-DOC 强制规则 2

5.2 BOARD-1 助教看板契约重写

验收标准
  1. THE API_Contract SHALL 将 BOARD-1 响应从 10 个通用字段扩展为包含基础字段和 4 维度专属字段的结构
  2. THE API_Contract SHALL 为每个助教 item 定义基础字段:id/name/initial/avatarGradient/level/skills/topCustomers,其中 skills 类型为 Array<{ text: string, cls: string }>(含 emoji 和样式类),topCustomers 类型为 string[](含 P6 AC3 四级 emoji 前缀,如 '💖 王先生'/'🧡 李女士'/'💛 张先生'/'💙 赵女士'
  3. THE API_Contract SHALL 为 perf 维度定义专属字段:perfHours(当期定档工时)、perfHoursBefore(上期定档工时,可选)、perfGap(距升档差距描述,可选)、perfReached(是否已达标)
  4. THE API_Contract SHALL 为 salary 维度定义专属字段:salary(工资总额)、salaryPerfHours(定档工时)、salaryPerfBefore(上期定档工时,可选)
  5. THE API_Contract SHALL 为 sv 维度定义专属字段:svAmount(客源储值总额)、svCustomerCount(储值客户数)、svConsume(储值消耗额)
  6. THE API_Contract SHALL 为 task 维度定义专属字段:taskRecall(召回任务完成数)、taskCallback(回访任务完成数)
  7. THE API_Contract SHALL 为 BOARD-1 定义请求参数:sort6 种排序枚举:perf_desc/perf_asc/salary_desc/salary_asc/sv_desc/task_desc)、skill5 种技能枚举:all/chinese/snooker/mahjong/karaoke)、time6 种时间范围枚举:month/quarter/last_month/last_3m/last_quarter/last_6m
  8. THE API_Contract SHALL 标注交叉约束:time=last_6msort=sv_desc 不兼容,后端收到此组合时返回 HTTP 400

5.3 BOARD-2 客户看板契约重写

验收标准
  1. THE API_Contract SHALL 将 BOARD-2 响应从 8 个通用字段扩展为包含基础字段和 8 维度专属字段的结构
  2. THE API_Contract SHALL 为每个客户 item 定义基础字段:id/name/initial/avatarCls/assistants,其中 assistants 类型为 Array<{ name: string, cls: string, heartScore: number, badge?: string, badgeCls?: string }>heartScore 范围 0-10前端通过 heart-icon 组件按 P6 AC3 四级映射渲染(💖>8.5 / 🧡>7 / 💛>5 / 💙≤5
  3. THE API_Contract SHALL 为 recall(最应召回)维度定义专属字段:idealDays/elapsedDays/overdueDays/visits30d/balance/recallIndex
  4. THE API_Contract SHALL 为 potential(最大消费潜力)维度定义专属字段:potentialTagsArray<{ text: string, theme: string }>/spend30d/avgVisits/avgSpend
  5. THE API_Contract SHALL 为 balance(最高余额)维度定义专属字段:balance/lastVisit/monthlyConsume/availableMonths
  6. THE API_Contract SHALL 为 recharge(最近充值)维度定义专属字段:lastRecharge/rechargeAmount/recharges60d/currentBalance
  7. THE API_Contract SHALL 为 recent(最近到店)维度定义专属字段:daysAgo/visitFreq/idealDays/visits30d/avgSpend
  8. THE API_Contract SHALL 为 spend60最高消费近60天维度定义专属字段spend60d/visits60d/highSpendTag/avgSpend
  9. THE API_Contract SHALL 为 freq60最频繁近60天维度定义专属字段visits60d/avgInterval/weeklyVisitsArray<{ val: number, pct: number }>8 周柱状图数据)/spend60d
  10. THE API_Contract SHALL 为 loyal最专一近60天维度定义专属字段intimacy/topCoachName/topCoachHeart/topCoachScore/coachName/coachRatio/coachDetailsArray<{ name, cls, heartScore, badge?, avgDuration, serviceCount, coachSpend, relationIdx }>
  11. THE API_Contract SHALL 为 BOARD-2 定义请求参数:dimension8 种维度枚举)、project5 种项目枚举:all/chinese/snooker/mahjong/karaoke)、page(页码,默认 1pageSize(每页条数,默认 20

5.4 CUST-1 客户详情契约重写

验收标准
  1. THE API_Contract SHALL 为 CUST-1 响应补充客户 Banner 字段:balance(余额)、consumption60d近60天消费idealInterval(理想到店间隔)、daysSinceVisit(距上次到店天数)
  2. THE API_Contract SHALL 为 CUST-1 响应补充 aiInsight 模块:summaryAI 分析摘要stringstrategies(策略建议列表,Array<{ color: string, text: string }>),数据来源标注为 biz.ai_cachecache_type=app4_analysis
  3. THE API_Contract SHALL 为 CUST-1 响应补充 coachTasks 模块(关联助教任务列表):每个助教含 name/level/levelColor/taskType/taskColor/bgClass/status/lastService/metricsArray<{ label, value, color? }>含近60天次数/总时长/次均时长)
  4. THE API_Contract SHALL 为 CUST-1 响应补充 favoriteCoaches 模块(最亲密助教):每位助教含 emoji/name/relationIndex/indexColor/bgClass/statsArray<{ label, value, color? }>,含基础课时/激励课时/上课次数/充值金额)
  5. THE API_Contract SHALL 将 CUST-1 消费记录从扁平结构重写为嵌套结构:每条记录含 id/typetable/shop/recharge 枚举)/date/tableName/startTime/endTime/duration/tableFee/tableOrigPrice/coachesArray<{ name, level, levelColor, courseType, hours, perfHours?, fee }>/foodAmount/foodOrigPrice/totalAmount/totalOrigPrice/payMethod/rechargeAmount
  6. THE API_Contract SHALL 为 CUST-1 响应补充 notes 模块(备注列表):每条备注含 id/tagLabel/createdAt/content
  7. THE API_Contract SHALL 标注会员信息获取规则:通过 member_id JOIN dim_member 获取手机号和昵称DWD-DOC 强制规则 DQ-6禁止直接使用 settlement_head.member_phone

5.5 COACH-1 助教详情契约重写

验收标准
  1. THE API_Contract SHALL 为 COACH-1 响应补充基本信息字段:workYears(工龄)、customerCount(客户数)、hireDate(入职日期)
  2. THE API_Contract SHALL 为 COACH-1 响应补充 performance 模块6 个绩效指标):monthlyHours/monthlySalary/customerBalance/tasksCompleted/perfCurrent/perfTarget
  3. THE API_Contract SHALL 为 COACH-1 响应补充 income 模块(收入明细):thisMonthlastMonth 各含 4 项收入分类(基础课时费/激励课时费/充值提成/酒水提成),每项含 label/amount/color
  4. THE API_Contract SHALL 为 COACH-1 响应补充 tierNodes 字段(档位节点数组,如 [0, 100, 130, 160, 190, 220]),供前端绩效进度条组件使用
  5. THE API_Contract SHALL 为 COACH-1 响应补充 historyMonths 模块(历史月份统计,最近 5+ 个月):每月含 month(标签)/estimated(是否预估)/customers/hours/salary/callbackDone/recallDone
  6. THE API_Contract SHALL 扩展 COACH-1 的 topCustomers 字段结构,从 5 个字段扩展为 10 个字段:补充 initial/avatarGradient/heartEmojiP6 AC3 四级映射:💖/🧡/💛/💙/relationScore关系指数0-10/scoreColor/balance
  7. THE API_Contract SHALL 为 COACH-1 响应补充近期服务明细中的 perfHours(折算工时)和 customerId 字段
  8. THE API_Contract SHALL 为 COACH-1 的任务分组(visibleTasks/hiddenTasks/abandonedTasks补充字段TaskItem 补充 noteCount/pinned/notesArray<{ pinned?, text, date }>AbandonedTask 补充 reason
  9. THE API_Contract SHALL 为 COACH-1 响应补充 notes 模块(备注列表):每条备注含 id/content/timestamp/aiScoreAI 应用 6 评分1-10展示用/customerName/tagLabel/createdAt

5.6 PERF-1 绩效概览契约重写

验收标准
  1. THE API_Contract SHALL 将 PERF-1 的 thisMonthRecords 从扁平数组重写为按日期分组的 DateGroup 结构:每组含 date(日期标签)/totalHours(当日总工时)/totalIncome(当日总收入)/records(记录列表),每条记录含 customerName/timeRange/hours/courseType/courseTypeClass/location/income
  2. THE API_Contract SHALL 为 PERF-1 响应补充收入档位数据:currentTier(当前档,含 basicRate/incentiveRate)、nextTier(下一档,含 basicRate/incentiveRate)、upgradeHoursNeeded(距升档所需工时)、upgradeBonus(升档奖金)
  3. THE API_Contract SHALL 为 PERF-1 响应补充 lastMonthIncome(上月收入)字段
  4. THE API_Contract SHALL 为 PERF-1 的 incomeItems 每项补充 desc 字段(费率×工时的拆分描述,如 "80元/h × 75h"
  5. THE API_Contract SHALL 为 PERF-1 的 newCustomers 补充 lastService(最后服务日期)和 count(服务次数)字段;为 regularCustomers 补充 hours(总工时)和 income(总收入)字段

5.7 TASK-1 绩效概览字段契约重写

验收标准
  1. THE API_Contract SHALL 将 TASK-1 响应中的 performance 从 4 个字段(totalHours/totalIncome/totalCustomers/monthLabel)扩展为 15+ 个字段,补充:tierNodes(档位节点数组)/basicHours(基础课时)/bonusHours(激励课时)/currentTier(当前档位索引)/nextTierHours(下一档位工时阈值)/tierCompleted(是否已达标)/bonusMoney(升档奖金)/incomeTrend(收入趋势,如 "↓368"/incomeTrendDirup/down/prevMonth(上月标签)
  2. THE API_Contract SHALL 为 TASK-1 的任务 item 补充可选扩展字段:lastVisitDays(距上次到店天数)、balance(客户余额)、aiSuggestionAI 建议摘要)

5.8 CHAT-1/2 对话模块契约重写

验收标准
  1. THE API_Contract SHALL 统一 CHAT-2 消息的时间字段名为 createdAt(替代前端使用的 timestamp 和契约定义的 created_at,遵循 camelCase 规范)
  2. THE API_Contract SHALL 为 CHAT-1 历史列表的每条记录补充 title(对话标题)字段
  3. THE API_Contract SHALL 为 CHAT-2 消息补充 referenceCard 可选字段:含 typecustomer/record 枚举)/title/summary/dataRecord<string, string> 键值对)
  4. THE API_Contract SHALL 补充 SSE 流式端点定义:POST /api/xcx/chat/stream,请求体含 chatId/content,响应为 text/event-stream
  5. THE API_Contract SHALL 标注 CHAT 消息查询端点支持 customerId 查询参数:后端根据 customerId 自动查找或创建对话,返回对应的 chatId 和消息列表

需求 6前端跨页面参数修复T0-6

用户故事: 作为助教或管理层用户,我希望在小程序中从一个页面跳转到另一个页面时,目标页面能正确加载对应的数据,而不会因为参数传递错误导致页面空白或加载错误数据。

6.1 task-detail 页面跳转修复

验收标准
  1. WHEN 用户从 task-detail 页面点击"问问助手"跳转到 chat 页面时THE Miniprogram SHALL 传递 customerId={detail.customerId} 参数(而非当前错误传递的 detail.id 即 taskId
  2. WHEN 用户从 task-detail 页面点击"查看全部服务记录"跳转到 customer-service-records 页面时THE Miniprogram SHALL 传递 customerId={detail.customerId} 参数(而非当前错误传递的 detail.id 即 taskId
  3. IF TASK-2 响应中不包含 customerId 字段THEN THE Miniprogram SHALL 无法完成上述跳转修复,因此本需求依赖 API 契约中 TASK-2 响应包含 customerId 字段的定义

6.2 customer-detail 页面跳转修复

验收标准
  1. WHEN 用户从 customer-detail 页面点击"查看服务记录"跳转到 customer-service-records 页面时THE Miniprogram SHALL 传递 customerId={detail.id} 参数(当前未传任何参数)
  2. WHEN 用户从 customer-detail 页面点击"问问助手"跳转到 chat 页面时THE Miniprogram SHALL 传递 customerId={detail.id} 参数(当前未传任何参数)
  3. THE Miniprogram SHALL 修复 customer-detail 页面的 loadDetail() 函数,从 onLoad(options)options.id 获取客户 ID替代当前通过 __route__ 解析的错误方式

6.3 coach-detail 页面跳转修复

验收标准
  1. WHEN 用户从 coach-detail 页面点击任务项跳转到 customer-detail 页面时THE Miniprogram SHALL 传递 id={customerId} 参数(而非当前错误传递的 name={customerName}),此修复依赖 COACH-1 响应中 TaskItem 包含 customerId 字段

6.4 performance 页面跳转修复

验收标准
  1. WHEN 用户从 performance 页面点击客户卡片或服务记录跳转到 task-detail 页面时THE Miniprogram SHALL 传递 id={taskId} 参数(而非当前错误传递的 customerName={name}),此修复依赖 PERF-1 响应中记录包含 taskId 字段

6.5 chat 页面多入口参数路由

验收标准
  1. WHEN chat 页面从 task-detail 或 customer-detail 跳转进入(携带 customerId 参数THE Miniprogram SHALL 使用 customerId 查询参数调用 CHAT 消息端点,由后端自动查找或创建对话
  2. WHEN chat 页面从 chat-history 跳转进入(携带 historyId 参数THE Miniprogram SHALL 使用 historyId 作为 chatId 直接加载历史消息
  3. WHEN chat 页面从 coach-detail 跳转进入(携带 coachId 参数THE Miniprogram SHALL 使用 coachId 作为上下文参数传递给 CHAT 端点

6.6 globalData.authUser 字段扩展

验收标准
  1. THE Miniprogram SHALL 在登录成功后(/api/xcx/me 响应)将 rolestoreNamecoachLevelavatar 字段存入 globalData.authUser,供 task-list Banner、performance Banner、performance-records Banner 等多个页面使用
  2. WHEN globalData.authUser 已包含上述字段时THE Miniprogram SHALL 不再需要各页面单独请求 /me 接口获取这些信息

需求 7契约文档一致性与完整性

用户故事: 作为后续子 specRNS1.1-1.4)的开发者,我希望重写后的 API 契约文档内部一致、无歧义,以便直接作为后端实现的唯一基准。

验收标准

  1. THE API_Contract SHALL 确保所有接口的响应字段名统一使用 camelCase 格式(与需求 2 的 CamelCase_Converter 输出一致)
  2. THE API_Contract SHALL 确保所有涉及金额的字段标注使用 items_sum 口径,禁止使用 consume_moneyDWD-DOC 强制规则 1
  3. THE API_Contract SHALL 确保所有涉及助教费用的字段标注使用 assistant_pd_money(陪打)+ assistant_cx_money(超休)拆分,禁止使用 service_feeDWD-DOC 强制规则 2
  4. THE API_Contract SHALL 确保所有涉及会员信息的字段标注通过 member_id JOIN dim_member 获取,禁止直接使用 member_phone/member_nameDWD-DOC 强制规则 DQ-6/DQ-7
  5. THE API_Contract SHALL 为每个接口标注数据源FDW 表名或业务表名),供后续子 spec 实现时参考
  6. THE API_Contract SHALL 确保重写后的 8 个接口响应定义BOARD-1/2/3、CUST-1、COACH-1、PERF-1、TASK-1 performance、CHAT-1/2与前端内联 mock 数据结构完全对齐,无字段遗漏或类型不匹配