348 lines
11 KiB
YAML
348 lines
11 KiB
YAML
# API Contract Schema
|
|
# The binding agreement between frontend and backend implementations
|
|
# Generated during design phase, validated during review phase
|
|
#
|
|
# This contract ensures:
|
|
# 1. Backend implements exactly the endpoints frontend expects
|
|
# 2. Frontend calls endpoints with correct methods/bodies
|
|
# 3. Both use the same TypeScript types from shared file
|
|
|
|
# ============================================================================
|
|
# CONTRACT METADATA
|
|
# ============================================================================
|
|
api_contract:
|
|
# Links to workflow
|
|
workflow_version: string # e.g., v001
|
|
design_document_revision: integer
|
|
|
|
# Timestamps
|
|
generated_at: timestamp
|
|
validated_at: timestamp | null
|
|
|
|
# Contract status
|
|
status: draft | active | violated
|
|
|
|
# ============================================================================
|
|
# SHARED TYPES (Source of truth for both agents)
|
|
# ============================================================================
|
|
# These types are generated into app/types/api.ts
|
|
# Both frontend and backend MUST import from this file
|
|
types:
|
|
description: "TypeScript interfaces shared between frontend and backend"
|
|
|
|
type_schema:
|
|
# Identity
|
|
id: string # type_<Name> (e.g., type_User, type_CreateUserRequest)
|
|
name: string # PascalCase type name (exported interface name)
|
|
|
|
# Type definition
|
|
definition:
|
|
type: object | array | enum | union
|
|
|
|
# For object types
|
|
properties:
|
|
- name: string # Property name (camelCase)
|
|
type: string # TypeScript type (string, number, boolean, other type name)
|
|
required: boolean
|
|
description: string
|
|
validation: string # Optional validation rule
|
|
|
|
# For enum types
|
|
enum_values: [string]
|
|
|
|
# For union types
|
|
union_members: [string] # Array of type names or literal types
|
|
|
|
# For array types
|
|
array_item_type: string # Type of array items
|
|
|
|
# Usage tracking
|
|
used_by:
|
|
requests: [string] # endpoint_ids that use this as request body
|
|
responses: [string] # endpoint_ids that use this as response
|
|
models: [string] # model_ids this type represents
|
|
|
|
# Example
|
|
example_type:
|
|
id: type_User
|
|
name: User
|
|
definition:
|
|
type: object
|
|
properties:
|
|
- name: id
|
|
type: string
|
|
required: true
|
|
description: "Unique user identifier"
|
|
- name: email
|
|
type: string
|
|
required: true
|
|
description: "User email address"
|
|
validation: email
|
|
- name: name
|
|
type: string
|
|
required: true
|
|
description: "Display name"
|
|
- name: createdAt
|
|
type: Date
|
|
required: true
|
|
description: "Account creation timestamp"
|
|
used_by:
|
|
responses: [api_get_user, api_create_user, api_list_users]
|
|
models: [model_user]
|
|
|
|
# ============================================================================
|
|
# ENDPOINT CONTRACTS (Binding specifications)
|
|
# ============================================================================
|
|
endpoints:
|
|
description: "API endpoint contracts with strict request/response typing"
|
|
|
|
endpoint_schema:
|
|
# Identity
|
|
id: string # api_<verb>_<resource> from design_document
|
|
|
|
# HTTP Specification
|
|
method: GET | POST | PUT | PATCH | DELETE
|
|
path: string # Exact path with params (e.g., /api/users/:id)
|
|
|
|
# Path parameters (extracted from path)
|
|
path_params:
|
|
- name: string
|
|
type: string # TypeScript type
|
|
description: string
|
|
|
|
# Query parameters (for GET requests)
|
|
query_params:
|
|
- name: string
|
|
type: string
|
|
required: boolean
|
|
default: any
|
|
description: string
|
|
|
|
# Request body (for POST/PUT/PATCH)
|
|
request_body:
|
|
type_id: string # Reference to types section (e.g., type_CreateUserRequest)
|
|
content_type: application/json
|
|
|
|
# Response specification
|
|
response:
|
|
# Success response
|
|
success:
|
|
status: integer # 200, 201, 204
|
|
type_id: string # Reference to types section
|
|
is_array: boolean # If response is array of type
|
|
|
|
# Error responses
|
|
errors:
|
|
- status: integer # 400, 401, 403, 404, 500
|
|
type_id: string # Error response type (usually type_ApiError)
|
|
description: string
|
|
|
|
# Authentication
|
|
auth:
|
|
required: boolean
|
|
roles: [string] # Required roles (empty = any authenticated)
|
|
|
|
# Contract version for compatibility
|
|
version: string # Semantic version of this endpoint spec
|
|
|
|
# Example
|
|
example_endpoint:
|
|
id: api_create_user
|
|
method: POST
|
|
path: /api/users
|
|
path_params: []
|
|
query_params: []
|
|
request_body:
|
|
type_id: type_CreateUserRequest
|
|
content_type: application/json
|
|
response:
|
|
success:
|
|
status: 201
|
|
type_id: type_User
|
|
is_array: false
|
|
errors:
|
|
- status: 400
|
|
type_id: type_ValidationError
|
|
description: "Invalid request body"
|
|
- status: 409
|
|
type_id: type_ApiError
|
|
description: "Email already exists"
|
|
auth:
|
|
required: false
|
|
roles: []
|
|
version: "1.0.0"
|
|
|
|
# ============================================================================
|
|
# FRONTEND USAGE CONTRACTS (What frontend expects to call)
|
|
# ============================================================================
|
|
frontend_calls:
|
|
description: "Expected API calls from frontend components/pages"
|
|
|
|
call_schema:
|
|
# Identity
|
|
id: string # call_<component>_<action>
|
|
|
|
# Source
|
|
source:
|
|
entity_id: string # page_xxx or component_xxx
|
|
file_path: string # Expected file location
|
|
|
|
# Target endpoint
|
|
endpoint_id: string # Reference to endpoints section
|
|
|
|
# Call context
|
|
purpose: string # Why this call is made
|
|
trigger: string # What triggers this call (onLoad, onClick, onSubmit)
|
|
|
|
# Data mapping
|
|
request_mapping:
|
|
# How component data maps to request
|
|
from_props: [string] # Props used in request
|
|
from_state: [string] # State used in request
|
|
from_form: [string] # Form fields used in request
|
|
|
|
response_handling:
|
|
# How response is handled
|
|
success_action: string # What happens on success
|
|
error_action: string # What happens on error
|
|
|
|
# Example
|
|
example_call:
|
|
id: call_signup_form_submit
|
|
source:
|
|
entity_id: component_signup_form
|
|
file_path: app/components/SignupForm.tsx
|
|
endpoint_id: api_create_user
|
|
purpose: "Submit registration form"
|
|
trigger: onSubmit
|
|
request_mapping:
|
|
from_form: [email, name, password]
|
|
response_handling:
|
|
success_action: "Redirect to dashboard"
|
|
error_action: "Display error message"
|
|
|
|
# ============================================================================
|
|
# BACKEND IMPLEMENTATION CONTRACTS (What backend must provide)
|
|
# ============================================================================
|
|
backend_routes:
|
|
description: "Required backend route implementations"
|
|
|
|
route_schema:
|
|
# Identity
|
|
id: string # route_<verb>_<path>
|
|
|
|
# Target endpoint
|
|
endpoint_id: string # Reference to endpoints section
|
|
|
|
# Implementation location
|
|
file_path: string # Expected file (e.g., app/api/users/route.ts)
|
|
export_name: string # Exported function name (GET, POST, etc.)
|
|
|
|
# Dependencies
|
|
uses_models: [string] # model_ids this route uses
|
|
uses_services: [string] # Service files this route depends on
|
|
|
|
# Implementation requirements
|
|
must_validate:
|
|
- field: string
|
|
rule: string
|
|
must_authenticate: boolean
|
|
must_authorize: [string] # Role checks required
|
|
|
|
# Example
|
|
example_route:
|
|
id: route_post_users
|
|
endpoint_id: api_create_user
|
|
file_path: app/api/users/route.ts
|
|
export_name: POST
|
|
uses_models: [model_user]
|
|
uses_services: [lib/auth.ts, lib/db.ts]
|
|
must_validate:
|
|
- field: email
|
|
rule: email
|
|
- field: password
|
|
rule: min:8
|
|
must_authenticate: false
|
|
must_authorize: []
|
|
|
|
# ============================================================================
|
|
# VALIDATION RULES
|
|
# ============================================================================
|
|
validation_rules:
|
|
contracts:
|
|
- "Every frontend_call must reference existing endpoint_id"
|
|
- "Every backend_route must reference existing endpoint_id"
|
|
- "Request body type_id must exist in types section"
|
|
- "Response type_id must exist in types section"
|
|
- "Path params in endpoint must match :param patterns in path"
|
|
|
|
types:
|
|
- "Every type must have unique id"
|
|
- "Type references (nested types) must exist"
|
|
- "Required properties cannot have default values"
|
|
|
|
implementation:
|
|
- "Frontend must import types from shared types file"
|
|
- "Backend must import types from shared types file"
|
|
- "HTTP methods must match contract specification"
|
|
- "Response shapes must conform to type definitions"
|
|
|
|
# ============================================================================
|
|
# GENERATED FILES
|
|
# ============================================================================
|
|
generated_files:
|
|
shared_types:
|
|
path: app/types/api.ts
|
|
description: "TypeScript interfaces for all API types"
|
|
template: |
|
|
// AUTO-GENERATED - DO NOT EDIT
|
|
// Source: .workflow/versions/vXXX/contracts/api_contract.yml
|
|
// Generated: {timestamp}
|
|
|
|
// === Types ===
|
|
{type_definitions}
|
|
|
|
// === API Paths (for type-safe fetch calls) ===
|
|
export const API_PATHS = {
|
|
{path_constants}
|
|
} as const;
|
|
|
|
// === API Response Types ===
|
|
{response_type_helpers}
|
|
|
|
api_client:
|
|
path: app/lib/api-client.ts
|
|
description: "Type-safe API client (optional)"
|
|
template: |
|
|
// AUTO-GENERATED - DO NOT EDIT
|
|
// Type-safe API client generated from contract
|
|
|
|
import type { * } from '@/types/api';
|
|
|
|
{api_client_methods}
|
|
|
|
# ============================================================================
|
|
# CONTRACT VIOLATION HANDLING
|
|
# ============================================================================
|
|
violations:
|
|
severity_levels:
|
|
critical:
|
|
- "Endpoint exists in frontend but not backend"
|
|
- "Method mismatch (frontend calls POST, backend has GET)"
|
|
- "Required field missing in implementation"
|
|
high:
|
|
- "Response type mismatch"
|
|
- "Missing error handling for documented errors"
|
|
medium:
|
|
- "Extra undocumented endpoint in backend"
|
|
- "Type property order differs"
|
|
low:
|
|
- "Description mismatch"
|
|
- "Optional field handling differs"
|
|
|
|
on_violation:
|
|
critical: "Block deployment, require immediate fix"
|
|
high: "Warn in review, require acknowledgment"
|
|
medium: "Report in review, fix recommended"
|
|
low: "Log for tracking"
|