# 审计记录：DWD 清理 + ODS 商品销售修复 + dim_staff_ex 修复

> 日期：2026-03-01 02:27:26
> Prompt-ID：P20260301-021708
> 审计触发原因：root-file, dir:admin-web, dir:backend, dir:etl, dir:miniprogram, dir:db, db-schema-change, dir:shared
> 变更规模：226 files changed, 9454 insertions(+), 217885 deletions(-)

---

## 变更概述

本次为跨模块大批量变更，核心工作包括三个独立任务：

1. **assistant_trash_event 残留清理**：已 DROP 的表（2026-02-22）的代码引用和 DDL 文档残留清理
2. **ODS_STORE_GOODS_SALES 窗口配置修复**：`requires_window=False` → `True`，恢复商品销售数据拉取
3. **dim_staff_ex FACT_MAPPINGS 列名修复**：驼峰列名 → 下划线列名，修复 SCD2 合并失败

同时包含前序累积的多模块变更（admin-web 营业日功能、backend 新路由/服务、miniprogram 认证流程、shared datetime_utils 等）。

---

## 本次对话文件变更

### 新增文件
- `docs/audit/prompt_logs/prompt_log_20260301_021708.md` — 本次对话的 Prompt 日志
- `docs/database/BD_Manual_20260301_cleanup_and_fixes.md` — DB 变更手册（三项修复）

### 修改文件（本次对话期间）
- `apps/etl/connectors/feiqiu/tasks/dwd/dwd_load_task.py` — dim_staff_ex FACT_MAPPINGS 列名修复
- `apps/etl/connectors/feiqiu/tasks/ods/ods_tasks.py` — ODS_STORE_GOODS_SALES 窗口配置修复
- `docs/database/ddl/etl_feiqiu__dwd.sql` — 移除 assistant_trash_event 残留约束/索引
- `docs/database/ddl/etl_feiqiu__ods.sql` — 移除 assistant_cancellation_records 残留约束/索引
- `docs/prd/specs/dwd-amount-duration-calibration.md` — 移除 assistant_trash_event 章节

---

## 高风险文件分类

### admin-web（6 文件）
营业日功能集成：`App.tsx` 初始化 businessDayStore、`TaskConfig.tsx` 添加 BusinessDayHint 组件、`TaskManager.tsx` 添加历史任务终止按钮。新增 `businessDay.ts` API、`BusinessDayHint.tsx` 组件、`businessDayStore.ts` 状态管理。

### backend（20 文件）
- 配置：新增 WX_APPID/WX_SECRET/WX_DEV_MODE/BUSINESS_DAY_START_HOUR
- 路由：member_birthday → member_retention_clue 重构；新增 admin_applications、business_day、xcx_tasks、xcx_notes
- 服务：新增 task_generator、task_expiry、recall_detector、note_reclassifier、trigger_scheduler
- 认证：xcx_auth 新增 dev-login 端点，用户状态 pending → new/pending 分离
- main.py：lifespan 注册触发器 job handler

### etl（14 文件）
- config：defaults/env_parser/settings 小幅调整
- orchestration：flow_runner 调整
- quality：consistency_checker 移除 assistant_cancellation_records 引用
- tasks/dwd：dwd_load_task.py dim_staff_ex 列名修复
- tasks/ods：ods_tasks.py ODS_STORE_GOODS_SALES 窗口修复
- tasks/dws：多个 DWS 任务调整（assistant_customer/daily/finance/monthly）
- scripts：多个脚本清理 assistant_trash_event 引用

### db（2 文件）
- `db/fdw/setup_fdw_reverse.sql` / `setup_fdw_reverse_test.sql`：FDW 配置更新

---

## 合规检查

| 检查项 | 状态 |
|--------|------|
| BD Manual 文档 | ✅ 已创建 `BD_Manual_20260301_cleanup_and_fixes.md` |
| DDL 基线同步 | ✅ 已更新 `etl_feiqiu__dwd.sql` + `etl_feiqiu__ods.sql` |
| 新增迁移 SQL | 无（本次为文档清理 + 代码修复，无新增迁移） |
| API 接口变更 | 否（`api_changed=false`） |
| OpenAPI Spec | 无需同步（`openapi_spec_stale=false`） |
| ETL 任务文档同步 | ⚠️ 已补齐（见下方文档校对段落） |

---

## 文档校对补齐

### 1. `apps/etl/connectors/feiqiu/tasks/ods/ods_tasks.py` → ETL 任务文档
- 更新 `apps/etl/connectors/feiqiu/docs/etl_tasks/ods_tasks.md`：`ODS_STORE_GOODS_SALES` 的「需要窗口」列从「否」改为「是」，反映 `requires_window=True` 修复

### 2. `apps/etl/connectors/feiqiu/tasks/dwd/dwd_load_task.py` → ETL 任务文档
- 更新 `apps/etl/connectors/feiqiu/docs/etl_tasks/dwd_tasks.md`：
  - 移除事实表映射中的 `dwd_assistant_trash_event` / `_ex` 两行
  - 新增 `dim_staff` / `dim_staff_ex` 维度映射（已存在但确认无误）
  - 映射总数从 40 对调整为 38 对

---


## 改动注解

