Claude Code Plugins

Community-maintained marketplace

Feedback

pre-dev-api-design

@LerianStudio/ring
0
0

Use after TRD to define component contracts and interfaces, before selecting protocols/technologies, when you need clear integration specifications

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name pre-dev-api-design
description Use after TRD to define component contracts and interfaces, before selecting protocols/technologies, when you need clear integration specifications

API/Contract Design - Defining Component Interfaces

Foundational Principle

Component contracts and interfaces must be defined before technology/protocol selection.

Jumping to implementation without contract definition creates:

  • Integration failures discovered during development
  • Inconsistent data structures across components
  • Teams blocked waiting for interface clarity
  • Rework when assumptions about contracts differ
  • No clear integration test boundaries

The API Design answers: WHAT data/operations components expose and consume? The API Design never answers: HOW those are implemented (protocols, serialization, specific tech).

When to Use This Skill

Use this skill when:

  • TRD has passed Gate 3 validation
  • System has multiple components that need to integrate
  • Building APIs (internal or external)
  • Microservices, modular monoliths, or distributed systems
  • Need clear contracts for parallel development

Mandatory Workflow

Phase 1: Contract Analysis (Inputs Required)

  1. Approved TRD (Gate 3 passed) - architecture patterns defined
  2. Approved Feature Map (Gate 2 passed) - feature interactions mapped
  3. Approved PRD (Gate 1 passed) - business requirements locked
  4. Identify integration points from TRD component diagram
  5. Extract data flows from Feature Map

Phase 2: Contract Definition

For each component interface:

  1. Define operations (what actions can be performed)
  2. Specify inputs (what data is required)
  3. Specify outputs (what data is returned)
  4. Define errors (what failure cases exist)
  5. Document events (what notifications are sent)
  6. Set constraints (validation rules, rate limits)
  7. Version contracts (how changes are managed)

Phase 3: Gate 4 Validation

MANDATORY CHECKPOINT - Must pass before proceeding to Data Modeling:

  • All TRD component interactions have contracts
  • Operations are clearly named and described
  • Inputs/outputs are fully specified
  • Error scenarios are documented
  • Events are defined with schemas
  • Constraints are explicit (validation, limits)
  • Versioning strategy is defined
  • No protocol specifics (REST/gRPC/GraphQL)
  • No technology implementations

Explicit Rules

✅ DO Include in API Design

  • Operation names and descriptions
  • Input parameters (name, type, required/optional, constraints)
  • Output structure (fields, types, nullable)
  • Error codes and descriptions
  • Event types and payloads
  • Validation rules (format, ranges, patterns)
  • Rate limits or quota policies
  • Idempotency requirements
  • Authentication/authorization needs (abstract)
  • Contract versioning strategy

❌ NEVER Include in API Design

  • HTTP verbs (GET/POST/PUT) or REST specifics
  • gRPC/GraphQL/WebSocket protocol details
  • URL paths or route definitions
  • Serialization formats (JSON/Protobuf/Avro)
  • Framework-specific code (middleware, decorators)
  • Database queries or ORM code
  • Infrastructure (load balancers, API gateways)
  • Specific authentication libraries (JWT libraries, OAuth packages)

Abstraction Rules

  1. Operation: Say "CreateUser" not "POST /api/v1/users"
  2. Data Type: Say "EmailAddress (validated)" not "string with regex"
  3. Error: Say "UserAlreadyExists" not "HTTP 409 Conflict"
  4. Auth: Say "Requires authenticated user" not "JWT Bearer token"
  5. Format: Say "ISO8601 timestamp" not "time.RFC3339"

Rationalization Table

Excuse Reality
"REST is obvious, just document endpoints" Protocol choice goes in Dependency Map. Define contracts abstractly.
"We need HTTP codes for errors" Error semantics matter; HTTP codes are protocol. Abstract the errors.
"Teams need to see JSON examples" JSON is serialization. Define structure; format comes later.
"The contract IS the OpenAPI spec" OpenAPI is protocol-specific. Design contracts first, generate specs later.
"gRPC/GraphQL affects the contract" Protocols deliver contracts. Design protocol-agnostic contracts first.
"We already know it's REST" Knowing doesn't mean documenting prematurely. Stay abstract.
"Framework validates inputs" Validation logic is universal. Document rules; implementation comes later.
"This feels redundant with TRD" TRD = components exist. API = how they talk. Different concerns.
"URL structure matters for APIs" URLs are HTTP-specific. Focus on operations and data.
"But API Design means REST API" API = interface. Could be REST, gRPC, events, or in-process. Stay abstract.

