Initial commit
This commit is contained in:
724
skills/pre-dev-api-design/SKILL.md
Normal file
724
skills/pre-dev-api-design/SKILL.md
Normal file
@@ -0,0 +1,724 @@
|
||||
---
|
||||
name: pre-dev-api-design
|
||||
description: |
|
||||
Gate 4: API contracts document - defines component interfaces and data contracts
|
||||
before protocol/technology selection. Large Track only.
|
||||
|
||||
trigger: |
|
||||
- TRD passed Gate 3 validation
|
||||
- System has multiple components that need to integrate
|
||||
- Building APIs (internal or external)
|
||||
- Large Track workflow (2+ day features)
|
||||
|
||||
skip_when: |
|
||||
- Small Track workflow → skip to Task Breakdown
|
||||
- Single component system → skip to Data Model
|
||||
- TRD not validated → complete Gate 3 first
|
||||
|
||||
sequence:
|
||||
after: [pre-dev-trd-creation]
|
||||
before: [pre-dev-data-model]
|
||||
---
|
||||
|
||||
# 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
|
||||
|
||||
```markdown
|
||||
# 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**:
|
||||
```markdown
|
||||
#### Operation: CreateUser
|
||||
**Endpoint**: POST /api/v1/users
|
||||
**Status Codes**:
|
||||
- 201 Created
|
||||
- 409 Conflict (email exists)
|
||||
- 400 Bad Request
|
||||
```
|
||||
|
||||
✅ **Correct**:
|
||||
```markdown
|
||||
#### 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**:
|
||||
```markdown
|
||||
**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**:
|
||||
```markdown
|
||||
**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:
|
||||
|
||||
```yaml
|
||||
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.**
|
||||
Reference in New Issue
Block a user