10 KiB
10 KiB
name, overview, todos, isProject
| name | overview | todos | isProject | |||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| PHP用例写法规则 | 在用户级 Cursor 新增 `php-use-case-style.mdc`,约束 slot 后端所有 PHP 业务代码(Controller/Logic/Service/Model/Command 等)的表达力与可维护性;并扩展 verify-slot-backend.sh 对 diff 中所有 touched 的 app/**/*.php 做轻量检查。仅约束本次 diff,不强制全盘重构历史代码。 |
|
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 - 生效方式:
alwaysApply: true(任意对话均注入;与backend-layering同级,避免只开 Logic 文件时漏规则) - 门禁脚本:
~/.cursor/hooks/verify-slot-backend.sh(仅git diff+ 路径app/) - 不在本阶段:强制重构历史代码(如
DailyRebateLogic::claim);可另开样板 PR
1. 新增规则 php-use-case-style.mdc
Frontmatter:
---
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;Controller:FreeCreditsController |
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;Logicassert*+ 条件更新;Service 封装 wallet + biz_id
1.5 与现有规则关系
- 分层职责:仍服从
backend-layering.mdc - 文档:仍服从
php-doc.mdc agent-completion-gate.mdc增加:任意改动app/**/*.php须遵守php-use-case-style
2. 扩展 verify-slot-backend.sh
对 CHANGED_PHP 且路径匹配 */app/* 的文件检查(不再限定 /logic/):
# 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. 数据流
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. 验收
- 打开任意
app/service/*.php或DailyRebateController.php,规则均应生效(alwaysApply) - 在 Controller diff 新增
catch (\RuntimeException+PARAMS_ERROR→ verify FAIL - 在 Service diff 新增
throw new \RuntimeException('活动未开')→ verify FAIL - 加
@use-case-exempt→ 该文件跳过 ~/.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;php-use-case-style.mdc 已不存在。verify 已具备 use-case 检查,但规则与 gate 引用断裂。本阶段只做规则对齐,不改业务代码。
6.1 修改 php-code.mdc
Frontmatter(删空 globs:):
---
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 范围:
## 强制要求(本次 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
- 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 验收
~/.cursor/rules/仅一份 PHP 总规范php-code.mdc,无悬空php-doc/php-use-case-style引用- 新开 Agent 对话,改
app/**PHP 时应看到用例写法 + PHPDoc ~/.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 |