Files
cursor/plans/跨服务_slot_sdk_约束_4e4faf5a.plan.md
2026-05-21 18:16:26 +08:00

149 lines
7.2 KiB
Markdown
Raw 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.

---
name: 跨服务 slot_sdk 约束
overview: 在用户级 Cursor 规则目录新增一条「跨服务通信」约束,用统一、可操作的术语规定:业务服务之间的 HTTP 互调必须经 `slot/sdk``slotsdk`)完成,并与现有 `backend-layering` 规则互补而不重复。
todos:
- id: create-mdc
content: 新建 /Users/ray/.cursor/rules/cross-service-sdk.mdcalwaysApply + 术语与调用规范)
status: completed
- id: consistency-check
content: 对照 backend-layering.mdc 确认交叉引用一致、无重复分层表
status: completed
- id: optional-readme
content: (可选)在 slot_sdk/readme.md 增加简短架构说明
status: completed
isProject: false
---
# 跨服务通信 Cursor 用户级约束
## 背景与目标
当前用户级规则在 [`/Users/ray/.cursor/rules/`](file:///Users/ray/.cursor/rules/) 已有:
- [`backend-layering.mdc`](file:///Users/ray/.cursor/rules/backend-layering.mdc) — 单服务内 Controller / Logic / Service 分层
- [`dev-environment.mdc`](file:///Users/ray/.cursor/rules/dev-environment.mdc) — Docker 本地开发
- [`php-doc.mdc`](file:///Users/ray/.cursor/rules/php-doc.mdc) — PHPDoc 规范
[`backend-layering.mdc`](file:///Users/ray/.cursor/rules/backend-layering.mdc) 仅在 Service 层职责里顺带提到「sdk」**没有**规定跨服务 HTTP 的入口、命名与新增 API 的流程。本次新增**独立规则**(单一职责,符合 create-rule 实践),`alwaysApply: true`,与现有三条规则一致。
代码库事实(供规则用语对齐):
- 包名:`slot/sdk`,命名空间 `slotsdk\`,仓库 [`slot_sdk`](file:///Users/ray/Documents/project/www/slot/slot_sdk)
- 典型消费方:`slot_admin``slot_agent``slot_console``slot_pwa`composer 依赖 `slot/sdk`
- 典型被调方:`slot_wallet``slot_user``slot_center` 等,对外暴露 `innerapi/*``api/*`
- 推荐调用链:`new {Domain}Client($config)->service()->{method}(...)`
- 项目内已有表述:[`slot_agent/doc/feature_agent.md`](file:///Users/ray/Documents/project/www/slot/slot_agent/doc/feature_agent.md) —「代理服不直连用户域表,统一通过 `slot_sdk` 调用户服 innerapi」
按你的选择:**规则只约束新代码走 slot_sdk不写 InnerCurlService / slot_lib 等 legacy 迁移条款。**
---
## 术语优化(写入规则正文)
| 避免说法 | 推荐说法 | 说明 |
| --- | --- | --- |
| 后端服务之间调用 / 中转 | **跨服务 HTTP 调用** | 明确是进程间 HTTP不是本地 Logic/Service |
| 通过 slot/sdk 中转 | **经 slot_sdk 调用** | `slot_sdk` = 客户端库;被调服务仍直接处理请求,库不做业务中转 |
| SDK / 封装 | **slot_sdk`slot/sdk`** | 与 composer 包名、仓库目录一致 |
| 各服务自己拼 URL | **在 slot_sdk 增加 `{Domain}Service` 方法** | 路径与 DTO 单点维护 |
| `app\service\WalletService` | **本地 WalletService** vs **slotsdk WalletService** | 防止与 SDK 类名混淆 |
核心定义(规则开篇 1 段):
> **slot_sdk** 是跨服务 HTTP 客户端库(`composer` 包 `slot/sdk`,命名空间 `slotsdk\`),用于**调用方服务**访问**被调服务**的 `innerapi/*` 或 `api/*` 接口。它不是独立部署的微服务。
---
## 拟新增文件
**路径:** [`/Users/ray/.cursor/rules/cross-service-sdk.mdc`](/Users/ray/.cursor/rules/cross-service-sdk.mdc)
**Frontmatter**
```yaml
---
description: 跨服务 HTTP 须经 slot_sdkslot/sdk调用禁止在业务服务内散落直连
alwaysApply: true
---
```
**正文结构(约 3545 行,中文为主):**
### 1. 适用范围
- 一个 Webman 服务需要 HTTP 访问另一个服务的 `innerapi` / `api` 时适用。
- **被调服务**自身实现 Controller/Logic/Model**不**为「被别人调」而引入 `slot/sdk`
- **调用方**若需调第三个服务,必须通过 `slot/sdk`(不在业务代码里手写 Guzzle/curl/拼 host+path
### 2. 标准调用方式
```php
use slotsdk\Config as SDKConfig;
use slotsdk\service\wallet\WalletClient;
$config = new SDKConfig([
'host' => ShareConfigService::get('walletApiHost'),
'headers' => ['server-name' => config('app.server_name')],
]);
$result = (new WalletClient($config))->service()->getStatistics($uids, $currency);
```
要点:
- Host 来自 center 下发的 `*ApiHost`(如 `walletApiHost``userApiHost`)。
- 请求头带 `server-name`,值为**当前调用方**服务名。
- 非零 `code``slotsdk\exception\ApiException` 抛出,调用方在 Logic/Gateway 层处理。
### 3. 新增 / 变更远程接口的流程
1. 在 [`slot_sdk/src/service/{domain}/`](file:///Users/ray/Documents/project/www/slot/slot_sdk/src/service/) 增加 `{Domain}Service` 方法、路径常量、必要时 `entity/*Entity`
2. 在调用方 Logic 或 `*GatewayService` 中调用Controller 保持薄。
3. **禁止**在 `slot_admin` / `slot_agent` 等多仓库重复写同一路径字符串。
### 4. 与 backend-layering 的衔接12 句)
- 跨服务访问在调用方落在 **Service 或 `*GatewayService`**Logic 编排用例;不把 HTTP 细节散落在 Controller。
- 与 [`backend-layering.mdc`](file:///Users/ray/.cursor/rules/backend-layering.mdc) 中「Service 可承载 sdk」一致本规则专门约束**跨服务边界**,不重复写分层表。
### 5. 命名与混淆规避
- SDK`slotsdk\service\{domain}\{Domain}Client``{Domain}Service``entity\{Name}Entity`
- 本地:`app\service\*`;若同名,用 `SDKConfig`、完整 namespace 或 import alias。
- 消费方封装重复调用:`UserReferralGatewayService` 这类 `*GatewayService` 模式。
---
## 与现有规则的关系
```mermaid
flowchart LR
subgraph userRules [用户级 .cursor/rules]
layering[backend-layering]
crossSdk[cross-service-sdk 新增]
docker[dev-environment]
phpdoc[php-doc]
end
layering -->|"单服务内分层"| Logic
crossSdk -->|"服务间 HTTP"| slot_sdk
slot_sdk --> innerapi[被调服务 innerapi/api]
```
- **不修改** [`backend-layering.mdc`](file:///Users/ray/.cursor/rules/backend-layering.mdc):避免一条规则过长;仅在 `cross-service-sdk` 末尾用交叉引用衔接。
- **不修改** [`dev-environment.mdc`](file:///Users/ray/.cursor/rules/dev-environment.mdc) / [`php-doc.mdc`](file:///Users/ray/.cursor/rules/php-doc.mdc)。
---
## 实施步骤(确认计划后执行)
1. 创建 [`cross-service-sdk.mdc`](/Users/ray/.cursor/rules/cross-service-sdk.mdc),填入上述 frontmatter 与正文。
2. 通读四条 `alwaysApply` 规则,确认无矛盾表述(尤其 Service 层与 Gateway 分工)。
3. (可选)在 [`slot_sdk/readme.md`](file:///Users/ray/Documents/project/www/slot/slot_sdk/readme.md) 补 510 行架构说明并链到 Cursor 规则 — **仅当你希望仓库内也有文档镜像**;非本次必需。
---
## 验收标准
- 新开 Cursor 会话、编辑任意 slot PHP 文件时Agent 应自动带上「跨服务须经 slot_sdk、新 API 先改 slot_sdk」约束。
- 术语统一使用:**跨服务 HTTP**、**调用方 / 被调方**、**slot_sdk**,避免「中转」「服务间随便 HTTP」等模糊说法。
- 规则正文不含 legacy 迁移条款(按你的选择)。