Claude-skill-registry endpoint-validator
Валидация REST API эндпоинтов на соответствие OpenAPI схеме и консистентность параметров. Использовать при реализации эндпоинтов, ревью кода или перед слиянием изменений API.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/collection" ~/.claude/skills/majiayu000-claude-skill-registry-endpoint-validator && rm -rf "$T"
skills/data/collection/SKILL.mdMikoPBX Endpoint Validating
Validate MikoPBX REST API endpoints for OpenAPI compliance, parameter consistency, and proper implementation.
What This Skill Does
- Validates DataStructure.php - Checks parameter definitions completeness
- Validates SaveRecordAction.php - Ensures 7-phase pattern compliance
- Tests Schema Validation - Verifies SCHEMA_VALIDATION_STRICT mode
- Generates Compliance Report - Provides actionable recommendations
When to Use
Use this skill when:
- Implementing new API endpoints
- Modifying existing endpoints
- Reviewing API code changes
- Before merging API-related pull requests
- User asks "validate my API changes"
- After making changes to DataStructure.php files
Quick Start
Step 1: Identify Files
# Find DataStructure and SaveRecordAction for a resource RESOURCE="Extensions" # Or: Providers, IncomingRoutes, etc. find src/PBXCoreREST/Lib -name "DataStructure.php" | grep -i "$RESOURCE" find src/PBXCoreREST/Lib -name "SaveRecordAction.php" | grep -i "$RESOURCE"
Expected locations:
src/PBXCoreREST/Lib/{Resource}/DataStructure.phpsrc/PBXCoreREST/Lib/{Resource}/SaveRecordAction.php
Step 2: Validate DataStructure
Check for required structure:
class DataStructure { public static function getParameterDefinitions(): array { return [ 'request' => [ 'param_name' => [ 'type' => 'string', // Required 'description' => '...', // Required 'example' => 'example_value', // Required 'required' => true, // Required // Optional constraints: 'maxLength' => 255, 'pattern' => '^regex$', 'enum' => ['value1', 'value2'], 'default' => 'default_value', ], ], 'response' => [ // Similar structure for response fields ], ]; } }
Quick Checks:
- ✅ Has
methodgetParameterDefinitions() - ✅ Every parameter has: type, description, example, required
- ✅ Validation constraints present (min/max, pattern, enum)
- ❌ NO
method (legacy)getParametersConfig() - ❌ NO
usageParameterSanitizationExtractor
See: Complete DataStructure Specification
Step 3: Validate SaveRecordAction
Check for 7-phase pattern compliance:
class SaveRecordAction extends BaseSaveAction { public function __invoke(ServerRequestInterface $request): ResponseInterface { // PHASE 1: Load DataStructure definitions $definitions = DataStructure::getParameterDefinitions(); // PHASE 2: Parse request & detect HTTP method $requestData = $this->parseRequest($request); $httpMethod = $request->getMethod(); // PHASE 3: Validate ID if present $id = $requestData['id'] ?? null; // PHASE 4: Load existing record for PUT/PATCH/DELETE $existingRecord = null; if (in_array($httpMethod, ['PUT', 'PATCH', 'DELETE']) && $id) { $existingRecord = $this->findRecordById($id); } // PHASE 5: Sanitize & apply defaults (POST only!) $sanitized = []; foreach ($requestDefs as $param => $def) { if (isset($requestData[$param])) { $sanitized[$param] = $this->sanitizeValue(...); } elseif ($httpMethod === 'POST' && isset($def['default'])) { $sanitized[$param] = $def['default']; // Only on POST! } } // PHASE 6: Validate parameters $errors = $this->validateParameters($sanitized, $requestDefs, $httpMethod); // PHASE 7: Business logic & persistence if ($httpMethod === 'POST') { return $this->respondSuccess($this->createRecord($sanitized), 201); } // ... PUT/PATCH/DELETE handling } }
Critical Checks:
- ✅ Defaults applied ONLY on POST, never on PATCH
- ✅ Required validation on POST and PUT, but NOT on PATCH
- ✅ HTTP method detection present
- ✅ Comprehensive WHY comments
- ❌ NO defaults on PATCH (common bug!)
See: Complete 7-Phase Pattern Guide
Top 5 Common Issues
1. 🔴 CRITICAL: Defaults Applied on PATCH
Problem:
// ❌ WRONG - Applies defaults on PATCH too! $value = $requestData[$param] ?? $def['default'] ?? null;
Why Bad: PATCH is for partial updates. Defaults overwrite existing values.
Fix:
// ✅ CORRECT - Only on POST if ($httpMethod === 'POST' && !isset($requestData[$param]) && isset($def['default'])) { $sanitized[$param] = $def['default']; }
See: All Anti-Patterns
2. 🔴 CRITICAL: Required Validation on PATCH
Problem:
// ❌ WRONG - Validates required on all methods if ($def['required'] && !isset($data[$param])) { $errors[] = "Required"; }
Why Bad: PATCH allows partial updates. User should update one field without sending all.
Fix:
// ✅ CORRECT - Skip required check for PATCH if (in_array($httpMethod, ['POST', 'PUT']) && $def['required'] && !isset($data[$param])) { $errors[] = "Required"; }
3. 🟡 HIGH: Hardcoded Validation
Problem: Validation rules in SaveRecordAction instead of DataStructure.
Fix: Move all validation constraints to DataStructure:
// In DataStructure.php 'number' => [ 'type' => 'string', 'pattern' => '^\d{2,8}$', // Define here 'maxLength' => 8, ] // SaveRecordAction uses these constraints automatically
4. 🟡 HIGH: Legacy Methods
Problems:
- Using
instead ofgetParametersConfig()getParameterDefinitions() - Using
classParameterSanitizationExtractor
Fix: Remove legacy code, use modern approach.
5. 🟢 MEDIUM: Missing Validation Constraints
Problem: Parameters missing min/max, pattern, enum constraints.
Fix: Add constraints to DataStructure:
'email' => [ 'type' => 'string', 'format' => 'email', // Add format 'maxLength' => 255, // Add length limit ]
Validation Workflow
1. Quick Visual Inspection
Read through files looking for:
- DataStructure has
✅getParameterDefinitions() - SaveRecordAction has method detection (
) ✅$httpMethod - Defaults only in POST conditional ✅
- Required validation skips PATCH ✅
- WHY comments present ✅
2. Test with CURL
CONTAINER_ID=$(docker ps --filter "ancestor=mikopbx/mikopbx" --format "{{.ID}}" | head -1) # Get auth token TOKEN="your-bearer-token" # Test POST (should apply defaults) curl -X POST "https://mikopbx-php83.localhost:8445/pbxcore/api/v3/extensions" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"number": "201", "type": "SIP"}' \ -k -v # Test PATCH (should NOT apply defaults) curl -X PATCH "https://mikopbx-php83.localhost:8445/pbxcore/api/v3/extensions/{id}" \ -H "Authorization: Bearer $TOKEN" \ -d '{"number": "202"}' \ -k -v # Verify: status should remain unchanged, not reset to default
3. Generate Report
Use the report template to document findings:
- DataStructure compliance score
- SaveRecordAction compliance score
- Critical issues found
- Prioritized recommendations
Testing Checklist
Essential tests to verify endpoint behavior:
POST Tests
- POST with all required succeeds (201)
- POST with missing required fails (400)
- POST applies defaults correctly
PUT Tests
- PUT with all required succeeds (200)
- PUT with missing required fails (400)
- PUT on non-existent fails (404)
PATCH Tests (Most Important!)
- PATCH with partial data succeeds (200)
- PATCH does NOT apply defaults (verify existing values preserved)
- PATCH does NOT require all required fields
- PATCH on non-existent fails (404)
DELETE Tests
- DELETE existing succeeds (200/204)
- DELETE non-existent fails (404)
See: Complete Validation Checklist
Output Format
Always provide structured compliance reports:
📋 API Endpoint Validation Report ================================== 🎯 Endpoint: POST /pbxcore/api/v3/extensions 📁 Resource: Extensions 📂 Files Analyzed: ✅ DataStructure.php: src/PBXCoreREST/Lib/Extensions/DataStructure.php ✅ SaveRecordAction.php: src/PBXCoreREST/Lib/Extensions/SaveRecordAction.php --- ## 🔍 DataStructure Analysis ✅ Structure: COMPLIANT ⚠️ Missing constraints on 3 parameters: - user_username: Add pattern validation - email: Add format => 'email' DataStructure Score: 85/100 ✅ --- ## 🔍 SaveRecordAction Analysis ❌ CRITICAL ISSUES: 1. Defaults applied on PATCH (Line 87) Impact: Partial updates overwrite existing values Fix: Wrap default logic in `if ($httpMethod === 'POST')` 2. Missing required validation for PUT (Line 145) Impact: PUT allows missing required fields Fix: Change to `if (in_array($httpMethod, ['POST', 'PUT']))` SaveRecordAction Score: 55/100 ❌ --- ## 📊 Overall Compliance Score Total Score: 72/100 ⚠️ Needs Improvement --- ## ✅ Recommendations (Priority Order) 🔴 CRITICAL (Must Fix): 1. Fix PATCH defaults bug (Line 87) - 15 min 2. Add PUT required validation (Line 145) - 10 min 🟡 HIGH PRIORITY: 3. Add validation constraints to DataStructure - 15 min --- 📝 Action Items: - [ ] Fix PATCH defaults bug - [ ] Add PUT required validation - [ ] Add missing constraints - [ ] Add regression test for PATCH - [ ] Run full test suite
Full Template: report-template.md
Pro Tips
- Always Check PATCH First - Most bugs are in PATCH handling
- Look for WHY Comments - They explain critical decisions
- Test Actual Behavior - Don't trust code inspection alone
- Use Schema Validation - Enable SCHEMA_VALIDATION_STRICT=1
- Focus on Defaults - Default application logic is #1 bug source
- Check Method Detection - Ensure
is actually used$httpMethod
Troubleshooting
Issue: Can't find DataStructure.php
# Search entire codebase find src -name "DataStructure.php" | grep -i "YourResource" # If not found, check if resource exists ls -la src/PBXCoreREST/Lib/ | grep -i "YourResource"
Issue: Schema validation not working
# Check if enabled docker exec $CONTAINER_ID env | grep SCHEMA_VALIDATION # If not set, add to docker-compose.yml: # environment: # SCHEMA_VALIDATION_STRICT: 1
Issue: Tests show unexpected behavior
# Check container logs for validation errors docker exec $CONTAINER_ID tail -100 /storage/usbdisk1/mikopbx/log/php/error.log
Additional Resources
Complete Documentation:
- DataStructure Specification - How to define parameters
- SaveRecordAction Pattern - 7-phase implementation guide
- Validation Checklist - Complete validation checklist
- Anti-Patterns - Common mistakes to avoid
- Report Template - Compliance report format
Related Skills:
- Fetch and analyze OpenAPI specmikopbx-openapi-analyzer
- Generate pytest tests from specmikopbx-api-test-generator
- Test after container restartmikopbx-docker-restart-tester
Success Criteria
Validation is successful when:
- ✅ DataStructure has complete parameter definitions
- ✅ No legacy patterns found
- ✅ SaveRecordAction follows 7-phase pattern
- ✅ Defaults only applied on POST
- ✅ Required validation only on POST/PUT (not PATCH)
- ✅ All validation from DataStructure, not hardcoded
- ✅ Schema validation tests pass
- ✅ PATCH preserves existing values (doesn't apply defaults)
- ✅ Compliance score ≥ 90/100
Quick Reference Card
| Check | DataStructure | SaveRecordAction |
|---|---|---|
| Has modern structure | | 7-phase pattern |
| No legacy code | No | No |
| Complete metadata | type, description, example | WHY comments |
| Validation constraints | min/max, pattern, enum | Uses DataStructure rules |
| Defaults handling | Defined in request section | Only applied on POST |
| Required validation | Marked with | POST & PUT only, not PATCH |
Example Validation Session
# 1. Locate files RESOURCE="Extensions" find src/PBXCoreREST/Lib -path "*/$RESOURCE/DataStructure.php" # Output: src/PBXCoreREST/Lib/Extensions/DataStructure.php # 2. Check DataStructure structure grep -n "getParameterDefinitions" src/PBXCoreREST/Lib/Extensions/DataStructure.php # Output: Line 15: public static function getParameterDefinitions(): array # 3. Check for legacy methods grep -n "getParametersConfig\|ParameterSanitizationExtractor" \ src/PBXCoreREST/Lib/Extensions/DataStructure.php # Output: (none) - Good! # 4. Check SaveRecordAction for PATCH defaults bug grep -A 2 "httpMethod.*POST" src/PBXCoreREST/Lib/Extensions/SaveRecordAction.php # Look for: if ($httpMethod === 'POST' && isset($def['default'])) # 5. Run PATCH test curl -X PATCH "https://mikopbx-php83.localhost:8445/pbxcore/api/v3/extensions/123" \ -H "Authorization: Bearer $TOKEN" \ -d '{"number": "202"}' -k | jq '.data.status' # Verify status didn't change to default value