Files
Neo-ZQYY/.kiro/specs/rns1-board-apis/requirements.md

336 lines
29 KiB
Markdown
Raw Blame History

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