Red Flags - STOP

If you catch yourself writing any of these in API Design, STOP:

  • HTTP methods (GET, POST, PUT, DELETE, PATCH)
  • URL paths (/api/v1/users, /users/{id})
  • Protocol names (REST, GraphQL, gRPC, WebSocket)
  • Status codes (200, 404, 500)
  • Serialization formats (JSON, XML, Protobuf)
  • Authentication tokens (JWT, OAuth2 tokens, API keys)
  • Framework code (Express routes, gRPC service definitions)
  • Transport mechanisms (HTTP/2, TCP, UDP)

When you catch yourself: Replace protocol detail with abstract contract. "POST /users" → "CreateUser operation"

Gate 4 Validation Checklist

Before proceeding to Data Modeling, verify:

Contract Completeness:

  • All component-to-component interactions have contracts
  • All external system integrations have contracts
  • All event/message contracts are defined
  • Client-facing APIs are fully specified

Operation Clarity:

  • Each operation has clear purpose and description
  • Operation names follow consistent naming convention
  • Idempotency requirements are documented
  • Batch operations are identified where relevant

Data Specification:

  • All input parameters are typed and documented
  • Required vs. optional is explicit
  • Output structures are complete
  • Null/empty cases are handled

Error Handling:

  • All error scenarios are identified
  • Error codes/types are defined
  • Error messages provide actionable guidance
  • Retry/recovery strategies are documented

Event Contracts:

  • All events are named and described
  • Event payloads are fully specified
  • Event ordering/delivery semantics documented
  • Event versioning strategy defined

Constraints & Policies:

  • Validation rules are explicit (format, range, pattern)
  • Rate limits or quotas are defined
  • Timeouts and deadlines are specified
  • Backward compatibility strategy exists

Technology Agnostic:

  • No protocol-specific details (REST/gRPC/etc)
  • No serialization format specifics
  • No framework or library names
  • Can implement in any protocol

Gate Result:

  • PASS: All checkboxes checked → Proceed to Data Modeling
  • ⚠️ CONDITIONAL: Remove protocol details → Re-validate
  • FAIL: Incomplete contracts → Add missing specifications

Contract Template

# API/Contract Design: [Project/Feature Name]

## Overview
- **TRD Reference**: [Link to approved TRD]
- **Feature Map Reference**: [Link to approved Feature Map]
- **Last Updated**: [Date]
- **Status**: Draft / Under Review / Approved

## Contract Versioning Strategy
- **Approach**: [e.g., Semantic versioning, Date-based, etc.]
- **Backward Compatibility**: [Policy for breaking changes]
- **Deprecation Process**: [How old contracts are sunset]

## Component Contracts

### Component: [Component Name]
**Purpose**: [What this component does - from TRD]

**Integration Points** (from TRD):
- Inbound: [Components that call this one]
- Outbound: [Components this one calls]

---

#### Operation: [OperationName]

**Purpose**: [What this operation does]

**Inputs**:
| Parameter | Type | Required | Constraints | Description |
|-----------|------|----------|-------------|-------------|
| userId | Identifier | Yes | Non-empty, UUID format | Unique user identifier |
| email | EmailAddress | Yes | Valid email format | User's email address |
| displayName | String | No | 3-50 chars, alphanumeric | Public display name |
| preferences | PreferenceSet | No | - | User preferences object |

**Input Validation Rules**:
- `email` must match pattern: `[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}`
- `displayName` must not contain profanity (filter list: [reference])
- `preferences.theme` must be one of: ["light", "dark", "auto"]

**Outputs** (Success):
| Field | Type | Nullable | Description |
|-------|------|----------|-------------|
| userId | Identifier | No | Created user's unique ID |
| createdAt | Timestamp | No | ISO8601 timestamp of creation |
| status | UserStatus | No | Account status: "active" | "pending_verification" |

**Output Structure Example** (abstract):

UserCreatedResponse { userId: Identifier createdAt: Timestamp status: UserStatus }


