228 lines
10 KiB
Markdown
228 lines
10 KiB
Markdown
---
|
||
name: PHP用例写法规则
|
||
overview: 在用户级 Cursor 新增 `php-use-case-style.mdc`,约束 slot 后端所有 PHP 业务代码(Controller/Logic/Service/Model/Command 等)的表达力与可维护性;并扩展 verify-slot-backend.sh 对 diff 中所有 touched 的 app/**/*.php 做轻量检查。仅约束本次 diff,不强制全盘重构历史代码。
|
||
todos:
|
||
- id: create-mdc
|
||
content: 创建 ~/.cursor/rules/php-use-case-style.mdc(全层 MUST/禁止、BAD/GOOD、按层对照表)
|
||
status: completed
|
||
- id: update-gate-rule
|
||
content: 在 agent-completion-gate.mdc 增加对 php-use-case-style 的引用(任意 PHP 改动)
|
||
status: completed
|
||
- id: extend-verify
|
||
content: 扩展 verify-slot-backend.sh:所有 app/**/*.php diff 检查 + @use-case-exempt
|
||
status: completed
|
||
- id: smoke-verify
|
||
content: 分别在 Logic/Controller/Service diff 触发自测 PASS/FAIL/豁免
|
||
status: completed
|
||
- id: merge-php-code
|
||
content: 用例写法合并进 php-code.mdc,修 frontmatter/强制要求/命名
|
||
status: completed
|
||
- id: fix-gate-refs
|
||
content: agent-completion-gate 引用改为 php-code
|
||
status: completed
|
||
- id: smoke-rules
|
||
content: 确认规则生效 + verify PASS
|
||
status: completed
|
||
isProject: false
|
||
---
|
||
|
||
# PHP 代码写法规则 + Verify 门禁(全层)
|
||
|
||
## 目标
|
||
|
||
让 AI 在改 **任意 slot 后端 PHP 业务代码** 时默认产出:**编排清晰、职责单一、业务异常语义正确、状态变更有条件更新与幂等键**,并对齐仓库内参照实现。
|
||
|
||
适用范围(规则 + verify 一致):
|
||
|
||
- `app/api/controller/**`
|
||
- `app/api/logic/**`、`app/innerapi/logic/**`、`app/napi/logic/**`
|
||
- `app/service/**`
|
||
- `app/model/**`
|
||
- `app/command/**`
|
||
- 其它 `app/**` 下业务 PHP(`validate`、`entity` 等按条适用)
|
||
|
||
**不覆盖**:`vendor/`、`tests/`(除非 diff 触及且单独约定)、纯配置/SQL 文件。
|
||
|
||
## 默认范围
|
||
|
||
- **规则文件**:用户级 [`~/.cursor/rules/php-use-case-style.mdc`](~/.cursor/rules/php-use-case-style.mdc)
|
||
- **生效方式**:`alwaysApply: true`(任意对话均注入;与 `backend-layering` 同级,避免只开 Logic 文件时漏规则)
|
||
- **门禁脚本**:[`~/.cursor/hooks/verify-slot-backend.sh`](~/.cursor/hooks/verify-slot-backend.sh)(仅 `git diff` + 路径 `app/`)
|
||
- **不在本阶段**:强制重构历史代码(如 `DailyRebateLogic::claim`);可另开样板 PR
|
||
|
||
## 1. 新增规则 `php-use-case-style.mdc`
|
||
|
||
**Frontmatter**:
|
||
|
||
```yaml
|
||
---
|
||
description: Slot PHP 写法——表达力、可维护、全层通用(Controller/Logic/Service/Model/Command)
|
||
alwaysApply: true
|
||
---
|
||
```
|
||
|
||
### 1.1 全层通用 MUST
|
||
|
||
| 条目 | 要求 |
|
||
|------|------|
|
||
| 单一职责 | 一个 public 方法只做一件事;编排方法目标 ≤25 行,超出拆 private |
|
||
| if 墙 | 禁止同一方法内连续 ≥4 个 `if (...) throw/return error`;合并为 `assert*` / `ensure*` |
|
||
| 业务异常 | 可预期业务失败用 `support\exception\BusinessException`;禁止用 `RuntimeException` 表示业务态(未开启、不可领、已过期等) |
|
||
| 魔法值 | 状态/类型用 Model 常量或 enum;禁止裸 `1/2/3` 散落(diff 新增代码) |
|
||
| 命名 | 方法名表达意图(`assertClaimable`、`markClaimedIfClaimable`),禁止 `doClaim`、`handle` 等空泛名(新增代码) |
|
||
| 参照 | 领取/入账编排:[`FreeCreditsLogic::claim`](slot_console/app/api/logic/FreeCreditsLogic.php);Controller:[`FreeCreditsController`](slot_console/app/api/controller/FreeCreditsController.php) |
|
||
|
||
### 1.2 按层补充(与 backend-layering 互补,不重复分层表)
|
||
|
||
| 分层 | 写法 MUST | 禁止 |
|
||
|------|-----------|------|
|
||
| **Controller** | 仅:Validate → 调 Logic/Service → `success/errorCode`;`catch BusinessException` 映射业务码 | 业务 if 墙、直接 `Db::`、直接 `gift()` |
|
||
| **Logic** | 用例编排:`buildContext` → `assert*` → `perform*` → `format*`;事务边界在此 | 纯转发 Model 无编排、跨服务裸 curl |
|
||
| **Service** | 可复用能力封装;外部系统(wallet/sdk)隔离;稳定 `biz_id` | Logic 型 Service(单用例整条流水线) |
|
||
| **Model** | 查询/写入 + `scope`/`mark*If*` 条件更新;金额字段注释单位(厘) | 业务编排、调 Wallet |
|
||
| **Command** | 薄入口:参数解析 → 调 Logic;日志 phase 结构化 | 复制 Logic 大段 if 墙 |
|
||
| **Validate** | 格式/必填/枚举 | 业务规则(「是否可领」应在 Logic assert) |
|
||
|
||
### 1.3 领取 / 入账 / 状态变更(凡涉及处均适用)
|
||
|
||
- MUST:条件更新(`where status = expected` 再 `update`),鼓励 Model 方法 `mark*If*`
|
||
- MUST:钱包/外部入账带稳定 `biz_id`(如 `daily_rebate:{uid}:{statDate}`)
|
||
- Controller:禁止 `catch (\RuntimeException)` 后一律 `PARAMS_ERROR`
|
||
|
||
### 1.4 BAD / GOOD(规则内各一段,≤8 行)
|
||
|
||
- BAD:Controller `catch RuntimeException` + Logic 5 连 throw + Service 仅 `return Model::find()`
|
||
- GOOD:Controller 捕 `BusinessException`;Logic `assert*` + 条件更新;Service 封装 wallet + biz_id
|
||
|
||
### 1.5 与现有规则关系
|
||
|
||
- 分层职责:仍服从 [`backend-layering.mdc`](~/.cursor/rules/backend-layering.mdc)
|
||
- 文档:仍服从 [`php-doc.mdc`](~/.cursor/rules/php-doc.mdc)
|
||
- [`agent-completion-gate.mdc`](~/.cursor/rules/agent-completion-gate.mdc) 增加:**任意改动 `app/**/*.php` 须遵守 `php-use-case-style`**
|
||
|
||
## 2. 扩展 `verify-slot-backend.sh`
|
||
|
||
对 **`CHANGED_PHP` 且路径匹配 `*/app/*`** 的文件检查(不再限定 `/logic/`):
|
||
|
||
```bash
|
||
# 1) diff 新增行含 throw new \RuntimeException(业务态误用)
|
||
# 豁免:文件含 @use-case-exempt
|
||
|
||
# 2) Controller(*/app/**/controller/*)diff 新增行:
|
||
# catch (\RuntimeException 且同文件/邻近行 PARAMS_ERROR → fail
|
||
|
||
# 3) 已有:BaseController、banlist、deleted class — 保持不变
|
||
```
|
||
|
||
**原则**:
|
||
|
||
- 只 FAIL **diff 新增行**(`git diff -U0` / `git diff --cached -U0`),不扫历史行
|
||
- `@use-case-exempt` 在文件前 5 行内则跳过该文件全部 use-case 检查
|
||
- 首期不 FAIL:方法行数、biz_id 参数名(写在规则 MUST,verify 二期)
|
||
|
||
## 3. 数据流
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph agent [Agent 改任意 app PHP]
|
||
rule[php-use-case-style alwaysApply]
|
||
layers[Controller Logic Service Model Command]
|
||
end
|
||
subgraph gate [完成前]
|
||
verify[verify-slot-backend app/** diff]
|
||
hook[stop hook followup]
|
||
end
|
||
rule --> layers
|
||
layers --> verify
|
||
verify -->|FAIL| hook
|
||
verify -->|PASS| done[可声称完成]
|
||
```
|
||
|
||
## 4. 验收
|
||
|
||
1. 打开任意 `app/service/*.php` 或 `DailyRebateController.php`,规则均应生效(alwaysApply)
|
||
2. 在 Controller diff 新增 `catch (\RuntimeException` + `PARAMS_ERROR` → verify FAIL
|
||
3. 在 Service diff 新增 `throw new \RuntimeException('活动未开')` → verify FAIL
|
||
4. 加 `@use-case-exempt` → 该文件跳过
|
||
5. `~/.cursor/hooks/verify-slot-backend.sh` 输出 PASS
|
||
|
||
## 5. 后续可选(本计划不含)
|
||
|
||
- 样板 PR:重构 `DailyRebateLogic::claim` + `DailyRebateController::claim`
|
||
- verify 二期:`gift(` / wallet 调用邻近 biz_id 检测;public 方法行数 WARN
|
||
|
||
---
|
||
|
||
## 6. 阶段二:合并进 `php-code.mdc`(待执行)
|
||
|
||
用户已将 PHPDoc 并入 [`php-code.mdc`](~/.cursor/rules/php-code.mdc);`php-use-case-style.mdc` 已不存在。verify 已具备 use-case 检查,但规则与 gate 引用断裂。本阶段只做规则对齐,不改业务代码。
|
||
|
||
### 6.1 修改 `php-code.mdc`
|
||
|
||
**Frontmatter**(删空 `globs:`):
|
||
|
||
```yaml
|
||
---
|
||
description: PHP 全局工程规范(PHPDoc + 用例写法 + AI 纪律)
|
||
alwaysApply: true
|
||
---
|
||
```
|
||
|
||
**在「代码原则」后插入新章节「用例写法(app/**)」**(约 35 行):
|
||
|
||
- MUST:业务失败 `support\exception\BusinessException`;禁止 `RuntimeException` 表业务态
|
||
- MUST:编排 public 方法 ≤25 行;同一方法禁止连续 ≥4 个 `if (...) throw` → 抽 `assert*`
|
||
- MUST:状态变更条件更新;钱包入账稳定 `biz_id`(`daily_rebate:{uid}:{date}`)
|
||
- 按层表(与 backend-layering 互补):Controller 禁止业务 if 墙 / 直接 gift;Logic 编排结构;禁止 Logic 型 Service
|
||
- 参照:`slot_console/app/api/logic/FreeCreditsLogic.php` :: `claim()`;`FreeCreditsController.php`
|
||
- BAD/GOOD 各一段(RuntimeException vs BusinessException;Controller catch)
|
||
- 豁免:文件前 5 行 `@use-case-exempt`(与 verify 一致)
|
||
|
||
**改写「强制要求」**(L84–92)为 diff 范围:
|
||
|
||
```markdown
|
||
## 强制要求(本次 diff 新增/修改须符合)
|
||
|
||
- PHP 8+;新增/修改的方法须有 typed parameter 与 return
|
||
- 新增类属性须 typed property
|
||
- 新建文件或本次 diff 触及的文件顶部可加 `declare(strict_types=1);`,禁止为达标改无关历史文件
|
||
```
|
||
|
||
**微调「命名规范」**:
|
||
|
||
- 禁止 `$tmp`、`$a`、`$b`、无业务含义的 `$data`/`$list`
|
||
- **删除** blanket 禁止 `$info`(与 `UserInfoEntity` 等冲突);改为禁止「无上下文的 `$info` 临时变量」
|
||
|
||
**文末增加「与 verify 对齐」**:
|
||
|
||
- diff 新增 `throw new RuntimeException`(业务态)→ verify FAIL
|
||
- Controller diff 新增 `catch RuntimeException` + `PARAMS_ERROR` → verify FAIL
|
||
|
||
### 6.2 修改 `agent-completion-gate.mdc`
|
||
|
||
```diff
|
||
- 3. 修改 PHP 后,最终回复含 `PHPDoc: checked`(见 php-doc 规则)。
|
||
- 4. 改动 `app/**/*.php` 须遵守 `php-use-case-style`(表达力、BusinessException、按层写法)。
|
||
+ 3. 修改 PHP 后,最终回复含 `PHPDoc: checked`(见 php-code 规则 PHPDoc 章节)。
|
||
+ 4. 改动 `app/**/*.php` 须遵守 `php-code` 用例写法章节(BusinessException、按层写法)。
|
||
```
|
||
|
||
### 6.3 不改动
|
||
|
||
- `verify-slot-backend.sh`(已含 use-case 检查)
|
||
- `backend-layering.mdc`、`cross-service-sdk.mdc`
|
||
|
||
### 6.4 验收
|
||
|
||
1. `~/.cursor/rules/` 仅一份 PHP 总规范 `php-code.mdc`,无悬空 `php-doc` / `php-use-case-style` 引用
|
||
2. 新开 Agent 对话,改 `app/**` PHP 时应看到用例写法 + PHPDoc
|
||
3. `~/.cursor/hooks/verify-slot-backend.sh` → PASS
|
||
|
||
### 6.5 执行 todos
|
||
|
||
| id | 内容 |
|
||
|----|------|
|
||
| merge-php-code | 按 6.1 更新 php-code.mdc |
|
||
| fix-gate-refs | 按 6.2 更新 agent-completion-gate.mdc |
|
||
| smoke-rules | 打开 DailyRebateLogic + 跑 verify |
|