# 字段补全复核文档（ODS + DWD 全量对照）

> 初始生成：2026-02-20 00:09
> 二次审核：2026-02-20（基于 dataflow 报告 + 数据库实际值验证）
> 用途：供人工复核字段排查结论，确认后再执行代码变更
> 数据源：test_etl_feiqiu（开发/测试环境）

---

## 全局汇总

| 指标              | 数量                                                                                                                                                                                                                         |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 涉及 ODS 表       | 12                                                                                                                                                                                                                           |
| 待新增/补映射字段 | 40                                                                                                                                                                                                                           |
| 需修复映射错误    | 4（① assistant_service_records site_assistant_id；② store_goods_sales_records discount_price 列名误导；③ store_goods_master batch_stock_qty 映射自错误源列；④ store_goods_master provisional_total_cost 映射自错误源列） |
| 跳过字段          | 6                                                                                                                                                                                                                            |
| 新建 DWD 表       | 2（goods_stock_movement 中优先级、settlement_ticket 待定）                                                                                                                                                                   |
| 需修改 ODS 配置   | 1（goods_stock_summary：`requires_window` 改 True + 添加 `time_fields`，重新采集后可正常建 DWD 表）                                                                                                                         |

### 分类说明

- **A 类**：现有 DWD 表新增列 + FACT_MAPPINGS
- **B 类**：DWD 列已存在，仅补 FACT_MAPPINGS
- **C 类**：需新建 DWD 表
- **🔴 修复类**：现有映射错误，需修正

---

## 🔴 映射错误修复（高优先级）

### assistant_service_records — site_assistant_id 映射错误

| 验证项                                                    | 结果                                                 |
| --------------------------------------------------------- | ---------------------------------------------------- |
| ODS `order_assistant_id` distinct 值                    | 5,292（订单级 ID，每次服务生成一个）                 |
| ODS `site_assistant_id` distinct 值                     | 63（助教档案 ID，对应 assistant_accounts_master.id） |
| 10,219 条记录中两者相等的                                 | **0 条**（完全不同的字段）                     |
| 两者值域交集                                              | **无交集**                                     |
| DWD `site_assistant_id` 匹配 ODS `order_assistant_id` | **100%**                                       |
| DWD `site_assistant_id` 匹配 ODS `site_assistant_id`  | **0%**                                         |

**问题**：DWD `dwd_assistant_service_log.site_assistant_id` 当前实际映射自 ODS `order_assistant_id`（订单级助教分配 ID），而非 ODS `site_assistant_id`（助教档案 ID）。

**影响**：助教维度 JOIN 失败或产生错误的业绩归属。DWD 中有 5,276 个 distinct 值（应为 ~63 个）。

**修复方案**：

1. FACT_MAPPINGS 中将 DWD `site_assistant_id` 的 ODS 源从 `order_assistant_id` 改为 `site_assistant_id`
2. 新增 DWD 列 `order_assistant_id`（bigint）到 dwd_assistant_service_log，映射 ODS `order_assistant_id`
3. 重新加载历史数据

---

## 1. assistant_accounts_master（助教账号档案）— A 类

### ✅ 待新增 / 补映射字段

| ODS 列 → DWD 列   | 类型          | 目标表           | 说明                                                                                         | 操作                        |
| ------------------ | ------------- | ---------------- | -------------------------------------------------------------------------------------------- | --------------------------- |
| `system_role_id` | bigint        | dim_assistant_ex | 系统角色 ID。采样值: 仅 `10`（1 个 distinct），0% NULL。当前所有助教同一角色，未来可能扩展 | 新增 DWD 列 + FACT_MAPPINGS |
| `job_num`        | text          | dim_assistant_ex | 备用工号。采样值: 全部 NULL（100% NULL，门店未启用）。保持完整性                             | 新增 DWD 列 + FACT_MAPPINGS |
| `cx_unit_price`  | numeric(18,2) | dim_assistant_ex | 促销时段单价。采样值: 全部 `0.00`（未启用差异化定价）。与工资计算相关                      | 新增 DWD 列 + FACT_MAPPINGS |
| `pd_unit_price`  | numeric(18,2) | dim_assistant_ex | 普通时段单价。采样值: 全部 `0.00`。与工资计算相关                                          | 新增 DWD 列 + FACT_MAPPINGS |

### ⏭️ 跳过字段

无

---

## 2. assistant_service_records（助教服务流水）— A 类