**Errors**:
| Error Code | Condition | Description | Retry? |
|------------|-----------|-------------|--------|
| InvalidEmail | Email format invalid | Provided email doesn't match format | No |
| EmailAlreadyExists | Email in use | Account with this email exists | No |
| RateLimitExceeded | Too many requests | Max 5 creates per hour per IP | Yes, after delay |
| ServiceUnavailable | Downstream failure | Dependency unavailable | Yes, with backoff |

**Idempotency**:
- Idempotent if called with same `email` within 5 minutes
- Returns existing user if already created

**Authorization**:
- Requires: Anonymous (public operation)
- Rate limited: 5 requests per hour per IP

**Related Operations**:
- Triggers Event: `UserCreated` (see Events section)
- May call: `SendVerificationEmail` (async)

---

#### Operation: [AnotherOperationName]
[Same structure as above]

---

## Event Contracts

### Event: UserCreated

**Purpose**: Notifies system that new user account was created

**When Emitted**: After successful user creation, before returning response

**Payload**:
| Field | Type | Nullable | Description |
|-------|------|----------|-------------|
| eventId | Identifier | No | Unique event identifier |
| timestamp | Timestamp | No | ISO8601 event timestamp |
| userId | Identifier | No | Created user's ID |
| email | EmailAddress | No | User's email (for notifications) |
| source | String | No | Registration source: "web" | "mobile" | "api" |

**Payload Structure Example** (abstract):

UserCreatedEvent { eventId: Identifier timestamp: Timestamp userId: Identifier email: EmailAddress source: String }


**Consumers**:
- Email Service (sends welcome email)
- Analytics Service (tracks signups)
- Audit Log Service (records event)

**Delivery Semantics**:
- At-least-once delivery
- Consumers must handle duplicates (idempotency required)

**Ordering**:
- No guaranteed ordering with other events
- Events for same `userId` are ordered

**Retention**:
- Events retained for 30 days in event store

---

### Event: [AnotherEvent]
[Same structure as above]

---

## Cross-Component Integration Contracts

### Integration: User Service → Email Service

**Purpose**: Send transactional emails to users

**Operations Used**:
- `SendEmail` (async, fire-and-forget)
- `GetEmailStatus` (query email delivery status)

**Contract Reference**: See Email Service component contracts

**Data Flow**:

UserService --[UserCreated event]--> EventBroker --[subscribe]--> EmailService EmailService --[SendEmail operation]--> EmailProvider


**Error Handling**:
- Email Service failures do NOT block User Service operations
- Retries handled by Email Service (3 attempts, exponential backoff)
- Dead-letter queue for permanent failures

---

### Integration: [Another Integration]
[Same structure as above]

---

## External System Contracts

### External System: Payment Gateway

**Purpose**: Process payments for user subscriptions

**Operations Exposed to Us**:
- `InitiatePayment`: Start payment transaction
- `CheckPaymentStatus`: Query transaction status
- `RefundPayment`: Reverse transaction

**Operations We Expose to Them**:
- `PaymentWebhook`: Receive payment status updates

**Contract Details**:

#### Operation: InitiatePayment (We call Them)

**Inputs**:
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| transactionId | Identifier | Yes | Our internal transaction ID |
| amount | MonetaryAmount | Yes | Amount in smallest currency unit (cents) |
| currency | CurrencyCode | Yes | ISO 4217 code (USD, EUR, etc.) |
| customerEmail | EmailAddress | Yes | Customer's email for receipt |

**Outputs**:
| Field | Type | Description |
|-------|------|-------------|
| paymentId | Identifier | Gateway's payment ID (store for status checks) |
| redirectUrl | URL | URL to redirect user for payment |
| expiresAt | Timestamp | Payment link expiration |

**Errors**:
| Error Code | Description |
|------------|-------------|
| InvalidAmount | Amount out of acceptable range |
| UnsupportedCurrency | Currency not supported |
| GatewayUnavailable | External service down |

---

#### Operation: PaymentWebhook (They call Us)

**Purpose**: Receive async payment status updates

**Inputs**:
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| paymentId | Identifier | Yes | Gateway's payment ID |
| status | PaymentStatus | Yes | "succeeded" | "failed" | "pending" |
| transactionId | Identifier | Yes | Our transaction ID (from InitiatePayment) |
| timestamp | Timestamp | Yes | Status update timestamp |
| signature | String | Yes | HMAC signature for verification |

