在前后端开发联调前 的提交20260223

This commit is contained in:
Neo
2026-02-23 23:02:20 +08:00
parent 254ccb1e77
commit fafc95e64c
1142 changed files with 10366960 additions and 36957 deletions

View File

@@ -0,0 +1,62 @@
# dwd_assistant_trash_event_ex 助教服务作废扩展表
> 生成时间2026-01-28
## 表信息
| 属性 | 值 |
|------|-----|
| Schema | dwd |
| 表名 | dwd_assistant_trash_event_ex |
| 主键 | assistant_trash_event_id |
| 主表 | dwd_assistant_trash_event |
| 记录数 | 98 |
| 说明 | 助教服务作废扩展表,记录台桌和台区名称 |
## 字段说明
| 序号 | 字段名 | 类型 | 可空 | 主键 | 说明 |
|------|--------|------|------|------|------|
| 1 | assistant_trash_event_id | BIGINT | NO | PK | 作废事件 ID → dwd_assistant_trash_event |
| 2 | table_name | VARCHAR(64) | YES | | 台桌名称。**热门值**: "888"(14), "发财"(8), "C1"(7), "M7"(6) |
| 3 | table_area_name | VARCHAR(64) | YES | | 台区名称。**枚举值**: "C区"(16), "K包"(14), "A区"(11), "发财"(8), "B区"(7), "麻将房"(7), "补时长"(7), "VIP包厢"(6) |
## 台区作废分布
| 台区名称 | 作废次数 | 占比 |
|----------|----------|------|
| C区 | 16 | 16.3% |
| K包 | 14 | 14.3% |
| A区 | 11 | 11.2% |
| 发财 | 8 | 8.2% |
| B区 | 7 | 7.1% |
| 麻将房 | 7 | 7.1% |
| 补时长 | 7 | 7.1% |
| VIP包厢 | 6 | 6.1% |
## 样本数据
| table_name | table_area_name |
|------------|-----------------|
| C1 | C区 |
| 补时长5 | 补时长 |
| VIP1 | VIP包厢 |
| 888 | K包 |
## 使用说明
**版本与最新值**
本表为事实表,无 SCD2 版本字段。
- 主表可用时间字段create_time
```sql
-- 取最新一条(按主表时间字段)
SELECT e.*
FROM dwd.dwd_assistant_trash_event m
JOIN dwd.dwd_assistant_trash_event_ex e ON m.assistant_trash_event_id = e.assistant_trash_event_id
ORDER BY m.create_time DESC NULLS LAST
LIMIT 1;
```
**使用示例**
与主表 `dwd_assistant_trash_event` 通过 `assistant_trash_event_id` 关联,提供台桌和台区名称信息。

View File

@@ -0,0 +1,85 @@
# DWD 层 DDL 同步修正 — 变更记录
> 结构性变更:修正 1 项差异(补充 1 个缺失字段定义)
## 溯源
- 日期2026-02-13Asia/Shanghai
- 工具:`scripts/compare_ddl_db.py --schema dwd --ddl-path database/schema_dwd_doc.sql`
- Direct causeDDL 对比脚本发现 `database/schema_dwd_doc.sql` 与数据库 `dwd` schema 实际状态存在 1 项差异,以数据库为准修正 DDL 文件。
## 变更内容
| Schema | 表名 | 操作 | 字段 | DDL 原定义 | 数据库实际 | 说明 |
|--------|------|------|------|-----------|-----------|------|
| `dwd` | `dwd_refund_ex` | DDL 补充字段 | `check_status` | — | `INTEGER` | 数据库中有但 DDL 中未定义(解析器 bug 导致遗漏,已修复) |
## 变更原因
1. `dwd_refund_ex.check_status`:该字段实际已存在于数据库中,对应 ODS 层 `refund_transactions.check_status`(退款审核状态)
2. DDL 解析器存在 bug 导致该字段在先前对比中被遗漏,修复解析器后重新对比发现此差异
3. 该字段由 DWD 加载任务从 ODS 层 `refund_transactions` 映射而来
## 影响范围
| 影响对象 | 影响程度 | 说明 |
|----------|----------|------|
| ETL 加载任务 | 无影响 | 本次仅修正 DDL 文档,不涉及数据库结构变更 |
| 后端 API | 无影响 | DDL 文件为文档性质,不影响运行时 |
| 小程序字段映射 | 无影响 | 小程序不直接读 DWD 层 |
| DWD 表级文档 | ⚠️ 需同步 | `BD_manual_dwd_refund_ex.md` 字段列表应包含 `check_status` |
| ODS→DWD 映射 | 无影响 | `check_status` 已在 DWD 加载映射中正确配置 |
**注意**:本次变更仅修正 DDL 文件(文档同步),数据库结构未发生任何变更。
## 回滚策略
本次为 DDL 文件修正(文档同步),无需数据库回滚。若需恢复 DDL 文件,使用 Git 回退即可:
```bash
git checkout HEAD~1 -- database/schema_dwd_doc.sql
```
若未来需要将数据库结构回退(不推荐):
```sql
-- 删除 check_status 列(会丢失已有数据)
ALTER TABLE dwd.dwd_refund_ex DROP COLUMN check_status;
```
## 验证 SQL
```sql
-- 1) 确认 dwd_refund_ex.check_status 存在且类型为 integer
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'dwd'
AND table_name = 'dwd_refund_ex'
AND column_name = 'check_status';
-- 预期1 行data_type = 'integer'
-- 2) 确认 ODS 层对应字段也存在(数据来源一致性)
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'ods'
AND table_name = 'refund_transactions'
AND column_name = 'check_status';
-- 预期1 行data_type = 'integer'
-- 3) 确认 dwd_refund_ex 表当前总列数
SELECT count(*) AS total_columns
FROM information_schema.columns
WHERE table_schema = 'dwd'
AND table_name = 'dwd_refund_ex';
-- 预期:列数包含 check_status
-- 4) 确认修正后 DDL 与数据库零差异(通过对比脚本验证)
-- python scripts/compare_ddl_db.py --schema dwd --ddl-path database/schema_dwd_doc.sql
-- 预期0 项差异
```
## 关联变更
- ODS 层同步修正:`docs/database/ODS/changes/2026-02-13_ddl_sync_ods.md``refund_transactions.check_status` 同步补充)
- DDL 文件:`database/schema_dwd_doc.sql`
- 对比结果:`docs/database/ddl_compare_results.md`

View File

