Skip to main content

piu-hyperf-sync

Deep sync a Hyperf PHP backend to PIU — extracts routes via Hyperf CLI, parses controller validation rules and response shapes, builds Eloquent model schemas, maps middleware to auth types, and creates PIU entities with full API documentation. Supports token-efficient incremental daily re-sync via manifest tracking. Use when the user says "sync hyperf", "import hyperf", "hyperf api sync", or when piu-backend-sync detects framework: "hyperf".

跳到安装

来源信息

仓库
dickwu/piu
最近来源活动
2026年3月29日 15:18
检测到的 SKILL.md 语言
英语
星标
4
分支
0

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

文件资源管理器
2 个文件

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
piu-hyperf-sync
description
Deep sync a Hyperf PHP backend to PIU — extracts routes via Hyperf CLI, parses controller validation rules and response shapes, builds Eloquent model schemas, maps middleware to auth types, and creates PIU entities with full API documentation. Supports token-efficient incremental daily re-sync via manifest tracking. Use when the user says "sync hyperf", "import hyperf", "hyperf api sync", or when piu-backend-sync detects framework: "hyperf".
# PIU Hyperf Sync Deep-syncs a Hyperf PHP backend API to PIU. Uses `php bin/hyperf.php describe:routes` as the authoritative route source, Claude's PHP comprehension for semantic extraction, and a manifest-based incremental sync for daily re-runs. ## Prerequisites - The Hyperf project must be bootable (`php bin/hyperf.php describe:routes` must work) - PIU must be running with MCP enabled (the `piu.ts` CLI from `piu-backend-sync` must connect) - Git must be available for commit tracking ## CLI Scripts This skill uses scripts from two locations: ```bash # Route parser (this skill) bun skills/piu-hyperf-sync/scripts/parse-routes.ts < routes.txt # PIU MCP client (from piu-backend-sync) bun skills/piu-backend-sync/scripts/piu.ts <command> [args...] ``` The PIU CLI path is relative to the PIU repo root. Set `PIU_ROOT` if running from elsewhere: ```bash PIU_ROOT=/Users/gwddeveloper/opensource/piu PIU_CLI="bun $PIU_ROOT/skills/piu-backend-sync/scripts/piu.ts" PARSE_ROUTES="bun $PIU_ROOT/skills/piu-hyperf-sync/scripts/parse-routes.ts" ``` --- ## Phase 0: Pre-flight Before starting, verify the environment and determine sync mode. ### Step 0.1 — Verify Hyperf CLI ```bash cd $REPO && php bin/hyperf.php describe:routes 2>&1 | head -5 ``` If this fails or shows an error, STOP. The Hyperf project is not bootable. Common fixes: - Missing composer dependencies: `composer install` - PHP extension missing: check `php -m` for `swoole`, `pdo`, `redis` - Config error: check `config/autoload/server.php` ### Step 0.2 — Get HEAD commit ```bash COMMIT=$(git -C $REPO rev-parse HEAD) echo "HEAD commit: $COMMIT" ``` ### Step 0.3 — Check for existing manifest ```bash MANIFEST="$REPO/.piu-sync/manifest.json" if [ -f "$MANIFEST" ]; then echo "Existing manifest found — incremental sync mode" echo "Last sync commit: $(cat $MANIFEST | bun -e 'console.log(JSON.parse(await Bun.stdin.text()).commit)')" # Jump to Phase 6 (Incremental Sync) unless --force else echo "No manifest — full sync mode" # Continue to Phase 1 fi ``` If the user passes `--force` or says "full sync", skip the manifest check and do a full sync regardless. --- ## Phase 1: Route Extraction Use the Hyperf CLI for authoritative route data, then parse into structured JSON. ### Step 1.1 — Extract routes ```bash cd $REPO && php bin/hyperf.php describe:routes 2>&1 > /tmp/piu-hyperf-routes-raw.txt cat /tmp/piu-hyperf-routes-raw.txt | $PARSE_ROUTES > /tmp/piu-hyperf-routes.json ``` This produces a JSON array: ```json [ { "server": "http", "method": "POST", "uri": "/user/task/create", "action": "App\\Controller\\User\\UserTaskController::create", "middleware": ["AuthToken"] } ] ``` ### Step 1.2 — Group into collections Read `/tmp/piu-hyperf-routes.json` and group routes by first URI path segment: | URI Prefix | Collection Name | path_prefix | |-----------|----------------|-------------| | `/user` | User | `/user` | | `/admin` | Admin | `/admin` | | `/public` | Public | `/public` | | `/patient` | Patient | `/patient` | | `/pre` | Pre | `/pre` | | `/appointment` | Appointment | `/appointment` | | `/reception` | Reception | `/reception` | | `/lab` | Lab | `/lab` | | `/auth` | Root | `` (empty) | | `/tool` | Root | `` (empty) | | `/` | Root | `` (empty) | Top-level routes without a clear group go into "Root". ### Step 1.3 — Map middleware to auth type For each route, determine the auth configuration from its middleware array: | Middleware | PIU Auth Config | Env Variable | |-----------|----------------|-------------| | `AuthToken` | `{"type":"bearer","token":"{{staff_token}}"}` | `staff_token` | | `AuthAdmin` | `{"type":"bearer","token":"{{admin_token}}"}` | `admin_token` | | `AuthReception` | `{"type":"bearer","token":"{{reception_token}}"}` | `reception_token` | | `AuthPatient` | `{"type":"bearer","token":"{{patient_token}}"}` | `patient_token` | | `PreAuth` | `{"type":"bearer","token":"{{pre_token}}"}` | `pre_token` | | `PreAuthWithStatus` | `{"type":"bearer","token":"{{pre_token}}"}` | `pre_token` | | `CheckInAuth` | `{"type":"bearer","token":"{{checkin_token}}"}` | `checkin_token` | | _(empty array)_ | `{"type":"none"}` | — | If a route has multiple auth middleware (shouldn't happen but possible), use the first non-CORS one. ### Step 1.4 — Save route snapshot ```bash cp /tmp/piu-hyperf-routes-raw.txt $REPO/.piu-sync/routes-snapshot.txt ``` This is used later for text-based diffing during incremental sync. --- ## Phase 2: Controller Analysis For each unique controller file referenced by routes, read the PHP source and extract validation rules, undocumented inputs, response shapes, and side effects. ### Step 2.1 — Identify controller files From the route JSON, extract unique controller file paths: ``` action: "App\\Controller\\User\\UserTaskController::create" -> file: app/Controller/User/UserTaskController.php -> method: create ``` The mapping is: replace `App\\` with `app/`, replace `\\` with `/`, append `.php`, strip `::method`. Group routes by controller file to minimize file reads. ### Step 2.2 — Read and analyze each controller For each controller file, read the full file and analyze every method that is mapped to a route. #### 2.2a — Extract validation rules Look for `$this->validation([...])` calls within each method. The rules array uses Laravel validation syntax: ```php $this->validation([ 'title' => 'required|string|max:200', 'assignee_id' => 'nullable|integer', 'priority' => 'nullable|integer|in:1,2,3,4', 'due_date' => 'nullable|date_format:Y-m-d H:i:s', 'label_ids' => 'nullable|array', 'label_ids.*' => 'integer', ]); ``` Parse each rule string into a PIU model field: | Laravel Rule | PIU field_type | required | description notes | |---|---|---|---| | `required` | — | `true` | — | | `nullable` | — | `false` | — | | `string` | `string` | — | — | | `integer` | `integer` | — | — | | `numeric` | `number` | — | — | | `boolean` | `boolean` | — | — | | `array` | `array` | — | Check `field.*` rule for element type | | `date` | `date` | — | — | | `date_format:F` | `datetime` | — | Add "format: F" to description | | `email` | `string` | — | Add "email format" to description | | `url` | `string` | — | Add "URL format" to description | | `in:a,b,c` | (base type) | — | Add "enum: a,b,c" to description | | `max:N` | — | — | Add "max: N" to description | | `min:N` | — | — | Add "min: N" to description | | `file` / `image` | `file` | — | Body type becomes `multipart` | | `json` | `object` | — | — | If no `required` or `nullable` is specified, default to `required: false`. Build a request model named `{ControllerShortName}{Method}Request` (e.g., `UserTaskCreateRequest`). #### 2.2b — Extract undocumented inputs Search the method body for `$this->request->input('field')` or `$this->request->input('field', default)` calls where `'field'` does NOT appear in the validation rules array. Add these as fields in the request model with `documented: false` in the description. Example: ``` {name: "keyword", field_type: "string", required: false, description: "Undocumented — found via $this->request->input()"} ``` Also check for: - `$this->request->all()` — means the endpoint accepts arbitrary fields - `(int) $this->request->input('field')` — the cast reveals the type #### 2.2c — Extract response shape Trace what `successResponse()` or `$this->response->json()` receives. Common patterns in this codebase: 1. **Direct model**: `successResponse($model->toArray())` -> Response model = the Eloquent model's serialized form (see Phase 3) 2. **Eager-loaded model**: `$model->load(['creator:id,first_name,last_name'])->toArray()` -> Response includes nested relation subsets 3. **Query select**: `User::query()->select(['id', 'name', 'email'])->get()` -> Response model = subset of fields 4. **Manual array**: `successResponse(['token' => $token, 'expires_in' => 3600])` -> Inline response model with explicit fields 5. **Collection map**: `$items->map(fn($i) => ['id' => $i->id, 'name' => $i->name])` -> Response model = array of mapped objects 6. **Paginated**: Methods using `->paginate()` or manual `page`/`per_page` logic -> Response wraps data in pagination metadata For all patterns, the outer wrapper is always: ```json {"code": 1, "message": "OK", "data": <inner_shape>} ``` Build a response model named `{ControllerShortName}{Method}Response`. #### 2.2d — Extract side effects Search each method body for: | Pattern | Side Effect | |---------|-------------| | `Helper::redisNotice()` or `->publish(` on Redis notice pool | Triggers notification via Redis pub/sub | | `Helper::redisChat()` or `->publish(` on Redis chat pool | Triggers chat event via Redis pub/sub | | `$this->push(` or `dispatch(` or `AsyncQueue` | Queues async job | | `EventDispatcherInterface` or `$this->eventDispatcher->dispatch(` | Fires domain event | | `AuditLogger::` or `AuditLog::create(` | Creates audit log entry | | `EmailSender::` | Sends email notification | Record these as a list of strings for inclusion in the endpoint documentation. #### 2.2e — Record method line ranges For each method analyzed, record the start and end line numbers for future method-level hashing: ```json { "create": {"line_start": 45, "line_end": 120}, "list": {"line_start": 122, "line_end": 180} } ``` Use the `public function methodName(` signature as the start marker and the next `public function` or end of class as the end marker. --- ## Phase 3: Model Extraction
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看