Files
Neo-ZQYY/docs/prd/specs/board-finance-coach-area.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

100 lines
3.7 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.
# 财务看板助教分析按区域细化 — 执行文档
> 日期2026-03-29 | 状态:待实施
## 背景
财务看板已完成区域维度重构(`board-finance-dws-area-refactor`overview/revenue 支持 9 区域过滤。助教分析板块coachAnalysis当前 area≠all 时隐藏,需要支持按区域过滤。
## 需求确认
- 展示方式A — area≠all 时自动按区域过滤,前端零改动(取消隐藏即可)
- 数据源:新建轻量 DWS 表,不改造现有 salary_calc 链路
- 跨区域:按区域拆分(同一助教在不同区域独立统计 hours
- 前端:取消隐藏,显示按区域过滤后的数据
## 数据链路
现有链路(不改动):
```
dwd_assistant_service_log → dws_assistant_daily_detail → dws_assistant_monthly_summary → dws_assistant_salary_calc
```
唯一键 `(site_id, assistant_id, stat_date/month)` 无区域维度,改造代价过大。
新增链路:
```
dwd_assistant_service_log + dim_table(area_name)
→ [CoachAreaHoursTask] → dws_coach_area_hours (新表)
后端 fdw_queries (area≠all 时 JOIN salary_calc 获取定价)
```
## 实施步骤
### 1. DDL — 创建 dws_coach_area_hours
```sql
CREATE TABLE dws.dws_coach_area_hours (
id BIGSERIAL PRIMARY KEY,
site_id BIGINT NOT NULL,
tenant_id BIGINT NOT NULL,
stat_month DATE NOT NULL,
assistant_id BIGINT NOT NULL,
area_code VARCHAR(20) NOT NULL,
base_hours NUMERIC(10,2) NOT NULL DEFAULT 0,
bonus_hours NUMERIC(10,2) NOT NULL DEFAULT 0,
room_hours NUMERIC(10,2) NOT NULL DEFAULT 0,
effective_hours NUMERIC(10,2) NOT NULL DEFAULT 0,
trashed_hours NUMERIC(10,2) NOT NULL DEFAULT 0,
base_service_count INTEGER NOT NULL DEFAULT 0,
bonus_service_count INTEGER NOT NULL DEFAULT 0,
room_service_count INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (site_id, stat_month, assistant_id, area_code)
);
CREATE OR REPLACE VIEW dws.v_dws_coach_area_hours AS
SELECT * FROM dws.dws_coach_area_hours
WHERE site_id = current_setting('app.current_site_id')::bigint;
GRANT SELECT ON dws.v_dws_coach_area_hours TO app_reader;
```
### 2. ETL 任务 — CoachAreaHoursTask
文件:`apps/etl/connectors/feiqiu/tasks/dws/coach_area_hours_task.py`
- extract`dwd_assistant_service_log` + `dwd_assistant_service_log_ex`(is_trash) + `dim_table`(scd2_is_current=1) 提取当月服务记录
- transform纯函数`resolve_area_code(area_name)` 映射区域,按 `(assistant_id, area_code)` 聚合 hours构建 hall/all 汇总行
- loaddelete-before-insert按 site_id + stat_month
- 注册到调度器
### 3. 后端改造
- `fdw_queries.py`:新增 `get_finance_coach_analysis_area(conn, site_id, start_date, end_date, area_code)`
-`v_dws_coach_area_hours` JOIN `v_dws_assistant_salary_calc` 按区域聚合
- SQL 层计算 pay = hours × course_price, share = hours × (price - deduction)
- `board_service.py``_build_coach_analysis` 接收 area_code
- area=all → 现有逻辑不变
- area≠all → 调用新查询
- 取消 `coach_analysis = None` 隐藏逻辑
### 4. 回填 + 联调
- 回填脚本:`scripts/ops/backfill_coach_area_hours.py`
- 联调验证area=all 回归 + area≠all 数据正确
### 5. 收尾
- DDL 合并到基线
- BD 手册
- 审计
## 风险
1. 助教跨区域按区域独立统计area≠all 只显示该区域 hours
2. NULL table_id计入 hall + all不计入具体区域
3. area=all 回归:必须与现有完全一致
4. salary_calc 同一助教同月可能多等级月中升级JOIN 时需注意