--- description: Backend layering responsibilities and Logic-Service boundaries alwaysApply: true --- # Backend Layering Rules | 分层 | 职责 | | --- | --- | | **Controller** | 接收请求;补充 header / 路由参数;调用 Validate;构建 DTO;调用 Logic / Service;返回统一响应 | | **Validate** | 参数必填、类型、长度、格式、枚举、数组结构 | | **DTO** | 承载已校验参数;做轻量格式整理;**不**做参数合法性判断;**不**查数据库;**不**写业务规则 | | **Logic** | 负责业务用例、流程编排、事务控制;可以调用本 Logic 内部方法组织步骤;简单逻辑可直接调用 Model;复杂或跨场景复用能力才调用 Service;**禁止返回 `array`**,固定形状结果返回 **Entity** | | **Service** | 只承载公共能力,例如 center / sdk / 公共配置 / 公共计算 / 跨业务复用逻辑;**不是**每张表都建一个 Service;**不是**把 Logic 方法简单搬过去;**禁止返回 `array`**,结构化结果返回 **Entity** | | **Model** | 数据查询;数据写入;scope / 搜索器 / 关联;把查询条件沉淀成模型方法 | ## Logic 与 Service 边界 - Logic 可以调用自己的私有方法或内部方法,用于拆分步骤、复用当前业务用例内的流程片段。 - 只有当某段能力具备跨场景复用价值、公共计算价值、公共配置访问、外部系统封装等公共属性时,才应抽到 Service。 - 不应创建只做中转的 Service 方法,例如 Logic 调用 Service,Service 再原样调用 Model 或另一个 Logic,且没有封装公共能力。 - 如果确实需要中转层,必须在代码或 PR 说明中解释原因,例如兼容历史接口、统一事务边界、隔离第三方 SDK、收敛跨模块依赖等。 ## Logic / Service 返回值 - **禁止** Logic / Service 方法返回 `array`(含 `@return array{...}`、`@return XxxEntity[]`)。 - 固定形状业务数据用 `app/entity/{业务域}/XxxEntity`(优先 `extends BaseEntity`);多条记录用列表/汇总 Entity 包装,不在 Logic/Service 签名上返回数组。 - 允许 `void`、标量、`?XxxEntity`、单个 Entity;禁止直接返回 Model。 - Controller 将 Entity 转为统一 HTTP 响应(如 `activeData()`);Validate / 入参 DTO 规则不变。 - `verify-slot-backend.sh` 对 diff 新增行自动检测上述规则;临时豁免见 `php-clean-code` §4 `@logic-service-array-exempt`。 ## Agent 完成前 MUST 1. **重命名/删除类**:对本次 diff 中删除的 `*.php`,类名不得出现在**其它已改动**的 PHP 文件中。 2. **新建/大改 `app/api/controller/*`**:必须 `extends \slotLib\basic\BaseController`,构造注入对应 `*Logic` + `*Validator`;参照 `slot_console/app/api/controller/FreeCreditsController.php`。 3. **禁止 Logic 型 Service**:不得新建以单业务用例编排为主、仅转发 Model/Logic 的 `app/service/*Service`(`*CalcService` 等公共计算除外)。 4. **声称完成前**:必须执行 `~/.cursor/hooks/verify-slot-backend.sh`,在最终回复粘贴脚本输出(`PASS` 或 `FAIL` 明细)。