Files
cursor/plans/Trial config by activity_code-d451269e.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

176 lines
8.0 KiB
Markdown
Raw Permalink 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.

<!-- d451269e-1f41-4d6f-ad1f-e7ac88a4925f -->
---
todos:
- id: "constants"
content: "TrialRewardConstantsACTIVITY_CODE + ext 键;移除 center CONFIG_KEY_*"
status: pending
- id: "model"
content: "ActivityModel::findActiveByCode(activity_code, source, now)"
status: pending
- id: "resolver"
content: "新增 TrialRewardActivityResolver从 activity.ext 解析 threshold/cap"
status: pending
- id: "logic"
content: "TrialFirstDepositLogic / queryRecord 改用 resolver去掉 ShareConfig trialReward"
status: pending
- id: "center-cleanup"
content: "删除 slot-center share_config activity.trialReward 块"
status: pending
- id: "seed-sql"
content: "新增 activity 表 patchtrial_reward + ext JSON"
status: pending
- id: "test-e2e"
content: "补 resolver 单测 + 联调验证(不依赖 center 业务配置)"
status: pending
isProject: false
---
# 试玩活动配置center 迁出,按 activity_code 解析
## 结论(对你问题的回应)
**我同意你的方向**,且比当前联调实现更贴合项目既有模式:
- **center 不应承载** `deposit_threshold``trial_withdrawal_cap``activity_id` 等业务参数;它只适合 `walletApiHost` 等基础设施。
- **活动服决定业务规则**:阈值、上限、开关、时间窗应来自 [`activity`](slot-activity/app/model/ActivityModel.php) 表(运营在 slot-admin 维护),与 [`DepositBonusLogic`](slot-activity/app/innerapi/logic/DepositBonusLogic.php) / [`SignInLogic`](slot-activity/app/api/logic/SignInLogic.php) 读 `ext` 的方式一致。
- **按 `activity_code` 定位**:代码里固定 `trial_reward`(你已选 PHP 常量),各环境 DB 里 `activity_id` 可以不同,**发版/切环境不依赖 center 改数字 ID**。
当前临时方案的问题:
```74:82:slot-center/config/share_config.php
'activity' => [
'trialReward' => [
'activity_id' => 9001,
'activity_code' => 'trial_reward',
'deposit_threshold' => 50,
'trial_withdrawal_cap' => 500,
],
],
```
[`TrialFirstDepositLogic`](slot-activity/app/innerapi/logic/TrialFirstDepositLogic.php) 通过 `ShareConfigService` 读上述键,与「活动服自治」冲突。
---
## 目标架构
```mermaid
sequenceDiagram
participant Pay as slot_pay
participant Act as slot_activity
participant DB as activity_table
participant Wal as slot_wallet
Pay->>Act: first_deposit(uid, source, order_no, ...)
Act->>DB: findActiveByCode(trial_reward, source, now)
DB-->>Act: activity_id + ext(deposit_threshold, cap, ...)
Act->>Wal: clearTrialBonusForPool
Act->>Act: persist trial_reward_record(uid, activity_id)
```
| 配置项 | 现位置 | 目标位置 |
|---|---|---|
| activity 身份 | center `trialReward.activity_id` | `activity.activity_code = trial_reward` → 得到 `activity_id` |
| deposit_threshold | center | `activity.ext.deposit_threshold`(美元,入库 *1000 |
| trial_withdrawal_cap | center | `activity.ext.trial_withdrawal_cap` |
| activity_code 常量 | center | [`TrialRewardConstants::ACTIVITY_CODE`](slot-activity/app/constants/TrialRewardConstants.php) |
center 保留:`walletApiHost`[`TrialWalletGatewayService`](slot-activity/app/service/wallet/TrialWalletGatewayService.php) 仍需要)。
---
## 实现步骤
### 1. 定义活动编码与 ext 键slot-activity
改 [`TrialRewardConstants.php`](slot-activity/app/constants/TrialRewardConstants.php)
- 新增 `ACTIVITY_CODE = 'trial_reward'`PHP 常量,跨环境稳定)
- 新增 ext 字段键名常量:`EXT_DEPOSIT_THRESHOLD`、`EXT_TRIAL_WITHDRAWAL_CAP` 等
- **删除** 指向 center 的 `CONFIG_KEY_ACTIVITY_ID / CODE / DEPOSIT_THRESHOLD / WITHDRAWAL_CAP`
- 保留 `DEFAULT_DEPOSIT_THRESHOLD`、`DEFAULT_WITHDRAWAL_CAP` 作为 **ext 缺省兜底**(与 SignIn 读 ext 缺字段时给默认值一致)
### 2. ActivityModel 增加按 code 查询
在 [`ActivityModel.php`](slot-activity/app/model/ActivityModel.php) 新增(对齐现有 `findMatchedSignInBySource` / `findActiveByIdForDeposit` 风格):
```php
public static function findActiveByCode(string $activityCode, string $source, string $now): ?self
```
条件:`activity_code` 精确匹配 + `status=1` + 时间窗 + `source_list` 命中(`all` 或 `$source`)。
可选后续:在 `slot-foundation` 增加 `ActivityType::TRIAL_WITHDRAWAL`admin 筛选用;**本期不强制**code 已足够唯一标识。
### 3. 抽取活动配置解析(避免 Logic 堆 ext 解析)
新增小类,例如 [`TrialRewardActivityResolver.php`](slot-activity/app/service/trial/TrialRewardActivityResolver.php)
- 输入:`source`(来自 [`TrialFirstDepositDto`](slot-activity/app/innerapi/dto/TrialFirstDepositDto.php)
- 输出:`activity_id`、`activity_code`(快照用)、`deposit_threshold`*1000、`trial_withdrawal_cap`*1000
- 活动不存在/未启用/未命中渠道 → 抛业务异常或返回明确 reason如 `activity_not_found`**禁止静默用 center 默认值**
解析规则:
- `activity_id` / `activity_code` 来自 DB 行
- 阈值从 `ext` 读,缺省用 `TrialRewardConstants::DEFAULT_*`,再 `MoneyTool::bigUnitToSmallUnit`
### 4. 改造 TrialFirstDepositLogic
改 [`TrialFirstDepositLogic.php`](slot-activity/app/innerapi/logic/TrialFirstDepositLogic.php)
- `handleFirstDeposit()`:先 `resolveActivity($dto->source)`,再用返回的 `activity_id` 查/建 `trial_reward_record`
- `persistPool()``activity_code`、阈值、cap 均来自 resolver**移除所有 `ShareConfigService::get(trialReward.*)`**
- `queryRecord()`:同样按 `ACTIVITY_CODE` resolve 后再 `findByUidActivity`
- `resolveThresholdAmount()` / `resolveWithdrawalCap()`:改为接收已解析的 Activity 或 config DTO不再读 center
失败语义建议:
| reason | 含义 |
|---|---|
| `activity_not_found` | 无生效的 trial_reward 活动 |
| `wallet_clear_failed` | wallet 清零失败(保持现有) |
| `duplicate` / `success` | 不变 |
### 5. 移除 center 试玩业务配置
改 [`slot-center/config/share_config.php`](slot-center/config/share_config.php)
- **删除整个 `activity.trialReward` 块**(不是只删 threshold
- 重启 center本地 dev 已习惯 `php webman restart -d`
### 6. 联调/上线数据activity 表种子
新增 SQL 补丁,例如 [`slot-activity/db/patch_trial_reward_activity.sql`](slot-activity/db/patch_trial_reward_activity.sql)(插入/更新 `activity` 行,`activity_code=trial_reward`
```json
{
"deposit_threshold": 50,
"trial_withdrawal_cap": 500,
"trial_bonus_amount": 20
}
```
字段建议:`status=1`、`new_user_only=1`、`first_deposit_only=0`(首充事件另管 Pool、`source_list=["all"]`、合理 `start_time/end_time`。`activity_id` 自增即可,**各环境可以不同**。
### 7. 测试调整
- 单测 [`TrialFirstDepositStatusTest`](slot-activity/tests/Unit/Logic/TrialFirstDepositStatusTest.php):纯状态机不变
- 新增 resolver 单测mock `ActivityModel` 或测 ext 解析私有方法ext 有/无字段、美元→*1000
- 联调:在 **slotMysql.s_activity** 执行 activity 种子后,重跑首充 happy-path不再依赖 center trialReward
---
## 不变更范围(刻意不做)
- **slot-pay**:仍只调 `/innerapi/trial-reward/first-deposit`,不传 `activity_id`符合「pay 只报事件activity 解析活动」)
- **slot-wallet / slot-sdk**:无改动
- **slot-admin 后台表单**:本期可先用 SQL 种子 + ext JSON完整 07 子需求的可视化配置可后续单独做
---
## 风险与注意
1. **必须先有 activity 行**:删掉 center 配置后,若 DB 无 `trial_reward` 活动,首充会 `activity_not_found`(比误用 9001 更安全)。
2. **历史联调数据**:若 `trial_reward_record` 里是 `activity_id=9001`,新环境 activity 自增 ID 不同;新用户无影响,老测试 uid 需清数据或对齐 activity_id。
3. **ShareConfigService 仍保留**:仅用于 `walletApiHost` 等,与试玩业务解耦。