Agent SkillsAgent Skills
git-tao

contract-validation

@git-tao/contract-validation
git-tao
0
0 forks
Updated 3/31/2026
View on GitHub

Validates frontend-backend API contracts. Apply when modifying API endpoints or service files.

Installation

$npx agent-skills-cli install @git-tao/contract-validation
Claude Code
Cursor
Copilot
Codex
Antigravity

Details

Path.claude/skills/contract-validation/SKILL.md
Branchmain
Scoped Name@git-tao/contract-validation

Usage

After installing, this skill will be available to your AI coding assistant.

Verify installation:

npx agent-skills-cli list

Skill Instructions


name: contract-validation description: "Validates frontend-backend API contracts. Apply when modifying API endpoints or service files."

Contract Validation Skill

Ensures frontend and backend API contracts remain synchronized.

When to Apply

  • Modifying API endpoints (backend)
  • Modifying service/API calls (frontend)
  • Adding new endpoints
  • Changing request/response schemas

Core Rules

1. Schema Consistency

Backend response MUST match frontend TypeScript interface:

# Backend (Python/FastAPI)
class UserResponse(BaseModel):
    user_id: str
    email: str
    created_at: datetime
// Frontend (TypeScript)
interface UserResponse {
    user_id: string;      // str -> string
    email: string;
    created_at: string;   // datetime -> ISO string
}

2. Endpoint Existence

Every frontend API call needs a backend endpoint:

// Frontend
export const getUser = (id: string) => api.get(`/users/${id}`);
# Backend MUST have:
@router.get("/users/{user_id}")
async def get_user(user_id: str) -> UserResponse:
    ...

3. Use Centralized API Client

// CORRECT
import api from '../utils/api';
const response = await api.get('/users/123');

// WRONG - direct axios/fetch
import axios from 'axios';
const response = await axios.get('http://localhost:8000/api/users/123');

Common Mismatches

Snake Case vs Camel Case

# Backend returns
{"user_id": "123", "created_at": "2025-01-01"}
// Frontend expects - MISMATCH!
interface User {
    userId: string;     // Wrong: should be user_id
    createdAt: string;  // Wrong: should be created_at
}

Optional vs Required

# Backend - field is optional
class Response(BaseModel):
    data: Optional[str] = None
// Frontend - assumes required - BUG!
interface Response {
    data: string;  // Should be: data?: string
}

Enum Mismatches

# Backend: lowercase
class Status(str, Enum):
    PENDING = "pending"
// Frontend: uppercase - WRONG
type Status = "PENDING";  // Should be "pending"

Verification Commands

# Find backend routes
grep -rn "@router\." backend/ --include="*.py"
grep -rn "router\.\(get\|post\)" backend/ --include="*.ts"

# Find frontend API calls
grep -rn "api\.\(get\|post\)" src/ --include="*.ts"

Checklist

  • Backend endpoint exists for frontend call
  • HTTP methods match
  • Field names match (snake_case)
  • Field types match
  • Optional fields marked with ?
  • Enum values match exactly