@@ -0,0 +1,94 @@
# DWD 层删除 dwd_settlement_head_ex.settle_list 冗余列 — 变更记录
> 结构性变更:删除 1 张表的 1 个 JSONB 列
## 溯源
- 日期2026-02-14Asia/Shanghai
- PromptP20260214-040000 — 删除 DWD 层 dwd_settlement_head_ex 的 settle_list JSONB 列
- Direct cause`settle_list` 列存储结算明细 JSON与 ODS 层 `payload` 中的 `settleList` 对象完全重复。ODS 层 `settlelist` 列已在 `20260214_drop_ods_settlelist.sql` 中删除DWD 层该列同样冗余。结算明细可随时从 ODS `payload->'settleList'` 按需提取。
## 变更内容
| Schema | 表名 | 操作 | 列名 | 原类型 | 说明 |
|--------|------|------|------|--------|------|
| `dwd` | `dwd_settlement_head_ex` | DROP COLUMN | `settle_list` | `JSONB` | 结算明细 JSON与 ODS payload 中 settleList 重复 |
### Before / After
- Before31 个字段order_settle_id PK + 29 个业务字段 + settle_list JSONB
- After30 个字段order_settle_id PK + 29 个业务字段)
## 变更原因
1. ODS 层 `settlement_records.payload`jsonb已存储完整 API 响应,其中包含 `settleList` 对象
2. ODS 层 `settlelist` 列已在同日迁移 `20260214_drop_ods_settlelist.sql` 中删除
3. DWD 层 `settle_list` 是从 ODS `settlelist` 映射而来的副本上游已删除DWD 层同步清理
4. DWD 加载映射(`dwd_load_task.py` FACT_MAPPINGS`settle_list` 映射已移除
## 影响范围
| 影响对象 | 影响程度 | 说明 |
|----------|----------|------|
| DWD 加载任务 | ✅ 已处理 | `dwd_load_task.py` FACT_MAPPINGS 中 `dwd_settlement_head_ex``settle_list` 映射已移除 |
| DWS 汇总层 | 无影响 | DWS 层不消费 `settle_list` 列 |
| API 契约 | 无影响 | API 响应结构不变 |
| 小程序 | 无影响 | 小程序不直接读 DWD 层 |
| BD 手册 | ✅ 已处理 | `BD_manual_dwd_settlement_head_ex.md` 字段列表已不含 `settle_list` |
## 回滚策略
```sql
-- 1) 恢复列结构
ALTER TABLE dwd.dwd_settlement_head_ex ADD COLUMN settle_list JSONB;
-- 2) 从 ODS payload 回填数据
UPDATE dwd.dwd_settlement_head_ex e
SET settle_list = o.payload->'settleList'
FROM ods.settlement_records o
WHERE e.order_settle_id = o.id;
```
**注意事项**
- 回滚后 `settle_list` 列数据为 NULL必须执行回填 UPDATE
- 若 ODS 中 `payload IS NULL` 的行,对应 DWD 行的 `settle_list` 将为 NULL无法恢复
## 验证 SQL
```sql
-- 1) 确认 settle_list 列已不存在
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'dwd'
AND table_name = 'dwd_settlement_head_ex'
AND column_name = 'settle_list';
-- 预期0 行
-- 2) 确认表当前列数
SELECT count(*) AS total_columns
FROM information_schema.columns
WHERE table_schema = 'dwd'
AND table_name = 'dwd_settlement_head_ex';
-- 预期30order_settle_id + 29 个业务字段)
-- 3) 确认 ODS payload 中 settleList 仍可按需提取
SELECT count(*)
FROM ods.settlement_records
WHERE payload IS NOT NULL AND payload->'settleList' IS NOT NULL;
-- 预期:> 0结算明细数据仍可从 ODS 获取)
-- 4) 确认 DWD 表数据完整性(主表-扩展表行数一致)
SELECT
(SELECT count(*) FROM dwd.dwd_settlement_head) AS main_count,
(SELECT count(*) FROM dwd.dwd_settlement_head_ex) AS ex_count;
-- 预期:两个计数相等
```
## 迁移文件
`database/migrations/20260214_drop_dwd_settle_list.sql`
## 关联变更
- ODS 层同日变更:`database/migrations/20260214_drop_ods_settlelist.sql`(删除 `settlement_records.settlelist``recharge_settlements.settlelist`
- BD 手册 ODS 变更记录:`docs/database/ODS/changes/20260214_drop_ods_settlelist.md`

View File

@@ -0,0 +1,56 @@
# dwd_assistant_trash_event 助教服务作废主表
> 生成时间2026-01-28
## 表信息
| 属性 | 值 |
|------|-----|
| Schema | dwd |
| 表名 | dwd_assistant_trash_event |
| 主键 | assistant_trash_event_id |
| 扩展表 | dwd_assistant_trash_event_ex |
| 记录数 | 98 |
| 说明 | 助教服务作废事实表,记录被取消/作废的助教服务记录 |
## 字段说明
| 序号 | 字段名 | 类型 | 可空 | 主键 | 说明 |
|------|--------|------|------|------|------|
| 1 | assistant_trash_event_id | BIGINT | NO | PK | 作废事件 ID |
| 2 | site_id | BIGINT | YES | | 门店 ID |
| 3 | table_id | BIGINT | YES | | 台桌 ID → dim_table |
| 4 | table_area_id | BIGINT | YES | | 台区 ID |
| 5 | assistant_no | VARCHAR(32) | YES | | 助教工号/昵称。**样本值**: "七七", "乔西", "球球"等 |
| 6 | assistant_name | VARCHAR(64) | YES | | 助教名称,与 assistant_no 相同 |
| 7 | charge_minutes_raw | INTEGER | YES | | 原计费时长(秒)。**样本值**: 0, 3600=1h, 10800=3h 等 |
| 8 | abolish_amount | NUMERIC(18,2) | YES | | 作废金额(元)。**样本值**: 0.00, 190.00, 570.00 等 |
| 9 | trash_reason | VARCHAR(255) | YES | | 作废原因(当前数据全为 NULL |
| 10 | create_time | TIMESTAMPTZ | YES | | 创建时间 |
| 11 | tenant_id | BIGINT | YES | | 租户 ID |
## 使用说明
**版本与最新值**
本表为事实表,无 SCD2 版本字段。
- 可用时间字段create_time
```sql
-- 取最新一条(按时间字段倒序)
SELECT *
FROM dwd.dwd_assistant_trash_event
ORDER BY create_time DESC NULLS LAST
LIMIT 1;
```
**使用示例**
```sql
-- 助教作废金额统计
SELECT
assistant_name,
COUNT(*) AS trash_count,
SUM(abolish_amount) AS total_abolished
FROM dwd.dwd_assistant_trash_event
GROUP BY assistant_name
ORDER BY total_abolished DESC;
```

View File

@@ -0,0 +1,141 @@
# DWS 层 DDL 同步修正 — 变更记录
> 结构性变更:修正 8 项差异(补充 5 个缺失字段、2 张缺失表、1 个缺失视图)
## 溯源
- 日期2026-02-13Asia/Shanghai
- 工具:`scripts/compare_ddl_db.py --schema dws --ddl-path database/schema_dws.sql`
- Direct causeDDL 对比脚本发现 `database/schema_dws.sql` 与数据库 `dws` schema 实际状态存在 8 项差异,以数据库为准修正 DDL 文件。
## 变更内容
### 缺失字段5 项)
| Schema | 表名 | 操作 | 字段 | 数据库类型 | 说明 |
|--------|------|------|------|-----------|------|
| `dws` | `dws_assistant_daily_detail` | DDL 补充字段 | `unique_customers` | `INTEGER` | 当日服务独立客户数 |
| `dws` | `dws_assistant_daily_detail` | DDL 补充字段 | `unique_tables` | `INTEGER` | 当日服务独立台桌数 |
| `dws` | `dws_assistant_finance_analysis` | DDL 补充字段 | `unique_customers` | `INTEGER` | 统计周期内独立客户数 |
| `dws` | `dws_assistant_monthly_summary` | DDL 补充字段 | `unique_customers` | `INTEGER` | 当月服务独立客户数 |
| `dws` | `dws_assistant_monthly_summary` | DDL 补充字段 | `unique_tables` | `INTEGER` | 当月服务独立台桌数 |
### 缺失表2 张)
| Schema | 表名 | 操作 | 说明 |
|--------|------|------|------|
| `dws` | `dws_member_assistant_intimacy` | DDL 补充整表 | 会员-助教亲密度指标表,记录会员与助教的互动频次和亲密度评分 |
| `dws` | `dws_member_recall_index` | DDL 补充整表 | 会员召回指数表,记录会员流失风险和召回优先级评分 |
### 缺失视图1 个)
| Schema | 视图名 | 操作 | 说明 |
|--------|--------|------|------|
| `dws` | `v_member_recall_priority` | DDL 补充视图 | 会员召回优先级视图,基于 `dws_member_recall_index` 计算召回排序 |
## 变更原因
1. `unique_customers` / `unique_tables` 字段DWS 汇总任务在运行时动态计算并写入的统计字段DDL 文件在初始编写时遗漏
2. `dws_member_assistant_intimacy` 表:会员-助教亲密度分析功能上线时创建DDL 文件未同步更新
3. `dws_member_recall_index` 表和 `v_member_recall_priority` 视图会员召回分析功能上线时创建DDL 文件未同步更新
## 影响范围
| 影响对象 | 影响程度 | 说明 |
|----------|----------|------|
| ETL 加载任务 | 无影响 | 本次仅修正 DDL 文档,不涉及数据库结构变更 |
| DWS 汇总任务 | 无影响 | 这些表/字段已在数据库中存在并被正常使用 |
| 后端 API | 无影响 | DDL 文件为文档性质,不影响运行时 |
| 小程序字段映射 | 无影响 | 小程序通过 API 访问,不直接读 DWS 层 |
| DWS 表级文档 | ⚠️ 需同步 | 新增表需补充 BD 手册表级文档;已有表文档需补充 `unique_customers`/`unique_tables` 字段 |
| 指数算法文档 | ⚠️ 需关注 | `dws_member_assistant_intimacy``dws_member_recall_index` 涉及自定义指数算法 |
**注意**:本次变更仅修正 DDL 文件(文档同步),数据库结构未发生任何变更。
## 回滚策略
本次为 DDL 文件修正(文档同步),无需数据库回滚。若需恢复 DDL 文件,使用 Git 回退即可:
```bash
git checkout HEAD~1 -- database/schema_dws.sql
```
若未来需要将数据库结构回退(不推荐,会丢失业务数据):
```sql
-- 1) 删除补充的字段
ALTER TABLE dws.dws_assistant_daily_detail DROP COLUMN unique_customers;
ALTER TABLE dws.dws_assistant_daily_detail DROP COLUMN unique_tables;
ALTER TABLE dws.dws_assistant_finance_analysis DROP COLUMN unique_customers;
ALTER TABLE dws.dws_assistant_monthly_summary DROP COLUMN unique_customers;
ALTER TABLE dws.dws_assistant_monthly_summary DROP COLUMN unique_tables;
-- 2) 删除视图(必须先于依赖表)
DROP VIEW IF EXISTS dws.v_member_recall_priority;
-- 3) 删除补充的表
DROP TABLE IF EXISTS dws.dws_member_recall_index;
DROP TABLE IF EXISTS dws.dws_member_assistant_intimacy;
```
## 验证 SQL
```sql
-- 1) 确认 dws_assistant_daily_detail 包含 unique_customers 和 unique_tables
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'dws'
AND table_name = 'dws_assistant_daily_detail'
AND column_name IN ('unique_customers', 'unique_tables')
ORDER BY column_name;
-- 预期2 行,均为 integer
-- 2) 确认 dws_assistant_monthly_summary 包含 unique_customers 和 unique_tables
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'dws'
AND table_name = 'dws_assistant_monthly_summary'
AND column_name IN ('unique_customers', 'unique_tables')
ORDER BY column_name;
-- 预期2 行,均为 integer
-- 3) 确认 dws_assistant_finance_analysis 包含 unique_customers
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'dws'
AND table_name = 'dws_assistant_finance_analysis'
AND column_name = 'unique_customers';
-- 预期1 行data_type = 'integer'
-- 4) 确认 dws_member_assistant_intimacy 表存在
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'dws'
AND table_name = 'dws_member_assistant_intimacy';
-- 预期1 行
-- 5) 确认 dws_member_recall_index 表存在
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'dws'
AND table_name = 'dws_member_recall_index';
-- 预期1 行
-- 6) 确认 v_member_recall_priority 视图存在
SELECT table_name, table_type
FROM information_schema.tables
WHERE table_schema = 'dws'
AND table_name = 'v_member_recall_priority';
-- 预期1 行table_type = 'VIEW'
-- 7) 确认修正后 DDL 与数据库零差异(通过对比脚本验证)
-- python scripts/compare_ddl_db.py --schema dws --ddl-path database/schema_dws.sql
-- 预期0 项差异
```
## 关联变更
- ODS 层同步修正:`docs/database/ODS/changes/2026-02-13_ddl_sync_ods.md`
- DWD 层同步修正:`docs/database/DWD/changes/2026-02-13_ddl_sync_dwd.md`
- DDL 文件:`database/schema_dws.sql`
- 对比结果:`docs/database/ddl_compare_results.md`

View File

@@ -0,0 +1,96 @@
# ODS 层 DDL 同步修正 — 变更记录
> 结构性变更:修正 4 项差异(删除 2 个冗余字段、修正 1 个字段类型、补充 1 个缺失字段)
## 溯源
- 日期2026-02-13Asia/Shanghai
- 工具:`scripts/compare_ddl_db.py --schema ods --ddl-path database/schema_ODS_doc.sql`
- Direct causeDDL 对比脚本发现 `database/schema_ODS_doc.sql` 与数据库 `ods` schema 实际状态存在 4 项差异,以数据库为准修正 DDL 文件。
## 变更内容
| Schema | 表名 | 操作 | 字段 | DDL 原定义 | 数据库实际 | 说明 |
|--------|------|------|------|-----------|-----------|------|
| `ods` | `recharge_settlements` | DDL 删除字段 | `settlelist` | `jsonb` | — | DDL 中有但数据库中不存在,属冗余定义 |
| `ods` | `settlement_records` | DDL 删除字段 | `settlelist` | `jsonb` | — | DDL 中有但数据库中不存在,属冗余定义 |
| `ods` | `tenant_goods_master` | DDL 修正类型 | `not_sale` | `BOOLEAN` | `INTEGER` | 字段类型不匹配,以数据库为准 |
| `ods` | `refund_transactions` | DDL 补充字段 | `check_status` | — | `INTEGER` | 数据库中有但 DDL 中未定义 |
## 变更原因
1. `recharge_settlements.settlelist``settlement_records.settlelist`DDL 文件中残留的字段定义,数据库中已在先前迁移(`20260214_drop_ods_settlelist.sql`中删除DDL 未同步清理
2. `tenant_goods_master.not_sale`DDL 定义为 `BOOLEAN`,但数据库实际为 `INTEGER`0/1 表示是否停售),以数据库为准修正
3. `refund_transactions.check_status`数据库中存在的审核状态字段DDL 文件中遗漏未定义
## 影响范围
| 影响对象 | 影响程度 | 说明 |
|----------|----------|------|
| ETL 加载任务 | 无影响 | 本次仅修正 DDL 文档,不涉及数据库结构变更 |
| 后端 API | 无影响 | DDL 文件为文档性质,不影响运行时 |
| 小程序字段映射 | 无影响 | 小程序不直接读 ODS 层 |
| ODS 表级文档 | ⚠️ 需同步 | 后续生成 ODS 表级文档时应以修正后的 DDL 为准 |
| DWD 加载映射 | 无影响 | `refund_transactions.check_status` 已在 DWD 层有对应映射 |
**注意**:本次变更仅修正 DDL 文件(文档同步),数据库结构未发生任何变更。数据库是"源头"DDL 文件是"文档"。
## 回滚策略
本次为 DDL 文件修正(文档同步),无需数据库回滚。若需恢复 DDL 文件,使用 Git 回退即可:
```bash
git checkout HEAD~1 -- database/schema_ODS_doc.sql
```
若未来需要将数据库结构回退到 DDL 修正前的状态(不推荐):
```sql
-- 1) 恢复 settlelist 列(数据不可恢复)
ALTER TABLE ods.recharge_settlements ADD COLUMN settlelist JSONB;
ALTER TABLE ods.settlement_records ADD COLUMN settlelist JSONB;
-- 2) 将 not_sale 改回 BOOLEAN需数据转换
ALTER TABLE ods.tenant_goods_master
ALTER COLUMN not_sale TYPE BOOLEAN USING (not_sale::INTEGER != 0);
-- 3) 删除 check_status 列
ALTER TABLE ods.refund_transactions DROP COLUMN check_status;
```
## 验证 SQL
```sql
-- 1) 确认 settlelist 列在数据库中确实不存在
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'ods'
AND table_name IN ('recharge_settlements', 'settlement_records')
AND column_name = 'settlelist';
-- 预期0 行
-- 2) 确认 tenant_goods_master.not_sale 实际类型为 integer
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'ods'
AND table_name = 'tenant_goods_master'
AND column_name = 'not_sale';
-- 预期data_type = 'integer'
-- 3) 确认 refund_transactions.check_status 存在且类型为 integer
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'ods'
AND table_name = 'refund_transactions'
AND column_name = 'check_status';
-- 预期1 行data_type = 'integer'
-- 4) 确认修正后 DDL 与数据库零差异(通过对比脚本验证)
-- python scripts/compare_ddl_db.py --schema ods --ddl-path database/schema_ODS_doc.sql
-- 预期0 项差异
```
## 关联文件
- DDL 文件:`database/schema_ODS_doc.sql`
- 对比结果:`docs/database/ddl_compare_results.md`

View File

@@ -0,0 +1,39 @@
# ODS 表与 API JSON 字段对齐 — 变更记录
> 无结构性变更
## 溯源
- 日期2026-02-13Asia/Shanghai
- PromptP20260213-210000 — 用新梳理的 API 返回 JSON 文档比对数据库 ODS 层
- Direct cause`scripts/compare_api_ods.py` 自动比对 22 张 ODS 表与 `docs/api-reference/` 文档中的 JSON 字段,结论为全部对齐,无需 ALTER
## 说明
迁移文件 `database/migrations/20260213_align_ods_with_api.sql` 为比对结论记录,不包含任何 DDL 语句。
- 比对范围:`ods` schema 下 22 张表
- 比对逻辑camelCase → snake_case 归一化匹配 + 去下划线纯小写兜底
- 结论:所有 ODS 表列已与 API JSON 响应字段完全对齐
- `stock_goods_category_tree``goodsCategoryList`/`total` 为响应包装层字段ODS 表已正确展开存储数组内的记录级字段,无需额外列
## 验证 SQL
```sql
-- 1) 确认 ods schema 下表数量
SELECT count(*) FROM information_schema.tables
WHERE table_schema = 'ods' AND table_type = 'BASE TABLE';
-- 2) 确认迁移文件未引入新列(对比前后列数应一致)
SELECT table_name, count(*) AS col_count
FROM information_schema.columns
WHERE table_schema = 'ods'
GROUP BY table_name
ORDER BY table_name;
-- 3) 确认无待执行的 pending migration迁移文件为纯注释不应产生任何变更
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'ods' AND table_name = 'assistant_accounts_master'
ORDER BY ordinal_position;
```

View File

@@ -0,0 +1,111 @@
# ODS 层删除 option_name / able_site_transfer 冗余列 — 变更记录
> 结构性变更:删除 2 张表各 1 个冗余列API JSON 中不存在ODS 全 NULL
## 溯源
- 日期2026-02-14Asia/Shanghai
- PromptP20260214-070000 — 删除 ODS 层 store_goods_sales_records.option_name 和 member_stored_value_cards.able_site_transfer
- Direct causeAPI vs ODS 比对报告v3-fixed中这两列被标注为"ODS 独有",经查证 API JSON 响应中从未返回这两个字段ODS 中全部为 NULL0 条非空数据),属于冗余列,应清理。
## 变更内容
| Schema | 表名 | 操作 | 列名 | 原类型 | 说明 |
|--------|------|------|------|--------|------|
| `ods` | `store_goods_sales_records` | DROP COLUMN | `option_name` | `text` | API 后续版本新增字段,实际从未返回数据,全 NULL |
| `ods` | `member_stored_value_cards` | DROP COLUMN | `able_site_transfer` | `integer` | API 后续版本新增字段,实际从未返回数据,全 NULL |
### Before / After
**store_goods_sales_records**
- Before52 个业务列 + 5 个 meta 列(含 `option_name text`
- After51 个业务列 + 5 个 meta 列(`option_name` 已移除)
**member_stored_value_cards**
- Before76 个业务列 + 5 个 meta 列(含 `able_site_transfer integer`
- After75 个业务列 + 5 个 meta 列(`able_site_transfer` 已移除)
## 变更原因
1. v3-fixed 比对报告显示 `option_name``able_site_transfer` 为"ODS 独有"字段
2. 全量 JSON 刷新审计100 条/接口)确认 API 响应中从未包含这两个字段
3. 数据库查询确认两列全部为 NULL无实际业务数据
4. 保留全 NULL 的冗余列会误导后续开发和数据分析
## 影响范围
| 影响对象 | 影响程度 | 说明 |
|----------|----------|------|
| ODS 抓取任务 | ⚠️ 需确认 | ODS 入库 INSERT/UPSERT 语句中若包含这两列需移除 |
| DWD 加载任务 | 无影响 | DWD 层未映射这两个字段(全 NULL 无法产生有意义的 DWD 数据) |
| API 契约 | 无影响 | API 响应结构不变,这两个字段本就不在 API 返回中 |
| 小程序 | 无影响 | 小程序不直接读 ODS 层 |
| 比对报告 | 需更新 | `docs/reports/api_ods_comparison_v3_fixed.md` 中两表的 ODS 独有字段需移除 |
## 回滚策略
```sql
-- 恢复列结构(数据不可恢复,因原始数据全为 NULL
ALTER TABLE ods.store_goods_sales_records ADD COLUMN option_name TEXT;
ALTER TABLE ods.member_stored_value_cards ADD COLUMN able_site_transfer INTEGER;
```
**注意事项**
- 回滚后两列数据均为 NULL与删除前一致无数据丢失风险
- 若未来 API 版本开始返回这两个字段,需重新 ADD COLUMN 并更新 ODS 入库逻辑
## 验证 SQL
```sql
-- 1) 确认 option_name 列已不存在
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'ods'
AND table_name = 'store_goods_sales_records'
AND column_name = 'option_name';
-- 预期0 行
-- 2) 确认 able_site_transfer 列已不存在
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'ods'
AND table_name = 'member_stored_value_cards'
AND column_name = 'able_site_transfer';
-- 预期0 行
-- 3) 确认两表当前列数
SELECT table_name, count(*) AS total_columns
FROM information_schema.columns
WHERE table_schema = 'ods'
AND table_name IN ('store_goods_sales_records', 'member_stored_value_cards')
GROUP BY table_name;
-- 预期store_goods_sales_records = 5651 业务 + 5 metamember_stored_value_cards = 8075 业务 + 5 meta
-- 4) 确认删除前数据确实全 NULL回溯验证迁移执行前运行
-- SELECT count(*) FROM ods.store_goods_sales_records WHERE option_name IS NOT NULL;
-- SELECT count(*) FROM ods.member_stored_value_cards WHERE able_site_transfer IS NOT NULL;
-- 预期:均为 0
```
## 迁移文件
`database/migrations/20260214_drop_ods_option_name_able_site_transfer.sql`
---
## 补充记录schema_ODS_doc.sql AI_CHANGELOG 标注
- 日期2026-02-14Asia/Shanghai
- PromptP20260214-070000同上
- 变更内容:在 `database/schema_ODS_doc.sql` 末尾追加 AI_CHANGELOG 注释块,记录 option_name / able_site_transfer 两列在 DDL 文档中的注释化处理
- 结论:**无结构性变更**(仅追加 SQL 注释,不涉及 DDL 操作)
<!--
AI_CHANGELOG:
- 日期: 2026-02-14
- Prompt: P20260214-070000 — ODS 清理与文档标注5 项任务)
- 直接原因: DB schema 变更(删除 2 列)必须同步 BD Manual
- 变更摘要: 新建 ODS 层变更记录文档,记录 option_name 和 able_site_transfer 的删除原因、影响、回滚策略和验证 SQL
- 风险与验证: 纯文档;验证:验证 SQL 执行结果与预期一致
-->

View File

@@ -0,0 +1,102 @@
# ODS 层删除 settlelist 冗余列 — 变更记录
> 结构性变更:删除 2 张表的 1 个 jsonb 列
## 溯源
- 日期2026-02-14Asia/Shanghai
- PromptP20260214-023000 — 删除 ODS 层 settlement_records / recharge_settlements 的 settlelist jsonb 列
- Direct cause`settlelist` 列与 `payload` 列数据完全重复(`payload` 存储完整 API 响应 JSON已包含 `settleList` 对象属于冗余存储。DWD 加载逻辑已改为从 `payload` 提取 `settleList`,该列不再被任何下游消费。
## 变更内容
| Schema | 表名 | 操作 | 列名 | 原类型 | 说明 |
|--------|------|------|------|--------|------|
| `ods` | `settlement_records` | DROP COLUMN | `settlelist` | `jsonb` | 存储原始 settleList 对象,与 payload 重复 |
| `ods` | `recharge_settlements` | DROP COLUMN | `settlelist` | `jsonb` | 存储原始 settleList 对象,与 payload 重复 |
### Before / After
**settlement_records**
- Before67 个业务列 + 5 个 meta 列(含 `settlelist jsonb`
- After66 个业务列 + 5 个 meta 列(`settlelist` 已移除)
**recharge_settlements**
- Before67 个业务列 + 5 个 meta 列(含 `settlelist jsonb`
- After66 个业务列 + 5 个 meta 列(`settlelist` 已移除)
## 变更原因
1. `payload`jsonb已存储完整的 API 响应 JSON其中包含 `settleList` 对象
2. `settlelist` 列是 ETL 入库时从 `payload` 中额外提取并单独存储的副本,属于冗余
3. API vs ODS 比对报告v3-fixed中已标注 `settlelist` 为"ODS jsonb 列(存储原始 settleList 对象)"
4. DWD 加载逻辑已修改为直接从 `payload->'settleList'` 提取数据
## 影响范围
| 影响对象 | 影响程度 | 说明 |
|----------|----------|------|
| DWD 加载任务 | ⚠️ 需确认 | DWD 加载必须已改为从 `payload` 提取 settleList不再读 `settlelist` 列 |
| ODS 抓取任务 | ⚠️ 需确认 | ODS 入库逻辑需移除对 `settlelist` 列的写入INSERT/UPSERT 语句) |
| API 契约 | 无影响 | API 响应结构不变,仅 ODS 存储方式调整 |
| 小程序 | 无影响 | 小程序不直接读 ODS 层 |
| 比对报告 | 需更新 | `docs/reports/api_ods_comparison_v3.md``scripts/ods_columns.json` 中 settlement_records / recharge_settlements 的列清单需移除 `settlelist` |
| 比对脚本 | 需更新 | `scripts/run_compare_v3_fixed.py``classify_ods_only()``settlelist` 的特殊处理可移除 |
## 回滚策略
```sql
-- 1) 恢复列结构
ALTER TABLE ods.settlement_records ADD COLUMN settlelist jsonb;
ALTER TABLE ods.recharge_settlements ADD COLUMN settlelist jsonb;
-- 2) 从 payload 回填数据(回滚后列为 NULL需重新提取
UPDATE ods.settlement_records
SET settlelist = payload->'settleList'
WHERE payload IS NOT NULL;
UPDATE ods.recharge_settlements
SET settlelist = payload->'settleList'
WHERE payload IS NOT NULL;
```
**注意事项**
- 回滚后 `settlelist` 列数据为 NULL必须执行回填 UPDATE
- 若历史数据中存在 `payload IS NULL` 的行,这些行的 `settlelist` 将永久丢失(无法恢复)
- 回填前建议先统计 `payload IS NULL` 的行数,评估数据损失范围
## 验证 SQL
```sql
-- 1) 确认 settlelist 列已不存在
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'ods'
AND table_name IN ('settlement_records', 'recharge_settlements')
AND column_name = 'settlelist';
-- 预期0 行
-- 2) 确认 payload 列仍存在且包含 settleList 数据
SELECT count(*)
FROM ods.settlement_records
WHERE payload IS NOT NULL AND payload->'settleList' IS NOT NULL;
-- 预期:> 0确认 payload 中有 settleList 数据可用)
-- 3) 确认两表当前列数(排除 meta 列后应为 66
SELECT table_name, count(*) AS total_columns
FROM information_schema.columns
WHERE table_schema = 'ods'
AND table_name IN ('settlement_records', 'recharge_settlements')
GROUP BY table_name;
-- 预期settlement_records = 7166 业务 + 5 metarecharge_settlements = 71
-- 4) 确认 DWD 加载可从 payload 正常提取 settleList
SELECT id, (payload->'settleList') IS NOT NULL AS has_settle_list
FROM ods.settlement_records
LIMIT 5;
-- 预期has_settle_list = true至少对 payload 非空的行)
```
## 迁移文件
`database/migrations/20260214_drop_ods_settlelist.sql`

View File

@@ -0,0 +1,70 @@
# assistant_cancellation_records 助教取消/作废记录
> 生成时间2026-02-14
## 表信息
| 属性 | 值 |
|------|-----|
| Schema | ods |
| 表名 | assistant_cancellation_records |
| 主键 | id, content_hash |
| 数据来源 | export/test-json-doc/assistant_cancellation_records.json |
| 说明 | 助教作废/取消记录 |
## 字段说明
| 序号 | 字段名 | 类型 | 可空 | 说明 |
|------|--------|------|------|------|
| 1 | id | BIGINT | NO | 本表主键 ID用于唯一标识一条记录 |
| 2 | siteid | BIGINT | YES | (待补充) |
| 3 | siteprofile | JSONB | YES | (待补充) |
| 4 | assistantname | TEXT | YES | (待补充) |
| 5 | assistantabolishamount | NUMERIC(18,2) | YES | (待补充) |
| 6 | assistanton | INTEGER | YES | (待补充) |
| 7 | pdchargeminutes | INTEGER | YES | (待补充) |
| 8 | tableareaid | BIGINT | YES | (待补充) |
| 9 | tablearea | TEXT | YES | (待补充) |
| 10 | tableid | BIGINT | YES | (待补充) |
| 11 | tablename | TEXT | YES | (待补充) |
| 12 | trashreason | TEXT | YES | (待补充) |
| 13 | createtime | TIMESTAMP | YES | (待补充) |
| 14 | source_file | TEXT | YES | ETL 元数据:原始导出文件名,用于数据追溯 |
| 15 | source_endpoint | TEXT | YES | ETL 元数据:采集来源(接口/文件路径),用于数据追溯 |
| 16 | fetched_at | TIMESTAMPTZ | YES | ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理 |
| 17 | payload | JSONB | NO | ETL 元数据:完整原始 JSON 记录快照,用于回溯与二次解析 |
| 18 | content_hash | TEXT | NO | ETL 元数据:对业务字段计算 SHA256用于变更检测与去重 |
| 19 | tenant_id | BIGINT | YES | 租户ID |
## 使用说明
```sql
-- 查询最新入库的记录
SELECT * FROM ods.assistant_cancellation_records
ORDER BY fetched_at DESC
LIMIT 10;
```
```sql
-- 按业务主键查询某条记录的所有版本
SELECT * FROM ods.assistant_cancellation_records
WHERE id = <value>
ORDER BY fetched_at DESC;
```
## ETL 元数据字段
| 字段名 | 类型 | 说明 |
|--------|------|------|
| content_hash | TEXT | 对业务字段计算 SHA256用于变更检测与去重 |
| source_file | TEXT | 原始导出文件名,用于数据追溯 |
| source_endpoint | TEXT | 采集来源(接口/文件路径),用于数据追溯 |
| fetched_at | TIMESTAMPTZ | 采集/入库时间戳,用于口径对齐与增量处理 |
| payload | JSONB | 完整原始 JSON 记录快照,用于回溯与二次解析 |
## 可回溯性
| 项目 | 说明 |
|------|------|
| 可回溯 | ✅ 完全可回溯(保留 payload 原始 JSON |
| 数据来源 | export/test-json-doc/assistant_cancellation_records.json |

View File

@@ -0,0 +1,50 @@
# 助教撤销记录GetAbolitionAssistant → assistant_cancellation_records 字段映射
> 生成时间2026-02-14
## 端点信息
| 属性 | 值 |
|------|-----|
| 接口路径 | `AssistantPerformance/GetAbolitionAssistant` |
| 请求方法 | POST |
| ODS 对应表 | `ods.assistant_cancellation_records` |
| JSON 数据路径 | `data.abolitionAssistants` |
## 字段映射
| JSON 字段 | ODS 列名 | 类型转换 | 说明 |
|-----------|----------|----------|------|
| id | id | int→BIGINT`parse_int` | 本表主键 ID用于唯一标识一条记录 |
| siteId | siteId | int→BIGINT`parse_int` | 门店 ID即该废除记录所在门店 |
| siteProfile | siteProfile | object→JSONB原样存储 | 门店信息快照 |
| assistantName | assistantName | string→TEXT原样 | 助教姓名/对外展示名称 |
| assistantAbolishAmount | assistantAbolishAmount | float→NUMERIC(18,2)`parse_decimal` | 与“助教废除”关联的金额字段 |
| assistantOn | assistantOn | int→INT`parse_int` | 助教编号(工号/序号) |
| pdChargeMinutes | pdChargeMinutes | int→INT`parse_int` | “已发生的计费时长(分钟)”,即这次助教服务在被废除前已经累计了多少分钟 |
| tableAreaId | tableAreaId | int→BIGINT`parse_int` | 台桌所在区域 ID |
| tableArea | tableArea | string→TEXT原样 | 台桌所属区域名称 |
| tableId | tableId | int→BIGINT`parse_int` | 球台/桌子的 ID |
| tableName | tableName | string→TEXT原样 | 台桌名称/编号,供人阅读 |
| trashReason | trashReason | string→TEXT原样 | 用于记录“废除原因”的文本描述,例如“顾客临时有事取消”“录入错误”“更换助教”等 |
| createTime | createTime | string→TIMESTAMP`parse_timestamp` | 这条“助教废除记录”被创建的时间,即系统正式记录“废除”操作的时刻 |
| tenant_id | tenant_id | int→BIGINT`parse_int` | 租户/品牌 ID |
## ETL 补充字段
| ODS 列名 | 生成逻辑 |
|-----------|----------|
| content_hash | 对业务字段(排除 ETL 元数据列)计算 SHA-256用于变更检测与去重 |
| source_file | 固定值:`assistant_cancellation_records.json`,标识原始导出文件 |
| source_endpoint | API 端点路径,如 `AssistantPerformance/GetAbolitionAssistant` |
| fetched_at | ETL 入库时间戳(`TIMESTAMPTZ DEFAULT now()` |
| payload | 完整原始 JSON 记录快照(`JSONB NOT NULL`),用于回溯与二次解析 |
## 类型转换规则
- **时间戳**:通过 `TypeParser.parse_timestamp()` 转换,支持 ISO 字符串和 Unix 毫秒时间戳,自动处理时区
- **金额**:通过 `TypeParser.parse_decimal(value, scale=2)` 转换,`ROUND_HALF_UP` 四舍五入
- **整数**:通过 `TypeParser.parse_int()` 转换,`None` 保持为 `NULL`
- **字符串**:原样保留,`None` / 空字符串均存为 `NULL` 或空文本
- **布尔值**API 返回 `true/false`ODS 存为 `BOOLEAN``INT`0/1
- **JSONB**`siteProfile``payload` 等复合对象直接以 `JSONB` 类型存储

View File

@@ -0,0 +1,56 @@
# DDL 对比结果报告
> 生成时间2025-07-25
> 工具:`scripts/compare_ddl_db.py --all`
> 共发现 **13 项差异**
---
## 1. ods ← database/schema_ODS_doc.sql4 项差异)
| 表名 | 差异类型 | 字段 | DDL 定义 | 数据库实际 | 说明 |
|------|----------|------|----------|-----------|------|
| recharge_settlements | DDL 多字段 | settlelist | jsonb | — | DDL 中有但数据库中不存在 |
| refund_transactions | DDL 缺字段 | check_status | — | integer | 数据库中有但 DDL 中未定义 |
| settlement_records | DDL 多字段 | settlelist | jsonb | — | DDL 中有但数据库中不存在 |
| tenant_goods_master | 类型不一致 | not_sale | boolean | integer | 字段类型不匹配 |
## 2. dwd ← database/schema_dwd_doc.sql1 项差异)
| 表名 | 差异类型 | 字段 | DDL 定义 | 数据库实际 | 说明 |
|------|----------|------|----------|-----------|------|
| dwd_refund_ex | DDL 缺字段 | check_status | — | integer | 数据库中有但 DDL 中未定义 |
## 3. dws ← database/schema_dws.sql8 项差异)
| 表名 | 差异类型 | 字段 | DDL 定义 | 数据库实际 | 说明 |
|------|----------|------|----------|-----------|------|
| dws_assistant_daily_detail | DDL 缺字段 | unique_customers | — | integer | 数据库中有但 DDL 中未定义 |
| dws_assistant_daily_detail | DDL 缺字段 | unique_tables | — | integer | 数据库中有但 DDL 中未定义 |
| dws_assistant_finance_analysis | DDL 缺字段 | unique_customers | — | integer | 数据库中有但 DDL 中未定义 |
| dws_assistant_monthly_summary | DDL 缺字段 | unique_customers | — | integer | 数据库中有但 DDL 中未定义 |
| dws_assistant_monthly_summary | DDL 缺字段 | unique_tables | — | integer | 数据库中有但 DDL 中未定义 |
| dws_member_assistant_intimacy | DDL 缺表 | — | — | — | 数据库中有但 DDL 中未定义整张表 |
| dws_member_recall_index | DDL 缺表 | — | — | — | 数据库中有但 DDL 中未定义整张表 |
| v_member_recall_priority | DDL 缺表 | — | — | — | 数据库中有但 DDL 中未定义(视图) |
## 4. etl_admin ← database/schema_etl_admin.sql0 项差异)
✓ 无差异DDL 与数据库完全一致。
---
## 差异汇总
| Schema | DDL 文件 | 差异数 | 缺表 | 多字段 | 缺字段 | 类型不一致 |
|--------|----------|--------|------|--------|--------|-----------|
| ods | schema_ODS_doc.sql | 4 | 0 | 2 | 1 | 1 |
| dwd | schema_dwd_doc.sql | 1 | 0 | 0 | 1 | 0 |
| dws | schema_dws.sql | 8 | 3 | 0 | 5 | 0 |
| meta | schema_etl_admin.sql | 0 | 0 | 0 | 0 | 0 |
| **合计** | | **13** | **3** | **2** | **7** | **1** |
## 后续操作
- **任务 4.2**:以数据库实际状态为准修正上述 DDL 文件
- **任务 4.3**:在对应层的 `changes/` 目录下生成差异说明文档

View File

@@ -0,0 +1,646 @@
# DWS 数据字典
## 概述
DWSData Warehouse Service层是数据仓库的汇总层基于DWD明细层数据构建为上层应用和报表提供预聚合的数据服务。
### 表清单
| 分类 | 表名 | 说明 | 更新频率 |
|------|------|------|----------|
| **配置表** | cfg_performance_tier | 绩效档位配置 | 手动维护 |
| | cfg_assistant_level_price | 助教等级定价 | 手动维护 |
| | cfg_bonus_rules | 奖金规则配置 | 手动维护 |
| | cfg_area_category | 台区分类映射 | 手动维护 |
| | cfg_skill_type | 技能课程类型映射 | 手动维护 |
| **助教维度** | dws_assistant_daily_detail | 助教日度业绩明细 | 每小时 |
| | dws_assistant_monthly_summary | 助教月度业绩汇总 | 每日 |
| | dws_assistant_customer_stats | 助教服务客户统计 | 每日 |
| | dws_assistant_salary_calc | 助教工资计算详情 | 月初 |
| | dws_assistant_recharge_commission | 助教充值提成 | Excel导入 |
| **客户维度** | dws_member_consumption_summary | 会员消费汇总 | 每日 |
| | dws_member_visit_detail | 会员来店明细 | 每日 |
| **指数** | dws_member_winback_index | 老客挽回指数WBI | 每2小时 |
| | dws_member_newconv_index | 新客转化指数NCI | 每2小时 |
| | v_member_recall_priority | 召回/转化优先级视图 | 实时 |
| | dws_member_assistant_relation_index | 客户-助教关系指数RS/OS/MS/ML | 每4小时 |
| | dws_ml_manual_order_source | ML人工台账宽表 | 按需导入 |
| | dws_ml_manual_order_alloc | ML人工台账分摊窄表 | 按需导入 |
| | dws_member_assistant_intimacy | 客户-助教亲密指数(兼容保留) | 停用 |
| **财务维度** | dws_finance_daily_summary | 财务日度汇总 | 每小时 |
| | dws_finance_income_structure | 收入结构分析 | 每日 |
| | dws_finance_discount_detail | 优惠明细 | 每日 |
| | dws_finance_recharge_summary | 充值统计 | 每日 |
| | dws_finance_expense_summary | 支出结构 | Excel导入 |
| | dws_assistant_finance_analysis | 助教收支分析 | 每日 |
| | dws_platform_settlement | 平台回款/服务费 | Excel导入 |
| **订单汇总** | dws_order_summary | 订单汇总 | 每日 |
---
## 关系指数补充2026-02-08
1. 关系指数已切换为单任务 `DWS_RELATION_INDEX`,统一写入 `dws_member_assistant_relation_index`
2. ML 改为人工台账唯一真源:`dws_ml_manual_order_alloc`
3. last-touch 仅保留备用代码路径,默认关闭。
4. 台账导入覆盖规则30天内按天覆盖超过30天按固定纪元 `2026-01-01` 的30天桶覆盖。
## 一、配置表
### 1.1 cfg_performance_tier - 绩效档位配置
| 字段 | 类型 | 说明 |
|------|------|------|
| tier_id | SERIAL | 档位ID主键 |
| tier_code | VARCHAR(20) | 档位代码(如 T0-T4 |
| tier_name | VARCHAR(50) | 档位名称 |
| tier_level | INTEGER | 档位等级(数字越大档位越高) |
| min_hours | NUMERIC(10,2) | 最低业绩小时数阈值(>= |
| max_hours | NUMERIC(10,2) | 最高业绩小时数阈值(<NULL=无上限 |
| base_deduction | NUMERIC(10,2) | 专业课抽成(元/小时),球房从基础课扣除 |
| bonus_deduction_ratio | NUMERIC(5,4) | 打赏课抽成比例0-1球房从附加课扣除 |
| vacation_days | INTEGER | 次月可休假天数 |
| vacation_unlimited | BOOLEAN | 休假自由标记最高档为TRUE |
| is_new_hire_tier | BOOLEAN | 是否为新入职专用档位(预留,当前规则不使用) |
| effective_from | DATE | 生效起始日期 |
| effective_to | DATE | 生效截止日期 |
**档位配置2026-03-01起**
| tier_code | tier_name | 业绩阈值 | 专业课抽成 | 打赏课抽成 | 休假 |
|-----------|-----------|----------|-----------|-----------|------|
| T0 | 0档-淘汰压力 | H < 120 | 28元/时 | 50% | 3天 |
| T1 | 1档-及格档 | 120 ≤ H < 150 | 18元/时 | 40% | 4天 |
| T2 | 2档-良好档 | 150 ≤ H < 180 | 13元/时 | 35% | 5天 |
| T3 | 3档-优秀档 | 180 ≤ H < 210 | 10元/时 | 30% | 6天 |
| T4 | 4档-销冠竞争 | H ≥ 210 | 8元/时 | 25% | 休假自由 |
**业务规则:**
- 绩效档位根据有效业绩小时数(基础课+附加课)匹配
- 新入职2026-03-01起按日均×30定档入职日期>25日时最高2档T2
- 支持按时间生效,历史月份使用历史规则
### 1.2 cfg_assistant_level_price - 助教等级定价
| 字段 | 类型 | 说明 |
|------|------|------|
| price_id | SERIAL | 定价ID主键 |
| level_code | INTEGER | 等级代码8/10/20/30/40 |
| level_name | VARCHAR(20) | 等级名称 |
| base_course_price | NUMERIC(10,2) | 基础课客户支付价格(元/小时) |
| bonus_course_price | NUMERIC(10,2) | 附加课客户支付价格固定190元 |
| effective_from | DATE | 生效起始日期 |
| effective_to | DATE | 生效截止日期 |
**等级定价(客户支付价格):**
| level_code | level_name | 基础课价格 | 附加课价格 |
|------------|------------|-----------|-----------|
| 8 | 助教管理 | 98元/时 | 190元/时 |
| 10 | 初级 | 98元/时 | 190元/时 |
| 20 | 中级 | 108元/时 | 190元/时 |
| 30 | 高级 | 118元/时 | 190元/时 |
| 40 | 星级 | 138元/时 | 190元/时 |
**注意:** 此价格为客户支付价格,助教实际收入需减去档位抽成
**包厢课:** 基础课口径,统一 138元/时
### 1.3 cfg_bonus_rules - 奖金规则配置
| 字段 | 类型 | 说明 |
|------|------|------|
| rule_id | SERIAL | 规则ID主键 |
| rule_type | VARCHAR(20) | 规则类型SPRINT/TOP_RANK |
| rule_code | VARCHAR(30) | 规则代码 |
| rule_name | VARCHAR(50) | 规则名称 |
| threshold_hours | NUMERIC(10,2) | 小时数阈值(冲刺奖金) |
| rank_position | INTEGER | 排名位置Top奖金 |
| bonus_amount | NUMERIC(12,2) | 奖金金额(元) |
| is_cumulative | BOOLEAN | 是否可累计 |
| priority | INTEGER | 优先级 |
| effective_from | DATE | 生效起始日期 |
| effective_to | DATE | 生效截止日期 |
**业务规则:**
- 冲刺奖金历史口径至2026-02-28不累计取最高档
- Top3奖金2026-03-01起生效1st=1000元2nd=600元3rd=400元并列都算
### 1.4 cfg_area_category - 台区分类映射
| 字段 | 类型 | 说明 |
|------|------|------|
| category_id | SERIAL | 分类ID主键 |
| source_area_name | VARCHAR(100) | 源区域名称来自dim_table.site_table_area_name |
| category_code | VARCHAR(20) | 分类代码 |
| category_name | VARCHAR(50) | 分类名称 |
| match_type | VARCHAR(10) | 匹配类型exact/like/default |
| match_priority | INTEGER | 匹配优先级(数字越小优先级越高) |
| is_active | BOOLEAN | 是否启用 |
**分类代码基于BD_manual_dim_table.md实际数据**
| category_code | category_name | 匹配规则 |
|---------------|---------------|----------|
| BILLIARD | 普通台球区 | A区, B区, C区 |
| BILLIARD_VIP | VIP台球包厢 | VIP包厢 |
| SNOOKER | 斯诺克区 | 斯诺克区 |
| MAHJONG | 麻将房 | 麻将房 |
| KTV | KTV包间 | K包 |
| SPECIAL | 补时长专用 | 补时长 |
| OTHER | 其他区域 | 默认匹配 |
### 1.5 cfg_skill_type - 技能课程类型映射
| 字段 | 类型 | 说明 |
|------|------|------|
| skill_type_id | SERIAL | 映射ID主键 |
| skill_id | BIGINT | 技能ID |
| skill_name | VARCHAR(50) | 技能名称 |
| course_type_code | VARCHAR(10) | 课程类型代码 |
| course_type_name | VARCHAR(20) | 课程类型名称 |
| is_active | BOOLEAN | 是否启用 |
**课程类型:**
- BASE = 基础课/陪打
- BONUS = 附加课/超休
---
## 二、助教维度表
### 2.1 dws_assistant_daily_detail - 助教日度业绩明细
**粒度:** 助教 + 日期
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| site_id | BIGINT | 门店ID |
| tenant_id | BIGINT | 租户ID |
| assistant_id | BIGINT | 助教ID |
| assistant_nickname | VARCHAR(50) | 助教花名 |
| stat_date | DATE | 统计日期 |
| assistant_level_code | INTEGER | 助教等级代码SCD2 as-of |
| assistant_level_name | VARCHAR(20) | 助教等级名称 |
| total_service_count | INTEGER | 总服务次数 |
| base_service_count | INTEGER | 基础课服务次数 |
| bonus_service_count | INTEGER | 附加课服务次数 |
| total_seconds | INTEGER | 总计费时长(秒) |
| base_seconds | INTEGER | 基础课计费时长 |
| bonus_seconds | INTEGER | 附加课计费时长 |
| total_hours | NUMERIC(10,2) | 总计费小时数 |
| base_hours | NUMERIC(10,2) | 基础课小时数 |
| bonus_hours | NUMERIC(10,2) | 附加课小时数 |
| total_ledger_amount | NUMERIC(12,2) | 总计费金额 |
| base_ledger_amount | NUMERIC(12,2) | 基础课计费金额 |
| bonus_ledger_amount | NUMERIC(12,2) | 附加课计费金额 |
| unique_customers | INTEGER | 服务客户数(去重) |
| unique_tables | INTEGER | 服务台桌数(去重) |
| trashed_seconds | INTEGER | 被废除的服务时长 |
| trashed_count | INTEGER | 被废除的服务次数 |
**数据来源:** dwd_assistant_service_log + dwd_assistant_trash_event
### 2.2 dws_assistant_monthly_summary - 助教月度业绩汇总
**粒度:** 助教 + 月份
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| site_id | BIGINT | 门店ID |
| assistant_id | BIGINT | 助教ID |
| stat_month | DATE | 统计月份(月第一天) |
| hire_date | DATE | 入职日期 |
| is_new_hire | BOOLEAN | 是否新入职 |
| work_days | INTEGER | 有服务天数 |
| total_hours | NUMERIC(10,2) | 总计费小时数 |
| base_hours | NUMERIC(10,2) | 基础课小时数 |
| bonus_hours | NUMERIC(10,2) | 附加课小时数 |
| effective_hours | NUMERIC(10,2) | 有效业绩小时数 |
| trashed_hours | NUMERIC(10,2) | 被废除小时数 |
| tier_id | INTEGER | 档位ID |
| tier_code | VARCHAR(20) | 档位代码 |
| tier_name | VARCHAR(50) | 档位名称 |
| rank_by_hours | INTEGER | 月度排名 |
| rank_with_ties | INTEGER | 考虑并列的排名 |
**业务规则:**
- 有效业绩 = total_hours - trashed_hours
- 新入职判断:入职日期 >= 月1日0点
- 排名按effective_hours降序并列都算
### 2.3 dws_assistant_customer_stats - 助教服务客户统计
**粒度:** 助教 + 客户 + 统计日期
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| assistant_id | BIGINT | 助教ID |
| member_id | BIGINT | 客户ID |
| stat_date | DATE | 统计基准日期 |
| first_service_date | DATE | 首次服务日期 |
| last_service_date | DATE | 最近服务日期 |
| total_service_count | INTEGER | 累计服务次数 |
| total_service_hours | NUMERIC(10,2) | 累计服务小时数 |
| service_count_7d | INTEGER | 近7天服务次数 |
| service_count_30d | INTEGER | 近30天服务次数 |
| service_count_90d | INTEGER | 近90天服务次数 |
| is_active_7d | BOOLEAN | 近7天是否活跃 |
| is_active_30d | BOOLEAN | 近30天是否活跃 |
**业务规则:**
- 散客member_id=0不进入此表
- 滚动窗口7/10/15/30/60/90天
### 2.4 dws_assistant_salary_calc - 助教工资计算详情
**粒度:** 助教 + 工资月份
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| assistant_id | BIGINT | 助教ID |
| assistant_nickname | VARCHAR(50) | 助教花名 |
| salary_month | DATE | 工资月份(月第一天) |
| assistant_level_code | INTEGER | 助教等级代码8/10/20/30/40 |
| assistant_level_name | VARCHAR(20) | 助教等级名称 |
| hire_date | DATE | 入职日期 |
| is_new_hire | BOOLEAN | 是否新入职 |
| effective_hours | NUMERIC(10,2) | 有效业绩小时数(基础课+附加课-废除) |
| base_hours | NUMERIC(10,2) | 基础课/专业课小时数 |
| bonus_hours | NUMERIC(10,2) | 附加课/打赏课小时数 |
| tier_id | INTEGER | 档位ID |
| tier_code | VARCHAR(20) | 档位代码(如 T0-T4 |
| tier_name | VARCHAR(50) | 档位名称 |
| rank_with_ties | INTEGER | 月度排名考虑并列用于Top3奖金 |
| base_course_price | NUMERIC(10,2) | 基础课客户支付价格98/108/118/138 |
| bonus_course_price | NUMERIC(10,2) | 附加课客户支付价格固定190 |
| base_deduction | NUMERIC(10,2) | 专业课抽成(元/小时),档位决定 |
| bonus_deduction_ratio | NUMERIC(5,4) | 打赏课抽成比例0-1档位决定 |
| base_income | NUMERIC(12,2) | 基础课收入 |
| bonus_income | NUMERIC(12,2) | 附加课收入 |
| total_course_income | NUMERIC(12,2) | 课时收入合计 |
| sprint_bonus | NUMERIC(12,2) | 冲刺奖金(历史/按规则配置) |
| top_rank_bonus | NUMERIC(12,2) | Top3排名奖金1st:1000, 2nd:600, 3rd:400 |
| recharge_commission | NUMERIC(12,2) | 充值提成 |
| other_bonus | NUMERIC(12,2) | 其他奖金(手动调整) |
| total_bonus | NUMERIC(12,2) | 奖金合计 |
| gross_salary | NUMERIC(12,2) | 应发工资 |
| vacation_days | INTEGER | 次月可休假天数 |
| vacation_unlimited | BOOLEAN | 休假自由标记最高档为TRUE |
| calc_notes | TEXT | 计算备注(异常说明等) |
**工资计算公式来自DWS数据库处理需求.md**
```
基础课收入 = 基础课小时数 × (客户支付价格 - 专业课抽成)
附加课收入 = 附加课小时数 × 190 × (1 - 打赏课抽成比例)
包厢课收入 = 包厢课小时数 × (138 - 专业课抽成)
应发工资 = 课时收入 + 奖金
```
**计算示例中级助教185小时3档**
- 基础课170小时: 170 × (108 - 10) = 16,660元
- 附加课15小时: 15 × 190 × (1 - 0.30) = 1,995元
- 课时收入: 18,655元
- Top3奖金未进入Top3: 0元
- 应发工资: 18,655元
---
## 三、客户维度表
### 3.1 dws_member_consumption_summary - 会员消费汇总
**粒度:** 会员 + 统计日期
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| member_id | BIGINT | 会员ID |
| stat_date | DATE | 统计基准日期 |
| first_consume_date | DATE | 首次消费日期 |
| last_consume_date | DATE | 最近消费日期 |
| total_visit_count | INTEGER | 累计到店次数 |
| total_consume_amount | NUMERIC(14,2) | 累计消费金额 |
| visit_count_7d | INTEGER | 近7天到店次数 |
| visit_count_30d | INTEGER | 近30天到店次数 |
| consume_amount_30d | NUMERIC(14,2) | 近30天消费金额 |
| cash_card_balance | NUMERIC(14,2) | 储值卡余额 |
| gift_card_balance | NUMERIC(14,2) | 赠送卡余额 |
| customer_tier | VARCHAR(20) | 客户分层 |
**客户分层规则:**
- 高价值90天内消费>=3次 且 消费金额>=1000
- 中等30天内有消费
- 低活跃90天内有消费但30天内无消费
- 流失90天内无消费
### 3.2 dws_member_visit_detail - 会员来店明细
**粒度:** 会员 + 订单
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| member_id | BIGINT | 会员ID |
| order_settle_id | BIGINT | 结账单ID |
| visit_date | DATE | 来店日期 |
| table_name | VARCHAR(50) | 台桌名称 |
| area_category | VARCHAR(20) | 区域分类 |
| table_fee | NUMERIC(12,2) | 台费 |
| goods_amount | NUMERIC(12,2) | 商品金额 |
| assistant_amount | NUMERIC(12,2) | 助教服务金额 |
| total_consume | NUMERIC(12,2) | 消费总额 |
| actual_pay | NUMERIC(12,2) | 实付金额 |
| assistant_services | JSONB | 助教服务明细JSON |
---
## 四、财务维度表
### 4.1 dws_finance_daily_summary - 财务日度汇总
**粒度:** 日期
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| stat_date | DATE | 统计日期 |
| gross_amount | NUMERIC(14,2) | 发生额合计 |
| table_fee_amount | NUMERIC(14,2) | 台费正价 |
| goods_amount | NUMERIC(14,2) | 商品正价 |
| assistant_pd_amount | NUMERIC(14,2) | 助教基础课正价 |
| assistant_cx_amount | NUMERIC(14,2) | 助教激励课正价 |
| discount_total | NUMERIC(14,2) | 优惠合计 |
| discount_groupbuy | NUMERIC(14,2) | 团购优惠 |
| discount_vip | NUMERIC(14,2) | 会员折扣 |
| discount_gift_card | NUMERIC(14,2) | 赠送卡抵扣 |
| discount_manual | NUMERIC(14,2) | 手动调整 |
| discount_rounding | NUMERIC(14,2) | 抹零 |
| discount_other | NUMERIC(14,2) | 其他优惠(手动调整拆分) |
| confirmed_income | NUMERIC(14,2) | 确认收入 |
| cash_inflow_total | NUMERIC(14,2) | 现金流入合计 |
| cash_pay_amount | NUMERIC(14,2) | 收银实付 |
| groupbuy_pay_amount | NUMERIC(14,2) | 团购支付金额 |
| platform_settlement_amount | NUMERIC(14,2) | 平台回款金额 |
| platform_fee_amount | NUMERIC(14,2) | 平台服务费+佣金 |
| recharge_cash_inflow | NUMERIC(14,2) | 充值现金流入 |
| card_consume_total | NUMERIC(14,2) | 卡消费合计 |
| cash_card_consume | NUMERIC(14,2) | 储值卡消费 |
| gift_card_consume | NUMERIC(14,2) | 赠送卡消费 |
| cash_outflow_total | NUMERIC(14,2) | 现金流出合计 |
| cash_balance_change | NUMERIC(14,2) | 现金结余 |
| recharge_count | INTEGER | 充值笔数 |
| recharge_total | NUMERIC(14,2) | 充值总额 |
| recharge_cash | NUMERIC(14,2) | 充值现金部分 |
| recharge_gift | NUMERIC(14,2) | 充值赠送部分 |
| first_recharge_count | INTEGER | 首充笔数 |
| renewal_count | INTEGER | 续充笔数 |
| order_count | INTEGER | 结账单数 |
| member_order_count | INTEGER | 会员订单数 |
| guest_order_count | INTEGER | 散客订单数 |
| avg_order_amount | NUMERIC(12,2) | 平均客单价 |
**计算公式:**
- 发生额 = table_charge_money + goods_money + assistant_pd_money + assistant_cx_money
- 团购支付金额 = pl_coupon_sale_amount > 0 ? pl_coupon_sale_amount : groupbuy_redemption.ledger_unit_price
- 团购优惠 = coupon_amount - 团购支付金额
- 优惠合计 = 团购优惠 + 会员折扣 + 赠送卡抵扣 + 手动调整 + 抹零
- 其他优惠 = adjust_amount - 大客户优惠不足0按0处理
- 确认收入 = 发生额 - 优惠合计
- 平台回款金额 = dws_platform_settlement.settlement_amount若无导入则使用团购支付金额
- 平台服务费 = commission_amount + service_fee
- 现金流入合计 = 收银实付 + 平台回款金额 + 充值现金流入
- 现金流出合计 = 支出汇总 + 平台服务费
- 现金结余 = 现金流入合计 - 现金流出合计
**财务指标数据来源矩阵(字段 → 来源 → 口径)**
| 字段 | 来源表 | 口径说明 |
|------|--------|----------|
| gross_amount | dwd_settlement_head | table_charge_money + goods_money + assistant_pd_money + assistant_cx_money |
| discount_groupbuy | dwd_settlement_head + dwd_groupbuy_redemption | coupon_amount - 团购支付金额 |
| discount_vip | dwd_settlement_head | member_discount_amount |
| discount_gift_card | dwd_settlement_head | gift_card_amount |
| discount_manual | dwd_settlement_head | adjust_amount手动调整总额 |
| discount_rounding | dwd_settlement_head | rounding_amount |
| discount_other | dwd_settlement_head | adjust_amount - 大客户优惠(配置映射) |
| confirmed_income | dwd_settlement_head | gross_amount - discount_total |
| cash_pay_amount | dwd_settlement_head | pay_amount收银实付 |
| groupbuy_pay_amount | dwd_settlement_head + dwd_groupbuy_redemption | pl_coupon_sale_amount 或 ledger_unit_price |
| platform_settlement_amount | dws_platform_settlement | settlement_amountExcel导入 |
| platform_fee_amount | dws_platform_settlement | commission_amount + service_fee |
| recharge_cash_inflow | dwd_recharge_order | pay_money现金充值 |
| cash_inflow_total | dwd_settlement_head + dws_platform_settlement + dwd_recharge_order | 收银实付 + 平台回款 + 充值现金 |
| cash_outflow_total | dws_finance_expense_summary + dws_platform_settlement | 支出汇总 + 平台服务费 |
| cash_balance_change | dws_finance_daily_summary | cash_inflow_total - cash_outflow_total |
### 4.2 dws_finance_recharge_summary - 充值统计
**粒度:** 日期
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| stat_date | DATE | 统计日期 |
| recharge_count | INTEGER | 充值笔数 |
| recharge_total | NUMERIC(14,2) | 充值总额(含赠送) |
| recharge_cash | NUMERIC(14,2) | 现金充值金额 |
| recharge_gift | NUMERIC(14,2) | 赠送金额 |
| first_recharge_count | INTEGER | 首充笔数 |
| first_recharge_cash | NUMERIC(14,2) | 首充现金 |
| renewal_count | INTEGER | 续充笔数 |
| renewal_cash | NUMERIC(14,2) | 续充现金 |
| cash_card_balance | NUMERIC(14,2) | 储值卡余额 |
| gift_card_balance | NUMERIC(14,2) | 赠送卡余额 |
**数据来源:** dwd_recharge_orderis_first字段区分首充/续充)
### 4.3 dws_finance_income_structure - 收入结构分析
**粒度:** 日期 + 结构类型 + 分类
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| stat_date | DATE | 统计日期 |
| structure_type | VARCHAR(20) | 结构类型INCOME_TYPE/AREA |
| category_code | VARCHAR(30) | 分类代码 |
| category_name | VARCHAR(50) | 分类名称 |
| income_amount | NUMERIC(14,2) | 收入金额 |
| income_ratio | NUMERIC(5,4) | 收入占比 |
| order_count | INTEGER | 订单数 |
| duration_minutes | INTEGER | 时长(分钟) |
**结构类型说明:**
1. **INCOME_TYPE按收入类型**
- TABLE_FEE = 台费收入
- GOODS = 商品收入
- ASSISTANT_BASE = 助教基础课
- ASSISTANT_BONUS = 助教附加课
2. **AREA按区域**
- 使用cfg_area_category映射BILLIARD/BILLIARD_VIP/SNOOKER/MAHJONG/KTV/OTHER
**数据来源:** dwd_settlement_head, dwd_table_fee_log, dwd_assistant_service_log
### 4.4 dws_finance_discount_detail - 优惠明细
**粒度:** 日期 + 优惠类型
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| stat_date | DATE | 统计日期 |
| discount_type_code | VARCHAR(30) | 优惠类型代码 |
| discount_type_name | VARCHAR(50) | 优惠类型名称 |
| discount_amount | NUMERIC(14,2) | 优惠金额 |
| discount_ratio | NUMERIC(5,4) | 优惠占比(占总优惠) |
| usage_count | INTEGER | 使用次数 |
| affected_orders | INTEGER | 影响订单数 |
**优惠类型:**
- GROUPBUY = 团购优惠coupon_amount - 团购实付金额)
- VIP = 会员折扣member_discount_amount
- GIFT_CARD = 赠送卡抵扣gift_card_amount
- ROUNDING = 抹零rounding_amount
- BIG_CUSTOMER = 大客户优惠(基于配置映射的手动调整)
- OTHER = 其他优惠(手动调整中除大客户外部分)
**数据来源:** dwd_settlement_head, dwd_groupbuy_redemption
### 4.5 dws_finance_expense_summary - 支出结构Excel导入
**粒度:** 月份 + 支出类型
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| expense_month | DATE | 支出月份 |
| expense_type_code | VARCHAR(30) | 支出类型代码 |
| expense_type_name | VARCHAR(50) | 支出类型名称 |
| expense_category | VARCHAR(20) | 支出大类 |
| expense_amount | NUMERIC(14,2) | 支出金额 |
| import_batch_no | VARCHAR(50) | 导入批次号 |
**支出类型:**
- RENT = 房租
- UTILITY = 水电费
- PROPERTY = 物业费
- SALARY = 工资
- REIMBURSE = 报销
- PLATFORM_FEE = 平台服务费
- OTHER = 其他
### 4.6 dws_platform_settlement - 平台回款Excel导入
**粒度:** 回款日期 + 平台 + 订单
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| settlement_date | DATE | 回款日期 |
| platform_type | VARCHAR(30) | 平台类型 |
| platform_name | VARCHAR(50) | 平台名称 |
| platform_order_no | VARCHAR(100) | 平台订单号 |
| order_settle_id | BIGINT | 关联的结账单ID |
| settlement_amount | NUMERIC(14,2) | 回款金额 |
| commission_amount | NUMERIC(14,2) | 佣金 |
| service_fee | NUMERIC(14,2) | 服务费 |
| gross_amount | NUMERIC(14,2) | 订单原始金额 |
| import_batch_no | VARCHAR(50) | 导入批次号 |
---
## 五、订单汇总
### 5.1 dws_order_summary - 订单汇总
**粒度:** 订单(结账单)
| 字段 | 类型 | 说明 |
|------|------|------|
| site_id | BIGINT | 门店ID |
| order_settle_id | BIGINT | 结账单ID |
| order_trade_no | VARCHAR(64) | 订单交易号 |
| order_date | DATE | 订单日期pay_time/create_time |
| tenant_id | BIGINT | 租户ID |
| member_id | BIGINT | 会员ID散客为0或NULL |
| member_flag | BOOLEAN | 是否会员订单 |
| recharge_order_flag | BOOLEAN | 是否充值订单(消费金额=0且实付>0 |
| item_count | INTEGER | 商品项数 |
| total_item_quantity | INTEGER | 商品总数量 |
| table_fee_amount | NUMERIC(14,2) | 台费实际金额 |
| assistant_service_amount | NUMERIC(14,2) | 助教服务实际金额 |
| goods_amount | NUMERIC(14,2) | 商品实际金额 |
| group_amount | NUMERIC(14,2) | 团购核销金额 |
| total_coupon_deduction | NUMERIC(14,2) | 券/团购抵扣 |
| member_discount_amount | NUMERIC(14,2) | 会员折扣 |
| manual_discount_amount | NUMERIC(14,2) | 手工调价 |
| order_original_amount | NUMERIC(14,2) | 原价估算(实付+优惠) |
| order_final_amount | NUMERIC(14,2) | 实付金额 |
| stored_card_deduct | NUMERIC(14,2) | 卡类抵扣(储值/充值/赠送) |
| external_paid_amount | NUMERIC(14,2) | 外部支付金额(实付-卡类抵扣) |
| total_paid_amount | NUMERIC(14,2) | 总实付金额 |
| book_table_flow | NUMERIC(14,2) | 台费流水 |
| book_assistant_flow | NUMERIC(14,2) | 助教流水 |
| book_goods_flow | NUMERIC(14,2) | 商品流水 |
| book_group_flow | NUMERIC(14,2) | 团购流水 |
| book_order_flow | NUMERIC(14,2) | 订单总流水 |
| order_effective_consume_cash | NUMERIC(14,2) | 有效消费现金 |
| order_effective_recharge_cash | NUMERIC(14,2) | 有效充值现金当前为0 |
| order_effective_flow | NUMERIC(14,2) | 有效流水 |
| refund_amount | NUMERIC(14,2) | 退款金额 |
| net_income | NUMERIC(14,2) | 净收入(实付-退款) |
| created_at | TIMESTAMPTZ | 创建时间 |
| updated_at | TIMESTAMPTZ | 更新时间 |
**数据来源:** dwd_settlement_head、dwd_table_fee_log、dwd_assistant_service_log、dwd_store_goods_sale、dwd_groupbuy_redemption、dwd_refund
---
## 六、时间分层机制
### 6.1 时间口径定义
| 时间窗口 | 说明 | 边界规则 |
|----------|------|----------|
| 本周 | 从本周一到今天 | 周起始日为周一 |
| 上周 | 上周一到上周日 | 完整7天 |
| 本月 | 从月1日到今天 | 月第一天0点起 |
| 上月 | 上月完整月份 | 完整自然月 |
| 前3个月不含本月 | 三个月前月初到上月末 | 不含当前月 |
| 前3个月含本月 | 两个月前月初到今天 | 含当前月 |
| 本季度 | 季度第一月1日到今天 | 季度起始 |
| 上季度 | 上季度完整三个月 | 完整自然季 |
| 最近半年 | 往前6个月不含本月 | 不含当前月 |
### 6.2 滚动窗口
支持以下滚动窗口统计:
- 近7天
- 近10天
- 近15天
- 近30天
- 近60天
- 近90天
### 6.3 环比计算
环比规则:对比上一个等长区间
- 如查询1月1日-1月15日环比为12月17日-12月31日
---
## 七、数据更新策略
| 表类型 | 更新频率 | 幂等方式 |
|--------|----------|----------|
| 日度明细表 | 每小时 | delete-before-insert按日期窗口 |
| 日度汇总表 | 每小时 | delete-before-insert按日期 |
| 月度汇总表 | 每日 | delete-before-insert按月份 |
| 客户统计表 | 每日 | delete-before-insert按统计日期 |
| Excel导入表 | 手动 | 按import_batch_no去重 |

View File

@@ -0,0 +1,124 @@
# ODS 数据字典
## 概述
ODSOperational Data Store层是数据仓库的操作数据存储层保留从上游 SaaS API 抽取的原始数据。所有 ODS 表位于 `ods` schema字段以 API 导出原样为主ETL 补充 `content_hash``source_file``source_endpoint``fetched_at``payload` 等元数据字段。
- Schema`ods`
- 来源 DDL`database/schema_ODS_doc.sql`
- 主键模式:所有 ODS 表均采用 `(业务主键, content_hash)` 复合主键,用于 SCD 变更检测
- 表级文档:`docs/database/ODS/main/BD_manual_{表名}.md`
- 字段映射文档:`docs/database/ODS/mappings/mapping_{API端点名}_{表名}.md`
## 表清单
| 序号 | 表名 | 中文说明 | 主键 | 记录数 | 数据来源API 端点) |
|------|------|----------|------|-------:|----------------------|
| 1 | `assistant_accounts_master` | 助教档案主数据 | id, content_hash | 223 | `PersonnelManagement/SearchAssistantInfo` |
| 2 | `assistant_cancellation_records` | 助教作废/取消记录 | id, content_hash | 100 | `AssistantPerformance/GetAbolitionAssistant` |
| 3 | `assistant_service_records` | 助教服务流水 | id, content_hash | 10,203 | `AssistantPerformance/GetOrderAssistantDetails` |
| 4 | `goods_stock_movements` | 商品库存变动流水 | sitegoodsstockid, content_hash | 35,005 | `GoodsStockManage/QueryGoodsOutboundReceipt` |
| 5 | `goods_stock_summary` | 商品库存汇总 | sitegoodsid, content_hash | 867 | `TenantGoods/GetGoodsStockReport` |
| 6 | `group_buy_packages` | 团购套餐主数据 | id, content_hash | 52 | `PackageCoupon/QueryPackageCouponList` |
| 7 | `group_buy_redemption_records` | 团购核销记录 | id, content_hash | 19,532 | `Site/GetSiteTableUseDetails` |
| 8 | `member_balance_changes` | 会员余额变更流水 | id, content_hash | 7,366 | `MemberProfile/GetMemberCardBalanceChange` |
| 9 | `member_profiles` | 会员档案/会员账户信息 | id, content_hash | 1,202 | `MemberProfile/GetTenantMemberList` |
| 10 | `member_stored_value_cards` | 会员储值/卡券账户列表 | id, content_hash | 2,008 | `MemberProfile/GetTenantMemberCardList` |
| 11 | `payment_transactions` | 支付流水 | id, content_hash | 24,674 | `PayLog/GetPayLogListPage` |
| 12 | `platform_coupon_redemption_records` | 平台券核销/使用记录 | id, content_hash | 18,125 | `Promotion/GetOfflineCouponConsumePageList` |
| 13 | `recharge_settlements` | 充值结算记录 | id, content_hash | 3,333 | `Site/GetRechargeSettleList` |
| 14 | `refund_transactions` | 退款流水 | id, content_hash | 50 | `Order/GetRefundPayLogList` |
| 15 | `settlement_records` | 结账/结算记录 | id, content_hash | 55,137 | `Site/GetAllOrderSettleList` |
| 16 | `settlement_ticket_details` | 结算小票明细 | ordersettleid, content_hash | 193 | `Order/GetOrderSettleTicketNew` |
| 17 | `site_tables_master` | 门店桌台主数据 | id, content_hash | 949 | `Table/GetSiteTables` |
| 18 | `stock_goods_category_tree` | 商品分类树 | id, content_hash | 9 | `TenantGoodsCategory/QueryPrimarySecondaryCategory` |
| 19 | `store_goods_master` | 门店商品主数据 | id, content_hash | 1,398 | `TenantGoods/GetGoodsInventoryList` |
| 20 | `store_goods_sales_records` | 门店商品销售流水 | id, content_hash | 17,563 | `TenantGoods/GetGoodsSalesList` |
| 21 | `table_fee_discount_records` | 台费折扣记录 | id, content_hash | 3,100 | `Site/GetTaiFeeAdjustList` |
| 22 | `table_fee_transactions` | 台费流水 | id, content_hash | 28,881 | `Site/GetSiteTableOrderDetails` |
| 23 | `tenant_goods_master` | 租户商品主数据 | id, content_hash | 176 | `TenantGoods/QueryTenantGoods` |
## 按业务域分类
### 会员域
| 表名 | 说明 | 记录数 |
|------|------|-------:|
| `member_profiles` | 会员档案/会员账户信息 | 1,202 |
| `member_stored_value_cards` | 会员储值/卡券账户列表 | 2,008 |
| `member_balance_changes` | 会员余额变更流水 | 7,366 |
### 助教域
| 表名 | 说明 | 记录数 |
|------|------|-------:|
| `assistant_accounts_master` | 助教档案主数据 | 223 |
| `assistant_service_records` | 助教服务流水 | 10,203 |
| `assistant_cancellation_records` | 助教作废/取消记录 | 100 |
### 订单/结算域
| 表名 | 说明 | 记录数 |
|------|------|-------:|
| `settlement_records` | 结账/结算记录 | 55,137 |
| `settlement_ticket_details` | 结算小票明细 | 193 |
| `payment_transactions` | 支付流水 | 24,674 |
| `refund_transactions` | 退款流水 | 50 |
| `recharge_settlements` | 充值结算记录 | 3,333 |
### 台费域
| 表名 | 说明 | 记录数 |
|------|------|-------:|
| `table_fee_transactions` | 台费流水 | 28,881 |
| `table_fee_discount_records` | 台费折扣记录 | 3,100 |
| `site_tables_master` | 门店桌台主数据 | 949 |
### 商品/库存域
| 表名 | 说明 | 记录数 |
|------|------|-------:|
| `tenant_goods_master` | 租户商品主数据 | 176 |
| `store_goods_master` | 门店商品主数据 | 1,398 |
| `store_goods_sales_records` | 门店商品销售流水 | 17,563 |
| `stock_goods_category_tree` | 商品分类树 | 9 |
| `goods_stock_summary` | 商品库存汇总 | 867 |
| `goods_stock_movements` | 商品库存变动流水 | 35,005 |
### 团购/平台域
| 表名 | 说明 | 记录数 |
|------|------|-------:|
| `group_buy_packages` | 团购套餐主数据 | 52 |
| `group_buy_redemption_records` | 团购核销记录 | 19,532 |
| `platform_coupon_redemption_records` | 平台券核销/使用记录 | 18,125 |
---
## ETL 元数据字段说明
所有 ODS 表均包含以下 ETL 补充字段:
| 字段名 | 类型 | 说明 |
|--------|------|------|
| `content_hash` | TEXT | 对业务字段计算 SHA256作为复合主键的一部分用于 SCD 变更检测 |
| `source_file` | TEXT | 数据来源文件名(如 `member_profiles.json` |
| `source_endpoint` | TEXT | 数据来源 API 端点路径 |
| `fetched_at` | TIMESTAMPTZ | 数据抓取/入库时间戳 |
| `payload` | JSONB | 完整原始 JSON 记录快照,用于数据回溯 |
## 数据更新策略
| 更新方式 | 说明 |
|----------|------|
| 全量抓取 | 主数据表(`*_master``*_profiles``*_packages``*_tree`)每次全量拉取 |
| 增量抓取 | 流水/事实表(`*_records``*_transactions``*_changes`)按时间窗口增量拉取 |
| 幂等入库 | 通过 `(业务主键, content_hash)` 复合主键实现 upsert相同内容不重复写入 |
## 相关文档
- 表级文档:[`docs/database/ODS/main/`](../ODS/main/) — 每张表的详细字段说明
- 字段映射:[`docs/database/ODS/mappings/`](../ODS/mappings/) — API JSON → ODS 字段映射
- DDL 定义:[`database/schema_ODS_doc.sql`](../../database/schema_ODS_doc.sql)
- DWD 数据字典:[`docs/database/overview/dwd_main_tables_dictionary.md`](dwd_main_tables_dictionary.md)
- DWS 数据字典:[`docs/database/overview/dws_tables_dictionary.md`](dws_tables_dictionary.md)