{"role":"user","message":{"content":[{"type":"text","text":"\nExplore slot_wallet for: (1) recharge/deposit logic where user gets credited, (2) existing one-time scripts or webman commands, (3) shared Redis usage patterns, (4) how wallet gets config from center. Return relevant file paths, class names, and code patterns for adding uid to Redis set on recharge.\n"}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"Exploring `slot_wallet` for recharge crediting, commands, Redis patterns, and center config.\n\n[REDACTED]"},{"type":"tool_use","name":"UpdateCurrentStep","input":{"current_step":"Exploring slot_wallet recharge"}},{"type":"tool_use","name":"Grep","input":{"pattern":"recharge|deposit|充值","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*.php","output_mode":"files_with_matches","head_limit":50}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/app/command/**/*.php","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet"}},{"type":"tool_use","name":"Grep","input":{"pattern":"Redis|redis","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*.php","output_mode":"files_with_matches","head_limit":40}},{"type":"tool_use","name":"Grep","input":{"pattern":"center|ShareConfig|getConfig","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*.php","output_mode":"files_with_matches","head_limit":40}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"pattern":"recharge|Recharge|inc\\(|sAdd|sadd|Redis::|support\\\\Redis","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*.php","output_mode":"content","head_limit":80}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/service/ShareConfigService.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/service/RedisKeyManagerService.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/service/wallet/RechargeExchangeService.php"}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php","offset":750,"limit":120}},{"type":"tool_use","name":"Grep","input":{"pattern":"sAdd|sadd|sRem|Redis::","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*.php","output_mode":"content"}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/*Controller*.php","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/config/app.php"}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"pattern":"recharge|Recharge","path":"/Users/ray/Documents/project/www/slot/slot_wallet/config","glob":"*"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/controller/WalletController.php","limit":120}},{"type":"tool_use","name":"Grep","input":{"pattern":"function recharge|->recharge\\(","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/config/redis.php"}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"pattern":"connection\\('share'\\)|share'","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php","limit":120}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/command/InitDB.php","limit":50}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/command/CleanupWalletLog.php","limit":50}},{"type":"tool_use","name":"Grep","input":{"pattern":"sharerediskey|share_redis","path":"/Users/ray/Documents/project/www/slot","glob":"*","head_limit":30}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/config/route.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/dto/request/wallet/WalletUpdateRequestDTO.php","limit":80}},{"type":"tool_use","name":"Grep","input":{"pattern":"sAdd|sadd","path":"/Users/ray/Documents/project/www/slot","glob":"*.php","head_limit":25}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/functions.php"}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/sharerediskey.php","target_directory":"/Users/ray/Documents/project/www/slot/slot_center"}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/console.php","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet"}},{"type":"tool_use","name":"Grep","input":{"pattern":"sendConsoleBus|InnerCurlService","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*.php","head_limit":30}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_console/app/service/user/UserRegisterEventService.php","offset":100,"limit":40}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/service/WalletService.php","limit":100}},{"type":"tool_use","name":"Grep","input":{"pattern":"WalletController|innerapi","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*"}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php","offset":1035,"limit":100}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/command/CreateWagerTask.php","limit":50}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/config/process.php"}},{"type":"tool_use","name":"Grep","input":{"pattern":"type.*recharge|rechargeSign","path":"/Users/ray/Documents/project/www/slot/slot_pay","glob":"*.php","head_limit":20}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_center/config/sharerediskey.php","limit":80}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"pattern":"wallet.*recharge|->recharge\\(|type.*recharge","path":"/Users/ray/Documents/project/www/slot/slot_pay","glob":"*.php","head_limit":30}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/service/RedLock.php","limit":50}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/validator/Wallet2Validator.php","limit":80}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/command/Test.php","limit":40}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/command/UpdateWagerTask.php","limit":40}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"pattern":"function recharge|wallet/update","path":"/Users/ray/Documents/project/www/slot/slot_pay","glob":"*.php","head_limit":25}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/config/cache.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/entity/common/RechargeExchangeEntity.php"}},{"type":"tool_use","name":"Grep","input":{"pattern":"maxRetry|RedLock|USER_WALLET_LOCKER","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*.php","head_limit":25}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_center/app/innerapi/controller/ShareConfigController.php","limit":60}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"pattern":"WalletService|walletApiHost","path":"/Users/ray/Documents/project/www/slot/slot_pay/app","glob":"*.php","head_limit":20}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php","offset":970,"limit":70}},{"type":"tool_use","name":"Grep","input":{"pattern":"recharge","path":"/Users/ray/Documents/project/www/slot/slot_sdk","glob":"**/wallet/**"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/api/controller/SiteController.php","limit":80}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"pattern":"function recharge","path":"/Users/ray/Documents/project/www/slot/slot_lib","glob":"*.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_pay/app/command/EventRecharge.php","offset":100,"limit":100}},{"type":"tool_use","name":"Grep","input":{"pattern":"plugin.*route|api/wallet","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*"}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_lib/src/services/WalletService.php","offset":120,"limit":50}},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/plugin/**/route.php","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/service/InnerCurlService.php","limit":40}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/route*.php","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/middleware/AuthMiddleware.php","offset":50,"limit":30}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/command/InitDB.php","offset":30,"limit":80}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/*","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet/config/plugin"}},{"type":"tool_use","name":"Grep","input":{"pattern":"WalletController|api/wallet","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*.php","head_limit":15}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Grep","input":{"pattern":"Route::","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*.php"}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_lib/src/services/WalletService.php","limit":50}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/support/bootstrap.php","offset":120,"limit":30}},{"type":"tool_use","name":"Read","input":{"path":"/Users/ray/Documents/project/www/slot/slot_wallet/app/service/WagerTaskService.php","limit":40}},{"type":"tool_use","name":"Grep","input":{"pattern":"correctWagerTask","path":"/Users/ray/Documents/project/www/slot/slot_wallet","glob":"*.php"}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"Glob","input":{"glob_pattern":"**/route.php","target_directory":"/Users/ray/Documents/project/www/slot/slot_wallet/app"}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"[REDACTED]"},{"type":"tool_use","name":"UpdateCurrentStep","input":{"current_step":"Exploring slot_wallet recharge","final_summary":"slot_wallet credits recharge via `POST /api/wallet/update` with `type=recharge`, dispatched to `WalletLogic::recharge()` → `inc()` then Redis/MQ side effects. There is no `sAdd` usage today; the best hook is beside `RechargeExchangeService::recharge()` using `Redis::connection('share')` and a center-defined `sharerediskey` entry.","completed_subtitle":"Mapped wallet recharge paths"}}]}} {"role":"assistant","message":{"content":[{"type":"text","text":"## 1. Recharge / deposit crediting flow\n\n### Entry point\n| Layer | Path | Class |\n|-------|------|-------|\n| HTTP | `POST /api/wallet/update` | `app\\api\\controller\\WalletController::update()` |\n| DTO | — | `app\\api\\dto\\request\\wallet\\WalletUpdateRequestDTO` (`type`, `fee`, `recharge`, `biz_id`, …) |\n| Dispatch | — | `app\\api\\logic\\WalletLogic::run()` — calls `$this->{$requestDTO->type}()` |\n| Recharge | — | `app\\api\\logic\\WalletLogic::recharge()` |\n| Sign recharge | — | `app\\api\\logic\\WalletLogic::rechargeSign()` |\n\nCaller example (from `slot_pay`): `slotLib\\services\\WalletService::recharge()` → `update(type=recharge, …)` → wallet API (`/Users/ray/Documents/project/www/slot/slot_lib/src/services/WalletService.php`). Pay command: `/Users/ray/Documents/project/www/slot/slot_pay/app/command/EventRecharge.php`.\n\n### `WalletLogic::recharge()` sequence\n\n```767:800:/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php\n public function recharge()\n {\n $freeCreditInitContext = $this->captureFreeCreditInitContext();\n $result = $this->inc();\n // ... post-credit side effects in try/catch ...\n $statModel->inc($this->requestDTO->currency, 'total_deposit', $this->requestDTO->recharge);\n $service = new RechargeExchangeService($this->requestDTO->uid);\n $service->recharge($this->requestDTO->recharge);\n $this->sendConsoleBus('Recharge', $this->requestDTO->recharge);\n $this->createTask(...);\n $this->maybeSendFreeCreditInit($freeCreditInitContext);\n return $result;\n }\n```\n\n1. **`captureFreeCreditInitContext()`** — snapshot before credit (first-recharge / free-credit freeze).\n2. **`inc()`** — DB credit inside transaction + optimistic retry (`maxRetry`).\n3. **Post-credit** (errors logged, do not roll back DB credit):\n - `WalletStatModel::inc(..., 'total_deposit', ...)`\n - `RechargeExchangeService::recharge()` — Redis cumulative recharge\n - `sendConsoleBus('Recharge', …)` — RabbitMQ → console\n - `createTask()` — wager task MQ (only if `RechargeExchangeService::isRecharge()`)\n - `maybeSendFreeCreditInit()` — first-recharge bus event\n\n### Balance credit (`inc()`)\n\n```837:866:/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php\n public function inc()\n {\n return $this->maxRetry(function () {\n // ...\n } elseif ($this->requestDTO->type == WalletLogModel::BIZ_TYPE_RECHARGE) {\n $withdraw = $this->requestDTO->fee;\n $ok = $walletService->inc($this->requestDTO->fee, 0, $this->requestDTO->bonus, ...);\n```\n\n- Recharge increases **`withdraw_balance`** by `fee` (total credited; gift included in `fee`).\n- `app\\service\\WalletService::inc()` → `WalletAccountModel::incBalance()`.\n- Log type: `WalletLogModel::BIZ_TYPE_RECHARGE` (`'recharge'`).\n\n### `rechargeSign()`\n`/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php` (~803–828): updates stats + `RechargeExchangeService` + task + bus; does **not** call `inc()` (sign-buy path assumes balance already handled elsewhere).\n\n### Supporting classes\n| File | Role |\n|------|------|\n| `/Users/ray/Documents/project/www/slot/slot_wallet/app/service/wallet/RechargeExchangeService.php` | Per-uid cumulative recharge in Redis hash |\n| `/Users/ray/Documents/project/www/slot/slot_wallet/app/entity/common/RechargeExchangeEntity.php` | `recharge` / `exchange` totals |\n| `/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/WalletStatModel.php` | `total_deposit` |\n| `/Users/ray/Documents/project/www/slot/slot_wallet/app/model/multi/WalletLogModel.php` | `BIZ_TYPE_RECHARGE` |\n| `/Users/ray/Documents/project/www/slot/slot_wallet/app/validator/Wallet2Validator.php` | `checkRecharge` rule |\n\n---\n\n## 2. Webman commands (one-off / ops)\n\nAll under `/Users/ray/Documents/project/www/slot/slot_wallet/app/command/`:\n\n| Command | `$defaultName` | Purpose |\n|---------|----------------|---------|\n| `InitDB.php` | `initDB` | Shard DDL; currently runs `correctWagerTask()` |\n| `CreateWagerTask.php` | `createWagerTask` | MQ consumer for wager-task creation |\n| `UpdateWagerTask.php` | `updateWagerTask` | MQ consumer for wager-task updates |\n| `CleanupWalletLog.php` | `cleanupWalletLog` | Batch delete old wallet logs |\n| `Test.php` | `test` | Dev/scratch (DDL snippets, locks, ShareConfig) |\n\nRun pattern: `docker exec -w /app/www/slot/slot_wallet php82 php webman `.\n\n`InitDB::correctWagerTask()` is the closest existing **one-time data fix** pattern for backfilling recharge-related state.\n\n---\n\n## 3. Redis usage in slot_wallet\n\n### Connections (`/Users/ray/Documents/project/www/slot/slot_wallet/config/redis.php`)\n- `default` / `lock` / `wallet` — env `REDIS_*`\n- `share` — env `SHARE_REDIS_*` (**defined but not used in wallet PHP code**)\n\n### Patterns (no `sAdd` / `sadd` in slot_wallet)\n\n| Pattern | Where | API |\n|---------|-------|-----|\n| Recharge totals hash | `RechargeExchangeService` | `Redis::hSet` / `hGet` on `recharge:exchange:{uid%10}` |\n| Rate limit | `AuthMiddleware::recordRate()` | `hIncrBy` + `expire` on `request:rate` |\n| Prometheus | `PrometheusService` | `hIncrBy` / `hGetAll` |\n| Wager task ID | `WagerTaskService` | `incr` / `set` on `wager:task:id` |\n| Center config cache | `ShareConfigService` | `get` / `setEx` on `center:*` |\n| Wallet balance cache | `WalletService` | `Cache::store('wallet')` → redis connection `wallet` |\n| Distributed lock | `RedLock` | `Redis::connection(config('app.redisLockerConnName'))` |\n\nKey manager: `/Users/ray/Documents/project/www/slot/slot_wallet/app/service/RedisKeyManagerService.php` — only shared key from center today: `ShareConfigService::get('sharerediskey.sourceReal')`.\n\n### Cross-service `sAdd` reference (not in wallet)\n- `slot_console`: `UserRegisterEventService::recordToSet()` — `Redis::sAdd` + `expire`\n- `slot_risk`: `Redis::connection('share')->sAdd('real:black', …)`\n- `slot_console` / `slot_user` / `slot_pwa`: `ShareCache::saddByShare()` → `redisByShare()->sadd()`\n\n---\n\n## 4. Config from center\n\n### `ShareConfigService` (`/Users/ray/Documents/project/www/slot/slot_wallet/app/service/ShareConfigService.php`)\n\n| Method | Endpoint | Use |\n|--------|----------|-----|\n| `load()` / `get($key)` | `{centerApiHost}/innerapi/share-config/all` | Hosts, `moneyFormat`, **`sharerediskey`**, per-server merge |\n| `configCenterData($groupCode, $uid)` | `.../config-center-data` | DB config groups |\n| `sourceInfo($uid)` | `.../sourceInfo` | Channel + `wagering_model` |\n| `configSourceCenterData(...)` | `.../config-source-center-data` | Channel overrides (e.g. recharge multiplier) |\n\n- Host: `config('app.centerApiHost')` from `CENTER_API_HOST` (`/Users/ray/Documents/project/www/slot/slot_wallet/config/app.php`).\n- HTTP: `app\\service\\InnerCurlService` (Guzzle, expects `code === 0`).\n- Key definitions live in center: `/Users/ray/Documents/project/www/slot/slot_center/config/sharerediskey.php`, exposed via `/Users/ray/Documents/project/www/slot/slot_center/app/innerapi/controller/ShareConfigController::all()`.\n\nUsage in wallet helpers: `app/functions.php` (`getNumberFormat`, `setNumberFormat` via `ShareConfigService::get('moneyFormat')`).\n\n---\n\n## 5. Adding uid to a Redis set on recharge\n\n### Best hook points (in order)\n\n1. **`WalletLogic::recharge()`** — right after `RechargeExchangeService::recharge()` (~781–782): covers normal pay flow; same try/catch as other post-credit work.\n2. **`RechargeExchangeService::recharge()`** — single place for all callers that update Redis recharge totals (including anything that only hits this service).\n3. **`WalletLogic::rechargeSign()`** — if sign-buy should count as “recharged user”.\n4. **One-time backfill command** — model after `InitDB` / `CleanupWalletLog`: scan `wallet_stat.total_deposit > 0` or read `recharge:exchange:*` hashes and `SADD` historical uids.\n\n### Recommended pattern (aligned with ecosystem)\n\n```php\n// 1) Add key in slot_center/config/sharerediskey.php, e.g. 'rechargedUids' => 'user:recharged'\n\n// 2) In RedisKeyManagerService:\npublic static function rechargedUidSetKey(): string\n{\n return ShareConfigService::get('sharerediskey.rechargedUids', 'user:recharged');\n}\n\n// 3) After successful recharge tracking:\n$key = RedisKeyManagerService::rechargedUidSetKey();\nRedis::connection('share')->sAdd($key, (string) $this->requestDTO->uid);\n// optional: expire on first member if set is time-bucketed (see console UserRegisterEventService)\n```\n\n**Notes:**\n- Use **`connection('share')`** for cross-service sets (wallet’s default Redis is service-local).\n- Register the key in **center `sharerediskey.php`** so all services resolve the same name via `ShareConfigService::get('sharerediskey.*')`.\n- `slot_wallet` has **no** `ShareCache` wrapper; either add a thin helper or call `Redis::connection('share')->sAdd` directly (as `slot_risk` does).\n- Post-credit block is **non-transactional** with DB — same as `sendConsoleBus` / `createTask`; a failed `sAdd` should only log, not fail the HTTP response after credit.\n- For **idempotent** membership, `SADD` is enough; for “only first recharge”, gate with `captureFreeCreditInitContext()['is_first_recharge']` or `total_deposit` before increment.\n\n### Request shape (for tests / pay integration)\n\n```json\n{\n \"type\": \"recharge\",\n \"uid\": 1401787,\n \"currency\": \"INR\",\n \"fee\": 5000,\n \"recharge\": 5000,\n \"biz_id\": \"order_xxx\",\n \"source\": \"all\",\n \"organization\": 1\n}\n```\n\n---\n\n### Quick file index\n\n| Concern | Absolute path |\n|---------|----------------|\n| Recharge logic | `/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php` |\n| Controller | `/Users/ray/Documents/project/www/slot/slot_wallet/app/api/controller/WalletController.php` |\n| Redis recharge totals | `/Users/ray/Documents/project/www/slot/slot_wallet/app/service/wallet/RechargeExchangeService.php` |\n| Redis keys | `/Users/ray/Documents/project/www/slot/slot_wallet/app/service/RedisKeyManagerService.php` |\n| Center config client | `/Users/ray/Documents/project/www/slot/slot_wallet/app/service/ShareConfigService.php` |\n| Redis config | `/Users/ray/Documents/project/www/slot/slot_wallet/config/redis.php` |\n| Commands | `/Users/ray/Documents/project/www/slot/slot_wallet/app/command/*.php` |\n| Pay → wallet client | `/Users/ray/Documents/project/www/slot/slot_lib/src/services/WalletService.php` |\n\n[REDACTED]"}]}}