feat(trial): wire reason through popup/check response (LES-1184)
背景
/api/trial/popup/check 一直返回 reason: null,不管前面命中了哪条 gate。Hugo 今天报:
{
"data": {
"eligible": false,
"reason": null, // ← 不管哪条 gate 都是 null
"trialPriceLabel": "$4.99",
...
}
}
这是 PR-A3 Reviewer P0 #1 留下的尾巴:当时引入了 TrialEligibilityMissReason 枚举 + TrialEligibilityResultVO,并在 agent 侧 TrialPopupCheckVO 加了 reason 字段;但 v3.1 PM 简化 那个 commit 把 TrialEligibilityService.isEligible 改回了 boolean 返回值,agent 侧的 reason 字段从此一直收到 null,运营 / 支持要排查只能去 fly_moon_payment 容器里 grep trial eligibility miss # 日志。
改动
| 文件 | 变化 |
|---|---|
flymoon-payment-api/.../enums/TrialEligibilityMissReason.java |
新增:与 agent 侧临时副本逐常量对齐 |
flymoon-payment-api/.../vo/TrialEligibilityResultVO.java |
新增:{eligible, reason} 结构化结果 |
flymoon-payment-api/.../vo/TrialPopupCheckVO.java |
加 reason 字段(与 agent 侧副本一致) |
flymoon-payment-provider/.../service/TrialEligibilityService.java |
单一 checkInternal() 实现,isEligible(Long) 退化为 boolean 适配器;fail-fast 顺序、日志关键字均未变 |
flymoon-payment-provider/.../service/TrialPopupService.java |
buildCheckVO 走 check() 并把 reason 拷到 VO;with-eligibility 内部重载改名为 buildCheckVOWithResult,保留快路径"少跑 4-5 个 selectCount"的性质 |
flymoon-payment-provider/.../service/TrialEligibilityServiceTest.java |
加 6 个 check() 分支断言(null userId / rollout / paid / used trial / freeloader / 全通过),每条都断 reason 与日志 #N 语义一致 |
reason → 日志关键字对照
#0 ROLLOUT_GATE trial eligibility miss #0 (rollout)
#1 ALREADY_PAID trial eligibility miss #1 (already paid)
#2 ALREADY_USED_TRIAL trial eligibility miss #2 (already used trial)
#3 FREELOADER trial eligibility miss #3 (freeloader)
+ NULL_USER_ID userId=null 短路
PRICE_NOT_CONFIGURED / DISMISS_FATIGUE / TOO_YOUNG / NO_REGISTRATION_RECORD 是 v3.1 删掉规则后的悬空常量,保留枚举位以便回滚或独立打点。
兼容性
-
flymoon-payment-api版本号 不动(1.0.20260520):仅追加字段 / 新增类型,Lombok@Builder加字段二进制兼容;agent 侧临时副本已先一步落地相同结构。 - Dubbo wire:payment 端在 VO 上设了
reason,agent 反序列化用自己的 VO,旧 cached1.0.20260508也能收(fastjson 忽略未知字段)。 -
isEligible(Long)-callers(createCheckoutSession/recordShown/recordDismiss)签名不变,行为零变化。
验证
-
mvn -pl flymoon-payment-api install -DskipTests✅ -
mvn -pl flymoon-payment-provider -Dtest='Trial*' test✅ 49 passed / 0 failed / 4 skipped -
TrialEligibilityServiceTest12 passed(6 旧 + 6 新check()分支)
验完不算完
部署到 s1 之后,前端可以拿任一 ineligible 用户调 /api/trial/popup/check,确认 reason 不再是 null 即可——本次 LES-1184 测试用户 (2057070570236346369) 是 #3 FREELOADER,预期返回值会变成 "reason": "FREELOADER"。
关联
- LES-1184
[MUL-1184](mention://issue/420221d2-ed21-4950-8b91-71038d96b8e1) - 前置:PR-A3 Reviewer P0 #1(引入枚举 / VO)
- 起因:v3.1 PM 简化 commit 把
isEligible改回 boolean - 同步任务(不在本 PR):删除 agent 侧
TrialFacadeService/TrialEligibilityResultVO/TrialPopupCheckVO/TrialEligibilityMissReason的"临时副本"——本 PR 把源头补齐了,下一次flymoon-payment-api版本 bump 即可清理。