This commit is contained in:
ray zhou
2026-05-29 17:23:17 +08:00
parent f71a5c59af
commit 1bcb6120dd
139 changed files with 4229 additions and 523 deletions

View File

@@ -15,6 +15,8 @@ alwaysApply: true
2. 在最终回复粘贴完整输出(以 `=== verify-slot-backend ===` 开头)。
3. 修改 PHP 后,最终回复含 `PHPDoc: checked`(见 `php-code` 规则 PHPDoc 章节)。
4. 改动 `app/**/*.php` 须遵守 `php-code` 用例写法章节BusinessException、按层写法
5. 修改 `app/**/logic/**/*.php` 时,完成前对照 `php-clean-code` **§3 参数与日志**、**§3 编排上下文与聚合 DTO** 与 **§8 自查**(不仅依赖 verify 脚本)。
6. 工作区在 `www/ray` 时,执行校验须:`SLOT_ROOT=/Users/ray/Documents/project/www/ray ~/.cursor/hooks/verify-slot-backend.sh`(避免 `PASS (no changed files)` 误判)。
## Hooks用户级 `~/.cursor/hooks.json`

View File

@@ -76,6 +76,20 @@ alwaysApply: true
- 业务规则判断优先使用 `ensureXxx()` 方法。
- 不要把查询、判断、写入、返回组装全部堆在一个大方法里。
### 参数与日志
- **禁止**为打日志、排障单独增加与该方法业务无关的参数(反例:`findPlatformById($platformId, $gameCode)` 且 `$gameCode` 只出现在 `Log::error`)。
- **查询 / 校验类方法**`find*`、`ensure*`)的参数必须等于该步骤的查询条件或判断依据。
- 跨多步共享的排障字段(如 `game_code`)应在 **用例编排方法**public Logic 入口或 `resolveXxx` 编排 private集中记录子步骤日志只写本子步骤真实使用的字段`platform_id`、`provider_code` 等)。
- 若多步都需要同一追溯上下文且步骤 ≥4再引入 readonly `XxxResolveContext`**禁止**向每个 private 方法重复挂相同标量。
### 编排上下文与聚合 DTO
- **禁止**编排方法先把子 DTO / Context 字段拆成局部变量,再原样传入聚合 DTO双份拷贝。反例`$uid = $dto->uid` 后 `new StartDTO($dto, $ctx, $uid, ...)`。
- **禁止**聚合 DTO 构造函数同时接收「可从已有只读字段推导」的重复标量。反例:同时存 `gameLaunchDto` 与 `gameCode`。
- 聚合上下文 DTO 应 **只组合** 子对象;派生值用 `uid()` / `providerCode()` 等 accessor 从子对象读取,或在用例方法内直接使用子 DTO 字段(二选一,不并存)。
- 子步骤 private 方法若需多字段,优先传 **一个** 聚合 DTO而不是再拆 3 个标量参数。
---
## 4. Logic / Service / Model 写法
@@ -106,25 +120,107 @@ alwaysApply: true
- Model 方法命名必须表达查询或写入意图,例如 `findEnabledById()`、`existsClaimedRecord()`、`sumValidBetAmount()`、`createClaimRecord()`。
- 避免 `getData()`、`getList()`、`handle()`、`process()`。
#### Model 类 PHPDoc新建 / 大改必须)
凡 **新建** 或 **大改** `app/model/**/*Model.php`(含 `app/**/model/` 下 Model类上必须有完整 PHPDoc**禁止** 只写类型、不写字段说明。
1. **类注释**`表名` + 一行业务说明(对齐 DDL `COMMENT` 或需求文档)。
2. **`@property`**:每个持久化字段一行,格式 `@property type $field 中文说明`(对齐表字段 `COMMENT`)。
3. **易混字段必须区分**:例如 `id`自增主键vs `session_id`对外标识vs `launch_request_id`(链路追踪)。
4. **状态字段**:写清「见 `STATUS_*` 常量」或列出枚举含义(与常量注释一致)。
5. **时间字段** `created_at` / `updated_at` 可简写为「创建时间」「更新时间」。
6. **状态类常量**`STATUS_*` 等):每个常量一行 `/** 中文说明 */`,与 `@property status` 描述一致。
反例(禁止):
```php
/**
* @property int $id
* @property string $session_id
*/
class GameLaunchSessionModel extends Model
```
正例(参照 `GGameModel`、`GameLaunchSessionModel`
```php
/**
* game_launch_session 游戏启动 Session 表。
*
* @property int $id 自增主键(表内行 ID非对外 session_id
* @property string $session_id 对外 Session 标识(如 sess_*
* @property int $status Session 状态,见 STATUS_* 常量
*/
class GameLaunchSessionModel extends Model
{
/** Session 有效 */
public const STATUS_ACTIVE = 1;
}
```
---
## 5. PHPDoc 与注释
Logic、Service、Model 的 public 方法建议写 PHPDoc。
### 默认规则(必须)
以下情况必须写 PHPDoc
**Logic / Service / Model 的 `public` 方法必须写 PHPDoc**,首行用**中文**说明业务动作或结果(很多人看不懂英文方法名,英文命名不能替代 PHPDoc
- 返回 `array`
- 参数是复杂 `array`
- 可能抛出业务异常
- 涉及状态流转
- 涉及钱包、订单、活动、游戏交易
- 方法语义不是一眼能看懂
`protected` 方法若承载业务步骤(非纯 getter/setter同样必须写中文 PHPDoc。
返回 array 必须写结构
最小合格格式
```php
/**
* 按对外 session_id 查询未过期且有效的 Launch Session。
*
* @throws BusinessException 会话不存在或已关闭时
*/
public static function findActiveBySessionId(string $sessionId): ?self
```
- 首行必须是中文,说明「做什么 / 业务结果」。
- 禁止只写 `/** get user */`、只有 `@param`/`@return` 类型而无中文业务说明。
- 禁止与签名完全重复的英文复述(无信息增量 → 不合格)。
### 唯一豁免:纯 getter / setter
仅以下方法可省略 PHPDoc
- 无业务分支、无事务、无外部调用、无查库写库的 `getXxx()` / `setXxx()`。
- 只读或只写入**单个**属性或 DTO 字段。
```php
// 可豁免
public function getUid(): int
{
return $this->uid;
}
// 不可豁免 — 必须中文 PHPDoc虽像查询但含业务条件与持久化
public static function findActiveBySessionId(string $sessionId): ?self
```
**不可豁免**(即使名称像 getter也必须写中文 PHPDoc
- `find*` / `create*` / `mark*` / `ensure*` / `is*` / `has*` / `launch*` / `close*` 等业务方法。
- 任何访问数据库、Redis、第三方接口、抛业务异常的方法。
### 附加要求(在通用中文 PHPDoc 之上)
除满足上文「默认规则」外,以下场景还须**额外**写明对应标签或结构(不在列表里也不能省略通用 PHPDoc
- 返回 `array`:必须用 `@return array{...}` 写清结构。
- 参数为复杂 `array`:必须用 `@param array{...} $name` 写清结构。
- 可能抛出业务异常:必须写 `@throws`(中文说明触发条件)。
- 涉及状态流转、钱包、订单、活动、游戏交易:首行中文说明中须点明状态/资金影响。
返回 array 结构示例:
```php
/**
* 查询用户钱包汇总。
*
* @return array{
* user_id: int,
* nickname: string,
@@ -133,7 +229,7 @@ Logic、Service、Model 的 public 方法建议写 PHPDoc。
*/
```
复杂 array 参数必须写结构
复杂 array 参数示例
```php
/**
@@ -142,15 +238,15 @@ Logic、Service、Model 的 public 方法建议写 PHPDoc。
* amount: int,
* order_no: string,
* remark?: string
* } $data
* } $walletChangePayload
*/
```
涉及异常必须写 `@throws`。
### 废话与行内注释
不要写废话 PHPDoc。简单 getter/setter、方法名和类型已足够清晰时不强制 PHPDoc
注释解释为什么,不解释做什么。复杂业务、幂等处理、分布式锁、状态流转、第三方接口兼容、历史兼容逻辑必须有注释
- **禁止废话 PHPDoc**:无信息增量、纯英文复述签名 → 不合格
- **除纯 getter/setter 外一律必须**:不得以「方法名够清晰」为由省略 PHPDoc。
- **行内注释**解释为什么,不解释做什么;方法 PHPDoc 首行仍要写「做什么」(中文)。复杂业务、幂等、分布式锁、状态流转、第三方兼容、历史兼容逻辑须在行内注释说明原因
---
@@ -190,6 +286,8 @@ Logic、Service、Model 的 public 方法建议写 PHPDoc。
- Logic 是否表达清晰业务流程?
- Service 是否确实是公共能力?
- Model 是否只做数据访问?
- 新建/大改 Model 是否有类注释 + 带中文说明的 `@property`易混字段、status 是否写清)?
- `STATUS_*` 等状态常量是否有中文注释?
- 多表写入是否有事务?
- 是否需要幂等?
- 是否吞异常?
@@ -197,9 +295,12 @@ Logic、Service、Model 的 public 方法建议写 PHPDoc。
- 是否泄露敏感信息?
- 返回数据是否明确?
- 是否直接返回 Model
- 返回 array 的方法是否写清楚 PHPDoc
- 复杂数组参数是否写清楚 PHPDoc
- 涉及异常的方法是否写了 `@throws`
- Logic / Service / Model 的 `public` 方法是否均有**中文** PHPDoc 首行(纯 getter/setter 除外)
- 是否存在只有 `@param`/`@return` 类型、无中文业务说明的 PHPDoc
- 返回 array / 复杂数组参数 / 抛异常的方法是否在通用 PHPDoc 之上补全了 `array{...}` 结构与 `@throws`
- 是否存在「仅用于日志」的多余参数?
- 是否存在「局部变量 + 聚合 DTO」双份承载同一业务字段
- 聚合 DTO 是否包含可推导的重复标量?
---