ok
This commit is contained in:
118
plans/console_innerapi_架构说明_46a7f4d3.plan.md
Normal file
118
plans/console_innerapi_架构说明_46a7f4d3.plan.md
Normal file
@@ -0,0 +1,118 @@
|
||||
---
|
||||
name: Console innerapi 架构说明
|
||||
overview: 说明 slot_console 在本项目中的双重角色(C 端 BFF + 活动域服务),slot_sdk ConsoleClient 仅封装 `/innerapi/*` 供后端互调;若要坚持「纯 BFF 不被后端调用」,需拆分活动域或改异步回调。
|
||||
todos: []
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# slot_console 为何可被 slot_sdk 调用?
|
||||
|
||||
## 结论(先答你的疑问)
|
||||
|
||||
**可以给别人调,但调的不是「给 App 用的 BFF 接口」,而是同一进程里的 `/innerapi/*` 内部契约。**
|
||||
|
||||
在本仓库里,`slot_console` **不是纯 BFF**,而是:
|
||||
|
||||
| 路由前缀 | 中间件 | 谁调用 | 职责 |
|
||||
| --- | --- | --- | --- |
|
||||
| `/api/*` | `AuthMiddleware`(JWT) | **C 端 App/PWA** | BFF:聚合 user/wallet/agent,暴露 Lucky Rewards 等 C 端 API |
|
||||
| `/innerapi/*` | `InnerAuthMiddleware` | **其它后端**(agent、admin、pwa…) | 活动域/内部能力:统计、邮件、游戏历史、**邀请回调** |
|
||||
| `/napi/*` | `NAuthMiddleware` | 大厅等 | 非 C 端 JWT 的另一套入口 |
|
||||
|
||||
[`slot_sdk` 的 `ConsoleClient`](slot_sdk/src/service/console/ConsoleClient.php) 注释已写明:**「slot_console 内部 API 客户端」**,封装的是 `innerapi/...`,不是 `api/lucky-reward/spin` 这类 C 端路径。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph clients [调用方]
|
||||
App[C端App]
|
||||
Agent[slot_agent]
|
||||
Admin[slot_admin]
|
||||
end
|
||||
|
||||
subgraph console [slot_console]
|
||||
ApiLayer["/api/* BFF"]
|
||||
InnerLayer["/innerapi/* 域服务"]
|
||||
Logic[LuckyRewardInviteLogic等]
|
||||
end
|
||||
|
||||
App --> ApiLayer
|
||||
Agent -->|"ConsoleClient via slot_sdk"| InnerLayer
|
||||
Admin --> InnerLayer
|
||||
ApiLayer --> Logic
|
||||
InnerLayer --> Logic
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## slot_sdk 里 console 接口是干什么的?
|
||||
|
||||
当前 [`ConsoleService`](slot_sdk/src/service/console/ConsoleService.php) 只有三类 **innerapi**:
|
||||
|
||||
1. `innerapi/free-credits/statistics|list` — **slot_admin** 后台统计代理
|
||||
2. `innerapi/lucky-reward/invite-bind-callback` — **slot_agent** 邀请绑定后回调转盘助力
|
||||
|
||||
**实际调用方**(仓库内):
|
||||
|
||||
- [`LuckyRewardInviteCallbackGatewayService`](slot_agent/app/service/LuckyRewardInviteCallbackGatewayService.php) → agent 调 console
|
||||
- [`ConsoleAPIService`](backend/slot_admin/app/service/api/ConsoleAPIService.php) / Free Credits 统计 → admin 调 console
|
||||
- [`slot_pwa` ConsoleService](slot_pwa/app/service/console/ConsoleService.php) → `innerapi/game/update-history`
|
||||
|
||||
C 端 **不会** 也 **不应该** 通过 slot_sdk 调 console;C 端直接打 `consoleApiHost` 的 `/api/*`。
|
||||
|
||||
---
|
||||
|
||||
## 为什么 agent 要调 console,而不是反过来?
|
||||
|
||||
这是 Lucky Rewards 需求里**刻意**定的边界(见 [01 文档](docs/requirements/lucky_rewards/01_slot_agent邀请回调对接方案.md)、[00 §1](docs/requirements/lucky_rewards/00_整体技术方案.md)):
|
||||
|
||||
- **agent**:只管邀请关系、代理树、绑码奖励(通用裂变)
|
||||
- **console**:拥有转盘业务状态(`lucky_reward_player`、Spin、helper、弹窗)
|
||||
- 邀请绑定成功后,agent 广播「关系已建立」→ console **裁决**是否算转盘有效助力并发 Spin
|
||||
|
||||
所以不是「BFF 被乱调」,而是 **活动域挂在 console 上**,agent 通过 innerapi 触发 console 内的 [`LuckyRewardInviteLogic::handleInviteBind()`](slot_console/app/api/logic/LuckyRewardInviteLogic.php)。
|
||||
|
||||
`/api` 与 `/innerapi` 可以共用同一套 Logic(invite 回调与 C 端 invite-link 都走 `LuckyRewardInviteLogic`),只是入口和鉴权不同。
|
||||
|
||||
---
|
||||
|
||||
## 「console 是 BFF」和现状如何对齐?
|
||||
|
||||
更准确的说法:
|
||||
|
||||
- **对 C 端**:console 的 `/api/*` 承担 BFF(薄 Controller + Logic 编排 + 调 user/wallet/agent SDK)
|
||||
- **对活动数据**:console 同时是 **活动域 owner**(表在 `s_common`,逻辑在 console),历史上 Free Credits、签到、红包等同构
|
||||
- **innerapi** = 把「活动域能力」暴露给 **trusted backend**,不是给浏览器/App
|
||||
|
||||
因此 slot_sdk 出现 `ConsoleClient` 与「console 有 BFF 职责」**不矛盾**——SDK 封装的是 **服务间** 调用,符合 [cross-service-sdk 规则](.cursor/rules/cross-service-sdk.mdc)(调用方用 slot_sdk,被调方实现 innerapi Controller/Logic)。
|
||||
|
||||
---
|
||||
|
||||
## 若你认为「BFF 绝不能被后端调」——可选演进(非现状)
|
||||
|
||||
只有当你要把 console **严格降级为纯 BFF** 时,才需要改架构;代价是拆服务或改通信方式:
|
||||
|
||||
| 方案 | 做法 | 优缺点 |
|
||||
| --- | --- | --- |
|
||||
| **A. 拆 slot_activity** | 转盘域独立服务;console 只转发 C 端;agent 调 activity 而非 console | 边界最清晰;迁移成本高 |
|
||||
| **B. MQ 替代 HTTP 回调** | agent 发 `lucky_reward_invite_bind` MQ,console 消费 | 解耦、可重试;需 MQ 契约与消费幂等 |
|
||||
| **C. 维持现状** | console = BFF + 活动域;innerapi 仅 trusted 服务 | **当前实现**;与现网 Free Credits innerapi 一致 |
|
||||
|
||||
**建议**:除非全站统一「活动全部拆独立服务」,否则 **C 方案是本项目既定模式**,不必因 slot_sdk 有 ConsoleClient 而视为设计错误。
|
||||
|
||||
---
|
||||
|
||||
## 安全与边界(现状)
|
||||
|
||||
- innerapi 走 [`InnerAuthMiddleware`](slot_console/app/middleware/InnerAuthMiddleware.php)(内网 + 日志;生产通常靠网络隔离 + `server-name` 头标识调用方)
|
||||
- agent 回调带 `server-name: agent`(见 [deploy 文档](slot_console/doc/lucky_reward_deploy.md))
|
||||
- **禁止**:在 agent/user 等业务代码里手写 `consoleApiHost + path` 字符串;应走 slot_sdk(与 wallet/user 一致)
|
||||
|
||||
---
|
||||
|
||||
## 无需改代码时的认知对齐
|
||||
|
||||
1. **slot_sdk ConsoleClient ≠ C 端调 console**
|
||||
2. **console `/api` = BFF;`/innerapi` = 活动域对后端开放**
|
||||
3. **agent → console** 是转盘需求文档明确的服务边界,不是临时 hack
|
||||
|
||||
若你后续希望 **agent 不再 HTTP 调 console**,再单独立项做方案 B(MQ)或方案 A(拆服务);当前代码与文档是一致的。
|
||||
Reference in New Issue
Block a user