### `apps/etl/connectors/feiqiu/tasks/dwd/dwd_load_task.py`
- 变更类型：修改
- 原始原因：dim_staff_ex 表始终为 0 行，排查发现 FACT_MAPPINGS 中 ODS 列名使用驼峰风格（如 `cashierpointid`），但 ODS 表 `staff_info_master` 实际列名为下划线风格（`cashier_point_id`），导致 SCD2 合并 SQL 执行报错，整表被静默跳过
- 思路分析：修正 7 个字段的 ODS 列名映射（驼峰 → 下划线），使 SQL 查询能正确引用 ODS 列。选择直接修改映射而非添加别名，因为 ODS 表列名已经是标准下划线风格
- 修改结果：dim_staff_ex 从 0 行恢复到 15 行（与 dim_staff 一致），SCD2 合并正常执行。影响范围仅限 DWD 装载流程中 dim_staff_ex 的处理

### `apps/etl/connectors/feiqiu/tasks/ods/ods_tasks.py`
- 变更类型：修改
- 原始原因：`dwd_store_goods_sale` 数据停滞在 2025-12-19（手动导入），排查发现 `ODS_STORE_GOODS_SALES` 的 `requires_window=False` 导致 API `/TenantGoods/GetGoodsSalesList` 不传时间参数，始终返回 0 条记录
- 思路分析：将 `requires_window` 改为 `True` 并添加 `time_fields=("startTime", "endTime")`，使 API 请求携带时间窗口参数。这与其他需要时间窗口的 ODS 任务（如 ODS_SETTLEMENT_RECORDS）保持一致
- 修改结果：ODS 层新增 26,759 条商品销售记录，DWD 层 `dwd_store_goods_sale` 数据延伸至 2026-02-25。后续 DWS 层商品相关报表数据将恢复完整

### `docs/database/ddl/etl_feiqiu__dwd.sql`
- 变更类型：修改
- 原始原因：`dwd_assistant_trash_event` 和 `_ex` 表已于 2026-02-22 DROP，但 DDL 基线文件中仍残留 PK 约束和索引定义
- 思路分析：移除已不存在表的约束和索引行，保持 DDL 基线与数据库实际状态一致
- 修改结果：DDL 基线文件清理完毕，不再包含已删除表的引用

### `docs/database/ddl/etl_feiqiu__ods.sql`
- 变更类型：修改
- 原始原因：上游 ODS 表 `assistant_cancellation_records` 已同步 DROP，DDL 基线残留 PK 约束和索引
- 思路分析：同上，清理残留定义
- 修改结果：DDL 基线文件清理完毕

### `docs/prd/specs/dwd-amount-duration-calibration.md`
- 变更类型：修改
- 原始原因：文档中包含已删除的 `dwd_assistant_trash_event` 表的章节（2.11）、存疑字段和数据新鲜度行
- 思路分析：移除与已删除表相关的所有文档段落，避免误导
- 修改结果：文档不再引用已删除的表

### `docs/audit/prompt_logs/prompt_log_20260301_021708.md`
- 变更类型：新增
- 原始原因：审计流程自动记录本次对话的 Prompt 日志，用于变更溯源
- 修改结果：记录了完整的对话上下文转移摘要，包含 5 个任务的状态和详细信息

### `docs/database/BD_Manual_20260301_cleanup_and_fixes.md`
- 变更类型：新增
- 原始原因：本次涉及 db-schema-change（DDL 文档变更 + 数据修复），需按规范创建 BD Manual
- 思路分析：将三个独立修复（trash_event 清理、ODS 窗口修复、dim_staff_ex 列名修复）合并为一份 BD Manual，包含完整的变更说明、兼容性影响、回滚策略和验证 SQL
- 修改结果：BD Manual 文档完整覆盖三项变更，提供 5 条验证 SQL

### 简要注解（非高风险修改文件）

| 文件 | 说明 |
|------|------|
| `apps/admin-web/src/App.tsx` | 启动时初始化 businessDayStore |
| `apps/admin-web/src/pages/TaskConfig.tsx` | 日期选择区域添加 BusinessDayHint 组件 |
| `apps/admin-web/src/pages/TaskManager.tsx` | 历史任务列表添加终止按钮（running 状态） |
| `apps/backend/app/config.py` | 新增微信小程序配置项 + 营业日分割点配置 |
| `apps/backend/app/main.py` | 路由注册更新 + lifespan 注册触发器 job handler |
| `apps/backend/app/routers/tasks.py` | 同步检查添加 ETL_ONLY_EXPECTED 白名单，避免误报 |
| `apps/backend/app/routers/xcx_auth.py` | 新增 dev-login 端点，用户状态 new/pending 分离 |
| `apps/backend/app/schemas/xcx_auth.py` | 新增 DevLoginRequest schema |
| `apps/backend/app/services/application.py` | 提交申请时自动更新用户状态 new→pending |
| `apps/backend/app/services/wechat.py` | 微信 code2Session 调用调整 |

---

## DDL/迁移检查

- 新增迁移 SQL：无
- DDL 基线状态：✅ 已同步更新

---

## DB 文档对账摘要

- BD Manual 已创建：`BD_Manual_20260301_cleanup_and_fixes.md`
- 覆盖变更：assistant_trash_event 清理、ODS_STORE_GOODS_SALES 修复、dim_staff_ex 修复
- 验证 SQL：5 条（确认表删除、数据回填、dim_staff_ex 恢复）

> 注：全量 DB 文档对账需连接测试库执行，本次审计记录中标注待执行状态。因 reasons 含 db-schema-change，全量对账应在后续专项执行。

---

*审计完成时间：2026-03-01 02:27:26 (Asia/Shanghai)*