### ✅ 待新增 / 补映射字段

| ODS 列 → DWD 列  | 类型   | 目标表                       | 说明                                                             | 操作                        |
| ----------------- | ------ | ---------------------------- | ---------------------------------------------------------------- | --------------------------- |
| `operator_id`   | bigint | dwd_assistant_service_log_ex | 操作员 ID。采样值:`2790687322443013`（1 个 distinct），0% NULL | 新增 DWD 列 + FACT_MAPPINGS |
| `operator_name` | text   | dwd_assistant_service_log_ex | 操作员名称。采样值:`收银员:郑丽珊`（1 个 distinct），0% NULL   | 新增 DWD 列 + FACT_MAPPINGS |

### ⏭️ 跳过字段

| ODS 列          | 跳过原因                                              |
| --------------- | ----------------------------------------------------- |
| `siteprofile` | jsonb 嵌套列，存储门店信息快照，不适合直接映射 DWD 列 |

### 🔴 需修复

见上方「映射错误修复」章节。`site_assistant_id` 当前错误映射自 `order_assistant_id`，需修正。

---

## 3. assistant_cancellation_records（助教废除记录）— A 类

### ✅ 待新增 / 更新补映射字段

| ODS 列 → DWD 列                | 类型    | 目标表                    | 说明                                                        | 操作                |
| ------------------------------- | ------- | ------------------------- | ----------------------------------------------------------- | ------------------- |
| `assistanton → assistant_no` | integer | dwd_assistant_trash_event | 更新字段，助教编号。采样值: 1~99，22 个 distinct，0% NULL。 | 更新 FACT_MAPPINGS |

### ⏭️ 跳过字段

| ODS 列          | 跳过原因     |
| --------------- | ------------ |
| `siteprofile` | jsonb 嵌套列 |

---

## 4. store_goods_sales_records（门店商品销售流水）

### 🔴 映射错误（需修正）

| 问题                               | 说明                                                                                                                  |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| DWD 列 `discount_price` 命名误导 | 当前映射自 ODS `discount_money`（折扣金额），而非 ODS `discount_price`（折后单价）。DWD 字段名应与 ODS 源字段一致 |

验证数据：

| 验证项                                          | 结果                     |
| ----------------------------------------------- | ------------------------ |
| DWD `discount_price` = ODS `discount_money` | 17563/17563 = 100% ✅    |
| DWD `discount_price` = ODS `discount_price` | 111/17563 = 0.6%（巧合） |

修正方案：将 DWD 列名 `discount_price` 重命名为 `discount_money`，使其与 ODS 源字段名一致。

### ✅ 待新增 / 补映射字段

| ODS 列 → DWD 列                         | 类型    | 目标表               | 说明                                                                                                                                                                                                                                                          | 操作                                                                            |
| ---------------------------------------- | ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| `discount_price` → `discount_price` | numeric | dwd_store_goods_sale | 折后单价。48 个 distinct，0% NULL。与 `ledger_unit_price`（台账单价/原价）92.7% 相同，7.3% 存在差异（即发生了折扣）。采样值: 0.00, 1.00, 2.00, 3.00, 3.50, 5.00, 8.00 等。分布 top 5: 5.00→5008次, 8.00→3284次, 6.00→1365次, 2.00→1291次, 10.00→1174次 | 先完成上述列名修正，释放 `discount_price` 名称后，新增 DWD 列 + FACT_MAPPINGS |

---

## 5. member_balance_changes（会员余额变动）— A 类

### ✅ 待新增 / 补映射字段

| ODS 列 → DWD 列 | 类型   | 目标表                       | 说明                                                                                                                                                       | 操作                        |
| ---------------- | ------ | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| `relate_id`    | bigint | dwd_member_balance_change_ex | 关联业务单据 ID（充值单/消费订单/退款单）。采样值: 3904 个 distinct，0% NULL。约 9% 关联 recharge_settlements，其余关联订单/退款等。余额变动溯源的关键外键 | 新增 DWD 列 + FACT_MAPPINGS |

### ⏭️ 跳过字段

无

---

## 6. tenant_goods_master（租户商品档案）

### ✅ 待新增 / 补映射字段

无

### ⏭️ 跳过字段

| ODS 列            | 跳过原因                                                                                                                                                                      |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `commoditycode` | 与 `commodity_code` 100% 冗余（353/353 条验证：`commoditycode` = `'{' + `commodity_code ` + '}'`，花括号包裹格式）。DWD 如需商品编码应映射 `commodity_code`（纯值） |

