|
@@ -1069,12 +1069,51 @@ hash / DefaultCases / 实跑 / PASS / FAIL / 崩溃 / Skipped
|
|
|
|
|
|
|
|
## 17. 活动链 9 支的**证据强度上限**(写在这里,因为它是这个批次的先天约束)
|
|
## 17. 活动链 9 支的**证据强度上限**(写在这里,因为它是这个批次的先天约束)
|
|
|
|
|
|
|
|
-三条实测事实(`spdump sql` / `spdump routines` / PHP 仓 `grep`,都可复跑):
|
|
|
|
|
|
|
+### 17.0 先说清"两侧的数据是怎么来的"——「输入来源」≠「真实度」
|
|
|
|
|
+
|
|
|
|
|
+**`yuansiwei_2026` 整个库一行数据都没有**(实测):
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+表 target legacy
|
|
|
|
|
+t_user_expense 0 8918
|
|
|
|
|
+t_user_expense_school 0 5287
|
|
|
|
|
+t_user_expense_log 0 90007
|
|
|
|
|
+t_campus 0 63
|
|
|
|
|
+t_user 0 68107
|
|
|
|
|
+t_courses_activity 0 90
|
|
|
|
|
+t_courses_activity_signed 0 1288
|
|
|
|
|
+t_user_divide_into 0 86
|
|
|
|
|
+t_user_divide_into_log 0 474
|
|
|
|
|
+t_courses_activity_user_discount 0 81
|
|
|
|
|
+t_courses_activity_used_log 0 8185
|
|
|
|
|
+t_course_payment 0 7
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+所以**不能**说"资金侧是真实构型、活动侧是种子"——target 侧**从来没有真实数据**,两侧都是按 case 现造的。
|
|
|
|
|
+真正有区别的是**输入来源**:
|
|
|
|
|
+
|
|
|
|
|
+| 维度 | 资金 / 机构 / 校区 / 人 | 活动 / 分账 / 课酬 |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| 造法 | **原值复制真实行**:`INSERT … SELECT … FROM finance_bk.…`,同一套 ROUND 口径 | **构造行**:`C1ActivityPlan` 之类的字面值,id 取 `max+1` 可控 |
|
|
|
|
|
+| 为什么 | 真实行可用,复制最省事也最可信 | 活动域**未迁移**(target 侧虽有 schema 但 0 行)+ id 空间要可控 |
|
|
|
|
|
+
|
|
|
|
|
+⚠ 一处必须记住的精度:两侧读的**不是同一个库**——target 的基线来自只读源 **`finance_bk`**,
|
|
|
|
|
+legacy 侧 SP 读克隆 **`legacy_oracle`**。两者能比,靠的是每个 case 都跑的
|
|
|
|
|
+`两侧基线逐分相等` 那条显式断言。**"原值复制"也有前提断言,不是天然相等。**
|
|
|
|
|
+
|
|
|
|
|
+**对外必带的一句证据强度说明**:
|
|
|
|
|
+
|
|
|
|
|
+> target 库**无任何迁移数据**。双跑验证的是「**同一操作在两种实现下的等价性**」,
|
|
|
|
|
+> **不验证**迁移后的数据分布。活动侧为构造行 —— 这不是"没找真实数据",而是活动域未迁移,
|
|
|
|
|
+> **真实活动数据没测、也测不了**。
|
|
|
|
|
+
|
|
|
|
|
+### 17.1 三条实测事实
|
|
|
|
|
|
|
|
1. **target 侧活动域 schema 齐、数据空**:
|
|
1. **target 侧活动域 schema 齐、数据空**:
|
|
|
- `t_courses_activity` / `_signed` / `_used_log` / `_user_discount` / `_user_discount_log` 全部 **0 行**;
|
|
|
|
|
|
|
+ `t_courses_activity` / `_signed` / `_used_log` / `_user_discount` / `_user_discount_log` 全部 **0 行**
|
|
|
|
|
+ (见 §17.0,其实**整个 target 库**都是 0 行);
|
|
|
legacy 侧 `t_courses_activity` = 90、`t_courses_activity_signed` = 1288。
|
|
legacy 侧 `t_courses_activity` = 90、`t_courses_activity_signed` = 1288。
|
|
|
- ⇒ **任何真实报名/真实赠送额度都只有 legacy 有,target 看不到。活动侧只能靠种子。**
|
|
|
|
|
|
|
+ ⇒ **任何真实报名 / 真实赠送额度都只有 legacy 有。活动侧只能构造行。**
|
|
|
2. **9 支里只有 1 支碰资金表**:
|
|
2. **9 支里只有 1 支碰资金表**:
|
|
|
`sp_courses_activity_use_activity_recommend`(`t_user_expense` / `t_user_expense_school` /
|
|
`sp_courses_activity_use_activity_recommend`(`t_user_expense` / `t_user_expense_school` /
|
|
|
`t_user_expense_log` type=107 / `total_recommended_amount`,共 14 处引用)。
|
|
`t_user_expense_log` type=107 / `total_recommended_amount`,共 14 处引用)。
|
|
@@ -1091,12 +1130,30 @@ hash / DefaultCases / 实跑 / PASS / FAIL / 崩溃 / Skipped
|
|
|
|
|
|
|
|
⇒ 活动链批次的**证据强度上限**:
|
|
⇒ 活动链批次的**证据强度上限**:
|
|
|
|
|
|
|
|
- | 支 | 两侧数据 | 能证明什么 |
|
|
|
|
|
|
|
+ | 支 | **输入来源** | 能证明什么 |
|
|
|
|---|---|---|
|
|
|---|---|---|
|
|
|
- | 5 支 A 档(其中 4 支无资金写) | 活动侧种子 + 资金侧 n/a | "照 dump 正文实现对了" + "种下去的活动状态演化对" |
|
|
|
|
|
- | `use_activity_recommend`(A 档唯一碰资金的) | 活动侧种子 + **资金侧可真实**(用户与推荐人都是真人真账户) | 上面两条 + 双表双列 `balance`/`total_recommended_amount` 同额 + 107 流水双发 |
|
|
|
|
|
- | 3 支 B 档 | 两侧都是合成 | **只有**"照 dump 正文实现对了" |
|
|
|
|
|
- | `user_discount_usable`(C 档) | 只读、无写 | 只有"返回值口径对了";且它是**死代码**,建议不进 `DefaultCases` |
|
|
|
|
|
|
|
+ | 5 支 A 档(其中 4 支无资金写) | 活动:构造行 | "照 dump 正文实现对了" + "构造行上的状态演化对" |
|
|
|
|
|
+ | `use_activity_recommend`(A 档唯一碰资金的) | 活动:构造行 | **资金:原值复制真实行 | 课酬:原值复制真实行**(`t_courses_student` 42050 行,其中 24133 行满足 `remainder_receivable>0 AND confirm_discount_userid>0`) | 上面两条 + 双表双列 `balance`/`total_recommended_amount` 同额 + 107 流水双发 + **嵌套 `CALL` 的欠费核销(第三域)** |
|
|
|
|
|
+ | 3 支 B 档 | 活动:构造行 | **只有**"照 dump 正文实现对了" |
|
|
|
|
|
+ | `user_discount_usable`(C 档) | 只读、无写 | 只有"返回值口径对了";它是**死代码**,建议不进 `DefaultCases` |
|
|
|
|
|
|
|
|
**报告里必须逐支标注上表的档位,不能笼统写"9 支全绿"** ——
|
|
**报告里必须逐支标注上表的档位,不能笼统写"9 支全绿"** ——
|
|
|
B/C 档的绿与 A 档的绿不是同一种绿,混在一张总表里就是把"没验证过生产构型"读成"生产上验证过了"。
|
|
B/C 档的绿与 A 档的绿不是同一种绿,混在一张总表里就是把"没验证过生产构型"读成"生产上验证过了"。
|
|
|
|
|
+
|
|
|
|
|
+### 17.2 W4(`use_activity_recommend`)的写入面是**三个域、两个用户**
|
|
|
|
|
+
|
|
|
|
|
+这是本批唯一跨域的一支,也是唯一需要新增快照维度的一支:
|
|
|
|
|
+
|
|
|
|
|
+| 域 | 写入 |
|
|
|
|
|
+|---|---|
|
|
|
|
|
+| 资金 | `t_user_expense_school` / `t_user_expense`(**可能 INSERT**)、`balance +m`、`total_recommended_amount +m`、`t_user_expense_log` **type=107 ×2**(用户 + 推荐人) |
|
|
|
|
|
+| 活动 | `t_courses_activity_used_log` INSERT(−m)、`t_courses_activity_signed`(activity_money_used=m, status=2) |
|
|
|
|
|
+| 课酬 | `CALL sp_courses_student_counteract_arrears_course` **×2** → `t_courses_student.remainder_receivable − / net_receipts +`,cursor 判据 `remainder_receivable>0 AND confirm_discount_userid>0 ORDER BY start_time ASC` |
|
|
|
|
|
+
|
|
|
|
|
+⇒ 现有 `SideSnapshot` 的 3 块(`Global` / `Campus` / `Campus2`)**全是 `c.LegacyUserID` 的**,
|
|
|
|
|
+不够用。缺两块:**推荐人账户**(否则"推荐人也 +m"不可断言,而它正是老带新的核心语义)
|
|
|
|
|
++ **课酬应收**(否则核销顺序与 `confirm_discount_userid>0` 过滤都验不了)。
|
|
|
|
|
+
|
|
|
|
|
+⚠ `t_user_expense_school` 的建行语句只写 `(userid, schoolid, campusid)` 三列 ⇒ 金额列
|
|
|
|
|
+`DEFAULT NULL` ⇒ `SET balance=balance+m` 仍是 **NULL** ⇒ **钱一分没到账、107 流水照写**。
|
|
|
|
|
+与 C1-11 同族但后果更重(不是"少扣",是"用户被告知发了奖励、余额没动"),线上有真实调用点。
|