Files
cursor/plans/跨服务_slot_sdk_约束_4e4faf5a.plan.md
ray zhou f71a5c59af ok
2026-05-29 11:21:40 +08:00

7.2 KiB
Raw Blame History

name, overview, todos, isProject
name overview todos isProject
跨服务 slot_sdk 约束 在用户级 Cursor 规则目录新增一条「跨服务通信」约束,用统一、可操作的术语规定:业务服务之间的 HTTP 互调必须经 `slot/sdk``slotsdk`)完成,并与现有 `backend-layering` 规则互补而不重复。
id content status
create-mdc 新建 /Users/ray/.cursor/rules/cross-service-sdk.mdcalwaysApply + 术语与调用规范) completed
id content status
consistency-check 对照 backend-layering.mdc 确认交叉引用一致、无重复分层表 completed
id content status
optional-readme (可选)在 slot_sdk/readme.md 增加简短架构说明 completed
false

跨服务通信 Cursor 用户级约束

背景与目标

当前用户级规则在 /Users/ray/.cursor/rules/ 已有:

backend-layering.mdc 仅在 Service 层职责里顺带提到「sdk」没有规定跨服务 HTTP 的入口、命名与新增 API 的流程。本次新增独立规则(单一职责,符合 create-rule 实践),alwaysApply: true,与现有三条规则一致。

代码库事实(供规则用语对齐):

  • 包名:slot/sdk,命名空间 slotsdk\,仓库 slot_sdk
  • 典型消费方:slot_adminslot_agentslot_consoleslot_pwacomposer 依赖 slot/sdk
  • 典型被调方:slot_walletslot_userslot_center 等,对外暴露 innerapi/*api/*
  • 推荐调用链:new {Domain}Client($config)->service()->{method}(...)
  • 项目内已有表述: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_sdkslot/sdk 与 composer 包名、仓库目录一致
各服务自己拼 URL 在 slot_sdk 增加 {Domain}Service 方法 路径与 DTO 单点维护
app\service\WalletService 本地 WalletService vs slotsdk WalletService 防止与 SDK 类名混淆

核心定义(规则开篇 1 段):

slot_sdk 是跨服务 HTTP 客户端库(composerslot/sdk,命名空间 slotsdk\),用于调用方服务访问被调服务innerapi/*api/* 接口。它不是独立部署的微服务。


拟新增文件

路径: /Users/ray/.cursor/rules/cross-service-sdk.mdc

Frontmatter

---
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. 标准调用方式

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(如 walletApiHostuserApiHost)。
  • 请求头带 server-name,值为当前调用方服务名。
  • 非零 codeslotsdk\exception\ApiException 抛出,调用方在 Logic/Gateway 层处理。

3. 新增 / 变更远程接口的流程

  1. slot_sdk/src/service/{domain}/ 增加 {Domain}Service 方法、路径常量、必要时 entity/*Entity
  2. 在调用方 Logic 或 *GatewayService 中调用Controller 保持薄。
  3. 禁止slot_admin / slot_agent 等多仓库重复写同一路径字符串。

4. 与 backend-layering 的衔接12 句)

  • 跨服务访问在调用方落在 Service 或 *GatewayServiceLogic 编排用例;不把 HTTP 细节散落在 Controller。
  • backend-layering.mdc 中「Service 可承载 sdk」一致本规则专门约束跨服务边界,不重复写分层表。

5. 命名与混淆规避

  • SDKslotsdk\service\{domain}\{Domain}Client{Domain}Serviceentity\{Name}Entity
  • 本地:app\service\*;若同名,用 SDKConfig、完整 namespace 或 import alias。
  • 消费方封装重复调用:UserReferralGatewayService 这类 *GatewayService 模式。

与现有规则的关系

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]

实施步骤(确认计划后执行)

  1. 创建 cross-service-sdk.mdc,填入上述 frontmatter 与正文。
  2. 通读四条 alwaysApply 规则,确认无矛盾表述(尤其 Service 层与 Gateway 分工)。
  3. (可选)在 slot_sdk/readme.md 补 510 行架构说明并链到 Cursor 规则 — 仅当你希望仓库内也有文档镜像;非本次必需。

验收标准

  • 新开 Cursor 会话、编辑任意 slot PHP 文件时Agent 应自动带上「跨服务须经 slot_sdk、新 API 先改 slot_sdk」约束。
  • 术语统一使用:跨服务 HTTP调用方 / 被调方slot_sdk,避免「中转」「服务间随便 HTTP」等模糊说法。
  • 规则正文不含 legacy 迁移条款(按你的选择)。