---

## 7. site_tables_master（台桌档案）— A 类

> 二次审核结论：原方案 14 个字段，经数据库验证后分为 3 个有多值 + 11 个单值。
> 用户要求全部纳入待新增映射。单值字段当前门店配置统一，未来多门店扩展后可能出现差异。

### ✅ 待新增 / 补映射字段

| ODS 列 → DWD 列           | 类型        | 目标表       | 说明                                                                           | 操作                        |
| -------------------------- | ----------- | ------------ | ------------------------------------------------------------------------------ | --------------------------- |
| `create_time`            | timestamptz | dim_table_ex | 台桌创建时间。值域: 2025-07-15 ~ 2025-12-12，0% NULL。可用于分析台桌上线时间线 | 新增 DWD 列 + FACT_MAPPINGS |
| `light_status`           | integer     | dim_table_ex | 灯光状态。2 个 distinct（1/2）。实时状态字段，SCD2 中会频繁变更                | 新增 DWD 列 + FACT_MAPPINGS |
| `tablestatusname`        | text        | dim_table_ex | 台桌状态名。3 个 distinct（空闲中/使用中/暂停中）。实时状态字段                | 新增 DWD 列 + FACT_MAPPINGS |
| `sitename`               | text        | dim_table_ex | 门店名称。当前单值（`朗朗桌球`），多门店扩展后有区分度                       | 新增 DWD 列 + FACT_MAPPINGS |
| `appletQrCodeUrl`        | text        | dim_table_ex | 小程序二维码 URL。运营/展示用途，含环境参数                                    | 新增 DWD 列 + FACT_MAPPINGS |
| `audit_status`           | integer     | dim_table_ex | 审核状态。当前单值（全部为 `2`，已审核通过）                                 | 新增 DWD 列 + FACT_MAPPINGS |
| `charge_free`            | integer     | dim_table_ex | 收费模式。当前单值（全部为 `0`，收费）                                       | 新增 DWD 列 + FACT_MAPPINGS |
| `delay_lights_time`      | integer     | dim_table_ex | 延迟关灯时间。当前单值（全部为 `0`，未启用）                                 | 新增 DWD 列 + FACT_MAPPINGS |
| `is_rest_area`           | integer     | dim_table_ex | 是否休息区。当前单值（全部为 `0`）                                           | 新增 DWD 列 + FACT_MAPPINGS |
| `only_allow_groupon`     | integer     | dim_table_ex | 仅允许团购。当前单值（全部为 `2`）                                           | 新增 DWD 列 + FACT_MAPPINGS |
| `order_delay_time`       | integer     | dim_table_ex | 订单延迟时间。当前单值（全部为 `0`）                                         | 新增 DWD 列 + FACT_MAPPINGS |
| `self_table`             | integer     | dim_table_ex | 自助台桌标记。当前单值（全部为 `1`）                                         | 新增 DWD 列 + FACT_MAPPINGS |
| `temporary_light_second` | integer     | dim_table_ex | 临时亮灯秒数。当前单值（全部为 `0`，未启用）                                 | 新增 DWD 列 + FACT_MAPPINGS |
| `virtual_table`          | integer     | dim_table_ex | 虚拟台桌标记。当前单值（全部为 `0`）                                         | 新增 DWD 列 + FACT_MAPPINGS |

---

## 8. recharge_settlements（充值结算单）— B 类

> 二次审核结论：5 个字段在 ODS 和 DWD 两侧数据全为 0（业务未启用），DWD 列已存在，仅需补 FACT_MAPPINGS。

### ✅ 待新增 / 补映射字段

| ODS 列 → DWD 列                                       | 类型          | 目标表             | 说明                                             | 操作               |
| ------------------------------------------------------ | ------------- | ------------------ | ------------------------------------------------ | ------------------ |
| `plcouponsaleamount → pl_coupon_sale_amount`        | numeric(18,2) | dwd_recharge_order | 平台券销售金额。ODS/DWD 两侧全为 0（业务未启用） | 仅补 FACT_MAPPINGS |
| `mervousalesamount → mervou_sales_amount`           | numeric(18,2) | dwd_recharge_order | 美团/大众点评等平台销售金额。全为 0              | 仅补 FACT_MAPPINGS |
| `electricitymoney → electricity_money`              | numeric(18,2) | dwd_recharge_order | 电费金额。全为 0                                 | 仅补 FACT_MAPPINGS |
| `realelectricitymoney → real_electricity_money`     | numeric(18,2) | dwd_recharge_order | 实际电费金额。全为 0                             | 仅补 FACT_MAPPINGS |
| `electricityadjustmoney → electricity_adjust_money` | numeric(18,2) | dwd_recharge_order | 电费调整金额。全为 0                             | 仅补 FACT_MAPPINGS |

