Skip to content
Development
Skill

/contract-standards

OpenAPI contract standards for API specification, versioning, and type generation.

From plugin
sdd
4459 skills7 agents3 commands
Install
$ npx -y skills add LiorCohen/sdd --skill contract-standards --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/contract-standards

Context preview

The summary Claude sees to decide when to auto-load this skill.

OpenAPI contract standards for API specification, versioning, and type generation.

SKILL.md

contract-standards.SKILL.md
name: contract-standards
description: OpenAPI contract standards for API specification, versioning, and type generation.

Contract Standards Skill

Standards for OpenAPI contract components that define API specifications and generate TypeScript types.

---

Purpose

Contract components are the single source of truth for API types:

1. **Define API shape** in OpenAPI 3.0 YAML 2. **Generate TypeScript types** consumed by server and webapp 3. **Validate API consistency** via Spectral linting 4. **Enable type-safe development** across the stack

---

Directory Structure

components/contract[-{name}]/
├── package.json          # Build scripts (generate:types, validate)
├── tsconfig.json         # TypeScript config for generated types
├── openapi.yaml          # OpenAPI 3.0 specification
├── .spectral.yaml        # Spectral linting rules (optional)
├── .gitignore            # Ignores generated/ directory
└── generated/            # Git-ignored generated output
    └── api-types.ts      # Generated TypeScript types

---

Config Schema

Contract components do not require application config from `components/config/`. They are build-time artifacts, not runtime services. The `contract-scaffolding` skill generates an `openapi.yaml`, `package.json` with type generation scripts, and a `generated/` directory for TypeScript types.

---

OpenAPI Specification Standards

Info Section

openapi: '3.0.3'
info:
  title: Project API
  version: '1.0.0'
  description: API description

Path Naming

| Pattern | Example | Use Case | |---------|---------|----------| | `/resources` | `/users` | Collection endpoint | | `/resources/{id}` | `/users/{userId}` | Single resource | | `/resources/{id}/subresources` | `/users/{userId}/orders` | Nested resources |

**Rules:**

  • Use plural nouns for collections (`/users`, not `/user`)
  • Use kebab-case for multi-word paths (`/user-profiles`)
  • Use camelCase for path parameters (`{userId}`)
  • Avoid verbs in paths (use HTTP methods instead)

Operation IDs

Operation IDs become handler function names:

paths:
  /users:
    get:
      operationId: listUsers      # -> handleListUsers
    post:
      operationId: createUser     # -> handleCreateUser
  /users/{userId}:
    get:
      operationId: getUser        # -> handleGetUser
    put:
      operationId: updateUser     # -> handleUpdateUser
    delete:
      operationId: deleteUser     # -> handleDeleteUser

**Rules:**

  • Use camelCase
  • Start with verb: `get`, `list`, `create`, `update`, `delete`
  • Be specific: `getUserProfile`, not `getProfile`

Request/Response Schemas

components:
  schemas:
    User:
      type: object
      required:
        - id
        - email
      properties:
        id:
          type: string
          format: uuid
        email:
          type: string
          format: email
        name:
          type: string
        createdAt:
          type: string
          format: date-time

    CreateUserRequest:
      type: object
      required:
        - email
      properties:
        email:
          type: string
          format: email
        name:
          type: string

    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
        message:
          type: string

**Naming Conventions:**

  • Resource schemas: `User`, `Order`, `Task`
  • Request schemas: `CreateUserRequest`, `UpdateOrderRequest`
  • Response wrappers (if needed): `UserListResponse`, `PaginatedResponse`
  • Errors: `Error`, `ValidationError`

Standard Error Responses

Define reusable error responses:

components:
  responses:
    BadRequest:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Authentication required
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

Health Endpoints

**Health check endpoints are NOT defined in the contract.** They are infrastructure endpoints implemented directly in the Operator layer:

  • `/health` - Liveness probe
  • `/readiness` - Readiness probe

These run on a separate port (e.g., 9090) from the main API.

---

Type Generation

Running Generation

<plugin-root>/fullstack-typescript/system/system-run.sh contract generate-types <component-name>

Generated Type Usage

Server and webapp consume types via workspace dependency:

// In server or webapp
import type { components, paths } from '@project/contract';

// Schema types
type User = components['schemas']['User'];
type CreateUserRequest = components['schemas']['CreateUserRequest'];

// Path types (for typed API clients)
type GetUserPath = paths['/users/{userId}']['get'];

Type Import Rules

  • **Always use `import type`** - Contract types are compile-time only
  • **Never modify generated files** - Regenerate instead
  • **Add to workspace dependencies** - Use `"workspace:*"` version

---

Versioning

API Versioning Strategy

| Strategy | When to Use | |----------|-------------| | URL path (`/v1/users`) | Breaking changes require new version | | No versioning | Internal APIs, rapid iteration |

For most SDD projects, avoid versioning until you have external consumers.

Schema Versioning

Track changes in `info.version`:

info:
  version: '1.0.0'  # Bump on breaking changes

---

Validation

Spectral Linting

<plugin-root>/fullstack-typescript/system/system-run.sh contract validate <component-name>

Uses `.spectral.yaml` for custom rules (optional).

Required Validations

1. **All paths have operationId** 2. **All schemas have required fields defined** 3. **Response

Read more
Ships withsdd

Structure for AI-assisted development AI coding assistants are powerful but chaotic. You prompt, you get code, but then what?

Get the whole plugin

Other skills on sdd.