This commit is contained in:
ray zhou
2026-06-29 14:51:55 +08:00
parent 225fb2bd28
commit 2dd9f17da9
319 changed files with 29461 additions and 9412 deletions

View File

@@ -0,0 +1,101 @@
---
name: slot-backend-completion-report
description: >-
Slot PHP 后端任务收尾自检:跑 verify 门禁、docker php -l、对照 php-clean-code
与 backend-layering 输出结构化检测报告。修改 app/**/*.php 后收尾前必读;用户说
「按规范检测」「检测代码」时也触发。
---
# Slot 后端完成前检测报告
用户级 Skill**禁止写死** `slot-xxx``/app/www/ray/...` 等服务路径;一律从**当前工作区 + git 仓库根 + Docker 挂载**推导。
## 何时执行
- 本次对话改动了任意 `app/**/*.php`
- 用户要求「按规范检测 / 检测代码 / 出检测报告」
- 准备写「已完成 / 可以合并 / 验收通过」之前
## 步骤(按顺序)
### 1. 跑统一脚本(推荐)
```bash
SLOT_ROOT="${SLOT_ROOT:-<当前 Cursor 工作区根目录>}" \
~/.cursor/skills/slot-backend-completion-report/scripts/report.sh
```
- `SLOT_ROOT` 默认为当前工作区根(可能在 `www/ray``www/slot` 等不同 monorepo 下)
- 脚本会:
1. 调用 `~/.cursor/hooks/verify-slot-backend.sh`
2. 对 git diff 中每个改动 `.php` 执行 `docker php -l`
### 2. 路径映射规则脚本已实现Agent 手工跑命令时同样遵守)
对每个改动 PHP 文件 `$f`
1. `repo=$(git -C "$(dirname "$f")" rev-parse --show-toplevel)`
2. 宿主机挂载根 → 容器根(见 `dev-environment`
- `SLOT_DOCKER_HOST_ROOT` 默认 `/Users/ray/Documents/project`
- `SLOT_DOCKER_CONTAINER_ROOT` 默认 `/app`
3. `container_wd="${SLOT_DOCKER_CONTAINER_ROOT}${repo#$SLOT_DOCKER_HOST_ROOT}"`
4. `docker exec -w "$container_wd" php82 php -l "${f#$repo/}"`
示例(由路径**推导**,非手写):
| git 仓库根(宿主机) | 容器 `-w` |
|----------------------|-----------|
| `.../project/www/ray/slot-admin` | `/app/www/ray/slot-admin` |
| `.../project/www/slot/slot_wallet` | `/app/www/slot/slot_wallet` |
仓库不在 `SLOT_DOCKER_HOST_ROOT` 下 → 跳过 docker 语法检查并在报告中说明。
### 3. 规范对照Agent 读 diff 后填表,脚本无法替代)
| 检查项 | 依据 | 做法 |
|--------|------|------|
| PHPDoc 中文首行 | `php-clean-code` §5 | 改动的方法均有中文说明 |
| 类常量注释 | `php-clean-code` §3 常量规则 | 所有 `const` 均有 `/** 中文说明 */` |
| Logic 参数与日志 | §3 参数与日志 | 无仅用于日志的多余参数 |
| 聚合 DTO | §3 编排上下文 | 无重复标量 / 双份拷贝 |
| Logic/Service 返回值 | `php-clean-code` §4 + `verify-slot-backend.sh` | 未返回 `array`;固定形状用 Entity |
| 分层 | `backend-layering` | Controller 薄、Logic 编排、无 Logic 型 Service |
| 业务异常 | `agent-completion-gate` | 不用 RuntimeException 表业务失败 |
`app/**/logic/**/*.php`§3 参数与日志、聚合 DTO、§8 自查**必须**逐项过一遍。
## 最终回复必须包含的章节
```markdown
## 检测结果
### 门禁脚本
(粘贴 report.sh 或 verify-slot-backend.sh 完整输出,以 `=== verify-slot-backend ===``=== slot-backend-completion-report ===` 开头)
### PHP 语法docker php -l
(粘贴 php -l 输出;无改动 PHP 写「无改动 PHP」
### 规范对照
| 项 | 结果 | 说明 |
|----|------|------|
| PHPDoc / 常量注释 | 通过/不通过 | … |
| Logic/Service 返回 Entity | 通过/不通过/不适用 | … |
| 分层 | 通过/不通过/不适用 | … |
| Logic §3 / §8若改 Logic | 通过/不适用 | … |
### 结论
通过 / 不通过(不通过须先修复再收尾)
PHPDoc: checked
```
## 禁止
- 未跑脚本、未对照规范就写「已完成」
- 只贴 `PASS` 一行、无规范对照表
- 在宿主机直接跑 `php` / `composer`(须 docker`dev-environment`
- 写死 `/app/www/ray/slot-xxx` 或假设固定 monorepo 目录
## 与 Hook 的关系
`~/.cursor/hooks.json``stop` 会自动跑 `verify-slot-backend.sh`;本 Skill 在此基础上补 **php -l****结构化 Markdown 报告**,二者互补。

View File

@@ -0,0 +1,86 @@
#!/bin/bash
# 跑 verify 门禁 + 对 git diff 中改动的 PHP 做 docker php -l。
# 路径由「当前工作区 + git 仓库根 + Docker 挂载」动态推导,不写死 slot-xxx。
set -euo pipefail
SLOT_ROOT="${SLOT_ROOT:-${WORKSPACE_ROOT:-$(pwd)}}"
SLOT_DOCKER_HOST_ROOT="${SLOT_DOCKER_HOST_ROOT:-/Users/ray/Documents/project}"
SLOT_DOCKER_CONTAINER_ROOT="${SLOT_DOCKER_CONTAINER_ROOT:-/app}"
PHP_CONTAINER="${PHP_CONTAINER:-php82}"
VERIFY_SCRIPT="${VERIFY_SCRIPT:-$HOME/.cursor/hooks/verify-slot-backend.sh}"
host_repo_to_container_wd() {
local repo="$1"
if [[ "$repo" != "$SLOT_DOCKER_HOST_ROOT"* ]]; then
echo ""
return 1
fi
echo "${SLOT_DOCKER_CONTAINER_ROOT}${repo#$SLOT_DOCKER_HOST_ROOT}"
}
collect_changed_php() {
local root="$1"
local d rel abs
for d in "$root"/* "$root"/backend "$root"/backend/*; do
[ -d "${d}/.git" ] || continue
git -C "$d" diff --quiet 2>/dev/null && git -C "$d" diff --cached --quiet 2>/dev/null && continue
while IFS= read -r rel; do
[ -z "$rel" ] && continue
[[ "$rel" != *.php ]] && continue
[[ "$rel" == vendor/* ]] && continue
abs="$d/$rel"
[ -f "$abs" ] || continue
printf '%s\n' "$abs"
done < <(
{ git -C "$d" diff --name-only 2>/dev/null
git -C "$d" diff --cached --name-only 2>/dev/null
} | sort -u
)
done | sort -u
}
echo "=== slot-backend-completion-report ==="
echo "SLOT_ROOT=$SLOT_ROOT"
echo "SLOT_DOCKER_HOST_ROOT=$SLOT_DOCKER_HOST_ROOT"
echo ""
echo "--- verify-slot-backend ---"
SLOT_ROOT="$SLOT_ROOT" bash "$VERIFY_SCRIPT" || verify_exit=$?
verify_exit=${verify_exit:-0}
echo ""
echo "--- php -l (docker) ---"
syntax_fail=0
changed_php=()
while IFS= read -r abs; do
[ -z "$abs" ] && continue
changed_php+=("$abs")
done < <(collect_changed_php "$SLOT_ROOT" || true)
if [ ${#changed_php[@]} -eq 0 ]; then
echo "(no changed php files)"
else
for abs in "${changed_php[@]}"; do
repo=$(git -C "$(dirname "$abs")" rev-parse --show-toplevel 2>/dev/null) || {
echo "SKIP (no git repo): $abs"
continue
}
rel="${abs#"$repo"/}"
container_wd=$(host_repo_to_container_wd "$repo") || {
echo "SKIP (outside docker mount): $abs"
continue
}
if ! docker exec -w "$container_wd" "$PHP_CONTAINER" php -l "$rel"; then
syntax_fail=1
fi
done
fi
echo ""
echo "=== summary ==="
if [ "$verify_exit" -ne 0 ] || [ "$syntax_fail" -ne 0 ]; then
echo "FAIL (verify=$verify_exit syntax=$syntax_fail)"
exit 1
fi
echo "PASS (verify + php -l)"
exit 0