Files
Neo-ZQYY/.kiro/specs/gift-card-breakdown/tasks.md

8.1 KiB
Raw Blame History

Implementation Plan: 赠送卡矩阵细分数据 (gift-card-breakdown)

Overview

贯穿全栈数据链路的改动DDL 新增 6 字段 → ETL 拆分填充 → RLS 视图 + FDW 同步 → 后端 SQL + 接口返回 → 小程序替换 mock。消费行因上游 API 限制,细分列保持 0。

Tasks

  • 1. DDL 迁移与基线同步

    • 1.1 创建 DDL 迁移脚本 db/etl_feiqiu/migrations/2026-xx-xx_add_gift_breakdown_fields.sql
      • ALTER TABLE 新增 6 个 NUMERIC(14,2) 字段NOT NULL DEFAULT 0
      • 使用 ADD COLUMN IF NOT EXISTS 保证幂等
      • Requirements: 1.1, 1.2
    • 1.2 同步 DDL 基线文件 docs/database/ddl/etl_feiqiu__dws.sql
      • dws_finance_recharge_summary 表定义中追加 6 个新字段
      • Requirements: 1.1
  • 2. ETL 赠送卡余额拆分

    • 2.1 修改 _extract_card_balances() 按 card_type_id 分组返回细分余额
      • 文件:apps/etl/connectors/feiqiu/tasks/dws/finance_recharge_task.py
      • 新增 GIFT_TYPE_FIELD_MAP 常量映射 card_type_id → 字段名
      • 返回值新增 gift_liquor_balancegift_table_fee_balancegift_voucher_balance
      • 保留原有 gift_balance 字段(向后兼容)
      • 某种卡类型无记录时对应字段返回 0
      • Requirements: 2.1, 2.2, 2.3
    • 2.2 编写属性测试ETL 余额提取 round-trip
      • Property 3: ETL 余额提取 round-trip
      • 生成随机 dim_member_card_account 记录mock DB验证各类型余额等于对应 card_type_id 的 balance 之和
      • 当某种卡类型无记录时,对应余额为 0
      • Validates: Requirements 2.1, 2.2, 2.3, 10.1
  • 3. ETL 赠送卡新增充值拆分

    • 3.1 新增 _extract_gift_recharge_breakdown() 方法
      • 文件:apps/etl/connectors/feiqiu/tasks/dws/finance_recharge_task.py
      • SQLdwd_recharge_order JOIN dim_member_card_accounttenant_member_card_idtenant_member_id)按 card_type_id 分组
      • 新增 GIFT_RECHARGE_FIELD_MAP 常量映射
      • 返回 {gift_liquor_recharge, gift_table_fee_recharge, gift_voucher_recharge},缺失卡类型默认 0
      • Requirements: 3.1, 3.2, 3.3
    • 3.2 编写属性测试ETL 新增提取 round-trip
      • Property 4: ETL 新增提取 round-trip
      • 生成随机 dwd_recharge_order + dim_member_card_account 记录mock DB验证各类型新增等于对应 card_type_id 的 point_amount 之和
      • 当某种卡类型无充值记录时,对应新增为 0
      • Validates: Requirements 3.1, 3.2, 3.3, 10.2
  • 4. ETL transform 合并细分字段

    • 4.1 修改 extract() 调用新方法并传递结果
      • 文件:apps/etl/connectors/feiqiu/tasks/dws/finance_recharge_task.py
      • 在 extract 返回值中新增 gift_recharge_breakdown key
      • Requirements: 4.1
    • 4.2 修改 transform() 将 6 个新字段写入 record dict
      • 使用 self.safe_decimal() 处理值,缺失 key 时填充 0
      • 沿用现有 delete-before-insert 幂等策略
      • Requirements: 4.1, 4.2, 4.3
    • 4.3 编写属性测试transform 正确合并细分字段
      • Property 5: transform 正确合并细分字段
      • 生成随机 card_balances dict 和 gift_recharge_breakdown dict验证 record 包含 6 个字段且值正确
      • 输入 dict 缺少某个 key 时,对应字段为 0
      • Validates: Requirements 4.1, 4.2
  • 5. Checkpoint — ETL 层验证

    • Ensure all tests pass, ask the user if questions arise.
  • 6. 数据库视图层同步

    • 6.1 RLS 视图重建 app.v_dws_finance_recharge_summary
      • 创建迁移脚本 db/zqyy_app/migrations/
      • CREATE OR REPLACE VIEW 包含全部 6 个新字段
      • 保持 site_id 行级安全过滤策略不变
      • Requirements: 5.1, 5.2, 5.3
    • 6.2 FDW 外部表同步
      • 创建/更新幂等脚本(先 DROP 再 IMPORT FOREIGN SCHEMA
      • 支持重复执行不报错
      • Requirements: 6.1, 6.2
  • 7. 后端接口修改

    • 7.1 修改 fdw_queries.get_finance_recharge() SQL 查询
      • 文件:apps/backend/app/services/fdw_queries.py
      • SQL 新增 6 个字段的 SUM 聚合
      • Requirements: 7.1
    • 7.2 修改 gift_rows 构建逻辑
      • 余额行:liquor/table_fee/voucher 填充对应细分余额
      • 新增行:liquor/table_fee/voucher 填充对应细分新增,total 使用三个细分之和
      • 消费行:liquor/table_fee/voucher 保持 0total 返回消费总额
      • Requirements: 7.2, 7.3, 7.4, 8.1, 8.2
    • 7.3 修改 _empty_recharge_data() 空默认值同步
      • 确保新增 6 个字段在空数据结构中默认为 0
      • Requirements: 7.5
    • 7.4 编写属性测试:余额恒等式
      • Property 1: 余额恒等式
      • 生成随机三种余额,验证 gift_card_balance = gift_liquor_balance + gift_table_fee_balance + gift_voucher_balance
      • Validates: Requirements 1.3, 10.3
    • 7.5 编写属性测试:新增恒等式
      • Property 2: 新增恒等式
      • 生成随机三种新增,验证 recharge_gift = gift_liquor_recharge + gift_table_fee_recharge + gift_voucher_recharge
      • Validates: Requirements 1.4
    • 7.6 编写属性测试:后端接口返回正确细分数据
      • Property 6: 后端接口返回正确的细分数据
      • 生成随机 DWS 行mock FDW 查询,验证 gift_rows 余额行和新增行的细分值等于对应字段 SUM
      • Validates: Requirements 7.2, 7.3
    • 7.7 编写属性测试:消费行细分列始终为 0
      • Property 7: 消费行细分列始终为 0
      • 验证 gift_rows 消费行的 liquor.valuetable_fee.valuevoucher.value 始终为 0
      • Validates: Requirements 7.4, 8.1, 8.2
    • 7.8 编写属性测试:环比计算对新字段正确适配
      • Property 8: 环比计算对新字段正确适配
      • 生成随机当期/上期数据,验证 compare=1 时 gift_rows 每个 cell 的 compare 等于 calc_compare(当期值, 上期值)
      • Validates: Requirements 7.6
  • 8. Checkpoint — 后端层验证

    • Ensure all tests pass, ask the user if questions arise.
  • 9. 小程序联调

    • 9.1 替换 board-finance.ts 中 mock 数据为真实 API 调用
      • 文件:apps/miniprogram/miniprogram/pages/board-finance/board-finance.ts
      • 移除 giftRows 硬编码 mock 数据
      • 使用 Finance_Board_API 返回的真实数据
      • 字段映射:liquor→winetable_fee→tablevoucher→coupon,在数据转换层处理
      • API 返回错误或超时时展示加载失败提示,不显示 mock 数据
      • Requirements: 9.1, 9.2, 9.3, 9.4
  • 10. 数据一致性验证

    • 10.1 创建验证 SQL 脚本
      • 验证余额恒等式:gift_card_balance = 三种余额之和
      • 验证新增恒等式:recharge_gift = 三种新增之和
      • 验证 DWS 与 DWD 源数据一致DWS 各类型余额 = DWD dim_member_card_account 对应 card_type_id 的 balance 之和
      • 脚本放置在 scripts/ops/ 或迁移目录
      • Requirements: 10.1, 10.2, 10.3
  • 11. BD 手册更新

    • 11.1 更新 BD_manual_dws_finance_recharge_summary.md
      • 文件:apps/etl/connectors/feiqiu/docs/database/DWS/main/BD_manual_dws_finance_recharge_summary.md
      • 新增 6 个字段的说明(字段名、类型、含义、数据来源)
      • 更新恒等式约束说明
      • 更新数据流向描述
      • Requirements: 1.1, 1.3, 1.4
  • 12. Final checkpoint — 全链路验证

    • Ensure all tests pass, ask the user if questions arise.

Notes

  • Tasks marked with * are optional and can be skipped for faster MVP
  • 设计文档使用 PythonETL、SQLDDL/查询、TypeScript小程序任务中代码示例沿用对应语言
  • 消费行因上游飞球 API 限制(dwd_settlement_head.gift_card_amount 仅提供总额),细分列保持 0
  • 属性测试使用 hypothesis 库,测试文件统一放置在 tests/test_gift_card_breakdown_properties.py
  • 单元测试放置在各模块的 tests/ 目录下
  • 所有 DDL 迁移脚本使用 IF NOT EXISTS 保证幂等
  • card_type_id 硬编码沿用现有 GIFT_CARD_TYPE_IDS 常量