--- name: PHPDoc Cursor 规则 overview: 在 Cursor 全局规则中新增 PHP PHPDoc 严格规范(类、方法、常量全覆盖),与现有 backend-layering 规则并列,并明确适用范围与模板,避免与「不写显而易见注释」的原则冲突。 todos: - id: create-php-doc-mdc content: "新建 /Users/ray/.cursor/rules/php-doc.mdc(globs: **/*.php,严格 PHPDoc 正文 + 示例)" status: completed - id: verify-rule-active content: 在 Cursor 中打开任意 .php 文件,确认规则被注入;用 WalletLogic 缺注释方法做一次试写验证 status: completed - id: optional-readme-sync content: (可选)将 PHPDoc §3.4 同步到 slot_wallet 等 README,与 Cursor 规则保持一致 status: completed isProject: false --- # 新增 PHPDoc 严格 Cursor 规则 ## 结论:要加,但不要写成「所有符号一刀切」的空话 你选择了 **严格全覆盖**。建议在 Cursor 里加一条 **独立规则文件**,与现有的 [`backend-layering.mdc`](/Users/ray/.cursor/rules/backend-layering.mdc) 并列,而不是塞进 layering 里(职责不同:一个管分层,一个管文档)。 **不建议**写成模糊的「所有都要 PHPDoc」——应写清 **哪些符号、最少哪些 tag、何时可写短句**。否则 Agent 会在 trivial 代码上堆 `@param int $uid uid` 这类无意义注释,与 [`slot_agent/README.md`](/Users/ray/Documents/project/www/slot/slot_agent/README.md) 第 9.3 节「不解释显而易见语句」打架。 ## 现状 | 来源 | PHPDoc 要求 | |------|-------------| | [`.cursor/rules/`](/Users/ray/.cursor/rules/) | 仅有 layering + dev-environment,**无 PHPDoc** | | [`slot_agent/README.md`](/Users/ray/Documents/project/www/slot/slot_agent/README.md) §6.2 | 已要求:业务类说明、公开方法说明、参数/返回值说明 | | 实际代码(如 [`WalletLogic.php`](/Users/ray/Documents/project/www/slot/slot_wallet/app/api/logic/WalletLogic.php)) | **不一致**:`run`/`register` 有块注释,`initWalletWithoutMoney`、`getBalance` 无 | 终端里曾出现给 `slot_wallet/README.md` 增加 §3.4 PHPDoc 的 diff,但当前 README **尚未落地**该节——规范应优先进 **Cursor rule**(Agent 每次都会读),README 可作为人类文档二次同步(可选)。 ## 推荐规则文件 **路径**:[`/Users/ray/.cursor/rules/php-doc.mdc`](/Users/ray/.cursor/rules/php-doc.mdc) **Frontmatter 建议**: ```yaml --- description: PHP PHPDoc requirements for all classes, methods, and constants globs: "**/*.php" alwaysApply: false --- ``` - 用 `globs: **/*.php`:编辑 PHP 时自动注入,不污染 Vue/TS 会话 - `alwaysApply: false`:与 layering 的 `true` 区分,减少非 PHP 任务 token ## 规则正文(严格版,建议写入 mdc) ### 1. 适用范围 - **新增或修改**的 PHP 文件中的:**class / interface / trait / enum**、**所有方法**(`public` / `protected` / `private`)、**所有类常量**(`const`) - 适用目录:`slot_*`、`backend/**` 下 PHP 业务代码 - **不追溯**改历史未动代码;但 **本次 diff 触及的符号** 若缺 PHPDoc,须一并补齐 ### 2. 最低 PHPDoc 内容 | 符号 | 必须包含 | |------|----------| | 类 / 接口 / Trait | 一行职责说明;复杂类可加 `@package`(可选) | | 方法 | 职责说明 + 每个参数的 `@param` + `@return`;有 `throw` 的须 `@throws` | | 类常量 | 一行说明业务含义(单位、枚举语义、与配置/表字段对应关系) | | 属性(若新增) | `@var` 或 typed property + 一行说明(仅当类型/语义不直观时) | 已有 **PHP 8+ 标量/对象类型声明** 时,`@param`/`@return` 仍要保留(与你选的 strict 一致),但 **描述句可短**,禁止空块或只复制类型名。 ### 3. 禁止项(与 slot_agent 注释原则对齐) - 禁止无 `@param` / `@return` 的空 `/** */` - 禁止 `@param int $id id` 式同义反复;语义、单位、边界写进描述 - 禁止用 PHPDoc 替代 Validate / Logic 里的业务校验说明 ### 4. 分层补充(与 layering 一致) 对以下层 **额外** 要求写清业务语义(不仅是类型): - **Controller**:接口用途、幂等/鉴权前提(若有) - **Logic**:用例步骤、事务边界、失败时行为 - **Service**:复用场景、调用方约束 - **Model**:查询条件、分表键、金额字段单位 - **DTO / Validate**:字段含义、与上游参数映射 ### 5. 示例模板(写入规则供 Agent 照抄) ```php /** * 首充前冻结免费余额。 * * @return WalletEntity|null 成功返回钱包实体;无需冻结时返回 null * @throws WalletException 余额不足或钱包不存在 */ public function freeCreditsFreeze(): ?WalletEntity ``` ```php /** 释放档位:单位分,对应配置 free_credits.release_tiers */ public const RELEASE_TIER_MIN = 100; ``` ## 与工具链的关系(可选,本期可不做的) Cursor rule **不能**在 CI 里自动 fail。若以后要机器 enforce,再单独加: - PHPStan + `phpstan/phpdoc-parser` 或 - PHPCS `Squiz.Commenting` / 自定义 sniff 本期仅 Cursor 规则即可满足「Agent 写码时遵守」。 ## 实施步骤 1. 新建 [`php-doc.mdc`](/Users/ray/.cursor/rules/php-doc.mdc),按上文写入 frontmatter + 正文 2. 在 Cursor Settings → Rules 确认该规则对 PHP 文件生效(`globs` 匹配) 3. (可选)把相同 §3.4 同步进 [`slot_wallet/README.md`](/Users/ray/Documents/project/www/slot/slot_wallet/README.md) 与其它服务 README,供人工 review 对照 4. 用一次小改动验证:例如在 `WalletLogic` 给无注释的 `getBalance` 补 PHPDoc,看 Agent 是否自动遵循 ## 风险与预期 - **Diff 变大**:strict 下每个新方法多 5–15 行注释,属预期成本 - **历史债**:全库补 doc 工作量巨大;规则应写明 **仅 touch 到的符号**,避免 Agent 一次性重构整文件 - **类型重复**:strict 仍保留 `@param`/`@return` 类型,利于 IDE/静态分析;描述聚焦「为什么/单位/边界」 ```mermaid flowchart LR subgraph rules [Cursor Rules] layering[backend-layering.mdc] phpdoc[php-doc.mdc] devenv[dev-environment.mdc] end subgraph code [PHP 改动] edit[编辑 PHP 文件] agent[Agent 生成/修改代码] end edit --> phpdoc edit --> layering agent --> phpdoc agent --> layering ```