**Outputs**:
| Field | Type | Description |
|-------|------|-------------|
| acknowledged | Boolean | Always true (confirms receipt) |

**Security**:
- Must verify HMAC signature before processing
- Signature algorithm: HMAC-SHA256
- Secret key: [stored in secrets management]

**Idempotency**:
- Must handle duplicate webhooks (same paymentId + status)
- Store processed webhook IDs for deduplication

---

## Data Type Definitions

### Custom Types

#### EmailAddress
- **Base Type**: String
- **Format**: Valid email format per RFC 5322
- **Constraints**: Max 254 characters, case-insensitive
- **Example**: "user@example.com"

#### Identifier
- **Base Type**: String
- **Format**: UUID v4
- **Constraints**: Non-empty, immutable
- **Example**: "550e8400-e29b-41d4-a716-446655440000"

#### Timestamp
- **Base Type**: String
- **Format**: ISO 8601 with timezone
- **Constraints**: UTC timezone, millisecond precision
- **Example**: "2025-10-23T16:45:00.123Z"

#### MonetaryAmount
- **Base Type**: Integer
- **Format**: Amount in smallest currency unit (cents, pence, etc.)
- **Constraints**: Non-negative, max value 9,223,372,036,854,775,807
- **Example**: 1999 (represents $19.99)

#### CurrencyCode
- **Base Type**: String
- **Format**: ISO 4217 three-letter code
- **Constraints**: Uppercase, exactly 3 characters
- **Example**: "USD", "EUR", "GBP"

#### UserStatus
- **Base Type**: Enum
- **Values**: "active", "suspended", "deleted", "pending_verification"
- **Description**: Current account status

---

## Naming Conventions

**Operations**:
- Use verb + noun format: `CreateUser`, `GetPayment`, `UpdateProfile`
- Be specific: `ArchiveUser` instead of `DeleteUser` if soft-delete

**Parameters**:
- Use camelCase: `userId`, `createdAt`, `displayName`
- Be descriptive: `subscriptionExpiresAt` not `expiry`
- Boolean parameters: prefix with `is`/`has`: `isActive`, `hasPermission`

**Events**:
- Use past tense: `UserCreated`, `PaymentProcessed`, `OrderShipped`
- Include entity: `OrderShipped` not just `Shipped`

**Errors**:
- Use noun + condition: `ResourceNotFound`, `InvalidInput`, `RateLimitExceeded`
- Be specific: `EmailAlreadyExists` not `DuplicateError`

---

## Rate Limiting & Quotas

### Per-Operation Limits

| Operation | Limit | Window | Scope |
|-----------|-------|--------|-------|
| CreateUser | 5 requests | 1 hour | Per IP address |
| GetUserProfile | 100 requests | 1 minute | Per user |
| UpdateProfile | 10 requests | 1 minute | Per user |
| SendPasswordReset | 3 requests | 1 hour | Per email |

### Quota Policies
- Free tier: 1,000 API calls per day
- Pro tier: 100,000 API calls per day
- Enterprise: Custom limits

### Exceeded Limit Behavior
- Return error: `RateLimitExceeded`
- Include retry info: `retryAfter` timestamp
- Do NOT process request

---

## Backward Compatibility Strategy

### Breaking Changes
**Definition**: Changes that require consumers to update
- Removing fields from outputs
- Adding required parameters to inputs
- Changing data types
- Renaming operations

**Process**:
1. Announce deprecation 90 days in advance
2. Support old + new contract in parallel
3. Monitor old contract usage
4. Remove old contract after 180 days

### Non-Breaking Changes
**Definition**: Changes consumers can ignore
- Adding optional parameters
- Adding new fields to outputs
- Adding new operations
- Adding new error codes

**Process**:
- Deploy immediately
- Document in changelog
- No consumer updates required

---

## Testing Contracts

### Contract Testing Strategy
- Use contract testing tools (language-agnostic)
- Provider tests verify contract implementation
- Consumer tests verify contract usage
- CI/CD validates contracts haven't broken

### Example Test Scenarios
**CreateUser Operation**:
- ✓ Valid input creates user successfully
- ✓ Duplicate email returns `EmailAlreadyExists`
- ✓ Invalid email returns `InvalidEmail`
- ✓ Missing required field returns `InvalidInput`
- ✓ Rate limit exceeded returns `RateLimitExceeded`
- ✓ Success emits `UserCreated` event

