| name | sync-postman |
| description | Sync Postman collection and environment after API changes. Diffs route files against docs/postman/coinwall-collection.json, adds missing endpoints, removes stale ones, updates request bodies and auth. Trigger after any route/endpoint change, or when user says "sync postman", "更新 postman", "同步接口文档". |
Sync Postman Collection
Keep docs/postman/coinwall-collection.json and docs/postman/coinwall-environment.json in sync with the actual API routes.
When to Trigger
This skill MUST run after any of these changes:
| Change | Action |
|---|
| New route / endpoint added | Add request to collection |
| Route removed | Remove request from collection |
| Route path changed | Update request URL |
| Request body schema changed | Update request body example |
| Auth requirement changed | Update request/folder auth |
| New environment variable used in routes | Add to environment file |
| New path parameter / query parameter | Update request URL / params |
Files
| File | Purpose |
|---|
docs/postman/coinwall-collection.json | Postman Collection v2.1 — all API requests |
docs/postman/coinwall-environment.json | Environment variables (baseUrl, tokens, IDs) |
Step 1 — Scan Route Files
Read ALL route registration in src/server/routes/index.ts to get mount paths, then scan each route file:
src/server/routes/auth.ts → /api/auth
src/server/routes/admin-auth.ts → /api/admin-auth
src/server/routes/admin.ts → /api/admin
src/server/routes/merchant.ts → /api/merchant
src/server/routes/api-keys.ts → /api/merchant/api-keys
src/server/routes/bots.ts → /api/merchant/bots
src/server/routes/webhook.ts → /api/merchant/webhooks
src/server/routes/notification.ts → /api/merchant (notification endpoints)
src/server/routes/fiat-configs.ts → /api/merchant/fiat-configs
src/server/routes/topup-orders.ts → /api/merchant/topup-orders
src/server/routes/demo.ts → /api/merchant/demo
src/server/routes/events.ts → /api/events
src/server/routes/health.ts → /api
src/server/routes/agent-public.ts → /api/agent
src/server/gateway/routes/*.ts → /api/gateway
Extract: HTTP method, full path, auth requirement, request body shape.
Step 2 — Diff Against Collection
Read the current collection JSON and compare:
- Missing endpoints — in routes but not in collection → add
- Stale endpoints — in collection but not in routes → remove
- Changed endpoints — path/method/body/auth mismatch → update
Step 3 — Update Collection
Follow these Postman conventions:
Folder Structure
| Folder | Mount Path | Auth |
|---|
| Health & Metrics | /api | None (except /metrics = admin) |
| Auth (Merchant) | /api/auth | None (except /me, /logout) |
| Auth (Admin) | /api/admin-auth | None (except /me, /logout) |
| Admin Management | /api/admin | Admin JWT — folder-level bearer {{adminToken}} |
| Merchant Dashboard | /api/merchant | Merchant JWT — folder-level bearer {{merchantToken}} |
| API Keys | /api/merchant/api-keys | Merchant JWT (interactive only) |
| Bots | /api/merchant/bots | Merchant JWT |
| Webhooks | /api/merchant/webhooks | Merchant JWT |
| Notifications | /api/merchant | Merchant JWT |
| Fiat Configs | /api/merchant/fiat-configs | Merchant JWT |
| Top-up Orders | /api/merchant/topup-orders | Merchant JWT |
| Demo | /api/merchant/demo | Merchant JWT |
| Agent Public API | /api/agent | Agent API key — X-API-Key: {{agentApiKey}} |
| x402 Discovery | /api/gateway/x402/discovery | None |
| SSE Events | /api/events | Merchant JWT (query param) |
Request Format
{
"name": "Human-Readable Name",
"request": {
"method": "POST",
"header": [
{ "key": "Content-Type", "value": "application/json" }
],
"url": {
"raw": "{{baseUrl}}/api/path",
"host": ["{{baseUrl}}"],
"path": ["api", "path"]
},
"body": {
"mode": "raw",
"raw": "{\n \"field\": \"value\"\n}",
"options": { "raw": { "language": "json" } }
}
}
}
Auth Patterns
- No auth: omit
auth property (inherits from folder, or set "auth": {"type": "noauth"})
- Merchant JWT: folder-level
"auth": {"type": "bearer", "bearer": [{"key": "token", "value": "{{merchantToken}}"}]}
- Admin JWT: same pattern with
{{adminToken}}
- Agent API Key:
"auth": {"type": "apikey", "apikey": [{"key": "key", "value": "X-API-Key"}, {"key": "value", "value": "{{agentApiKey}}"}, {"key": "in", "value": "header"}]}
Token-Saving Scripts
Authenticate and refresh endpoints MUST have test scripts:
if (pm.response.code === 200) {
var data = pm.response.json();
pm.environment.set("merchantToken", data.token);
pm.environment.set("merchantRefreshToken", data.refreshToken);
}
if (pm.response.code === 200) {
var data = pm.response.json();
pm.environment.set("adminToken", data.token);
pm.environment.set("adminRefreshToken", data.refreshToken);
}
Path Variables
Use {{variable}} for dynamic segments:
| Variable | Used in |
|---|
{{baseUrl}} | All requests |
{{merchantToken}} | Merchant auth |
{{adminToken}} | Admin auth |
{{agentApiKey}} | Agent API key |
{{merchantUuid}} | x402 discovery, gateway |
{{resourceId}} | Resource CRUD |
{{agentId}} | Pay Agent CRUD |
{{webhookId}} | Webhook CRUD |
{{apiKeyId}} | API key CRUD |
{{announcementId}} | Announcement CRUD |
Step 4 — Update Environment
If new variables are needed (e.g., a new entity ID placeholder), add to coinwall-environment.json.
Step 5 — Validate
node -e "
const c = require('./docs/postman/coinwall-collection.json');
function count(items) { return items.reduce((s, i) => s + (i.item ? count(i.item) : 1), 0); }
console.log('Requests:', count(c.item));
console.log('Folders:', c.item.length);
"
Verify the JSON is valid and the count matches the actual number of endpoints.
Step 6 — Report
Output a summary:
Postman collection synced:
| Action | Count | Details |
|---------|-------|---------|
| Added | 3 | POST /api/merchant/foo, GET /api/merchant/bar, ... |
| Removed | 1 | DELETE /api/merchant/old |
| Updated | 2 | PUT /api/merchant/baz (body changed), ... |
| Total | 126 → 128 requests |
Rules
- JSON must be valid — no trailing commas, no comments
- Collection format: Postman v2.1 (
https://schema.getpostman.com/json/collection/v2.1.0/collection.json)
- Content-Type header on all POST/PUT requests
- Folder-level auth — don't repeat auth on individual requests when the folder has it
- Request body examples should use realistic placeholder values, not empty objects
- Keep folder ordering consistent with the table above
- Environment secrets (
merchantToken, adminToken, agentApiKey) use "type": "secret"