### ⏭️ 跳过字段

无

---

## 9. store_goods_master（门店商品档案）

🔴 映射错误（需修正）

| # | DWD 列                                        | 当前映射 ODS 列                         | 正确 ODS 列                            | 验证                                                                                     |
| - | --------------------------------------------- | --------------------------------------- | -------------------------------------- | ---------------------------------------------------------------------------------------- |
| 1 | dim_store_goods.`batch_stock_qty`           | `stock`（当前库存）                   | `batch_stock_quantity`（批次库存）   | 1744 行中仅 127 行相等（7.3%），两者 distinct 分别为 96 vs 240，语义完全不同             |
| 2 | dim_store_goods_ex.`provisional_total_cost` | `total_purchase_cost`（实际采购成本） | `provisional_total_cost`（暂估成本） | 1744 行中 1631 行相等（93.5%），但 113 行不同；distinct 分别为 5 vs 17，是不同的成本维度 |

修正方案：

1. `batch_stock_qty` 的 FACT_MAPPINGS 从 `stock` 改为 `batch_stock_quantity`
2. `provisional_total_cost` 的 FACT_MAPPINGS 从 `total_purchase_cost` 改为 `provisional_total_cost`

### ✅ 待新增 / 补映射字段

以下 ODS 字段当前未出现在任何 DWD 表中（既不在 FACT_MAPPINGS 中，也无法同名自动映射）：

| ODS 列 → DWD 列           | 类型          | 目标表          | 说明                                                                                 | 操作                       |
| -------------------------- | ------------- | --------------- | ------------------------------------------------------------------------------------ | -------------------------- |
| `batch_stock_quantity`   | numeric(18,2) | dim_store_goods | 批次库存数量。96 个 distinct，0% NULL。修正 `batch_stock_qty` 映射后此字段自动覆盖 | 修正 FACT_MAPPINGS（见上） |
| `provisional_total_cost` | numeric(18,2) | dim_store_goods | 暂估总成本。5 个 distinct，0% NULL。修正映射后此字段自动覆盖                         | 修正 FACT_MAPPINGS（见上） |

### ⏭️ 跳过字段

| ODS 列             | 跳过原因                                                                    |
| ------------------ | --------------------------------------------------------------------------- |
| `time_slot_sale` | ODS 列不存在。payload 中仅 19.8% 记录有值，且全部为单一值 `"2"`，无区分度 |

---

## 10. goods_stock_summary（库存汇总）— C 类（需修改 ODS 任务配置后重新采集）

> 三次审核结论（API 实测验证）：
> - 原结论"range 系列全为 0、建议暂缓"已推翻
> - 实测发现：该 API 支持 `startTime`/`endTime` 参数，传入日期范围后 range 字段返回真实汇总数据
> - 当前 range 全为 0 的原因：ODS 任务配置 `requires_window=False`，从未向 API 传递日期参数
> - 该表本质是**报表型 API**（带时间范围聚合能力），不是纯维表

### API 实测结果

| 测试场景 | 参数 | range 字段结果 |
| -------- | ---- | -------------- |
| ① 无日期参数（当前行为） | 无 | 全部为 0 |
| ② `startTime`/`endTime`（30 天） | `startTime=2026-01-20, endTime=2026-02-19` | **有真实数据**（rangeIn=24, rangeOut=-3, rangeSale=3, rangeSaleMoney=24.0 等） |
| ③ `rangeStartTime`/`rangeEndTime` | 同上日期 | 全部为 0（API 不识别此参数名） |

结论：API 仅识别 `startTime`/`endTime` 参数名。

### ODS 任务配置现状

```python
# apps/etl/connectors/feiqiu/tasks/ods/ods_tasks.py
OdsTaskSpec(
    code="ODS_INVENTORY_STOCK",
    table_name="ods.goods_stock_summary",
    endpoint="/TenantGoods/GetGoodsStockReport",
    requires_window=False,  # ← 问题根因：从不传日期参数
    ...
)
```

### 修复方案