---

## Gate 4 Validation

**Validation Date**: [Date]
**Validated By**: [Person/team]

- [ ] All component contracts defined
- [ ] All operations have inputs/outputs
- [ ] Error scenarios documented
- [ ] Events fully specified
- [ ] External integrations covered
- [ ] No protocol specifics included
- [ ] Ready for Data Modeling (Gate 5)

**Approval**: ☐ Approved | ☐ Needs Revision | ☐ Rejected
**Next Step**: Proceed to Data Modeling (`pre-dev-data-model`)

Common Violations and Fixes

Violation 1: Protocol-Specific Details

Wrong:

#### Operation: CreateUser
**Endpoint**: POST /api/v1/users
**Status Codes**:
- 201 Created
- 409 Conflict (email exists)
- 400 Bad Request

Correct:

#### Operation: CreateUser
**Purpose**: Create new user account

**Inputs**: [userId, email, displayName]
**Outputs**: UserCreatedResponse
**Errors**:
- EmailAlreadyExists (email in use)
- InvalidInput (validation failure)

Violation 2: Implementation in Contract

Wrong:

**Validation**:
```javascript
if (!/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/.test(email)) {
  throw new ValidationError("Invalid email");
}

✅ **Correct**:
```markdown
**Validation Rules**:
- `email` must match email format per RFC 5322
- Pattern: local@domain.tld
- Max length: 254 characters

Violation 3: Technology-Specific Types

Wrong:

**Output**:
```json
{
  "userId": "uuid",
  "createdAt": "Date",
  "profile": "Map<String, Any>"
}

✅ **Correct**:
```markdown
**Outputs**:
| Field | Type | Description |
|-------|------|-------------|
| userId | Identifier | UUID format |
| createdAt | Timestamp | ISO8601 timestamp |
| profile | ProfileObject | User profile data |

Confidence Scoring

Use this to adjust your interaction with the user:

Confidence Factors:
  Contract Completeness: [0-30]
    - All operations documented: 30
    - Most operations covered: 20
    - Significant gaps: 10

  Interface Clarity: [0-25]
    - Clear, unambiguous contracts: 25
    - Some interpretation needed: 15
    - Vague or conflicting: 5

  Integration Complexity: [0-25]
    - Simple point-to-point: 25
    - Moderate dependencies: 15
    - Complex orchestration: 5

  Error Handling Coverage: [0-20]
    - All scenarios documented: 20
    - Common cases covered: 12
    - Minimal coverage: 5

Total: [0-100]

Action:
  80+: Generate complete contracts autonomously
  50-79: Present options for user selection
  <50: Ask clarifying questions about integration needs

Output Location

Always output to: docs/pre-development/api-design/api-contracts-[feature-name].md

After API Design Approval

  1. ✅ Lock the contracts - interfaces are now reference for implementation
  2. 🎯 Use contracts as input for Data Modeling (next phase: pre-dev-data-model)
  3. 🚫 Never add protocol specifics to contracts retroactively
  4. 📋 Keep contracts technology-agnostic until Dependency Map

Quality Self-Check

Before declaring API Design complete, verify:

  • All TRD integration points have contracts
  • Operations are clearly named and described
  • Inputs are fully specified (type, required, constraints)
  • Outputs are complete (all fields documented)
  • Error scenarios are comprehensive
  • Events have full payload specifications
  • Validation rules are explicit
  • Rate limits are defined
  • Idempotency is documented where relevant
  • Zero protocol specifics (REST/gRPC/etc)
  • Zero implementation code
  • Contracts are testable
  • Backward compatibility strategy exists
  • Gate 4 validation checklist 100% complete

The Bottom Line

If you wrote API contracts with HTTP endpoints or gRPC services, remove them.

Contracts are protocol-agnostic. Period. No REST. No GraphQL. No HTTP codes.

Protocol choices go in Dependency Map. That's a later phase. Wait for it.

Violating this separation means:

  • You're locked into a protocol before evaluating alternatives
  • Contracts can't be reused across different delivery mechanisms
  • You can't objectively compare REST vs. gRPC vs. messaging
  • Teams can't work in parallel with clear interface agreements

Define the contract. Stay abstract. Choose protocol later.