在前后端开发联调前 的提交20260223
This commit is contained in:
1
.kiro/specs/dataflow-field-completion/.config.kiro
Normal file
1
.kiro/specs/dataflow-field-completion/.config.kiro
Normal file
@@ -0,0 +1 @@
|
||||
{"generationMode": "requirements-first"}
|
||||
447
.kiro/specs/dataflow-field-completion/design.md
Normal file
447
.kiro/specs/dataflow-field-completion/design.md
Normal file
@@ -0,0 +1,447 @@
|
||||
# 设计文档:数据流字段补全与前后端联调
|
||||
|
||||
## 概述
|
||||
|
||||
本设计基于 `dataflow_2026-02-19_190440.md` 数据流分析报告,覆盖两大任务:
|
||||
|
||||
1. **字段补全**:对 11 张 ODS/DWD 表执行字段映射补全,包括 DDL 更新、ETL loader/task 代码同步、文档精化
|
||||
2. **DWS 库存汇总**:在 DWS 层新建日/周/月三个粒度的库存汇总表,基于 DWD goods_stock_summary 数据构建
|
||||
3. **前后端联调**:确保 admin-web 前端与 FastAPI 后端的 ETL 执行流程完整可用,含计时和黑盒测试
|
||||
|
||||
核心设计原则:
|
||||
- **执行依据**:字段补全部分基于排查结论文档 `export/SYSTEM/REPORTS/field_audit/field_review_for_user.md`(由 `FIELD_AUDIT_ROOT` 环境变量配置路径)
|
||||
- **先确认再新增**:对每个疑似缺失字段,必须先排查是否已存在(可能是命名差异、已映射到其他列、或已在 FACT_MAPPINGS 中以不同名称配置),确认确实缺失后才执行新增
|
||||
- 所有字段映射变更通过 `DwdLoadTask.FACT_MAPPINGS` 声明式配置,不修改核心合并逻辑
|
||||
- 新建 DWD 表遵循现有 main/ex 分表模式(核心字段 → main 表,扩展字段 → ex 表)
|
||||
- DDL 变更通过迁移脚本(`db/etl_feiqiu/migrations/`)执行,同步更新 schema 文件
|
||||
- 控制无效字段新增:仅在确认字段确实缺失且有业务价值时才新增
|
||||
|
||||
## 架构
|
||||
|
||||
### 现有 ETL 数据流架构
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
API[上游 SaaS API] -->|JSON| ODS_Loader[GenericODSLoader]
|
||||
ODS_Loader -->|UPSERT| ODS[(ODS 表)]
|
||||
ODS -->|SELECT| DWD_Task[DwdLoadTask]
|
||||
DWD_Task -->|SCD2 合并| DIM[(DWD 维度表)]
|
||||
DWD_Task -->|增量插入| FACT[(DWD 事实表)]
|
||||
```
|
||||
|
||||
### 字段映射机制
|
||||
|
||||
`DwdLoadTask` 使用两层映射策略:
|
||||
1. **自动映射**:ODS 列名与 DWD 列名相同时自动匹配
|
||||
2. **显式映射**:通过 `FACT_MAPPINGS` 字典声明 `(dwd_col, ods_expr, cast_type)` 三元组
|
||||
|
||||
本次变更主要操作 `FACT_MAPPINGS` 和 `TABLE_MAP`,以及对应的 DDL。
|
||||
|
||||
### 前后端联调架构
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
AdminWeb[Admin Web<br/>React + Ant Design] -->|HTTP/WS| Backend[FastAPI 后端]
|
||||
Backend -->|subprocess| ETL[ETL CLI]
|
||||
ETL -->|SQL| DB[(PostgreSQL)]
|
||||
Backend -->|WebSocket| AdminWeb
|
||||
```
|
||||
|
||||
## 字段排查结论(已完成)
|
||||
|
||||
排查工作已完成,详细结论见 `export/SYSTEM/REPORTS/field_audit/field_review_for_user.md`。
|
||||
|
||||
排查方法包括:查 DWD 表现有列、查 FACT_MAPPINGS、查 ODS 表现有列、查自动映射、查 API JSON 样本、数据库实际数据验证。排查发现 4 个映射错误、21 个待新增字段、2 张需新建 DWD 表、6 个跳过字段。
|
||||
|
||||
## 组件与接口
|
||||
|
||||
### 任务 1:字段补全涉及的组件
|
||||
|
||||
| 组件 | 文件路径 | 变更类型 |
|
||||
|------|---------|---------|
|
||||
| DWD 加载任务 | `tasks/dwd/dwd_load_task.py` | 修改 `FACT_MAPPINGS`、`TABLE_MAP` |
|
||||
| ODS DDL | `db/etl_feiqiu/schemas/ods.sql` | 新增列(store_goods_master 嵌套展开) |
|
||||
| DWD DDL | `db/etl_feiqiu/schemas/dwd.sql` | 新增列、新建表 |
|
||||
| 迁移脚本 | `db/etl_feiqiu/migrations/` | 新增 ALTER TABLE / CREATE TABLE |
|
||||
| ODS 加载器 | `loaders/ods/generic.py` | 可能需要扩展 columns 列表 |
|
||||
| BD_Manual 文档 | `docs/database/` | 更新字段说明 |
|
||||
|
||||
### 任务 2:前后端联调涉及的组件
|
||||
|
||||
| 组件 | 文件路径 | 变更类型 |
|
||||
|------|---------|---------|
|
||||
| 执行 API | `apps/backend/app/routers/` | 调试/修复参数传递 |
|
||||
| 执行页面 | `apps/admin-web/src/pages/TaskManager.tsx` | 调试/修复前端逻辑 |
|
||||
| 计时模块 | `apps/etl/connectors/feiqiu/utils/` | 新增计时器工具 |
|
||||
| 黑盒测试 | `apps/etl/connectors/feiqiu/quality/` | 新增数据一致性检查 |
|
||||
|
||||
## 数据模型
|
||||
|
||||
### 字段补全分类
|
||||
|
||||
根据 `field_review_for_user.md` 排查结论,将变更分为四类:
|
||||
|
||||
#### 🔴 映射错误修复(高优先级)
|
||||
|
||||
| 表 | 问题 | 修正方案 |
|
||||
|----|------|---------|
|
||||
| assistant_service_records | DWD `site_assistant_id` 错误映射自 ODS `order_assistant_id` | 修正映射源 + 新增 `order_assistant_id` 列 |
|
||||
| store_goods_sales_records | DWD `discount_price` 实际映射自 ODS `discount_money`(列名误导) | 重命名 DWD 列 + 新增真正的 `discount_price` |
|
||||
| store_goods_master | `batch_stock_qty` 映射自 `stock`(错误),`provisional_total_cost` 映射自 `total_purchase_cost`(错误) | 修正 FACT_MAPPINGS 源列 |
|
||||
|
||||
#### A 类:新增 DWD 列 + FACT_MAPPINGS
|
||||
|
||||
| 表 | 新增字段数 | DWD 目标 |
|
||||
|----|----------|---------|
|
||||
| assistant_accounts_master | 4 | dim_assistant_ex |
|
||||
| assistant_service_records | 2 | dwd_assistant_service_log_ex |
|
||||
| assistant_cancellation_records | 0(仅更新映射) | dwd_assistant_trash_event |
|
||||
| member_balance_changes | 1 | dwd_member_balance_change_ex |
|
||||
| site_tables_master | 14 | dim_table_ex |
|
||||
|
||||
#### B 类:仅补 FACT_MAPPINGS(DWD 列已存在)
|
||||
|
||||
| 表 | 说明 |
|
||||
|----|------|
|
||||
| recharge_settlements | 5 个字段,DWD 列已存在,ODS/DWD 两侧数据全为 0(业务未启用) |
|
||||
|
||||
#### 跳过(无需变更)
|
||||
|
||||
| 表 | 原因 |
|
||||
|----|------|
|
||||
| tenant_goods_master | `commoditycode` 与 `commodity_code` 100% 冗余(花括号包裹格式),跳过 |
|
||||
| store_goods_master(time_slot_sale) | ODS 列不存在,跳过 |
|
||||
|
||||
#### C 类:需新建 DWD 表
|
||||
|
||||
| 表 | ODS 字段数 | DWD 新表 | 备注 |
|
||||
|----|----------|---------|------|
|
||||
| goods_stock_summary | 14 | dwd_goods_stock_summary | 需先修改 ODS 配置 `requires_window=True` 并重新采集 |
|
||||
| goods_stock_movements | 19 | dwd_goods_stock_movement | 事实表,按 createtime 增量加载 |
|
||||
|
||||
#### C 类:疑似需新建 DWD 表(需排查是否有替代方案)
|
||||
|
||||
| 表 | ODS 字段数 | 疑似新建 DWD 表 | 排查重点 |
|
||||
|----|----------|---------------|---------|
|
||||
| goods_stock_summary | 14 | dwd_goods_stock_summary | 确认是否有意不建 DWD 表(如数据直接在 ODS 层使用) |
|
||||
| goods_stock_movements | 19 | dwd_goods_stock_movement | 同上 |
|
||||
|
||||
### 已确认的映射关系(排查结论)
|
||||
|
||||
以下映射关系已通过数据库实际数据验证确认:
|
||||
|
||||
| 字段 | 排查结论 | 所在表 |
|
||||
|------|---------|-------|
|
||||
| discount_price (store_goods_sales) | 🔴 DWD `discount_price` 实际映射自 ODS `discount_money`,需重命名 + 新增 | store_goods_sales_records |
|
||||
| commoditycode (tenant_goods) | ⏭️ 与 `commodity_code` 100% 冗余,跳过 | tenant_goods_master |
|
||||
| site_assistant_id (assistant_service) | 🔴 DWD 错误映射自 ODS `order_assistant_id`,需修正 | assistant_service_records |
|
||||
| recharge 电费/券字段 | ✅ DWD 列已存在,仅需补 FACT_MAPPINGS(数据全为 0) | recharge_settlements |
|
||||
| batch_stock_qty (store_goods) | 🔴 错误映射自 `stock`,应映射自 `batch_stock_quantity` | store_goods_master |
|
||||
| provisional_total_cost (store_goods) | 🔴 错误映射自 `total_purchase_cost`,应映射自 `provisional_total_cost` | store_goods_master |
|
||||
|
||||
### 新建 DWD 表设计
|
||||
|
||||
#### dwd_goods_stock_summary
|
||||
|
||||
```sql
|
||||
CREATE TABLE dwd.dwd_goods_stock_summary (
|
||||
site_goods_id bigint NOT NULL,
|
||||
goods_name text,
|
||||
goods_unit text,
|
||||
goods_category_id bigint,
|
||||
goods_category_second_id bigint,
|
||||
category_name text,
|
||||
range_start_stock numeric,
|
||||
range_end_stock numeric,
|
||||
range_in numeric,
|
||||
range_out numeric,
|
||||
range_sale numeric,
|
||||
range_sale_money numeric(12,2),
|
||||
range_inventory numeric,
|
||||
current_stock numeric,
|
||||
site_id bigint,
|
||||
tenant_id bigint,
|
||||
fetched_at timestamptz,
|
||||
PRIMARY KEY (site_goods_id)
|
||||
);
|
||||
```
|
||||
|
||||
#### dwd_goods_stock_movement
|
||||
|
||||
```sql
|
||||
CREATE TABLE dwd.dwd_goods_stock_movement (
|
||||
site_goods_stock_id bigint NOT NULL,
|
||||
tenant_id bigint,
|
||||
site_id bigint,
|
||||
site_goods_id bigint,
|
||||
goods_name text,
|
||||
goods_category_id bigint,
|
||||
goods_second_category_id bigint,
|
||||
unit text,
|
||||
price numeric(12,2),
|
||||
stock_type integer,
|
||||
change_num numeric,
|
||||
start_num numeric,
|
||||
end_num numeric,
|
||||
change_num_a numeric,
|
||||
start_num_a numeric,
|
||||
end_num_a numeric,
|
||||
remark text,
|
||||
operator_name text,
|
||||
create_time timestamptz,
|
||||
fetched_at timestamptz,
|
||||
PRIMARY KEY (site_goods_stock_id)
|
||||
);
|
||||
```
|
||||
|
||||
### recharge_settlements 映射关系
|
||||
|
||||
ODS 列与 DWD 列的对应关系(命名转换):
|
||||
|
||||
| ODS 列(驼峰) | DWD 列(蛇形) |
|
||||
|---------------|--------------|
|
||||
| plcouponsaleamount | pl_coupon_sale_amount |
|
||||
| mervousalesamount | mervou_sales_amount |
|
||||
| electricitymoney | electricity_money |
|
||||
| realelectricitymoney | real_electricity_money |
|
||||
| electricityadjustmoney | electricity_adjust_money |
|
||||
|
||||
这 5 个字段在 `dwd_recharge_order` 中已有列定义但缺少 FACT_MAPPINGS 条目,需要补充映射。
|
||||
|
||||
### store_goods_master 映射修正
|
||||
|
||||
根据排查结论,该表存在两个映射错误(非新增字段):
|
||||
|
||||
| DWD 列 | 当前错误映射 ODS 列 | 正确 ODS 列 | 验证结果 |
|
||||
|--------|-------------------|------------|---------|
|
||||
| `batch_stock_qty` | `stock`(当前库存) | `batch_stock_quantity`(批次库存) | 仅 7.3% 行相等 |
|
||||
| `provisional_total_cost` | `total_purchase_cost`(实际采购成本) | `provisional_total_cost`(暂估成本) | 93.5% 行相等但 113 行不同 |
|
||||
|
||||
`time_slot_sale` ODS 列不存在,跳过。`goodsStockWarningInfo` 嵌套展开不在本次范围内。
|
||||
|
||||
### DWS 库存汇总表设计(日/周/月)
|
||||
|
||||
基于 `field_review_for_user.md` 第 10 章发现,goods_stock_summary API 支持 `startTime`/`endTime` 参数返回时间范围内的库存汇总数据。在 ODS 任务配置修改(`requires_window=True` + `time_fields=("startTime", "endTime")`)并重新采集后,DWD 层 `dwd_goods_stock_summary` 将拥有带时间范围的真实数据,可在此基础上构建 DWS 层汇总。
|
||||
|
||||
#### 三张 DWS 表
|
||||
|
||||
| 表名 | 粒度 | 任务代码 | stat_period |
|
||||
|------|------|---------|-------------|
|
||||
| `dws.dws_goods_stock_daily_summary` | 日 | `DWS_GOODS_STOCK_DAILY` | `'daily'` |
|
||||
| `dws.dws_goods_stock_weekly_summary` | 周 | `DWS_GOODS_STOCK_WEEKLY` | `'weekly'` |
|
||||
| `dws.dws_goods_stock_monthly_summary` | 月 | `DWS_GOODS_STOCK_MONTHLY` | `'monthly'` |
|
||||
|
||||
#### DDL 设计(三张表结构相同)
|
||||
|
||||
```sql
|
||||
CREATE TABLE dws.dws_goods_stock_daily_summary (
|
||||
site_id bigint NOT NULL,
|
||||
tenant_id bigint,
|
||||
stat_date date NOT NULL,
|
||||
site_goods_id bigint NOT NULL,
|
||||
goods_name text,
|
||||
goods_unit text,
|
||||
goods_category_id bigint,
|
||||
goods_category_second_id bigint,
|
||||
category_name text,
|
||||
range_start_stock numeric,
|
||||
range_end_stock numeric,
|
||||
range_in numeric,
|
||||
range_out numeric,
|
||||
range_sale numeric,
|
||||
range_sale_money numeric(12,2),
|
||||
range_inventory numeric,
|
||||
current_stock numeric,
|
||||
stat_period text NOT NULL DEFAULT 'daily',
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (site_id, stat_date, site_goods_id)
|
||||
);
|
||||
```
|
||||
|
||||
周度表和月度表结构相同,仅表名和 `stat_period` 默认值不同(`'weekly'` / `'monthly'`)。
|
||||
|
||||
#### 任务实现模式
|
||||
|
||||
继承 `BaseDwsTask`,实现 `extract` / `transform` / `load` 三阶段:
|
||||
|
||||
- **extract**:从 `dwd.dwd_goods_stock_summary` 按时间范围查询数据
|
||||
- **transform**:按粒度(日/周/月)对 `stat_date` 进行分组聚合,计算各库存指标
|
||||
- 日度:直接取 DWD 数据(`stat_date` = 采集日期)
|
||||
- 周度:按 ISO 周分组,`stat_date` = 周一日期
|
||||
- 月度:按自然月分组,`stat_date` = 月首日期
|
||||
- **load**:使用 `upsert` 写入目标表,主键冲突时更新
|
||||
|
||||
#### 前置依赖
|
||||
|
||||
- 需求 7(goods_stock_summary 新建 DWD 表)必须先完成
|
||||
- ODS 任务配置修改(`requires_window=True`)必须先完成并重新采集数据
|
||||
|
||||
#### 文件位置
|
||||
|
||||
- DDL:`db/etl_feiqiu/schemas/dws.sql`
|
||||
- 迁移脚本:`db/etl_feiqiu/migrations/{date}__create_dws_goods_stock_summary.sql`
|
||||
- 任务代码:`apps/etl/connectors/feiqiu/tasks/dws/goods_stock_daily_task.py`、`goods_stock_weekly_task.py`、`goods_stock_monthly_task.py`
|
||||
|
||||
### settlement_ticket_details 彻底移除设计
|
||||
|
||||
从项目中完整移除 `settlement_ticket_details`(结账小票详情)相关的所有代码、DDL、配置、文档和数据。
|
||||
|
||||
#### 需要移除的文件/代码位置
|
||||
|
||||
| 层级 | 文件路径 | 移除内容 |
|
||||
|------|---------|---------|
|
||||
| ETL 任务定义 | `tasks/ods/ods_tasks.py` | `OdsTaskSpec("ODS_SETTLEMENT_TICKET", ...)`、`OdsSettlementTicketTask` 类、`ENABLED_ODS_CODES` 中的条目、`ODS_TASK_CLASSES` 覆盖 |
|
||||
| ETL 校验 | `tasks/verification/dwd_verifier.py` | `settlement_ticket_details` 主键映射条目 |
|
||||
| ETL 校验 | `tasks/verification/ods_verifier.py` | 相关注释和特殊处理逻辑 |
|
||||
| ETL 手动导入 | `tasks/utility/manual_ingest_task.py` | `settlement_ticket_details` 的表映射和配置 |
|
||||
| JSON 存储 | `utils/json_store.py` | `/order/getordersettleticketnew` 的路径映射 |
|
||||
| ODS 间隙检查 | `scripts/check/check_ods_gaps.py` | `_check_settlement_tickets` 函数及调用 |
|
||||
| 黑盒调试 | `scripts/debug/debug_blackbox.py` | `ODS_SETTLEMENT_TICKET` 跳过逻辑 |
|
||||
| DDL | `db/etl_feiqiu/schemas/ods.sql`、`schema_ODS_doc.sql` | `settlement_ticket_details` 建表语句和注释 |
|
||||
| 种子数据 | `db/etl_feiqiu/seeds/seed_ods_tasks.sql` | `ODS_SETTLEMENT_TICKET` 条目 |
|
||||
| 索引检查 | `scripts/ops/check_ods_latest_indexes.py` | `idx_ods_settlement_ticket_details_latest` |
|
||||
| 分析脚本 | `scripts/ops/gen_full_dataflow_doc.py` | ODS spec 条目和特殊跳过逻辑 |
|
||||
| 分析脚本 | `scripts/ops/gen_field_review_doc.py` | 第 12 章 settlement_ticket_details 配置 |
|
||||
| 分析脚本 | `scripts/ops/gen_api_field_mapping.py` | 表名列表中的条目 |
|
||||
| 分析脚本 | `scripts/ops/field_audit.py` | 排查配置和特殊处理 |
|
||||
| 分析脚本 | `scripts/ops/export_dwd_field_review.py` | 字段列表配置 |
|
||||
| 分析脚本 | `scripts/ops/dataflow_analyzer.py` | ODS spec 条目和跳过逻辑 |
|
||||
| 文档 | `docs/database/etl_feiqiu_schema_migration.md` | 索引条目 |
|
||||
| ETL 文档 | `apps/etl/connectors/feiqiu/docs/etl_tasks/` | 任务表格条目 |
|
||||
| 单元测试 | `tests/unit/test_ods_tasks.py` | `test_ods_settlement_ticket_by_payment_relate_ids` |
|
||||
|
||||
#### 迁移脚本
|
||||
|
||||
```sql
|
||||
-- 移除 settlement_ticket_details 表和索引
|
||||
DROP INDEX IF EXISTS ods.idx_ods_settlement_ticket_details_latest;
|
||||
DROP TABLE IF EXISTS ods.settlement_ticket_details;
|
||||
|
||||
-- 移除 meta.ods_task_registry 中的任务注册
|
||||
DELETE FROM meta.ods_task_registry WHERE task_code = 'ODS_SETTLEMENT_TICKET';
|
||||
```
|
||||
|
||||
#### 注意事项
|
||||
|
||||
- `export/` 下的报告文件(`field_audit_report.md`、`dataflow_api_ods_dwd.md` 等)为历史产物,不需要手动清理,下次重新生成时自然不再包含
|
||||
- `docs/audit/` 下的审计日志为历史记录,保留不动
|
||||
- `tmp/` 下的临时文件不需要处理
|
||||
|
||||
|
||||
|
||||
## 正确性属性
|
||||
|
||||
*正确性属性是一种在系统所有合法执行中都应成立的特征或行为——本质上是对系统应做什么的形式化陈述。属性是人类可读规格与机器可验证正确性保证之间的桥梁。*
|
||||
|
||||
### Property 1:FACT_MAPPINGS 字段映射正确性
|
||||
|
||||
*对于任意* ODS 表行和任意已配置的 `FACT_MAPPINGS` 条目 `(dwd_col, ods_expr, cast_type)`,当 DWD 加载任务执行后,DWD 目标行中 `dwd_col` 列的值应等于从 ODS 行中按 `ods_expr` 提取并按 `cast_type` 转换后的值。
|
||||
|
||||
**Validates: Requirements 1.1, 1.2, 2.1, 3.1, 4.1, 5.1, 6.1, 6.2, 7.2, 8.2, 9.1, 10.3, 11.1**
|
||||
|
||||
### Property 2:FACT_MAPPINGS 引用完整性
|
||||
|
||||
*对于任意* `FACT_MAPPINGS` 中的映射条目,其 DWD 目标列名必须存在于对应 DWD 表的列定义中,其 ODS 源表达式引用的列名必须存在于对应 ODS 表的列定义中(或为合法的 SQL 表达式)。
|
||||
|
||||
**Validates: Requirements 6.3**
|
||||
|
||||
### Property 3:TABLE_MAP 覆盖完整性
|
||||
|
||||
*对于任意* 在 `TABLE_MAP` 中注册的 DWD 表,该表的所有非 SCD2 列要么在 `FACT_MAPPINGS` 中有显式映射,要么在对应 ODS 表中存在同名列(自动映射)。
|
||||
|
||||
**Validates: Requirements 7.2, 8.2**
|
||||
|
||||
### Property 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),修正后 DWD 目标列的值应等于从正确的 ODS 源列提取的值,而非修正前的错误源列。
|
||||
|
||||
**Validates: Requirements 2.1, 4.1, 10.3**
|
||||
|
||||
### Property 5:ETL 参数解析与 CLI 命令构建正确性
|
||||
|
||||
*对于任意* 合法的 ETL 执行参数组合(门店列表、数据源模式、校验模式、时间范围、窗口切分、force-full 标志、任务选择),Backend 构建的 CLI 命令字符串应包含所有指定参数,且参数值与输入一致。
|
||||
|
||||
**Validates: Requirements 14.1, 14.2**
|
||||
|
||||
### Property 6:数据一致性检查正确性
|
||||
|
||||
*对于任意* ODS 行和对应的 DWD 行,黑盒测试检查器应能正确识别:(a) ODS 中存在但 DWD 中缺失的字段,(b) ODS 与 DWD 之间值不一致的字段。
|
||||
|
||||
**Validates: Requirements 16.2, 16.3**
|
||||
|
||||
### Property 7:计时器记录完整性
|
||||
|
||||
*对于任意* ETL 步骤序列,计时器输出应包含每个步骤的名称、开始时间、结束时间和耗时,且耗时等于结束时间减去开始时间。
|
||||
|
||||
**Validates: Requirements 15.2**
|
||||
|
||||
### Property 8:DWS 库存汇总粒度聚合正确性
|
||||
|
||||
*对于任意* DWD 库存汇总数据集和任意汇总粒度(日/周/月),DWS 汇总任务的 transform 输出应满足:(a) 每条记录的 `stat_period` 与任务粒度一致,(b) 同一 `(site_id, stat_date, site_goods_id)` 组合不重复,(c) 日度汇总的记录数不少于周度和月度汇总的记录数。
|
||||
|
||||
**Validates: Requirements 12.2, 12.3, 12.4, 12.5, 12.6**
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 字段补全错误处理
|
||||
|
||||
| 场景 | 处理方式 |
|
||||
|------|---------|
|
||||
| DDL 迁移失败 | 回滚事务,记录错误日志,不影响其他表 |
|
||||
| ODS 列不存在 | 跳过该映射条目,记录 WARNING 日志 |
|
||||
| 类型转换失败 | 使用 NULLIF + CAST 兜底,转换失败写入 NULL |
|
||||
| 新建 DWD 表主键冲突 | 使用 ON CONFLICT DO UPDATE 策略 |
|
||||
|
||||
### DWS 库存汇总错误处理
|
||||
|
||||
| 场景 | 处理方式 |
|
||||
|------|---------|
|
||||
| DWD 源表无数据 | 跳过汇总,记录 WARNING 日志 |
|
||||
| 跨周/跨月边界数据不完整 | 按已有数据汇总,不补零 |
|
||||
| upsert 主键冲突 | 使用 ON CONFLICT DO UPDATE 更新已有记录 |
|
||||
| DWD 表尚未创建(前置依赖未完成) | 抛出明确错误,提示需先完成需求 7 |
|
||||
|
||||
### 前后端联调错误处理
|
||||
|
||||
| 场景 | 处理方式 |
|
||||
|------|---------|
|
||||
| 参数校验失败 | 返回 422 状态码,附带详细错误信息 |
|
||||
| ETL 子进程超时 | 设置超时阈值,超时后终止进程并返回错误 |
|
||||
| WebSocket 断连 | 前端自动重连,后端缓存最近日志 |
|
||||
| 黑盒测试发现不一致 | 记录差异明细到报告,不中断流程 |
|
||||
|
||||
## 测试策略
|
||||
|
||||
### 属性测试
|
||||
|
||||
使用 `hypothesis` 库进行属性测试,每个属性至少运行 100 次迭代。
|
||||
|
||||
- **Property 1-3**:通过 FakeDB 模拟 ODS/DWD 表结构,生成随机 ODS 行数据,验证 FACT_MAPPINGS 映射逻辑
|
||||
- **Property 4**:对修正后的映射字段,验证 DWD 值来自正确的 ODS 源列
|
||||
- **Property 5**:生成随机参数组合,验证 CLI 命令构建
|
||||
- **Property 6**:生成随机 ODS/DWD 行对,验证一致性检查逻辑
|
||||
- **Property 7**:生成随机步骤序列,验证计时器输出
|
||||
- **Property 8**:生成随机 DWD 库存数据,验证日/周/月三个粒度的聚合逻辑正确性
|
||||
|
||||
测试标签格式:`Feature: dataflow-field-completion, Property N: {property_text}`
|
||||
|
||||
### 单元测试
|
||||
|
||||
- DDL 迁移脚本语法正确性(SQL 解析)
|
||||
- 各表 FACT_MAPPINGS 条目的具体映射值验证
|
||||
- DWS 库存汇总任务的边界值测试(跨周/跨月数据、空数据集)
|
||||
- 前端参数表单的边界值测试
|
||||
- 计时器精度测试
|
||||
|
||||
### 集成测试
|
||||
|
||||
- 端到端 ETL 执行:从 API JSON 到 DWD 落库的完整流程
|
||||
- 前后端联调:从 Admin Web 触发到 ETL 完成的完整流程
|
||||
- 黑盒测试:全量数据一致性验证
|
||||
|
||||
### 测试工具
|
||||
|
||||
- ETL 单元测试使用 `tests/unit/task_test_utils.py` 提供的 FakeDB/FakeAPI
|
||||
- 属性测试使用 `hypothesis` 库
|
||||
- 后端测试使用 `pytest` + FastAPI TestClient
|
||||
228
.kiro/specs/dataflow-field-completion/requirements.md
Normal file
228
.kiro/specs/dataflow-field-completion/requirements.md
Normal file
@@ -0,0 +1,228 @@
|
||||
# 需求文档:数据流字段补全与前后端联调
|
||||
|
||||
## 简介
|
||||
|
||||
本特性基于 `dataflow_2026-02-19_190440.md` 数据流分析报告,完成三大任务:
|
||||
1. 补全 11 张 ODS/DWD 表中缺失的字段映射(含 DDL 更新、ETL loader/task 代码同步、文档精化)
|
||||
2. 在 DWS 层新建库存汇总表,支持日/周/月三个粒度的库存数据汇总
|
||||
3. 管理后台(admin-web)前后端联调,确保 ETL 全流程可通过 Web 界面正确触发和执行
|
||||
|
||||
## 术语表
|
||||
|
||||
- **ETL_System**:飞球连接器 ETL 系统(`apps/etl/connectors/feiqiu/`),负责从上游 API 抽取数据并经 ODS→DWD→DWS 三层处理
|
||||
- **ODS**:Operational Data Store,原始数据层,保留 API 返回的原始字段
|
||||
- **DWD**:Data Warehouse Detail,明细数据层,经清洗、标准化后的业务字段
|
||||
- **DDL**:Data Definition Language,数据库表结构定义(位于 `db/etl_feiqiu/schemas/`)
|
||||
- **Loader**:ETL 加载器(`loaders/`),负责将 ODS 数据清洗映射到 DWD 表
|
||||
- **Task**:ETL 任务(`tasks/`),编排 loader 的执行逻辑
|
||||
- **Admin_Web**:管理后台(`apps/admin-web/`),React + Vite + Ant Design 前端
|
||||
- **Backend**:FastAPI 后端(`apps/backend/`),提供 ETL 调度和数据查询 API
|
||||
- **SCD2**:缓慢变化维度类型 2,用于维度表历史版本追踪
|
||||
- **BD_Manual**:业务数据字典文档(`docs/database/`),记录字段含义和映射关系
|
||||
- **Field_Mapping**:字段映射关系,描述 API JSON → ODS 列 → DWD 列的对应关系
|
||||
- **DWS**:Data Warehouse Summary,汇总数据层,按业务维度聚合的统计数据
|
||||
- **BaseDwsTask**:DWS 任务基类(`tasks/dws/base_dws_task.py`),提供 extract/transform/load 三阶段框架
|
||||
|
||||
## 执行依据
|
||||
|
||||
本需求文档的字段补全部分基于以下排查结论文档:
|
||||
- `export/SYSTEM/REPORTS/field_audit/field_review_for_user.md` — 逐表逐字段的排查结论与操作建议
|
||||
|
||||
## 需求
|
||||
|
||||
### 需求 1:assistant_accounts_master 字段补全
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望将助教账号档案表中 4 个未映射的 ODS 字段(system_role_id、job_num、cx_unit_price、pd_unit_price)补全到 DWD 层,以便下游分析可以使用完整的助教档案数据。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN ETL_System 执行 assistant_accounts_master 的 DWD 加载任务, THE Loader SHALL 将 ODS 列 `system_role_id` 映射到 DWD 目标表 `dim_assistant_ex` 的对应列
|
||||
2. WHEN ETL_System 执行 assistant_accounts_master 的 DWD 加载任务, THE Loader SHALL 将 ODS 列 `job_num`、`cx_unit_price`、`pd_unit_price` 映射到 DWD 目标表 `dim_assistant_ex` 的对应列
|
||||
3. WHEN 新字段被添加到 DWD 表, THE DDL SHALL 在 `db/etl_feiqiu/schemas/dwd.sql` 中包含对应的 ALTER TABLE 或 CREATE 语句
|
||||
4. WHEN 字段映射完成后, THE BD_Manual SHALL 更新对应的字段说明文档,消除"待补充""待分析"等模糊描述
|
||||
|
||||
### 需求 2:assistant_service_records 字段补全
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望将助教服务流水表中 3 个未映射的 ODS 字段(site_assistant_id、operator_id、operator_name)补全到 DWD 层,以便追踪服务操作员信息。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN ETL_System 执行 assistant_service_records 的 DWD 加载任务, THE Loader SHALL 将 ODS 列 `site_assistant_id`、`operator_id`、`operator_name` 映射到 DWD 目标表 `dwd_assistant_service_log_ex` 的对应列
|
||||
2. WHEN 新字段被添加到 DWD 表, THE DDL SHALL 在 `dwd.sql` 中包含对应的列定义
|
||||
3. WHEN 字段映射完成后, THE BD_Manual SHALL 更新对应的字段说明文档
|
||||
|
||||
### 需求 3:assistant_cancellation_records 字段补全
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望将助教废除记录表中 1 个未映射的 ODS 字段(assistanton)补全到 DWD 层。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN ETL_System 执行 assistant_cancellation_records 的 DWD 加载任务, THE Loader SHALL 将 ODS 列 `assistanton` 映射到 DWD 目标表 `dwd_assistant_trash_event_ex` 的对应列
|
||||
2. WHEN 新字段被添加到 DWD 表, THE DDL SHALL 在 `dwd.sql` 中包含对应的列定义
|
||||
3. WHEN 字段映射完成后, THE BD_Manual SHALL 对 `assistanton` 字段进行语义分析并补充精确说明
|
||||
|
||||
### 需求 4:store_goods_sales_records 字段补全
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望将门店商品销售流水表中 1 个未映射的 ODS 字段(discount_price)补全到 DWD 层,以便分析折后单价。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN ETL_System 执行 store_goods_sales_records 的 DWD 加载任务, THE Loader SHALL 将 ODS 列 `discount_price` 映射到 DWD 目标表 `dwd_store_goods_sale_ex` 的对应列
|
||||
2. WHEN 新字段被添加到 DWD 表, THE DDL SHALL 在 `dwd.sql` 中包含对应的列定义,类型为 `numeric`(金额精度)
|
||||
3. WHEN 字段映射完成后, THE BD_Manual SHALL 更新对应的字段说明文档
|
||||
|
||||
### 需求 5:member_balance_changes 字段补全
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望将会员余额变动表中 1 个未映射的 ODS 字段(relate_id)补全到 DWD 层,以便关联充值记录或订单。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN ETL_System 执行 member_balance_changes 的 DWD 加载任务, THE Loader SHALL 将 ODS 列 `relate_id` 映射到 DWD 目标表 `dwd_member_balance_change_ex` 的对应列
|
||||
2. WHEN 新字段被添加到 DWD 表, THE DDL SHALL 在 `dwd.sql` 中包含对应的列定义
|
||||
3. WHEN 字段映射完成后, THE BD_Manual SHALL 更新对应的字段说明文档
|
||||
|
||||
|
||||
### 需求 6:recharge_settlements 字段补全与映射建立
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望将充值结算表中 5 个 ODS→DWD 未映射字段补全,并为 5 个 DWD 无 ODS 源字段建立正确的映射关系,以便电费和券销售额数据完整流转。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN ETL_System 执行 recharge_settlements 的 DWD 加载任务, THE Loader SHALL 将 ODS 列 `electricityadjustmoney`、`electricitymoney`、`mervousalesamount`、`plcouponsaleamount`、`realelectricitymoney` 映射到 DWD 目标表 `dwd_recharge_order` 的对应列
|
||||
2. WHEN DWD 表存在无 ODS 源的列(`pl_coupon_sale_amount`、`mervou_sales_amount`、`electricity_money`、`real_electricity_money`、`electricity_adjust_money`), THE Loader SHALL 建立从 ODS 对应列到这些 DWD 列的映射关系
|
||||
3. WHEN 映射建立后, THE ETL_System SHALL 确保 ODS 列名(驼峰式)与 DWD 列名(蛇形式)之间的命名转换正确
|
||||
4. WHEN 字段映射完成后, THE DDL SHALL 同步更新,THE BD_Manual SHALL 更新对应的字段说明文档
|
||||
|
||||
### 需求 7:goods_stock_summary 新建 DWD 表与字段映射
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望为库存汇总表新建 DWD 目标表,并将 14 个 ODS 字段完整映射,以便库存数据可在 DWD 层使用。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN ETL_System 需要加载 goods_stock_summary 数据到 DWD 层, THE DDL SHALL 在 `dwd.sql` 中创建新的 DWD 目标表(如 `dwd_goods_stock_summary`)
|
||||
2. WHEN DWD 目标表创建后, THE Loader SHALL 将全部 14 个 ODS 列(sitegoodsid、goodsname、goodsunit、goodscategoryid、goodscategorysecondid、categoryname、rangestartstock、rangeendstock、rangein、rangeout、rangesale、rangesalemoney、rangeinventory、currentstock)映射到 DWD 目标表
|
||||
3. WHEN 新表创建后, THE ETL_System SHALL 创建对应的 DWD loader 和 task 代码
|
||||
4. WHEN 新表创建后, THE BD_Manual SHALL 为新表编写完整的字段说明文档
|
||||
|
||||
### 需求 8:goods_stock_movements 新建 DWD 表与字段映射
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望为库存变化记录表新建 DWD 目标表,并将 19 个 ODS 字段完整映射,以便库存变动明细可在 DWD 层使用。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN ETL_System 需要加载 goods_stock_movements 数据到 DWD 层, THE DDL SHALL 在 `dwd.sql` 中创建新的 DWD 目标表(如 `dwd_goods_stock_movement`)
|
||||
2. WHEN DWD 目标表创建后, THE Loader SHALL 将全部 19 个 ODS 列映射到 DWD 目标表
|
||||
3. WHEN 新表创建后, THE ETL_System SHALL 创建对应的 DWD loader 和 task 代码
|
||||
4. WHEN 新表创建后, THE BD_Manual SHALL 为新表编写完整的字段说明文档
|
||||
|
||||
### 需求 9:site_tables_master 字段补全
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望将台桌维表中 14 个未映射的 ODS 字段补全到 DWD 层,以便台桌配置信息完整可用。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN ETL_System 执行 site_tables_master 的 DWD 加载任务, THE Loader SHALL 将 14 个 ODS 列(sitename、appletQrCodeUrl、audit_status、charge_free、create_time、delay_lights_time、is_rest_area、light_status、only_allow_groupon、order_delay_time、self_table、tablestatusname、temporary_light_second、virtual_table)映射到 DWD 目标表 `dim_table_ex` 的对应列
|
||||
2. WHEN 新字段被添加到 DWD 表, THE DDL SHALL 在 `dwd.sql` 中包含对应的列定义
|
||||
3. WHEN 字段映射完成后, THE BD_Manual SHALL 更新对应的字段说明文档,消除"待补充""待分析"等模糊描述
|
||||
|
||||
### 需求 10:store_goods_master 字段补全与嵌套展开
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望将门店商品档案表中的平层未映射字段、嵌套对象字段、ODS→DWD 未映射字段全部补全,以便商品档案数据完整。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN ETL_System 执行 store_goods_master 的 ODS 加载任务, THE Loader SHALL 将 API 平层字段 `time_slot_sale` 映射到 ODS 表的对应列
|
||||
2. WHEN ETL_System 执行 store_goods_master 的 ODS 加载任务, THE Loader SHALL 将嵌套对象 `goodsStockWarningInfo` 的 4 个子字段(site_goods_id、sales_day、warning_day_max、warning_day_min)展开并映射到 ODS 表的对应列
|
||||
3. WHEN ETL_System 执行 store_goods_master 的 DWD 加载任务, THE Loader SHALL 将 ODS 列 `batch_stock_quantity`、`provisional_total_cost` 以及展开后的库存预警字段映射到 DWD 目标表(根据字段用途自动分配到 `dim_store_goods` 或 `dim_store_goods_ex`)
|
||||
4. WHEN 新字段被添加, THE DDL SHALL 同步更新 `ods.sql` 和 `dwd.sql`
|
||||
5. WHEN 字段映射完成后, THE BD_Manual SHALL 更新对应的字段说明文档
|
||||
|
||||
### 需求 11:tenant_goods_master 字段补全
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望将租户商品档案表中 1 个未映射的 ODS 字段(commoditycode)补全到 DWD 层。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN ETL_System 执行 tenant_goods_master 的 DWD 加载任务, THE Loader SHALL 将 ODS 列 `commoditycode` 映射到 DWD 目标表 `dim_tenant_goods_ex` 的对应列
|
||||
2. WHEN 新字段被添加到 DWD 表, THE DDL SHALL 在 `dwd.sql` 中包含对应的列定义
|
||||
3. WHEN 字段映射完成后, THE BD_Manual SHALL 更新对应的字段说明文档
|
||||
|
||||
### 需求 12:DWS 库存汇总(日/周/月)
|
||||
|
||||
**用户故事:** 作为数据分析师,我希望在 DWS 层拥有日度、周度、月度三个粒度的库存汇总表,以便按不同时间维度分析商品库存变化趋势。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN 需求 7(goods_stock_summary 新建 DWD 表)完成且 ODS 任务配置已修改(`requires_window=True` + `time_fields=("startTime", "endTime")`)并重新采集数据后, THE ETL_System SHALL 具备构建 DWS 库存汇总的数据基础
|
||||
2. WHEN ETL_System 执行 DWS_GOODS_STOCK_DAILY 任务, THE ETL_System SHALL 从 DWD 层 `dwd_goods_stock_summary` 提取数据,按日粒度汇总并写入 `dws.dws_goods_stock_daily_summary`
|
||||
3. WHEN ETL_System 执行 DWS_GOODS_STOCK_WEEKLY 任务, THE ETL_System SHALL 从 DWD 层提取数据,按周粒度汇总并写入 `dws.dws_goods_stock_weekly_summary`
|
||||
4. WHEN ETL_System 执行 DWS_GOODS_STOCK_MONTHLY 任务, THE ETL_System SHALL 从 DWD 层提取数据,按月粒度汇总并写入 `dws.dws_goods_stock_monthly_summary`
|
||||
5. THE DWS 库存汇总表 SHALL 包含以下字段:site_id、tenant_id、stat_date(汇总日期)、site_goods_id、goods_name、goods_unit、goods_category_id、goods_category_second_id、category_name(商品维度)、range_start_stock、range_end_stock、range_in、range_out、range_sale、range_sale_money、range_inventory、current_stock(库存指标)、stat_period(汇总粒度标识:'daily'/'weekly'/'monthly')
|
||||
6. THE DWS 库存汇总表 SHALL 以 `(site_id, stat_date, site_goods_id)` 为主键,支持按门店、日期、商品维度的唯一性约束
|
||||
7. WHEN DWS 库存汇总任务执行时, THE ETL_System SHALL 继承 `BaseDwsTask`,实现 `extract` / `transform` / `load` 三阶段
|
||||
8. WHEN DWS 库存汇总表创建后, THE DDL SHALL 在 `db/etl_feiqiu/schemas/dws.sql` 中包含建表语句,迁移脚本放在 `db/etl_feiqiu/migrations/`
|
||||
9. WHEN DWS 库存汇总任务代码创建后, THE ETL_System SHALL 将任务代码放在 `apps/etl/connectors/feiqiu/tasks/dws/` 目录下
|
||||
|
||||
### 需求 17:彻底移除 settlement_ticket_details
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望从项目中彻底移除 settlement_ticket_details(结账小票详情)相关的所有代码、DDL、配置、文档和数据,以便简化系统维护并消除无用的数据流。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN 移除任务完成后, THE ETL_System SHALL 不再包含 `ODS_SETTLEMENT_TICKET` 任务代码(从 `ods_tasks.py` 的 `ENABLED_ODS_CODES`、`ODS_TASK_CLASSES`、`OdsSettlementTicketTask` 类中移除)
|
||||
2. WHEN 移除任务完成后, THE DDL SHALL 不再包含 `ods.settlement_ticket_details` 表定义(从 `ods.sql` / `schema_ODS_doc.sql` 中移除建表语句和注释)
|
||||
3. WHEN 移除任务完成后, THE ETL_System SHALL 从以下位置移除所有 settlement_ticket_details 引用:
|
||||
- `tasks/ods/ods_tasks.py`(OdsTaskSpec、OdsSettlementTicketTask 类、ENABLED_ODS_CODES)
|
||||
- `tasks/verification/dwd_verifier.py`、`tasks/verification/ods_verifier.py`
|
||||
- `tasks/utility/manual_ingest_task.py`
|
||||
- `utils/json_store.py`
|
||||
- `scripts/check/check_ods_gaps.py`
|
||||
- `scripts/debug/debug_blackbox.py`
|
||||
4. WHEN 移除任务完成后, THE ETL_System SHALL 从 `db/etl_feiqiu/seeds/seed_ods_tasks.sql` 中移除 `ODS_SETTLEMENT_TICKET`
|
||||
5. WHEN 移除任务完成后, THE BD_Manual SHALL 从 `docs/database/etl_feiqiu_schema_migration.md` 和 ETL 任务文档中移除相关条目
|
||||
6. WHEN 移除任务完成后, THE ETL_System SHALL 编写迁移脚本 `DROP TABLE IF EXISTS ods.settlement_ticket_details` 和 `DROP INDEX IF EXISTS ods.idx_ods_settlement_ticket_details_latest`
|
||||
7. WHEN 移除任务完成后, THE ETL_System SHALL 从 `scripts/ops/` 下的分析脚本(`gen_full_dataflow_doc.py`、`gen_field_review_doc.py`、`gen_api_field_mapping.py`、`field_audit.py`、`export_dwd_field_review.py`、`dataflow_analyzer.py`、`check_ods_latest_indexes.py`)中移除相关引用
|
||||
8. WHEN 移除任务完成后, THE ETL_System SHALL 从单元测试 `tests/unit/test_ods_tasks.py` 中移除 `test_ods_settlement_ticket_by_payment_relate_ids` 测试
|
||||
|
||||
### 需求 13:文档精化
|
||||
|
||||
**用户故事:** 作为数据工程师,我希望对所有涉及的 BD_Manual 文档进行精细化更新,消除所有模糊描述,以便团队成员可以准确理解每个字段的含义。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN 文档精化任务执行时, THE BD_Manual SHALL 逐个文档、逐项排查所有"待补充""待处理""未确定""未定义"等缺失内容
|
||||
2. WHEN 文档精化任务执行时, THE BD_Manual SHALL 将"金额字段""XX 相关""XXX 类"等粗略说明替换为精确的字段语义描述
|
||||
3. WHEN 字段说明需要精化时, THE ETL_System SHALL 通过手动字段名称分析、上下文推测、遍历值/枚举值分析、代码取用情况分析来确定字段含义
|
||||
4. WHEN 文档更新完成后, THE BD_Manual SHALL 确保每个字段说明包含:字段类型、业务含义、取值范围或枚举值、在代码中的使用位置
|
||||
|
||||
### 需求 14:Admin-Web 前后端联调
|
||||
|
||||
**用户故事:** 作为系统管理员,我希望通过管理后台 Web 界面触发 ETL 全流程执行,以便可视化管理数据处理任务。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN 管理员在 Admin_Web 中配置 ETL 参数(全部门店、api_full、仅校验修复且校验前从 API 获取、自定义范围 2025-11-01 至 2026-02-20、窗口切分 10 天、force-full、全选常用功能), THE Backend SHALL 正确接收并解析这些参数
|
||||
2. WHEN Backend 接收到 ETL 执行请求, THE Backend SHALL 将参数转换为 ETL_System 可识别的命令并触发执行
|
||||
3. WHEN ETL 任务执行时, THE Admin_Web SHALL 实时展示任务执行状态和进度
|
||||
4. WHEN 所有选中的任务执行完成后, THE ETL_System SHALL 确保数据处理结果正确(源数据与落库数据/字段一致)
|
||||
|
||||
### 需求 15:ETL 执行计时机制
|
||||
|
||||
**用户故事:** 作为系统管理员,我希望 ETL 执行过程中有详细的计时记录,以便分析各步骤的性能瓶颈。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN ETL 任务开始执行, THE ETL_System SHALL 启动计时器,记录每个步骤和分步骤的开始时间
|
||||
2. WHEN 每个步骤完成时, THE ETL_System SHALL 记录该步骤的耗时(精确到毫秒)
|
||||
3. WHEN 全部任务执行完成后, THE ETL_System SHALL 输出详细颗粒度的计时结果文档,包含每个步骤名称、开始时间、结束时间、耗时
|
||||
|
||||
### 需求 16:黑盒测试机制
|
||||
|
||||
**用户故事:** 作为质量保证工程师,我希望在 ETL 全流程完成后执行黑盒测试,验证数据源与落库数据的一致性。
|
||||
|
||||
#### 验收标准
|
||||
|
||||
1. WHEN 所有 ETL 步骤顺利完成后, THE ETL_System SHALL 以黑盒测试者角度检查数据源和落库数据/字段情况是否一致
|
||||
2. WHEN 黑盒测试执行时, THE ETL_System SHALL 对比 API 源数据与 ODS 落库数据的字段完整性
|
||||
3. WHEN 黑盒测试执行时, THE ETL_System SHALL 对比 ODS 数据与 DWD 落库数据的映射正确性
|
||||
4. WHEN 黑盒测试完成后, THE ETL_System SHALL 输出黑盒测试报告,包含每张表的检查结果、差异明细、通过/失败状态
|
||||
304
.kiro/specs/dataflow-field-completion/tasks.md
Normal file
304
.kiro/specs/dataflow-field-completion/tasks.md
Normal file
@@ -0,0 +1,304 @@
|
||||
# 实现计划:数据流字段补全与前后端联调
|
||||
|
||||
## 概述
|
||||
|
||||
按"先排查确认 → 再 DDL 变更 → 再代码映射 → 再移除废弃表 → 再 DWS 汇总 → 再文档精化 → 最后联调"的顺序,分阶段推进。每个表的字段补全遵循"先确认再新增"原则。
|
||||
|
||||
执行依据:`export/SYSTEM/REPORTS/field_audit/field_review_for_user.md`(逐表逐字段排查结论)
|
||||
|
||||
## 任务
|
||||
|
||||
- [x] 1. 字段排查脚本与基础设施
|
||||
- [x] 1.1 编写字段排查脚本 `scripts/ops/field_audit.py`
|
||||
- 连接数据库,对每张目标表执行排查流程:查 DWD 现有列、查 FACT_MAPPINGS 现状、查 ODS 列、查自动映射
|
||||
- 输出排查记录表(markdown 格式),标注每个字段的排查结论和建议操作
|
||||
- 覆盖 11 张表的所有疑似缺失字段
|
||||
- _Requirements: 1.1-1.4, 2.1-2.3, 3.1-3.3, 4.1-4.3, 5.1-5.3, 6.1-6.4, 7.1-7.4, 8.1-8.4, 9.1-9.3, 10.1-10.5, 11.1-11.3_
|
||||
|
||||
- [x] 1.2 执行排查脚本,生成排查报告
|
||||
- 运行脚本,审查输出结果
|
||||
- _Requirements: 1.1-1.4_
|
||||
|
||||
- [x] 1.3 逐字段调查与推测,确认排查结论(由 Kiro 执行)
|
||||
- 结论文档:`export/SYSTEM/REPORTS/field_audit/field_review_for_user.md`
|
||||
- 脚本输出仅为线索,不能直接作为最终结论
|
||||
- 对脚本标记为"缺失"或"对不齐"的每个字段,Kiro 需逐一执行以下调查:
|
||||
- 查阅 FACT_MAPPINGS 源码,确认是否已以其他名称/表达式映射
|
||||
- 查阅 DWD DDL,确认是否已有同语义列(命名差异)
|
||||
- 查阅 ODS loader 代码,确认 ODS 列是否真实写入
|
||||
- 结合字段命名规律、上下文语义、业务逻辑进行推测
|
||||
- 必要时查询数据库实际数据(SELECT DISTINCT / 采样)辅助判断
|
||||
- 对每个字段标注最终决策:无需变更 / 仅补映射 / 新增列+映射 / 跳过(附理由)
|
||||
- 将调查过程和推测依据记录到排查报告中,确保可追溯
|
||||
- _Requirements: 1.1-1.4, 2.1-2.3, 3.1-3.3, 4.1-4.3, 5.1-5.3, 6.1-6.4, 7.1-7.4, 8.1-8.4, 9.1-9.3, 10.1-10.5, 11.1-11.3_
|
||||
|
||||
- [x] 2. Checkpoint - 排查结果确认
|
||||
- 此项已完成,最终文档为:`export/SYSTEM/REPORTS/field_audit/field_review_for_user.md`
|
||||
|
||||
- [x] 3. 🔴 映射错误修复(高优先级)
|
||||
- 依据:`field_review_for_user.md` 映射错误修复章节
|
||||
|
||||
- [x] 3.1 assistant_service_records — site_assistant_id 映射错误修正
|
||||
- 当前问题:DWD `dwd_assistant_service_log.site_assistant_id` 错误映射自 ODS `order_assistant_id`(订单级 ID),应映射自 ODS `site_assistant_id`(助教档案 ID)
|
||||
- 修正 FACT_MAPPINGS:将 DWD `site_assistant_id` 的 ODS 源从 `order_assistant_id` 改为 `site_assistant_id`
|
||||
- 新增 DWD 列 `order_assistant_id`(bigint)到 `dwd_assistant_service_log`,映射 ODS `order_assistant_id`
|
||||
- 编写迁移脚本
|
||||
- 需重新加载历史数据
|
||||
- _Requirements: 2.1, 2.2_
|
||||
|
||||
- [x] 3.2 store_goods_sales_records — discount_price 列名误导修正
|
||||
- 当前问题:DWD `discount_price` 实际映射自 ODS `discount_money`(折扣金额),而非 ODS `discount_price`(折后单价)
|
||||
- 将 DWD 列名 `discount_price` 重命名为 `discount_money`
|
||||
- 新增 DWD 列 `discount_price`(numeric),映射 ODS `discount_price`(折后单价)
|
||||
- 编写迁移脚本
|
||||
- _Requirements: 4.1, 4.2_
|
||||
|
||||
- [x] 3.3 store_goods_master — batch_stock_qty 和 provisional_total_cost 映射源修正
|
||||
- `batch_stock_qty` 的 FACT_MAPPINGS 从 `stock`(当前库存)改为 `batch_stock_quantity`(批次库存)
|
||||
- `provisional_total_cost` 的 FACT_MAPPINGS 从 `total_purchase_cost`(实际采购成本)改为 `provisional_total_cost`(暂估成本)
|
||||
- 需重新加载历史数据
|
||||
- _Requirements: 10.3_
|
||||
|
||||
- [x] 4. A 类表:新增 DWD 列 + FACT_MAPPINGS
|
||||
- 依据:`field_review_for_user.md` 各表"待新增/补映射字段"
|
||||
|
||||
- [x] 4.1 assistant_accounts_master — 新增 4 个字段到 dim_assistant_ex
|
||||
- 新增列:`system_role_id`(bigint)、`job_num`(text)、`cx_unit_price`(numeric(18,2))、`pd_unit_price`(numeric(18,2))
|
||||
- 更新 `dwd.sql`,添加 FACT_MAPPINGS 条目
|
||||
- 编写迁移脚本
|
||||
- _Requirements: 1.1, 1.2, 1.3_
|
||||
|
||||
- [x] 4.2 assistant_service_records — 新增 2 个字段到 dwd_assistant_service_log_ex
|
||||
- 新增列:`operator_id`(bigint)、`operator_name`(text)
|
||||
- 跳过 `siteprofile`(jsonb 嵌套列)
|
||||
- 更新 `dwd.sql`,添加 FACT_MAPPINGS 条目
|
||||
- 编写迁移脚本
|
||||
- _Requirements: 2.1, 2.2_
|
||||
|
||||
- [x] 4.3 assistant_cancellation_records — 更新 FACT_MAPPINGS
|
||||
- 更新映射:ODS `assistanton` → DWD `dwd_assistant_trash_event.assistant_no`
|
||||
- 跳过 `siteprofile`(jsonb 嵌套列)
|
||||
- _Requirements: 3.1_
|
||||
|
||||
- [x] 4.4 member_balance_changes — 新增 1 个字段到 dwd_member_balance_change_ex
|
||||
- 新增列:`relate_id`(bigint)— 关联业务单据 ID
|
||||
- 更新 `dwd.sql`,添加 FACT_MAPPINGS 条目
|
||||
- 编写迁移脚本
|
||||
- _Requirements: 5.1, 5.2_
|
||||
|
||||
- [x] 4.5 site_tables_master — 新增 14 个字段到 dim_table_ex
|
||||
- 新增列:`create_time`(timestamptz)、`light_status`(integer)、`tablestatusname`(text)、`sitename`(text)、`appletQrCodeUrl`(text)、`audit_status`(integer)、`charge_free`(integer)、`delay_lights_time`(integer)、`is_rest_area`(integer)、`only_allow_groupon`(integer)、`order_delay_time`(integer)、`self_table`(integer)、`temporary_light_second`(integer)、`virtual_table`(integer)
|
||||
- 更新 `dwd.sql`,添加 FACT_MAPPINGS 条目
|
||||
- 编写迁移脚本
|
||||
- _Requirements: 9.1, 9.2_
|
||||
|
||||
- [x] 4.6 tenant_goods_master — 无需变更(跳过)
|
||||
- `commoditycode` 与 `commodity_code` 100% 冗余(花括号包裹格式),已确认跳过
|
||||
- _Requirements: 11.1(已确认无需操作)_
|
||||
|
||||
- [x] 4.7 编写 A 类表字段映射属性测试
|
||||
- **Property 1: FACT_MAPPINGS 字段映射正确性**
|
||||
- **Validates: Requirements 1.1, 1.2, 2.1, 3.1, 4.1, 5.1, 9.1**
|
||||
|
||||
- [x] 5. B 类表:仅补 FACT_MAPPINGS / 修正映射
|
||||
- 依据:`field_review_for_user.md` B 类表章节
|
||||
|
||||
- [x] 5.1 recharge_settlements — 补充 5 个 FACT_MAPPINGS 条目
|
||||
- 仅补映射(DWD 列已存在,ODS/DWD 两侧数据全为 0,业务未启用):
|
||||
- `plcouponsaleamount → pl_coupon_sale_amount`
|
||||
- `mervousalesamount → mervou_sales_amount`
|
||||
- `electricitymoney → electricity_money`
|
||||
- `realelectricitymoney → real_electricity_money`
|
||||
- `electricityadjustmoney → electricity_adjust_money`
|
||||
- 无需 DDL 变更,无需迁移脚本
|
||||
- _Requirements: 6.1, 6.2, 6.3_
|
||||
|
||||
- [x] 5.2 编写 B 类表属性测试
|
||||
- **Property 2: FACT_MAPPINGS 引用完整性**
|
||||
- **Validates: Requirements 6.3**
|
||||
|
||||
- [x] 5.5. Checkpoint - 映射修复与 A/B 类表完成确认
|
||||
- 确保所有映射错误已修正、A/B 类表的 FACT_MAPPINGS、DDL、迁移脚本都已更新
|
||||
- Ask the user if questions arise.
|
||||
|
||||
- [x] 6. C 类表:新建 DWD 表与完整映射
|
||||
- 依据:`field_review_for_user.md` C 类表章节
|
||||
|
||||
- [x] 6.1 goods_stock_summary — 修改 ODS 配置 + 新建 DWD 表
|
||||
- 步骤 1:修改 ODS 任务配置 `requires_window=True` + `time_fields=("startTime", "endTime")`
|
||||
- 步骤 2:重新采集历史数据(按时间窗口分批)
|
||||
- 步骤 3:编写 DDL 创建 `dwd.dwd_goods_stock_summary`(14 个字段)
|
||||
- 步骤 4:在 `TABLE_MAP` 中注册,在 `FACT_MAPPINGS` 中添加映射
|
||||
- 步骤 5:创建 DWD loader 和 task 代码
|
||||
- 编写迁移脚本
|
||||
- _Requirements: 7.1, 7.2, 7.3_
|
||||
|
||||
- [x] 6.2 goods_stock_movements — 新建 DWD 表
|
||||
- 编写 DDL 创建 `dwd.dwd_goods_stock_movement`(19 个字段,事实表,按 createtime 增量加载)
|
||||
- 在 `TABLE_MAP` 中注册,在 `FACT_MAPPINGS` 中添加映射(驼峰 → 蛇形命名)
|
||||
- 创建 DWD loader 和 task 代码
|
||||
- 编写迁移脚本
|
||||
- _Requirements: 8.1, 8.2, 8.3_
|
||||
|
||||
- [x] 6.3 编写 C 类表属性测试
|
||||
- **Property 3: TABLE_MAP 覆盖完整性**
|
||||
- **Validates: Requirements 7.2, 8.2**
|
||||
|
||||
- [x] 7. Checkpoint - 全部字段补全完成
|
||||
- 确保所有 11 张表的字段补全工作完成,所有测试通过,ask the user if questions arise.
|
||||
|
||||
- [x] 7.3. 彻底移除 settlement_ticket_details
|
||||
- [x] 7.3.1 移除 ETL 核心代码中的 settlement_ticket_details
|
||||
- 从 `tasks/ods/ods_tasks.py` 中移除:`OdsTaskSpec("ODS_SETTLEMENT_TICKET", ...)`、`OdsSettlementTicketTask` 类、`ENABLED_ODS_CODES` 中的条目、`ODS_TASK_CLASSES` 覆盖
|
||||
- 从 `tasks/verification/dwd_verifier.py` 中移除主键映射条目
|
||||
- 从 `tasks/verification/ods_verifier.py` 中移除相关注释和特殊处理
|
||||
- 从 `tasks/utility/manual_ingest_task.py` 中移除表映射和配置
|
||||
- 从 `utils/json_store.py` 中移除 `/order/getordersettleticketnew` 路径映射
|
||||
- _Requirements: 17.1, 17.3_
|
||||
|
||||
- [x] 7.3.2 移除 DDL、种子数据和迁移脚本
|
||||
- 从 `db/etl_feiqiu/schemas/ods.sql` 和 `schema_ODS_doc.sql` 中移除建表语句和注释
|
||||
- 从 `db/etl_feiqiu/seeds/seed_ods_tasks.sql` 中移除 `ODS_SETTLEMENT_TICKET`
|
||||
- 编写迁移脚本:`DROP TABLE IF EXISTS ods.settlement_ticket_details`、`DROP INDEX`、`DELETE FROM meta.ods_task_registry`
|
||||
- _Requirements: 17.2, 17.4, 17.6_
|
||||
|
||||
- [x] 7.3.3 移除分析脚本和工具中的引用
|
||||
- 从 `scripts/ops/` 下移除:`gen_full_dataflow_doc.py`、`gen_field_review_doc.py`、`gen_api_field_mapping.py`、`field_audit.py`、`export_dwd_field_review.py`、`dataflow_analyzer.py`、`check_ods_latest_indexes.py` 中的相关引用
|
||||
- 从 `scripts/check/check_ods_gaps.py` 中移除 `_check_settlement_tickets` 函数及调用
|
||||
- 从 `scripts/debug/debug_blackbox.py` 中移除跳过逻辑
|
||||
- _Requirements: 17.7_
|
||||
|
||||
- [x] 7.3.4 移除文档和测试中的引用
|
||||
- 从 `docs/database/etl_feiqiu_schema_migration.md` 中移除索引条目
|
||||
- 从 `apps/etl/connectors/feiqiu/docs/etl_tasks/` 中移除任务表格条目
|
||||
- 从 `tests/unit/test_ods_tasks.py` 中移除 `test_ods_settlement_ticket_by_payment_relate_ids`
|
||||
- _Requirements: 17.5, 17.8_
|
||||
|
||||
- [x] 7.5. DWS 库存汇总(日/周/月)
|
||||
- 前置依赖:任务 6.1(goods_stock_summary DWD 表)完成、ODS 任务配置修改(`requires_window=True`)完成并重新采集数据
|
||||
|
||||
- [x] 7.5.1 编写 DWS 库存汇总 DDL 与迁移脚本
|
||||
- 在 `db/etl_feiqiu/schemas/dws.sql` 中添加三张表的建表语句:`dws_goods_stock_daily_summary`、`dws_goods_stock_weekly_summary`、`dws_goods_stock_monthly_summary`
|
||||
- 编写迁移脚本 `db/etl_feiqiu/migrations/{date}__create_dws_goods_stock_summary.sql`
|
||||
- 主键:`(site_id, stat_date, site_goods_id)`
|
||||
- 字段:site_id, tenant_id, stat_date, site_goods_id, goods_name, goods_unit, goods_category_id, goods_category_second_id, category_name, range_start_stock, range_end_stock, range_in, range_out, range_sale, range_sale_money, range_inventory, current_stock, stat_period, created_at, updated_at
|
||||
- _Requirements: 12.5, 12.6, 12.8_
|
||||
|
||||
- [x] 7.5.2 实现 DWS_GOODS_STOCK_DAILY 任务
|
||||
- 在 `apps/etl/connectors/feiqiu/tasks/dws/` 下创建 `goods_stock_daily_task.py`
|
||||
- 继承 `BaseDwsTask`,实现 `extract` / `transform` / `load` 三阶段
|
||||
- extract:从 `dwd.dwd_goods_stock_summary` 按时间范围查询
|
||||
- transform:按日粒度汇总,`stat_period='daily'`
|
||||
- load:upsert 写入 `dws.dws_goods_stock_daily_summary`
|
||||
- _Requirements: 12.2, 12.7_
|
||||
|
||||
- [x] 7.5.3 实现 DWS_GOODS_STOCK_WEEKLY 任务
|
||||
- 创建 `goods_stock_weekly_task.py`,按 ISO 周分组,`stat_date` = 周一日期,`stat_period='weekly'`
|
||||
- _Requirements: 12.3, 12.7_
|
||||
|
||||
- [x] 7.5.4 实现 DWS_GOODS_STOCK_MONTHLY 任务
|
||||
- 创建 `goods_stock_monthly_task.py`,按自然月分组,`stat_date` = 月首日期,`stat_period='monthly'`
|
||||
- _Requirements: 12.4, 12.7_
|
||||
|
||||
- [x] 7.5.5 注册 DWS 库存汇总任务到任务调度
|
||||
- 在任务注册表中添加 `DWS_GOODS_STOCK_DAILY`、`DWS_GOODS_STOCK_WEEKLY`、`DWS_GOODS_STOCK_MONTHLY`
|
||||
- 确保任务依赖关系正确(依赖 DWD goods_stock_summary 加载完成)
|
||||
- _Requirements: 12.9_
|
||||
|
||||
- [x] 7.5.6 编写 DWS 库存汇总属性测试
|
||||
- **Property 8: DWS 库存汇总粒度聚合正确性**
|
||||
- **Validates: Requirements 12.2, 12.3, 12.4, 12.5, 12.6**
|
||||
|
||||
|
||||
- [x] 8. 文档精化
|
||||
- [x] 8.1 精化 A/B/C 类表涉及的 BD_Manual 文档
|
||||
- 逐个文档、逐项排查所有"待补充""待处理""未确定""未定义"等缺失内容
|
||||
- 将"金额字段""XX 相关""XXX 类"等粗略说明替换为精确的字段语义描述
|
||||
- 通过字段名称分析、上下文推测、遍历值/枚举值分析、代码取用情况分析确定字段含义
|
||||
- 确保每个字段说明包含:字段类型、业务含义、取值范围或枚举值、在代码中的使用位置
|
||||
- _Requirements: 13.1, 13.2, 13.3, 13.4_
|
||||
|
||||
- [x] 8.2 更新 dataflow 分析报告中涉及表的字段说明
|
||||
- 同步更新 `docs/database/` 下对应的文档
|
||||
- _Requirements: 1.4, 2.3, 3.3, 4.3, 5.3, 6.4, 7.4, 8.4, 9.3, 10.5, 11.3_
|
||||
|
||||
- [x] 9. Checkpoint - 文档精化完成
|
||||
- 确保所有文档更新完毕,无遗留的"待补充"标记,ask the user if questions arise.
|
||||
|
||||
- [x] 10. Admin-Web 前后端联调
|
||||
- [x] 10.1 排查并修复后端 ETL 执行 API
|
||||
- 检查 `apps/backend/app/routers/` 中 ETL 执行相关路由
|
||||
- 确保参数解析正确:全部门店、api_full、仅校验修复且校验前从 API 获取、自定义范围 2025-11-01 至 2026-02-20、窗口切分 10 天、force-full、全选常用功能
|
||||
- 确保参数正确转换为 ETL CLI 命令
|
||||
- _Requirements: 14.1, 14.2_
|
||||
|
||||
- [x] 10.2 排查并修复前端 TaskManager 页面
|
||||
- 检查 `apps/admin-web/src/pages/TaskManager.tsx` 中的参数配置表单
|
||||
- 确保所有参数选项可正确选择和提交
|
||||
- 确保任务执行状态实时展示(WebSocket 日志流)
|
||||
- _Requirements: 14.3_
|
||||
|
||||
- [x] 10.3 实现 ETL 执行计时器模块
|
||||
- 在 `apps/etl/connectors/feiqiu/utils/` 中新增计时器工具
|
||||
- 记录每个步骤和分步骤的开始时间、结束时间、耗时(精确到毫秒)
|
||||
- 全部任务完成后输出计时结果文档
|
||||
- _Requirements: 15.1, 15.2, 15.3_
|
||||
|
||||
- [x] 10.4 编写计时器属性测试
|
||||
- **Property 7: 计时器记录完整性**
|
||||
- **Validates: Requirements 15.2**
|
||||
|
||||
- [x] 10.5 编写 ETL 参数解析属性测试
|
||||
- **Property 5: ETL 参数解析与 CLI 命令构建正确性**
|
||||
- **Validates: Requirements 14.1, 14.2**
|
||||
|
||||
- [x] 11. 黑盒测试机制
|
||||
- [x] 11.1 实现数据一致性检查器
|
||||
- 在 `apps/etl/connectors/feiqiu/quality/` 中新增一致性检查模块
|
||||
- 实现 API 源数据 vs ODS 落库数据的字段完整性对比
|
||||
- 实现 ODS 数据 vs DWD 落库数据的映射正确性对比
|
||||
- 输出黑盒测试报告(每张表的检查结果、差异明细、通过/失败状态)
|
||||
- _Requirements: 16.1, 16.2, 16.3, 16.4_
|
||||
|
||||
- [x] 11.2 编写数据一致性检查属性测试
|
||||
- **Property 6: 数据一致性检查正确性**
|
||||
- **Validates: Requirements 16.2, 16.3**
|
||||
|
||||
- [x] 12. 端到端联调验证
|
||||
- [x] 12.1 执行完整 ETL 流程并验证数据正确性
|
||||
- 将 `EtlTimer` 集成到 `orchestration/flow_runner.py` 的 `FlowRunner.run()` 方法中
|
||||
- 增量 ETL 和校验分支均包裹计时步骤(`INCREMENT_ETL`、`VERIFICATION`、`FETCH_BEFORE_VERIFY`)
|
||||
- `timer.finish(write_report=True)` 在 Flow 结束时自动输出计时报告到 `ETL_REPORT_ROOT`
|
||||
- 产出物:`export/ETL-Connectors/feiqiu/REPORTS/etl_timing_*.md`
|
||||
- _Requirements: 14.4, 15.3_
|
||||
|
||||
- [x] 12.2 执行黑盒测试并生成报告
|
||||
- 将 `ConsistencyChecker` 集成到 `FlowRunner.run()` 的 `_run_post_consistency_check()` 方法中
|
||||
- ETL Flow 完成后自动运行一致性检查(API vs ODS + ODS vs DWD),输出报告到 `ETL_REPORT_ROOT`
|
||||
- 独立验证脚本 `scripts/ops/run_post_etl_reports.py` 确认报告生成正常
|
||||
- 实际执行结果:API vs ODS 22/22 通过,ODS vs DWD 38/42 通过
|
||||
- 产出物:`export/ETL-Connectors/feiqiu/REPORTS/consistency_report_*.md`
|
||||
- _Requirements: 16.1, 16.4_
|
||||
|
||||
- [x] 12.3 前后端浏览器联调验证(2026-02-20)
|
||||
- 启动后端 `uvicorn app.main:app --reload`(localhost:8000)+ 前端 `pnpm dev`(localhost:5173)
|
||||
- 浏览器登录管理后台,进入"任务配置"页面
|
||||
- 配置:Flow=ods_dwd, 处理模式=仅增量, dry-run=✓, 本地JSON=✓, 回溯24h
|
||||
- 点击"直接执行"→ 自动跳转"任务管理 > 历史"tab
|
||||
- 验证结果:status=success, duration=22.5s, exit_code=0
|
||||
- CLI 命令正确构建:`python -m cli.main --flow ods_dwd --processing-mode increment_only --tasks DWD_LOAD_FROM_ODS --lookback-hours 24 --overlap-seconds 600 --dry-run --data-source offline --store-id 2790685415443269`
|
||||
- 执行日志实时推送到前端 Modal(WebSocket /ws/logs/{id})✅
|
||||
- 计时报告自动生成:`etl_timing_20260220_073610.md`(2步骤,总耗时20.78s)✅
|
||||
- 一致性检查报告自动生成:`consistency_report_20260220_073610.md` ✅
|
||||
- _Requirements: 14.1, 14.2, 14.3, 14.4, 15.3, 16.4_
|
||||
|
||||
- [x] 13. Final checkpoint - 全部完成
|
||||
- 确保所有字段补全、文档精化、前后端联调、黑盒测试均已完成,ask the user if questions arise.
|
||||
|
||||
## 备注
|
||||
|
||||
- 标记 `*` 的任务为可选,可跳过以加速 MVP
|
||||
- 每个任务引用具体需求编号以确保可追溯
|
||||
- Checkpoint 确保增量验证
|
||||
- 属性测试验证通用正确性属性,单元测试验证具体示例和边界情况
|
||||
- 所有涉及 `loaders/`、`tasks/`、`db/` 的变更属于高风险路径,完成后需触发 `/audit`
|
||||
Reference in New Issue
Block a user