1. 将 `requires_window` 改为 `True`
2. 添加 `time_fields=("startTime", "endTime")`，使调度器按窗口传入日期范围
3. 重新采集历史数据（按时间窗口分批）
4. 采集完成后，range 字段将有真实汇总数据，可正常建设 DWD 表

### 数据概况（当前，修复前）

| 指标                                                     | 值                 |
| -------------------------------------------------------- | ------------------ |
| 总行数                                                   | 1,088              |
| distinct 商品数                                          | 173                |
| 所有字段 NULL 率                                         | 0%                 |
| rangein/rangeout/rangesale/rangesalemoney/rangeinventory | 全部为 0（因未传日期参数） |
| currentstock 值域                                        | 0 ~ 976            |
| rangestartstock/rangeendstock 值域                       | 0 ~ 976            |

### ✅ 待新增 / 补映射字段

| ODS 列 → DWD 列      | 类型 | 目标表                          | 说明                                                                                                                 | 操作                                                  |
| --------------------- | ---- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| `全部 14 个 ODS 列` |      | dwd_goods_stock_summary（新建） | 修改 ODS 任务配置（`requires_window=True` + `time_fields`）并重新采集后，range 字段将有真实数据，可正常建设 DWD 表 | 修改 ODS 配置 → 重新采集 → 新建 DWD 表 |

### ⏭️ 跳过字段

无

---

## 11. goods_stock_movements（库存变动明细）— C 类（建议优先级：中）

> 二次审核结论：35,606 行流水数据，时间跨度 7 个月，数据质量优秀（除 remark 外所有字段 0% NULL）。
> 支持双单位管理（changenum/changenuma），是库存管理的核心流水数据。

### 数据概况

| 指标              | 值                                                  |
| ----------------- | --------------------------------------------------- |
| 总行数            | 35,606                                              |
| distinct 流水 ID  | 34,961                                              |
| distinct 商品     | 165                                                 |
| distinct 库存类型 | 6（1=销售出库, 2=采购入库, 4=盘点调整, 7/8/9=其他） |
| distinct 操作人   | 8                                                   |
| 价格范围          | 2.00 ~ 11,360.00                                    |
| 变动数量范围      | -66 ~ 1,000                                         |
| 时间范围          | 2025-07-18 ~ 2026-02-14                             |
| remark NULL 率    | 96.4%（仅特殊操作时填写）                           |
| 其他字段 NULL 率  | 全部 0%                                             |

### ✅ 待新增 / 补映射字段

| ODS 列 → DWD 列      | 类型 | 目标表                           | 说明                                             | 操作                                                  |
| --------------------- | ---- | -------------------------------- | ------------------------------------------------ | ----------------------------------------------------- |
| `全部 19 个 ODS 列` |      | dwd_goods_stock_movement（新建） | 事实表，按 createtime 增量加载。驼峰 → 蛇形命名 | 新建 DWD 表 + TABLE_MAP + FACT_MAPPINGS + loader/task |

### ⏭️ 跳过字段

无

---

## 附录：其他表（无字段新增需求，仅记录跳过项）

### payment_transactions / refund_transactions / platform_coupon_redemption_records / table_fee_transactions / table_fee_discount_records

这些表的 ODS→DWD 未映射字段均为 `siteprofile` 和/或 `tableprofile`（jsonb 嵌套列），全部跳过。

### stock_goods_category_tree

`categoryboxes`（jsonb）跳过——子分类信息已通过表本身的行级记录（每行一个分类节点 + pid 父子关系）表达，categoryboxes 是冗余的嵌套视图。

### group_buy_packages

API→ODS 未映射（平层）2 个数组字段：

- `tenantTableAreaIdList[]`：ODS 已有 `tenant_table_area_id_list`（jsonb），72.9% NULL
- `tableAreaNameList[]`：ODS `table_area_id_list` 全为 NULL，但 payload 中有值（`["A区"]`, `["B区"]` 等）。存在字段名映射错位，建议后续修复 ODS 平层化映射

---

## 详细审核报告（分批）

完整的逐字段数据库验证结果见：

- `field_review_batch1_1.1.1-1.1.9.md` — 第一批（助教/商品/支付/退款/券核销）
- `field_review_batch2_1.1.12-1.1.17.md` — 第二批（余额变动/充值结算/团购/库存/台桌）
- `field_review_batch3_1.1.18-1.1.21.md` — 第三批（分类树/门店商品/台费折扣/租户商品）
