Files
Neo-ZQYY/docs/prd/specs/board-finance-phase2-validation.md
Neo 6f8f12314f feat: 累积功能变更 — 聊天集成、租户管理、小程序更新、ETL 增强、迁移脚本
包含多个会话的累积代码变更:
- backend: AI 聊天服务、触发器调度、认证增强、WebSocket、调度器最小间隔
- admin-web: ETL 状态页、任务管理、调度配置、登录优化
- miniprogram: 看板页面、聊天集成、UI 组件、导航更新
- etl: DWS 新任务(finance_area_daily/board_cache)、连接器增强
- tenant-admin: 项目初始化
- db: 19 个迁移脚本(etl_feiqiu 11 + zqyy_app 8)
- packages/shared: 枚举和工具函数更新
- tools: 数据库工具、报表生成、健康检查
- docs: PRD/架构/部署/合约文档更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 00:03:48 +08:00

163 lines
6.4 KiB
Markdown
Raw Permalink 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.
# SPEC: 财务看板 Phase 2 — 144 组合全量验证
> 创建日期2026-03-28
> 前置 SPEC`board-finance-phase2`(已完成 T1-T6 + bugfix
> 状态:已完成 ✅2026-03-28
> 优先级P1
---
## 一、目标
遍历财务看板全部 144 种筛选组合8 时间 × 9 区域 × 2 环比),验证后端 API 返回数据与前端 `page.data` 一致性。
## 二、组合矩阵
### 时间筛选8 种)
| 枚举值 | 显示 | 当期范围 | 上期范围 |
|--------|------|---------|---------|
| month | 本月 | 月首~今天 | 上月首~上月同日 |
| lastMonth | 上月 | 上月首~上月末 | 再上月首~再上月末 |
| week | 本周 | 周一~今天 | 上周一~上周同天 |
| lastWeek | 上周 | 上周一~上周日 | 再上周一~再上周日 |
| quarter3 | 前3个月 | 往前3月首~上月末 | 再往前等长 |
| quarter | 本季度 | 季首~今天 | 上季首~上季同天 |
| lastQuarter | 上季度 | 上季首~上季末 | 再上季首~再上季末 |
| half6 | 最近6个月 | 往前6月首~上月末 | 再往前等长 |
### 区域筛选9 种)
| 枚举值 | 显示 | 影响板块 |
|--------|------|---------|
| all | 全部区域 | 6 板块全显示 |
| hall | 大厅 | 隐藏:预收资产/现金流出/助教分析 |
| hallA | A区 | 同上 |
| hallB | B区 | 同上 |
| hallC | C区 | 同上 |
| vip | 台球包厢 | 同上 |
| snooker | 斯诺克 | 同上 |
| mahjong | 麻将房 | 同上 |
| ktv | 团建房 | 同上 |
### 环比开关2 种)
| 值 | 说明 |
|----|------|
| 0 | 关闭,环比字段为空 |
| 1 | 开启,环比字段有值 |
## 三、验证项清单
每种组合需验证以下字段(共 6 板块):
### 3.1 经营一览overview— 始终显示
| # | 字段 | 验证规则 |
|---|------|---------|
| O1 | occurrence | ≥0数字类型 |
| O2 | discount | ≥0数字类型 |
| O3 | discountRate | 0~1 之间 |
| O4 | confirmedRevenue | = occurrence - discount |
| O5 | cashIn | ≥0 |
| O6 | cashOut | ≥0 |
| O7 | cashBalance | = cashIn - cashOut |
| O8 | balanceRate | cashIn>0 时 = cashBalance/cashIn |
| O9 | area≠all 时 | occurrence/discount/confirmedRevenue 应与 revenue 板块一致 |
| O10 | compare=1 时 | 8 个 xxxCompare 字段非空,格式为 "X.X%" / "持平" / "新增" |
| O11 | compare=0 时 | 8 个 xxxCompare 字段为空/null |
### 3.2 预收资产recharge— 仅 area=all 时返回
| # | 字段 | 验证规则 |
|---|------|---------|
| R1 | area≠all 时 | recharge 为 null |
| R2 | actualIncome | ≥0 |
| R3 | firstCharge + renewCharge | ≈ actualIncome |
| R4 | cardBalance | ≥0快照值 |
| R5 | allCardBalance | ≥ cardBalance |
| R6 | giftRows | 长度 3新增/消费/余额) |
| R7 | compare=1 时 | allCardBalanceCompare 非空 |
### 3.3 应计收入确认revenue— 始终显示
| # | 字段 | 验证规则 |
|---|------|---------|
| V1 | structureRows | 长度 ≥ 3至少有主行+助教+食品) |
| V2 | area≠all 时 | structureRows 只含对应区域 |
| V3 | totalOccurrence | = SUM(structureRows 非 isSub 行的 amount) |
| V4 | discountTotal | = SUM(discountItems 的 amount) |
| V5 | confirmedTotal | = totalOccurrence - discountTotal |
| V6 | discountItems | 长度 5团购/会员折扣/手动调整/赠送卡/其他) |
| V7 | channelItems | 长度 3 |
| V8 | priceItems | 长度 3 |
| V9 | structureRows 优惠列 | 主行 discount = discountTotal子行按占比分摊 |
| V10 | compare=1 时 | totalOccurrenceCompare/confirmedTotalCompare 非空 |
| V11 | compare=1 时 | structureRows 各行 bookedCompare 非空 |
### 3.4 现金流入cashflow— 始终显示
| # | 字段 | 验证规则 |
|---|------|---------|
| C1 | consumeItems | 长度 2-3纸币/线上/团购 或 合并项/团购) |
| C2 | rechargeItems | 长度 1 |
| C3 | total | = SUM(consumeItems) + SUM(rechargeItems) |
| C4 | consumeItems 各项 | desc 非空(柜台现金收款等) |
| C5 | compare=1 时 | totalCompare 非空,各项 compare 非空 |
### 3.5 现金流出expense— 仅 area=all 时显示
| # | 字段 | 验证规则 |
|---|------|---------|
| E1 | operationItems | 长度 ≥ 3 |
| E2 | fixedItems | 长度 ≥ 4 |
| E3 | coachItems | 长度 ≥ 4 |
| E4 | platformItems | 长度 ≥ 3 |
| E5 | total | = SUM(所有 items) |
### 3.6 助教分析coachAnalysis— 仅 area=all 时显示
| # | 字段 | 验证规则 |
|---|------|---------|
| A1 | basic.rows | 长度 1-4初/中/高/星) |
| A2 | basic.totalPay | = SUM(rows.pay) |
| A3 | basic.totalShare | = SUM(rows.share) |
| A4 | basic.avgHourly | 13~28 范围(基础课) |
| A5 | incentive.rows | 长度 0-4 |
| A6 | compare=1 时 | basic/incentive 各行 payCompare/shareCompare 非空 |
## 四、执行方案
### 4.1 后端 API 验证Python 脚本)
`scripts/ops/validate_board_finance.py`,遍历 144 种组合:
1. 登录获取 tokendev-login
2. 循环调用 `GET /api/xcx/board/finance?time=X&area=Y&compare=Z`
3. 对每个响应按验证项清单检查
4. 输出问题清单到 `export/board-finance-validation.md`
### 4.2 前端 page.data 验证(微信开发者工具)
对后端验证发现问题的组合,用 `evaluate_script` 验证:
1. 连接开发者工具ws://127.0.0.1:9420
2. `page.setData({ selectedTime, selectedArea, compareEnabled })` + `page._loadData()`
3. 等待 5 秒后读取 `page.data`
4. 对比后端 API 返回值与 `page.data` 是否一致
### 4.3 优化策略
144 种组合中,很多是等价的:
- area=all 时 6 板块全显示area≠all 时只有 3 板块overview/revenue/cashflow
- compare=0 时不需要验证环比字段
- 不同区域的验证逻辑相同,只是数据不同
可以分层验证:
1. 第一层8 时间 × 2 环比 × area=all = 16 种(全板块)
2. 第二层8 时间 × 1 区域hallA 代表)× 2 环比 = 16 种(验证区域过滤)
3. 第三层:对剩余 7 个区域,只验证 month × compare=0 = 7 种(验证区域数据差异)
4. 总计16 + 16 + 7 = 39 种(覆盖所有逻辑分支)
## 五、执行环境
- 后端:`cd apps/backend && uvicorn app.main:app --reload`
- 微信开发者工具:端口 9420
- 数据库pg-etl-testtest_etl_feiqiu
- 脚本 cwd项目根目录
## 六、产出物
- `scripts/ops/validate_board_finance.py` — 验证脚本
- `export/board-finance-validation.md` — 验证报告(问题清单)
- 如有问题,修复后重跑验证直到全部通过