29 KiB
需求文档 — RNS1.3:三看板接口
简介
RNS1.3 是 NS1 小程序后端 API 补全项目的第四个子 spec,负责实现 3 个看板接口(BOARD-1 助教看板、BOARD-2 客户看板、BOARD-3 财务看板)、CONFIG-1 技能配置接口、以及前端看板筛选修复。看板是管理层视角的核心功能,其中 BOARD-3 财务看板是全项目最复杂的单个接口(6 个独立板块、200+ 字段、60+ 环比数据点)。
依赖
- RNS1.0(基础设施与契约重写)必须先完成:全局响应包装中间件(
ResponseWrapperMiddleware)、camelCase 转换(CamelModel)、重写后的 API 契约 - RNS1.1 / RNS1.2 可并行开发,无直接依赖
- 后端已有
fdw_queries.py(FDW 查询集中封装)、task_manager.py、note_service.py - 前端已有 13 个页面(P5.2 交付),当前使用 mock 数据
来源文档
docs/prd/Neo_Specs/RNS1-split-plan.md— 拆分计划主文档(RNS1.3 章节,T3-1 ~ T3-7)docs/miniprogram-dev/API-contract.md— API 契约(BOARD-1/2/3、CONFIG-1 完整定义)docs/prd/Neo_Specs/NS1-xcx-backend-api.md— 原始 spec(八¾ 看板筛选交叉矩阵为权威参考)docs/prd/Neo_Specs/miniprogram-storyboard-walkthrough-gaps.md— 管理层视角走查报告(G1~G10 看板相关 Gap)docs/prd/Neo_Specs/storyboard-walkthrough-assistant-view.md— 助教视角走查报告docs/reports/DWD-DOC/— 金额口径与字段语义权威标杆文档
术语表
- Backend:FastAPI 后端应用,位于
apps/backend/ - Miniprogram:微信小程序前端应用,位于
apps/miniprogram/ - BOARD_1_API:助教看板接口
GET /api/xcx/board/coaches,返回助教排行列表(4 维度专属字段) - BOARD_2_API:客户看板接口
GET /api/xcx/board/customers,返回客户排行列表(8 维度专属字段) - BOARD_3_API:财务看板接口
GET /api/xcx/board/finance,返回 6 个板块的财务数据(overview/recharge/revenue/cashflow/expense/coachAnalysis) - CONFIG_1_API:技能类型列表接口
GET /api/xcx/config/skill-types,返回助教技能类型配置 - FDW:PostgreSQL Foreign Data Wrapper,后端通过直连 ETL 库查询
app.v_*RLS 视图 - items_sum:DWD-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_dws_assistant_salary_calc:ETL RLS 视图,提供助教绩效/档位/收入/工资数据
- v_dws_assistant_monthly_summary:ETL RLS 视图,提供助教月度汇总(客户数、储值额等)
- v_dim_assistant:ETL RLS 视图,提供助教基本信息(姓名、技能、入职日期等)
- v_dim_member:ETL RLS 视图,提供会员基本信息(nickname、mobile),通过
member_id关联,取scd2_is_current=1 - v_dim_member_card_account:ETL RLS 视图,提供会员卡余额,通过
tenant_member_id关联,取scd2_is_current=1 - v_dws_member_assistant_relation_index:ETL RLS 视图,提供会员与助教的关系指数
- v_dws_member_consumption_summary:ETL RLS 视图,提供会员消费汇总
- v_dws_finance_daily_summary:ETL RLS 视图,提供财务日报汇总数据(经营一览 8 指标 + 现金流入/流出),BOARD-3 overview/cashflow/expense 板块的主数据源
- v_dws_finance_income_structure:ETL RLS 视图,提供收入结构表 + 正价/优惠/渠道明细,BOARD-3 revenue 板块数据源
- v_dws_finance_recharge_summary:ETL RLS 视图,提供储值卡 + 赠送卡矩阵数据,BOARD-3 recharge 板块数据源
- v_dws_finance_discount_detail:ETL RLS 视图,提供优惠明细(大客户优惠/其他优惠拆分),BOARD-3 revenue 板块辅助数据源
- v_dws_finance_expense_summary:ETL RLS 视图,提供现金流出 4 子分组明细,BOARD-3 expense 板块数据源
- v_dws_platform_settlement:ETL RLS 视图,提供平台结算数据(汇来米/美团/抖音),BOARD-3 expense.platformItems 数据源
- coach_tasks:业务库
biz.coach_tasks表,存储助教任务分配与状态 - user_assistant_binding:认证库
auth.user_assistant_binding表,映射小程序用户与助教身份 - dimType:BOARD-1 中根据
sort参数映射的维度类型(perf/salary/sv/task),决定卡片展示模板 - 环比:月环比,与上一个相同时间周期对比(本月 vs 上月、本周 vs 上周等),返回百分比字符串 + 方向标记
- GiftRow:赠送卡 3×4 矩阵中的一行(新增/消费/余额),每行含 4 列(合计/酒水卡/台费卡/抵用券)
- RevenueStructureRow:收入结构表中的一行(9 行含子行),含发生额、优惠、入账金额
- CoachAnalysisTable:助教分析子表(基础课或激励课),含汇总行 + 按等级分行(初级/中级/高级/星级)
需求
需求 1:实现 BOARD-1 助教看板(T3-1)
用户故事: 作为管理者,我希望在助教看板中按不同维度(定档业绩/工资/客源储值/任务完成)查看助教排行,并支持技能筛选和时间范围切换,以便评估和对比各助教的工作表现。
验收标准
1.1 请求参数与筛选
- THE BOARD_1_API SHALL 接受 3 个查询参数:
sort(排序维度,6 种枚举:perf_desc/perf_asc/salary_desc/salary_asc/sv_desc/task_desc)、skill(技能筛选,5 种枚举:all/chinese/snooker/mahjong/karaoke)、time(时间范围,6 种枚举:month/quarter/last_month/last_3m/last_quarter/last_6m) - IF
time=last_6m且sort=sv_desc,THEN THE BOARD_1_API SHALL 返回 HTTP 400{ code: 400, message: "最近6个月不支持客源储值排序" } - THE BOARD_1_API SHALL 根据
time参数计算对应的日期范围(本月=当月1日末日、上月=上月1日末日、本季度=季度首日~末日、前3个月=不含本月的前3个月、上季度=上季度、最近6个月=不含本月的前6个月)
1.2 基础字段(所有维度共享)
- THE BOARD_1_API SHALL 为每个助教 item 返回基础字段:
id(助教 ID)、name(助教姓名)、initial(姓名首字)、avatarGradient(头像渐变色标识)、level(等级 key:star/senior/middle/junior)、skills(技能列表,Array<{ text: string, cls: string }>)、topCustomers(Top 客户列表,含亲密度 emoji 前缀,如['💖 王先生', '💛 李女士']) - THE BOARD_1_API SHALL 从
v_dim_assistant获取助教基本信息,从v_dws_assistant_salary_calc获取等级(assistant_level_name) - THE BOARD_1_API SHALL 从
v_dws_member_assistant_relation_index按亲密度降序取 Top 3 客户,拼接亲密度 emoji(P6 AC3 四级映射:rs_display > 8.5→ 💖,> 7→ 🧡,> 5→ 💛,≤ 5→ 💙)+ 客户姓名作为topCustomers
1.3 perf 维度专属字段
- WHEN
sort为perf_desc或perf_asc时,THE BOARD_1_API SHALL 返回 perf 维度字段:perfHours(当期定档工时)、perfHoursBefore(上期定档工时,可选)、perfGap(距升档差距描述,如"距升档 13.8h",已达标时不返回)、perfReached(是否已达标) - THE BOARD_1_API SHALL 从
v_dws_assistant_salary_calc查询当期和上期的定档工时数据,根据档位阈值计算perfGap和perfReached
1.4 salary 维度专属字段
- WHEN
sort为salary_desc或salary_asc时,THE BOARD_1_API SHALL 返回 salary 维度字段:salary(预估工资总额,元)、salaryPerfHours(定档工时)、salaryPerfBefore(上期定档工时,可选) - THE BOARD_1_API SHALL 使用
items_sum口径计算salary字段(DWD-DOC 强制规则 1)
1.5 sv 维度专属字段
- WHEN
sort为sv_desc时,THE BOARD_1_API SHALL 返回 sv 维度字段:svAmount(客源储值总额,元)、svCustomerCount(储值客户数)、svConsume(储值消耗额,元) - THE BOARD_1_API SHALL 从
v_dws_assistant_monthly_summary获取助教月度储值汇总数据(客源储值额、储值客户数、储值消耗额),该视图已按助教维度预聚合
1.6 task 维度专属字段
- WHEN
sort为task_desc时,THE BOARD_1_API SHALL 返回 task 维度字段:taskRecall(召回任务完成数)、taskCallback(回访任务完成数) - THE BOARD_1_API SHALL 从
biz.coach_tasks查询指定时间范围内status='completed'的任务,按task_type分类统计
1.7 排序与返回策略
- THE BOARD_1_API SHALL 根据
sort参数对结果排序(perf_desc按定档工时降序、perf_asc按定档工时升序、salary_desc按工资降序、salary_asc按工资升序、sv_desc按储值额降序、task_desc按任务完成总数降序) - THE BOARD_1_API SHALL 始终返回所有维度的字段(扁平结构),前端根据当前
sort选择性渲染对应卡片模板,切换维度时无需重新请求
需求 2:实现 BOARD-2 客户看板(T3-2)
用户故事: 作为管理者,我希望在客户看板中按 8 个维度(最应召回/最大消费潜力/最高余额/最近充值/最近到店/最高消费60天/最频繁60天/最专一60天)查看客户排行,每个维度展示不同的专属字段卡片和关联助教信息,以便从多角度评估客户价值和服务需求。
验收标准
2.1 请求参数与分页
- THE BOARD_2_API SHALL 接受 4 个查询参数:
dimension(维度,8 种枚举:recall/potential/balance/recharge/recent/spend60/freq60/loyal)、project(项目筛选,5 种枚举:all/chinese/snooker/mahjong/karaoke)、page(页码,默认 1)、pageSize(每页条数,默认 20,上限 100) - THE BOARD_2_API SHALL 返回分页结构:
items(客户列表)、total(总数)、page(当前页)、pageSize(每页条数),支持前端 20 条懒加载
2.2 基础字段(所有维度共享)
- THE BOARD_2_API SHALL 为每个客户 item 返回基础字段:
id(客户 member_id)、name(客户姓名)、initial(姓名首字)、avatarCls(头像样式类)、assistants(关联助教列表,Array<{ name, cls, heartScore, badge?, badgeCls? }>) - THE BOARD_2_API SHALL 通过
member_idLEFT JOINv_dim_member(取scd2_is_current=1)获取客户姓名(DQ-6) - THE BOARD_2_API SHALL 从
biz.coach_tasks+ 亲密度计算获取assistants列表,按亲密度降序排列,当前跟进助教(cls='assistant--assignee')置顶
2.3 recall 维度专属字段
- WHEN
dimension=recall时,THE BOARD_2_API SHALL 返回:idealDays(理想到店间隔天数)、elapsedDays(已过天数)、overdueDays(超期天数 = elapsedDays - idealDays)、visits30d(近30天到店次数)、balance(余额,格式化字符串)、recallIndex(召回指数) - THE BOARD_2_API SHALL 按 WBI(召回指数)降序排列 recall 维度结果
2.4 potential 维度专属字段
- WHEN
dimension=potential时,THE BOARD_2_API SHALL 返回:potentialTags(潜力标签列表,Array<{ text, theme }>)、spend30d(近30天消费)、avgVisits(月均到店)、avgSpend(次均消费) - THE BOARD_2_API SHALL 按 SPI(消费潜力指数)降序排列 potential 维度结果
2.5 balance 维度专属字段
- WHEN
dimension=balance时,THE BOARD_2_API SHALL 返回:balance(当前余额)、lastVisit(最近到店描述,如"3天前")、monthlyConsume(月均消耗)、availableMonths(可用月数,如"约0.8个月") - THE BOARD_2_API SHALL 按
balance_amount降序排列 balance 维度结果
2.6 recharge 维度专属字段
- WHEN
dimension=recharge时,THE BOARD_2_API SHALL 返回:lastRecharge(最后充值日期)、rechargeAmount(充值金额)、recharges60d(近60天充值次数)、currentBalance(当前余额) - THE BOARD_2_API SHALL 按
last_recharge_date降序排列 recharge 维度结果
2.7 recent 维度专属字段
- WHEN
dimension=recent时,THE BOARD_2_API SHALL 返回:daysAgo(距今天数)、visitFreq(到店频率,如"6.2次/月")、idealDays(理想间隔)、visits30d(近30天到店)、avgSpend(次均消费) - THE BOARD_2_API SHALL 按
last_visit_date降序排列 recent 维度结果
2.8 spend60 维度专属字段
- WHEN
dimension=spend60时,THE BOARD_2_API SHALL 返回:spend60d(近60天消费总额)、visits60d(近60天到店次数)、highSpendTag(是否高消费标记)、avgSpend(次均消费) - THE BOARD_2_API SHALL 使用
items_sum口径计算spend60d(DWD-DOC 强制规则 1),按items_sum_60d降序排列
2.9 freq60 维度专属字段
- WHEN
dimension=freq60时,THE BOARD_2_API SHALL 返回:visits60d(近60天到店次数)、avgInterval(平均到店间隔,如"5.0天")、weeklyVisits(最近8周到店柱状图,Array<{ val: number, pct: number }>,固定长度 8)、spend60d(近60天消费) - THE BOARD_2_API SHALL 按
visit_count_60d降序排列 freq60 维度结果 - THE BOARD_2_API SHALL 计算
weeklyVisits中每周的pct为相对于 8 周最大值的百分比(0-100)
2.10 loyal 维度专属字段
- WHEN
dimension=loyal时,THE BOARD_2_API SHALL 返回:intimacy(专一度指数)、topCoachName(最亲密助教姓名)、topCoachHeart(最亲密助教亲密度分数)、topCoachScore(最亲密助教关系指数)、coachName(主助教姓名)、coachRatio(主助教占比,如"78%")、coachDetails(助教明细列表,Array<{ name, cls, heartScore, badge?, avgDuration, serviceCount, coachSpend, relationIdx }>) - THE BOARD_2_API SHALL 按
max_rs(最大关系指数)降序排列 loyal 维度结果
2.11 维度切换策略
- THE BOARD_2_API SHALL 按
dimension参数仅返回对应维度的专属字段(减少传输量和查询开销),切换维度时前端重新请求
需求 3:实现 BOARD-3 经营一览 + 预收资产(T3-3)
用户故事: 作为管理者,我希望在财务看板中查看经营一览(8 项核心指标及环比)和预收资产(储值卡 + 赠送卡矩阵),并支持时间范围、区域筛选和环比开关,以便全面掌握门店的经营状况和预收资产变动。
验收标准
3.1 请求参数
- THE BOARD_3_API SHALL 接受 3 个查询参数:
time(时间范围,8 种枚举:month/lastMonth/week/lastWeek/quarter3/quarter/lastQuarter/half6)、area(区域筛选,7 种枚举:all/hall/hallA/hallB/hallC/mahjong/teamBuilding)、compare(环比开关,0或1,默认0) - THE BOARD_3_API SHALL 根据
time参数计算当期日期范围(month=当月1日末日、末日、lastMonth=上月1日week=本周一本周日、上周日、lastWeek=上周一quarter3=前3个月不含本月、quarter=本季度首日~末日、lastQuarter=上季度、half6=最近6个月不含本月) - WHEN
compare=1时,THE BOARD_3_API SHALL 计算上期日期范围(与当期相同长度的前一个周期),分别查询当期和上期数据后计算环比百分比 - WHEN
compare=0时,THE BOARD_3_API SHALL 不返回任何环比字段(xxxCompare/isDown/isFlat),减少查询开销
3.2 经营一览 overview(8 指标 + 8 环比)
- THE BOARD_3_API SHALL 返回
overview板块,包含 8 项核心指标:occurrence(发生额/正价)、discount(总优惠,负值)、discountRate(折扣率)、confirmedRevenue(成交/确认收入)、cashIn(实收/现金流入)、cashOut(现金支出)、cashBalance(现金结余)、balanceRate(结余率) - WHEN
compare=1时,THE BOARD_3_API SHALL 为 overview 每项指标返回 3 个环比字段:xxxCompare(环比百分比字符串,如"12.5%"或"持平")、xxxDown(是否下降,boolean)、xxxFlat(是否持平,boolean) - THE BOARD_3_API SHALL 从
v_dws_finance_daily_summary查询经营一览数据(按日期范围聚合),使用items_sum口径计算所有金额(DWD-DOC 强制规则 1)
3.3 预收资产 recharge(储值卡 + 赠送卡矩阵)
- WHEN
area=all时,THE BOARD_3_API SHALL 返回recharge板块,包含储值卡 5 项指标:actualIncome(充值实收)、firstCharge(首充)、renewCharge(续费)、consumed(消耗)、cardBalance(储值卡总余额) - THE BOARD_3_API SHALL 返回
recharge.giftRows(赠送卡 3×4 矩阵),3 行(新增/消费/余额)× 4 列(合计/酒水卡/台费卡/抵用券),每个单元格含值和环比字段,共 24 个数据字段 + 24 个环比字段 - THE BOARD_3_API SHALL 返回
recharge.allCardBalance(全类别会员卡余额合计 = 储值卡 + 赠送卡) - WHEN
area不等于all时,THE BOARD_3_API SHALL 将recharge板块返回null(储值卡数据不按区域拆分,选中具体区域时无意义) - THE BOARD_3_API SHALL 从
v_dws_finance_recharge_summary查询预收资产数据
需求 4:实现 BOARD-3 应计收入 + 现金流入(T3-4)
用户故事: 作为管理者,我希望在财务看板中查看应计收入确认(收入结构表含区域子行、正价/优惠/渠道明细)和现金流入(消费收款 + 充值收款),以便分析收入构成和现金来源。
验收标准
4.1 应计收入确认 revenue
- THE BOARD_3_API SHALL 返回
revenue.structureRows(收入结构表),包含 9 行含子行标记:主行(开台与包厢、助教基础课、助教激励课、食品酒水)+ 子行(A区/B区/C区/团建区/麻将区,属于"开台与包厢"的子行,isSub=true),每行含id、name、desc(可选)、amount(发生额)、discount(优惠金额)、booked(入账金额)、bookedCompare(入账环比,可选) - THE BOARD_3_API SHALL 对收入结构表中助教行使用
assistant_pd_money(基础课/陪打)和assistant_cx_money(激励课/超休)拆分(DWD-DOC 强制规则 2),禁止使用service_fee - THE BOARD_3_API SHALL 返回
revenue.priceItems(正价明细,4 项)、revenue.totalOccurrence(发生额合计)、revenue.discountItems(优惠明细,4 项)、revenue.confirmedTotal(确认收入合计)、revenue.channelItems(渠道明细,3 项:储值卡结算冲销/现金线上支付/团购核销确认收入) - THE BOARD_3_API SHALL 从
v_dws_finance_income_structure(收入结构主表)+v_dws_finance_discount_detail(优惠明细辅助)查询应计收入数据
4.2 现金流入 cashflow
- THE BOARD_3_API SHALL 返回
cashflow板块,包含consumeItems(消费收款,3 项:纸币现金/线上收款/团购平台)、rechargeItems(充值收款,1 项:会员充值到账)、total(现金流入合计) - THE BOARD_3_API SHALL 确保
consumeItems中platform_settlement_amount和groupbuy_pay_amount互斥(DWD-DOC 强制规则 8:现金流互斥) - THE BOARD_3_API SHALL 从
v_dws_finance_daily_summary查询现金流入数据(消费收款 + 充值收款字段均在财务日报中)
需求 5:实现 BOARD-3 现金流出 + 助教分析(T3-5)
用户故事: 作为管理者,我希望在财务看板中查看现金流出(经营/固定/助教分成/平台服务费 4 个子分组)和助教分析(基础课 + 激励课各按 4 等级分行),以便分析支出结构和助教成本。
验收标准
5.1 现金流出 expense
- THE BOARD_3_API SHALL 返回
expense板块,包含 4 个子分组:operationItems(经营支出,3 项:食品饮料/耗材/报销)、fixedItems(固定支出,4 项:房租/水电/物业/人员工资)、coachItems(助教分成,4 项:基础课分成/激励课分成/充值提成/额外奖金)、platformItems(平台服务费,3 项:汇来米/美团/抖音) - THE BOARD_3_API SHALL 返回
expense.total(现金流出合计)及其环比字段 - THE BOARD_3_API SHALL 对
coachItems中基础课分成使用assistant_pd_money,激励课分成使用assistant_cx_money(DWD-DOC 强制规则 2) - THE BOARD_3_API SHALL 从
v_dws_finance_expense_summary(支出明细 4 子分组,含助教分成)+v_dws_platform_settlement(平台服务费:汇来米/美团/抖音)查询现金流出数据
5.2 助教分析 coachAnalysis
- THE BOARD_3_API SHALL 返回
coachAnalysis板块,包含basic(基础课/陪打)和incentive(激励课/超休)两个子表,结构完全相同 - THE BOARD_3_API SHALL 为每个子表返回汇总行:
totalPay(总课时费)、totalShare(总分成)、avgHourly(平均时薪),各含环比字段 - THE BOARD_3_API SHALL 为每个子表返回
rows(按等级分行,4 行:初级/中级/高级/星级),每行含level(等级名)、pay(课时费)、share(分成)、hourly(时薪),各含环比字段和方向标记(payDown/shareDown/hourlyFlat) - THE BOARD_3_API SHALL 从
v_dws_assistant_salary_calc按assistant_level_name分组聚合助教分析数据
需求 6:实现 CONFIG-1 技能类型列表(T3-6)
用户故事: 作为管理者,我希望助教看板的技能筛选选项从后端配置表动态获取(而非前端硬编码),以便在新增技能类型时无需发版更新前端。
验收标准
- THE CONFIG_1_API SHALL 实现
GET /api/xcx/config/skill-types端点,返回技能类型列表,每项含key(枚举值,如chinese/snooker/mahjong/karaoke)、label(中文标签)、emoji(表情符号)、cls(前端样式类) - THE CONFIG_1_API SHALL 从 ETL cfg 表读取技能类型配置数据
- IF ETL cfg 表查询失败或无数据,THEN THE CONFIG_1_API SHALL 返回空数组,前端
api.ts中的硬编码列表作为 mock 回退 - THE CONFIG_1_API SHALL 对响应设置合理的缓存策略(技能类型变更频率极低)
需求 7:前端看板筛选修复(T3-7)
用户故事: 作为管理者,我希望在看板页面切换筛选条件时能立即看到更新后的数据(而非停留在旧数据),以便实时对比不同维度和时间范围的数据。
验收标准
7.1 BOARD-1 筛选修复(F1, F6)
- THE Miniprogram SHALL 修复
board-coach页面的onSortChange、onSkillChange、onTimeChange事件处理函数,在更新 data 状态后调用this.loadData()重新请求 API - THE Miniprogram SHALL 在
board-coach页面实现time=last_6m+sort=sv_desc的互斥约束:选择last_6m时禁用sv_desc选项,或选择sv_desc时禁用last_6m选项
7.2 BOARD-2 筛选修复 + 分页补充(F2, F3)
- THE Miniprogram SHALL 修复
board-customer页面的onDimensionChange、onProjectChange事件处理函数,在更新 data 状态后调用this.loadData()重新请求 API - THE Miniprogram SHALL 为
board-customer页面补充分页参数(page/pageSize)和"加载更多"懒加载逻辑(onReachBottom触发加载下一页,pageSize=20) - THE Miniprogram SHALL 修改
services/api.ts中fetchBoardCustomers函数签名,增加page和pageSize参数
7.3 BOARD-3 筛选修复 + 签名扩展(F4, F5)
- THE Miniprogram SHALL 修改
services/api.ts中fetchBoardFinance函数签名,从{ date?: string }扩展为{ time: string, area: string, compare: number } - THE Miniprogram SHALL 修复
board-finance页面的onTimeChange、onAreaChange事件处理函数,在更新 data 状态后使用新参数调用fetchBoardFinance重新请求 API - THE Miniprogram SHALL 修复
board-finance页面的toggleCompare函数,切换环比开关后使用compare=0或compare=1参数重新请求 API - WHEN
area不等于all时,THE Miniprogram SHALL 隐藏预收资产板块(recharge为null时不渲染该 section)
需求 8:全局约束与数据隔离
用户故事: 作为系统管理员,我希望所有看板和配置接口都遵循统一的权限控制、数据隔离和数据质量规则,以确保数据安全和口径一致。
验收标准
8.1 权限与认证
- THE Backend SHALL 对所有 RNS1.3 接口(BOARD_1_API、BOARD_2_API、BOARD_3_API、CONFIG_1_API)执行
require_approved()权限检查,确保用户状态为approved - THE Backend SHALL 对 BOARD_1_API 验证用户具有
view_board_coach权限,对 BOARD_2_API 验证用户具有view_board_customer权限,对 BOARD_3_API 验证用户具有view_board_finance权限 - THE Backend SHALL 对所有 RNS1.3 接口通过
SET LOCAL app.current_site_id实现门店级数据隔离(FDW 查询通过_fdw_context上下文管理器统一执行)
8.2 DWD-DOC 强制规则
- THE Backend SHALL 对所有涉及金额的字段统一使用
items_sum口径(DWD-DOC 强制规则 1),禁止使用consume_money - THE Backend SHALL 对所有涉及助教费用的字段使用
assistant_pd_money(陪打/基础课)+assistant_cx_money(超休/激励课)拆分(DWD-DOC 强制规则 2),禁止使用service_fee - THE Backend SHALL 对所有涉及会员信息的查询通过
member_idLEFT JOINv_dim_member(取scd2_is_current=1)获取姓名和手机号(DWD-DOC 强制规则 DQ-6),禁止直接使用settlement_head.member_phone或member_name - THE Backend SHALL 确保支付渠道恒等式
balance_amount = recharge_card_amount + gift_card_amount(DWD-DOC 强制规则 3),三者不可重复计算 - THE Backend SHALL 确保现金流互斥:
platform_settlement_amount和groupbuy_pay_amount互斥(DWD-DOC 强制规则 8)
8.3 优雅降级
- IF 某个看板板块的数据源查询失败,THEN THE Backend SHALL 对该板块返回空默认值(空对象或空数组),不影响其他板块和整体响应
- THE Backend SHALL 对所有 FDW 查询异常进行捕获和日志记录,返回降级响应而非 HTTP 500
8.4 环比计算通用规则
- THE Backend SHALL 对所有环比计算采用统一公式:
compareValue = (当期值 - 上期值) / 上期值 × 100%,格式化为百分比字符串(如"12.5%") - WHEN 上期值为 0 且当期值不为 0 时,THE Backend SHALL 返回
xxxCompare: "新增",xxxDown: false,xxxFlat: false - WHEN 上期值和当期值均为 0 时,THE Backend SHALL 返回
xxxCompare: "持平",xxxDown: false,xxxFlat: true - THE Backend SHALL 根据环比值设置方向标记:正值 →
isDown=false,负值 →isDown=true,零值 →isFlat=true
需求 9:正确性属性(Property-Based Testing)
用户故事: 作为开发者,我希望通过属性测试验证看板接口的数据一致性和业务规则正确性,以便在开发阶段发现口径错误和数据异常。
验收标准
9.1 BOARD-1 排序不变量
- FOR ALL BOARD_1_API 响应(
sort=perf_desc),列表 SHALL 按perfHours降序排列(前一项的perfHours≥ 后一项的perfHours) - FOR ALL BOARD_1_API 响应(
sort=salary_asc),列表 SHALL 按salary升序排列(前一项的salary≤ 后一项的salary)
9.2 BOARD-2 分页不变量
- FOR ALL 相同参数的 BOARD_2_API 请求(相同
dimension、project),page=1返回的totalSHALL 等于page=2返回的total(总数在分页间保持一致) - FOR ALL BOARD_2_API 响应,
items.lengthSHALL 小于等于pageSize
9.3 BOARD-3 经营一览恒等式
- FOR ALL BOARD_3_API 响应中的
overview,confirmedRevenueSHALL 近似等于occurrence减去discount的绝对值(在浮点精度范围内),验证收入确认公式 - FOR ALL BOARD_3_API 响应中的
overview,cashBalanceSHALL 近似等于cashIn减去cashOut(在浮点精度范围内),验证现金结余公式
9.4 BOARD-3 预收资产区域约束
- FOR ALL BOARD_3_API 响应(
area不等于all),rechargeSHALL 为null,验证预收资产区域隐藏规则
9.5 BOARD-3 环比开关一致性
- FOR ALL BOARD_3_API 响应(
compare=0),响应 JSON 中 SHALL 不包含任何以Compare、Down、Flat结尾的字段,验证环比开关关闭时不返回环比数据
9.6 BOARD-3 支付渠道恒等式
- FOR ALL BOARD_3_API 响应中涉及支付渠道的数据,
balance_amountSHALL 等于recharge_card_amount + gift_card_amount(DWD-DOC 强制规则 3),验证支付渠道恒等式
9.7 幂等性
- FOR ALL 相同参数的 BOARD_3_API 请求(相同
time、area、compare),在数据未变更的情况下,两次请求 SHALL 返回相同的overview.occurrence和overview.cashBalance值
9.8 BOARD-1 交叉约束
- FOR ALL BOARD_1_API 请求(
time=last_6m且sort=sv_desc),响应 SHALL 为 HTTP 400,验证不兼容参数组合的拒绝规则