yumi-java/rc-service/rc-service-console/docs/country-dashboard-metric-reconcile-plan.md

94 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 国家数据大屏口径对账与修复计划
## 基准说明
- 对账日期:`2026-05-27`
- 统计时区:`Asia/Riyadh`
- 统计窗口:`2026-05-27 00:00:00``2026-05-28 00:00:00`
- 系统来源:`LIKEI`
- 对账方式:旧 Java 源表口径结果 vs 当前 `country_dashboard_*` 预聚合结果。
- 注意:日内数据会继续增长,金额和人数会随时间变化。本文中的“之前数据”来自本轮对账快照;后续修复验证必须重新跑同一窗口源表对账。
## 总体结论
当前大屏切到预聚合后,差异主要来自三类问题:
1. 旧 Java 是直接按 Mongo/SQL 源表字段聚合CDC worker 有些字段改成了用户国家表、wallet 事件或部分表事件,口径没有完全复刻。
2. 部分 Mongo 源表没有进入 CDC日活、礼物流水、幸运礼物、工资转移等需要单独的 reconcile/增量任务。
3. 留存基数与留存命中当前使用 worker 自己的用户国家表和活跃集合,和旧 Java 的注册 cohort + active log 口径不一致。
## 字段对账表
| 字段 | 旧 Java 口径 | 旧口径源表结果 | 当前预聚合结果 | 差异 | 差异原因 | 修复方案 | 状态 |
| --- | --- | ---: | ---: | ---: | --- | --- | --- |
| 新增 | 按 admin 用户列表展示口径统计 `user_base_info` 创建时间,展示日等于 `create_time + 8h` 后的日期;按用户国家归组。 | 之前用户列表显示约 57部署期间增长到 60 | 修复前明显少算 | 修复前不稳定 | worker 原先按数据库原始时间截日,和 admin 用户列表展示日不一致。 | 已改 worker 的新用户统计窗口为 `create_time + 8h` 展示日;回填目标日期并重建 `DAY/ALL`。 | 已修 |
| 日活 | Mongo `user_daily_active_log`,按 `activeDate + sysOrigin` 过滤;先按 `registerCountryCode,userId` 去重,再按 `registerCountryCode` 计数。 | 984 | 844 | -140 | worker 原先读取 active log 后,又强依赖 `dashboard_cdc_user_country` 做国家归类,用户国家缺失或删除标记会把活跃用户过滤掉;旧 Java 不查用户国家表。 | 已改 worker日活直接使用 active log 的 `sysOrigin/registerCountryCode`;只有 active log 国家为空才 fallback 用户国家表。 | 已修 |
| 新增充值 | 旧 Java 订单口径中,新注册用户在窗口内产生的充值。 | 2 | 2 | 0 | 当前已对齐。 | 保持现状;后续只做回归验证。 | 正常 |
| Google 充值 | Google 订单成功支付金额,按订单完成时间落入统计窗口。 | 63 | 63 | 0 | 当前已对齐。 | 保持现状;后续只做回归验证。 | 正常 |
| MifaPay 充值 | MifaPay 订单成功支付金额,按订单完成时间落入统计窗口。 | 0 | 0 | 0 | 当前已对齐。 | 保持现状;后续只做回归验证。 | 正常 |
| 币商充值 | 币商/代理充值流水,旧 Java 从币商充值相关 SQL 表聚合。 | 0 | 0 | 0 | 当前已对齐。 | 保持现状;后续只做回归验证。 | 正常 |
| 总充值 | Google + MifaPay + 币商等充值汇总。 | 63 | 63 | 0 | 当前已对齐。 | 保持现状;后续只做回归验证。 | 正常 |
| 工资兑换 | 旧 Java 包含 SQL 工资账户流水和 Mongo bank 流水中的工资兑换口径。 | 6.75 | 0 | -6.75 | worker 当前没有完整接入工资兑换相关 SQL/Mongo 流水。 | 增加工资兑换 reconcile读取旧 Java 使用的 SQL 表和 Mongo `user_bank_running_water` 条件,按用户国家归组写 `salary_exchange`;补回填。 | 待修 |
| 工资转移 | 旧 Java 来自 Mongo `user_bank_running_water` 的工资转移口径。 | 38 | 0 | -38 | worker 当前未接入 Mongo bank 转移流水。 | 增加 Mongo bank reconcile复刻旧 Java 的转移类型、状态、时间字段、金额单位,写 `salary_transfer`;补回填。 | 待修 |
| 礼物消耗 | Mongo `gift_give_running_water`;旧 Java 条件包含 `refunded != true``userId != null`、窗口内 `createTime`、指定 `sysOrigin``luckyGift != true``originId` 为数字、`dynamicContentId` 为空或不存在;金额取 `giftValue.actualAmount`。 | 7,276,368 | 3,327,288 | -3,949,080 | worker 当前没有完整复刻 Mongo `gift_give_running_water` 条件,可能只覆盖部分礼物事件或国家映射。 | 新增/修正 gift reconcile直接按旧 Java Mongo 条件聚合普通礼物消耗,写 `gift_consume`;不要从 wallet `LUCKY_GIFT` 反推普通礼物。 | 待修 |
| 幸运礼物流水 | 旧 Java 从 `game_lucky_gift_count` 聚合幸运礼物总流水。 | 2,279,050 | 0 | -2,279,050 | `game_lucky_gift_count` 有源数据,但 worker/预聚合没有写入 `lucky_gift_total_flow`。 | 新增 lucky gift reconcile按旧 Java 查询条件读取 `game_lucky_gift_count`,写 `lucky_gift_total_flow`,同时写用户去重表 `LUCKY_GIFT_USER`。 | 待修 |
| 幸运礼物人数 | 旧 Java 从 `game_lucky_gift_count` 按用户去重统计参与人数。 | 101 | 0 | -101 | 同幸运礼物流水,用户去重表未写。 | lucky gift reconcile 写 `country_dashboard_period_user_metric.metric_type='LUCKY_GIFT_USER'`,再重建汇总人数。 | 待修 |
| 幸运礼物返奖 | 旧 Java 从 `game_lucky_gift_count` 聚合返奖金额。 | 1,892,900 | 0 | -1,892,900 | 同幸运礼物流水,返奖字段未写。 | lucky gift reconcile 写 `lucky_gift_payout`。 | 待修 |
| 幸运礼物利润 | `幸运礼物流水 - 幸运礼物返奖`。 | 386,150 | 0 | -386,150 | 流水和返奖都缺失导致利润为 0。 | 修复幸运礼物流水和返奖后自动恢复;利润不应单独写源数据。 | 待修 |
| 游戏流水 | 旧 Java 从 `wallet_gold_asset_record_*` 和游戏统计表按游戏下注/消耗事件聚合。 | 109,688,935 | 74,509,547 | -35,179,388 | worker 当前游戏聚合少覆盖部分 `event_type` 或表来源,且用户去重也随之少算。 | 按旧 Java 的 game event_type 列表逐项核对,补齐 consume 事件映射;对每类事件做源表 vs 预聚合差异拆分。 | 待修 |
| 游戏人数 | 旧 Java 按游戏流水参与用户去重。 | 176 | 113 | -63 | 游戏流水事件少覆盖,导致用户去重同步少算。 | 游戏流水修复时同步写 `GAME_USER` 去重表;重建 `DAY/ALL`。 | 待修 |
| 游戏返奖 | 旧 Java 从游戏返奖/中奖事件聚合。 | 107,776,247 | 72,064,472 | -35,711,775 | worker 当前 payout 事件覆盖不完整,返奖少算幅度大于流水少算。 | 按旧 Java payout event_type 和 `game_lucky_box_count` 等来源补齐映射;验证 consume/payout 各自差值。 | 待修 |
| 游戏利润 | `游戏流水 - 游戏返奖`。 | 1,912,688 | 2,445,075 | +532,387 | 流水和返奖都少算,但返奖少算更多,所以利润虚高。 | 修复游戏流水和游戏返奖后重算;利润不单独写源数据。 | 待修 |
| 次日留存 | 旧 Java注册 cohort 来自用户注册表;命中来自 Mongo `user_daily_active_log` 的目标活跃日期。 | 0 / 0 | 84 / 127 | +84 / +127 | 当前留存基数和命中口径与旧 Java 不一致,使用了 worker 用户国家表和当前 active 集合。 | 重写 retention reconcile注册 cohort 复刻旧 Java `listNewUserCohorts`,活跃命中直接查 active log按国家分别写 base/user。 | 待修 |
| 七日留存 | 同上,目标日期为注册日 + 7。 | 0 / 0 | 25 / 60 | +25 / +60 | 同次日留存。 | 同 retention reconcile支持 D7。 | 待修 |
| 30 日留存 | 同上,目标日期为注册日 + 30。 | 0 / 0 | 5 / 7 | +5 / +7 | 同次日留存。 | 同 retention reconcile支持 D30。 | 待修 |
## 已完成修复记录
### 新增
- 修改点:`dashboard-cdc-worker` 新增用户统计使用 admin 用户列表展示日,即 `create_time + 8h` 后的日期。
- 验证结果:`2026-05-27` 修复后源数据和预聚合从 57 增长到 60增长来自部署期间新增的 3 个用户。
- 结论:新增已与用户列表显示口径对齐。
### 日活
- 修改点:`dashboard-cdc-worker/internal/storage/active_reconcile.go`
- 提交:`0b5e687 Align daily active metric with active log`
- 部署镜像:`dashboard-cdc-worker:daily-active-log-country-20260527-0b5e687`
- 验证结果:`2026-05-27`
- Mongo 旧 Java 口径:`1054`
- `country_dashboard_period_metric` 预聚合:`1054`
- 差值:`0`
- 结论:日活已与旧 Java active log 口径对齐。
## 后续修复顺序建议
1. 工资兑换、工资转移:影响字段少,数据源明确,先补 Mongo/SQL reconcile。
2. 礼物消耗:复刻 `gift_give_running_water` 条件,避免继续从 wallet 侧错误推导。
3. 幸运礼物:直接接 `game_lucky_gift_count`,同时写金额和人数去重。
4. 游戏流水、游戏返奖、游戏人数:按 event_type 拆分差异后逐类补齐。
5. 留存:最后统一重写,因为它依赖新增口径和日活口径都稳定。
## 每项修复后的验证模板
每修一个字段,都必须跑同一套对账:
```sql
-- 预聚合结果
SELECT
SUM(<metric_column>) AS precomputed_value
FROM country_dashboard_period_metric
WHERE period_type = 'DAY'
AND period_key = '2026-05-27'
AND stat_timezone = 'Asia/Riyadh'
AND sys_origin = 'LIKEI';
```
源表侧按旧 Java 条件单独查一遍,并输出:
| 字段 | 旧 Java 源表结果 | 预聚合结果 | 差值 | 是否通过 |
| --- | ---: | ---: | ---: | --- |
| 待验证字段 | 0 | 0 | 0 | 是/否 |