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

@@ -0,0 +1,137 @@
---
name: StartDTO 去重与规范
overview: 收紧 `GameLaunchSessionStartDTO` 为仅组合两个子 DTO + accessor 派生字段,简化 `launchWithSession` 编排;并在 `php-clean-code.mdc` 增加「禁止编排层双份拷贝 / DTO 重复标量」规则。
todos:
- id: refactor-start-dto
content: GameLaunchSessionStartDTO仅 2 子 DTO + uid/providerCode/gameCode accessor
status: completed
- id: refactor-launch-logic
content: 简化 launchWithSessionfindReusableLaunch 收 StartDTOcreateLaunchSession 用 accessor
status: completed
- id: update-rules-dto-dup
content: php-clean-code §3 增加「编排上下文与聚合 DTO」§8 与 agent-completion-gate 补充自查
status: completed
- id: verify-start-dto
content: docker php -l + SLOT_ROOT verify-slot-backend.sh
status: completed
isProject: false
---
# StartDTO 去重重构 + 规范加固
## 问题
[`launchWithSession`](slot-pwa/app/api/logic/GameLaunchSessionLogic.php) 中:
```php
$uid = (int) $gameLaunchDto->uid;
$providerCode = $gameLaunchContext->providerCode;
$gameCode = $gameLaunchDto->gameCode;
// ...
new GameLaunchSessionStartDTO($gameLaunchDto, $gameLaunchContext, $uid, $providerCode, $gameCode);
```
[`GameLaunchSessionStartDTO`](slot-pwa/app/api/dto/GameLaunchSessionStartDTO.php) 同时持有 `gameLaunchDto``gameLaunchContext` **以及** 可从二者推导的 `uid` / `providerCode` / `gameCode`,属于 **编排层双份拷贝**,违反 DRY 与 [`php-clean-code.mdc`](/Users/ray/.cursor/rules/php-clean-code.mdc)「参数应表达业务需要、聚合 DTO 不重复字段」精神。
```mermaid
flowchart LR
subgraph before [当前]
DTO[GameLaunchDTO]
CTX[GameLaunchContextDTO]
locals[uid providerCode gameCode]
Start[GameLaunchSessionStartDTO 5 fields]
DTO --> locals
CTX --> locals
DTO --> Start
CTX --> Start
locals --> Start
end
```
## 一、代码重构
### 1. 收紧 `GameLaunchSessionStartDTO`
**文件:** [`slot-pwa/app/api/dto/GameLaunchSessionStartDTO.php`](slot-pwa/app/api/dto/GameLaunchSessionStartDTO.php)
- 构造函数仅保留:
- `GameLaunchDTO $gameLaunchDto`
- `GameLaunchContextDTO $gameLaunchContext`
- 派生字段通过 **accessor** 提供(单一数据源):
- `uid(): int``(int) $gameLaunchDto->uid`
- `providerCode(): string``$gameLaunchContext->providerCode`
- `gameCode(): string``$gameLaunchDto->gameCode`
### 2. 简化 `launchWithSession`
**文件:** [`slot-pwa/app/api/logic/GameLaunchSessionLogic.php`](slot-pwa/app/api/logic/GameLaunchSessionLogic.php)
目标形态(可读性优先):
```php
public function launchWithSession(GameLaunchDTO $gameLaunchDto): GameLaunchSessionResultDTO
{
$launchStart = new GameLaunchSessionStartDTO(
$gameLaunchDto,
$this->resolveGameLaunchContext($gameLaunchDto)
);
$reusedLaunch = $this->findReusableLaunch($launchStart);
if ($reusedLaunch !== null) {
return $reusedLaunch;
}
return $this->createLaunchSessionAndFetchUrl($launchStart);
}
```
- 删除 `$gameLaunchContext` / `$uid` / `$providerCode` / `$gameCode` 四个中间局部变量。
### 3. `findReusableLaunch` 收参为 StartDTO
将签名由 `(int $uid, string $providerCode, string $gameCode)` 改为:
```php
private function findReusableLaunch(GameLaunchSessionStartDTO $launchStart): ?GameLaunchSessionResultDTO
```
方法内使用 `$launchStart->uid()``providerCode()``gameCode()`,避免再次拆三个标量传递。
### 4. `createLaunchSessionAndFetchUrl` 统一 accessor
- `$launchStart->uid` 等改为 `$launchStart->uid()`(及 `providerCode()``gameCode()`
- Provider `launch()` 调用统一为 `$launchStart->uid()` + `$launchStart->gameLaunchContext->externalGameCode`(不再混用 `$launchStart->gameLaunchDto->uid`
**改动范围:** 仅上述 2 个 PHP 文件,无 API / 路由变更。
## 二、用户级规范更新
### [`php-clean-code.mdc`](/Users/ray/.cursor/rules/php-clean-code.mdc)
**§3「参数与日志」** 后增加小节 **「编排上下文与聚合 DTO」**
- **禁止**编排方法先把子 DTO/Context 字段拆成局部变量,再原样传入聚合 DTO双份拷贝。反例`$uid = $dto->uid``new StartDTO($dto, $ctx, $uid, ...)`
- **禁止**聚合 DTO 构造函数同时接收「可从已有只读字段推导」的重复标量。反例:同时存 `gameLaunchDto``gameCode`
- 聚合上下文 DTO 应 **只组合** 子对象;派生值用 `uid()` / `providerCode()` 等 accessor 从子对象读取,或在用例方法内直接使用子 DTO 字段(二选一,不并存)。
- 子步骤 private 方法若需多字段,优先传 **一个** 聚合 DTO而不是再拆 3 个标量参数。
**§8 Agent 自查** 增加:
- 是否存在「局部变量 + 聚合 DTO」双份承载同一业务字段
- 聚合 DTO 是否包含可推导的重复标量?
### [`agent-completion-gate.mdc`](/Users/ray/.cursor/rules/agent-completion-gate.mdc)
在 Logic 自查条(现有第 5 条)中补充:**§3 编排上下文与聚合 DTO**。
## 三、验收
1. `launchWithSession` 无仅用于组 DTO 的 `$uid` / `$providerCode` / `$gameCode` 局部变量。
2. `GameLaunchSessionStartDTO` 构造函数仅 2 个参数。
3. `docker exec -w /app/www/ray/slot-pwa php82 php -l` 对相关文件通过。
4. `SLOT_ROOT=/Users/ray/Documents/project/www/ray ~/.cursor/hooks/verify-slot-backend.sh``PASS`
## 范围外
- 不改动 `GameLaunchContextDTO` / `GameLaunchSessionCreateParams` 结构。
- 不修改 verify 脚本(仍依赖规则 + 自查)。