修复(#3): 抽奖 EligibilitySnapshot.UnmetReasons 空字符串违反 MySQL JSON 校验
Closes HIF-3 (Stage 1 P0 from QA smoke)
F4 (P0): EligibilitySnapshot.UnmetReasons=\"\" → MySQL error 3140 (Invalid JSON text: The document is empty)
- 修法:方式 A 对称守卫 UnmetReasons=\"[]\" (与 PrizeSnapshot.Config 的 \"{}\" 守卫模式一致)
- Stage 1 只有 passed=true 分支进 insertSnapshots,语义正确
F5 (P2 顺手): EvaluatedAt 显式 time.Now() 避免 GORM zero time 触 sql_mode STRICT
回归护栏:TestInsertSnapshots_UnmetReasonsIsValidJSON 用 sqlmock per-arg matcher (unmetReasonsNotEmpty + evaluatedAtNotZero),退化时 t.Fatalf 立即抛出
CI 全绿;2 files, +108/-0;无 DB 变更
架构师侧透明:这是 PR C review 时漏检查——PrizeSnapshot.Config 的空串守卫看到了,但没同步检查 EligibilitySnapshot.UnmetReasons。single-code-path 的错觉是审查盲点,Stage 2 起会 sweep 所有 JSON/字符串写库字段。
This commit is contained in:
@@ -383,6 +383,14 @@ func (s *Service) insertSnapshots(ctx context.Context, tx *gorm.DB, draw *lotter
|
||||
UserId: draw.UserId,
|
||||
ActivityId: draw.ActivityId,
|
||||
Passed: passedEligibility,
|
||||
// UnmetReasons 是 JSON 列,MySQL 拒绝空字符串(error 3140)——
|
||||
// Stage 1 只有 passed=true 进 insertSnapshots,语义上"没有未过项",
|
||||
// 用 "[]" 与 PrizeSnapshot.Config 的 "{}" 守卫对称。
|
||||
// Stage 2 若开始持久化 passed=false 的失败评估,再改成真正的 marshal。
|
||||
UnmetReasons: "[]",
|
||||
// 显式 time.Now():GORM 遇 zero time 有时会传 '0000-00-00 00:00:00',
|
||||
// 触 sql_mode STRICT。不依赖 DB DEFAULT CURRENT_TIMESTAMP。
|
||||
EvaluatedAt: time.Now(),
|
||||
}
|
||||
return tx.WithContext(ctx).Create(&es).Error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user