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>
This commit is contained in:
Neo
2026-04-06 00:03:48 +08:00
parent 70324d8542
commit 6f8f12314f
515 changed files with 76604 additions and 7456 deletions

View File

@@ -0,0 +1,162 @@
# 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` — 验证报告(问题清单)
- 如有问题,修复后重跑验证直到全部通过