diff --git a/src/modules/bmm/workflows/3-solutioning/create-api-spec/api-checklist.md b/src/modules/bmm/workflows/3-solutioning/create-api-spec/api-checklist.md new file mode 100644 index 00000000..5205f4b2 --- /dev/null +++ b/src/modules/bmm/workflows/3-solutioning/create-api-spec/api-checklist.md @@ -0,0 +1,117 @@ +# API Design Checklist + +## Resource Design +- [ ] Resources use plural nouns (users, orders, products) +- [ ] Resource names are lowercase with hyphens (user-profiles) +- [ ] Relationships expressed via nesting or links +- [ ] No verbs in resource paths (use HTTP methods instead) + +## HTTP Methods +- [ ] GET for reading (no side effects) +- [ ] POST for creating new resources +- [ ] PUT for full resource replacement +- [ ] PATCH for partial updates +- [ ] DELETE for removing resources +- [ ] HEAD for metadata requests (if needed) +- [ ] OPTIONS for CORS preflight (automatic) + +## Status Codes +- [ ] 200 OK for successful GET/PUT/PATCH +- [ ] 201 Created for successful POST +- [ ] 204 No Content for successful DELETE +- [ ] 400 Bad Request for malformed requests +- [ ] 401 Unauthorized for missing/invalid auth +- [ ] 403 Forbidden for insufficient permissions +- [ ] 404 Not Found for missing resources +- [ ] 409 Conflict for state conflicts +- [ ] 422 Unprocessable Entity for validation errors +- [ ] 429 Too Many Requests for rate limiting +- [ ] 500 Internal Server Error (avoid exposing details) + +## Request Design +- [ ] Content-Type headers required for POST/PUT/PATCH +- [ ] Accept headers for content negotiation +- [ ] Query parameters for filtering/sorting/pagination +- [ ] Path parameters for resource identifiers +- [ ] Request body validation documented + +## Response Design +- [ ] Consistent envelope structure (data, meta, links, error) +- [ ] Timestamps in ISO 8601 format +- [ ] IDs as strings (UUIDs recommended) +- [ ] Pagination for list endpoints +- [ ] HATEOAS links where appropriate + +## Pagination +- [ ] Page-based or cursor-based pagination +- [ ] Default and maximum limits defined +- [ ] Total count available +- [ ] Navigation links included + +## Filtering & Sorting +- [ ] Filter syntax documented +- [ ] Sortable fields specified +- [ ] Default sort order defined +- [ ] Multiple sort fields supported + +## Authentication +- [ ] Auth method documented (Bearer, API Key, OAuth2) +- [ ] Token format specified (JWT structure) +- [ ] Token expiration documented +- [ ] Refresh token flow if applicable + +## Authorization +- [ ] Per-endpoint permissions documented +- [ ] Role-based access defined +- [ ] Resource ownership rules clear + +## Versioning +- [ ] Versioning strategy chosen (URL, header, parameter) +- [ ] Major version in URL (/v1/, /v2/) +- [ ] Deprecation policy documented +- [ ] Breaking changes defined + +## Error Handling +- [ ] Error response format consistent +- [ ] Error codes meaningful and documented +- [ ] Validation errors include field details +- [ ] No sensitive info in error messages + +## Security +- [ ] HTTPS required +- [ ] Rate limiting implemented +- [ ] CORS properly configured +- [ ] Input validation on all fields +- [ ] SQL injection prevention +- [ ] No sensitive data in URLs + +## Documentation +- [ ] OpenAPI 3.0+ specification complete +- [ ] All endpoints documented +- [ ] Request/response examples provided +- [ ] Authentication documented +- [ ] Error codes listed + +## Testing +- [ ] Mock server available +- [ ] Example requests for each endpoint +- [ ] Postman/Insomnia collection exported +- [ ] SDK generation tested + +--- + +## Quick Validation + +```bash +# Validate OpenAPI spec +npx @stoplight/spectral-cli lint api-spec.yaml + +# Alternative validation +npx swagger-cli validate api-spec.yaml + +# Generate types (TypeScript) +npx openapi-typescript api-spec.yaml -o types.d.ts + +# Start mock server +npx @stoplight/prism-cli mock api-spec.yaml +``` diff --git a/src/modules/bmm/workflows/3-solutioning/create-api-spec/instructions.md b/src/modules/bmm/workflows/3-solutioning/create-api-spec/instructions.md new file mode 100644 index 00000000..ae7b85b3 --- /dev/null +++ b/src/modules/bmm/workflows/3-solutioning/create-api-spec/instructions.md @@ -0,0 +1,309 @@ +# API Design Workflow Instructions + +## Overview + +Design APIs using a contract-first approach. This workflow produces OpenAPI 3.0+ specifications, mock server configurations, and client SDK generation guidance. + +## Workflow Steps + +### Step 1: Context Loading + +**Load existing documentation:** +1. Load PRD for feature requirements +2. Load Architecture document for system design +3. Load project-context.md for coding standards +4. Identify existing API patterns (if any) + +### Step 2: API Style Selection + +**Ask user for API style:** +``` +API Style Selection + +Available styles: +1. [rest] RESTful API (OpenAPI 3.0+) +2. [graphql] GraphQL Schema +3. [grpc] gRPC/Protocol Buffers +4. [websocket] WebSocket Event Schema + +Select style [1-4]: +``` + +### Step 3: Resource Identification + +**For REST APIs, identify resources:** +1. Extract nouns from PRD (users, orders, products, etc.) +2. Map to REST resources +3. Identify relationships (1:1, 1:N, N:N) +4. Determine resource hierarchy + +**Questions to ask:** +- What are the main entities in this system? +- How do entities relate to each other? +- What operations are needed for each entity? +- Are there any batch operations required? + +### Step 4: Endpoint Design + +**For each resource, design endpoints:** + +| Operation | Method | Path Pattern | Example | +|-----------|--------|--------------|---------| +| List | GET | /resources | GET /users | +| Create | POST | /resources | POST /users | +| Read | GET | /resources/{id} | GET /users/123 | +| Update | PUT/PATCH | /resources/{id} | PATCH /users/123 | +| Delete | DELETE | /resources/{id} | DELETE /users/123 | +| Nested | GET | /resources/{id}/subs | GET /users/123/orders | + +**Naming conventions:** +- Use plural nouns for resources +- Use kebab-case for multi-word resources +- Use path parameters for identifiers +- Use query parameters for filtering/pagination + +### Step 5: Request/Response Design + +**For each endpoint, define:** + +1. **Request body schema** (POST/PUT/PATCH) + - Required vs optional fields + - Data types and formats + - Validation rules (min/max, pattern, enum) + +2. **Response schema** + - Success response structure + - Error response structure + - Pagination format + +3. **Headers** + - Authentication headers + - Content-Type + - Custom headers + +**Standard response format:** +```json +{ + "data": { ... }, + "meta": { + "page": 1, + "limit": 20, + "total": 100 + }, + "links": { + "self": "/users?page=1", + "next": "/users?page=2" + } +} +``` + +**Standard error format:** +```json +{ + "error": { + "code": "VALIDATION_ERROR", + "message": "Request validation failed", + "details": [ + { "field": "email", "message": "Invalid email format" } + ] + } +} +``` + +### Step 6: Authentication & Authorization + +**Define security scheme:** +```yaml +securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + apiKey: + type: apiKey + in: header + name: X-API-Key + oauth2: + type: oauth2 + flows: + authorizationCode: + authorizationUrl: /oauth/authorize + tokenUrl: /oauth/token + scopes: + read: Read access + write: Write access +``` + +**Apply security to endpoints:** +- Public endpoints (no auth) +- Authenticated endpoints (user token) +- Admin-only endpoints (role-based) + +### Step 7: Generate OpenAPI Specification + +**Create OpenAPI 3.0+ document:** + +```yaml +openapi: 3.0.3 +info: + title: {project_name} API + version: 1.0.0 + description: | + {api_description} + +servers: + - url: https://api.example.com/v1 + description: Production + - url: https://staging-api.example.com/v1 + description: Staging + - url: http://localhost:3000/v1 + description: Development + +paths: + /resources: + get: + summary: List resources + operationId: listResources + tags: + - Resources + parameters: + - $ref: '#/components/parameters/page' + - $ref: '#/components/parameters/limit' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/ResourceList' + +components: + schemas: + Resource: + type: object + properties: + id: + type: string + format: uuid + name: + type: string + required: + - id + - name + + parameters: + page: + name: page + in: query + schema: + type: integer + default: 1 + limit: + name: limit + in: query + schema: + type: integer + default: 20 + maximum: 100 +``` + +### Step 8: API Documentation + +**Generate API design document with:** + +1. **Overview** + - API purpose and scope + - Base URL and versioning strategy + - Authentication methods + +2. **Quick Start** + - Getting API credentials + - Making first request + - Common patterns + +3. **Resource Reference** + - Detailed endpoint documentation + - Request/response examples + - Error codes + +4. **Best Practices** + - Rate limiting guidance + - Pagination recommendations + - Error handling + +### Step 9: Mock Server Guidance + +**Provide mock server setup:** + +```bash +# Using Prism (OpenAPI) +npm install -g @stoplight/prism-cli +prism mock api-spec.yaml + +# Using json-server (simple) +npm install -g json-server +json-server --watch db.json + +# Using MSW (frontend mocking) +npm install msw --save-dev +``` + +**Include sample mock data:** +```json +{ + "users": [ + { "id": "1", "name": "Alice", "email": "alice@example.com" }, + { "id": "2", "name": "Bob", "email": "bob@example.com" } + ] +} +``` + +### Step 10: SDK Generation Guidance + +**Client SDK generation options:** + +```bash +# OpenAPI Generator +npx @openapitools/openapi-generator-cli generate \ + -i api-spec.yaml \ + -g typescript-axios \ + -o ./sdk + +# Available generators: +# - typescript-axios +# - typescript-fetch +# - python +# - go +# - java +# - csharp +``` + +**Type generation (TypeScript):** +```bash +# Using openapi-typescript +npx openapi-typescript api-spec.yaml -o types.d.ts +``` + +### Step 11: Validation Checklist + +Before completing: +- [ ] All PRD features have corresponding endpoints +- [ ] Resource naming follows conventions +- [ ] Request/response schemas complete +- [ ] Authentication defined for protected endpoints +- [ ] Error responses documented +- [ ] Pagination implemented for list endpoints +- [ ] OpenAPI spec validates (use swagger-cli validate) +- [ ] Examples provided for complex endpoints + +### Step 12: Output Files + +**Save to:** +- OpenAPI spec: `{output_file}` (api-spec.yaml) +- API design doc: `{output_doc}` (api-design.md) + +**Notify user with:** +- Summary of endpoints created +- Link to specification file +- Mock server quick start +- Next steps (implementation, SDK generation) diff --git a/src/modules/bmm/workflows/3-solutioning/create-api-spec/openapi.template.yaml b/src/modules/bmm/workflows/3-solutioning/create-api-spec/openapi.template.yaml new file mode 100644 index 00000000..8f77ab32 --- /dev/null +++ b/src/modules/bmm/workflows/3-solutioning/create-api-spec/openapi.template.yaml @@ -0,0 +1,467 @@ +openapi: 3.0.3 +info: + title: "{{project_name}} API" + version: "{{api_version}}" + description: | + {{api_description}} + + ## Authentication + {{auth_description}} + + ## Rate Limiting + {{rate_limit_description}} + + contact: + name: API Support + email: api@example.com + license: + name: MIT + url: https://opensource.org/licenses/MIT + +servers: + - url: https://api.{{domain}}/v{{major_version}} + description: Production + - url: https://staging-api.{{domain}}/v{{major_version}} + description: Staging + - url: http://localhost:{{port}}/v{{major_version}} + description: Development + +tags: + # Define tags for each resource group + - name: Authentication + description: Authentication and authorization endpoints + - name: Users + description: User management operations + # Add more tags as needed + +paths: + # Authentication endpoints + /auth/login: + post: + summary: Authenticate user + operationId: login + tags: + - Authentication + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/LoginRequest' + responses: + '200': + description: Authentication successful + content: + application/json: + schema: + $ref: '#/components/schemas/AuthResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '422': + $ref: '#/components/responses/ValidationError' + + /auth/logout: + post: + summary: Logout user + operationId: logout + tags: + - Authentication + security: + - bearerAuth: [] + responses: + '204': + description: Logout successful + '401': + $ref: '#/components/responses/Unauthorized' + + # Resource template - copy and customize + /resources: + get: + summary: List resources + operationId: listResources + tags: + - Resources + security: + - bearerAuth: [] + parameters: + - $ref: '#/components/parameters/page' + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/filter' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/ResourceListResponse' + '401': + $ref: '#/components/responses/Unauthorized' + + post: + summary: Create resource + operationId: createResource + tags: + - Resources + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateResourceRequest' + responses: + '201': + description: Resource created + content: + application/json: + schema: + $ref: '#/components/schemas/ResourceResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '422': + $ref: '#/components/responses/ValidationError' + + /resources/{id}: + parameters: + - $ref: '#/components/parameters/resourceId' + + get: + summary: Get resource by ID + operationId: getResource + tags: + - Resources + security: + - bearerAuth: [] + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/ResourceResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + patch: + summary: Update resource + operationId: updateResource + tags: + - Resources + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateResourceRequest' + responses: + '200': + description: Resource updated + content: + application/json: + schema: + $ref: '#/components/schemas/ResourceResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '422': + $ref: '#/components/responses/ValidationError' + + delete: + summary: Delete resource + operationId: deleteResource + tags: + - Resources + security: + - bearerAuth: [] + responses: + '204': + description: Resource deleted + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: JWT authentication token + + apiKey: + type: apiKey + in: header + name: X-API-Key + description: API key for service-to-service calls + + parameters: + page: + name: page + in: query + description: Page number for pagination + schema: + type: integer + minimum: 1 + default: 1 + + limit: + name: limit + in: query + description: Number of items per page + schema: + type: integer + minimum: 1 + maximum: 100 + default: 20 + + sort: + name: sort + in: query + description: Sort field and direction (e.g., -createdAt for descending) + schema: + type: string + example: "-createdAt" + + filter: + name: filter + in: query + description: Filter expression + schema: + type: string + example: "status:active" + + resourceId: + name: id + in: path + required: true + description: Resource identifier + schema: + type: string + format: uuid + + schemas: + # Authentication schemas + LoginRequest: + type: object + required: + - email + - password + properties: + email: + type: string + format: email + password: + type: string + format: password + minLength: 8 + + AuthResponse: + type: object + properties: + accessToken: + type: string + refreshToken: + type: string + expiresIn: + type: integer + description: Token expiry in seconds + tokenType: + type: string + default: Bearer + + # Resource schemas (template) + Resource: + type: object + properties: + id: + type: string + format: uuid + readOnly: true + name: + type: string + minLength: 1 + maxLength: 255 + description: + type: string + status: + type: string + enum: [active, inactive, archived] + default: active + createdAt: + type: string + format: date-time + readOnly: true + updatedAt: + type: string + format: date-time + readOnly: true + required: + - name + + CreateResourceRequest: + allOf: + - $ref: '#/components/schemas/Resource' + - type: object + required: + - name + + UpdateResourceRequest: + type: object + properties: + name: + type: string + description: + type: string + status: + type: string + enum: [active, inactive, archived] + + ResourceResponse: + type: object + properties: + data: + $ref: '#/components/schemas/Resource' + + ResourceListResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Resource' + meta: + $ref: '#/components/schemas/PaginationMeta' + links: + $ref: '#/components/schemas/PaginationLinks' + + # Pagination + PaginationMeta: + type: object + properties: + page: + type: integer + limit: + type: integer + total: + type: integer + totalPages: + type: integer + + PaginationLinks: + type: object + properties: + self: + type: string + format: uri + first: + type: string + format: uri + prev: + type: string + format: uri + nullable: true + next: + type: string + format: uri + nullable: true + last: + type: string + format: uri + + # Error schemas + Error: + type: object + properties: + error: + type: object + properties: + code: + type: string + message: + type: string + details: + type: array + items: + type: object + properties: + field: + type: string + message: + type: string + + responses: + Unauthorized: + description: Authentication required + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + error: + code: UNAUTHORIZED + message: Authentication required + + Forbidden: + description: Permission denied + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + error: + code: FORBIDDEN + message: Permission denied + + NotFound: + description: Resource not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + error: + code: NOT_FOUND + message: Resource not found + + ValidationError: + description: Validation error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + error: + code: VALIDATION_ERROR + message: Request validation failed + details: + - field: email + message: Invalid email format + + RateLimitExceeded: + description: Rate limit exceeded + headers: + X-RateLimit-Limit: + schema: + type: integer + X-RateLimit-Remaining: + schema: + type: integer + X-RateLimit-Reset: + schema: + type: integer + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + error: + code: RATE_LIMIT_EXCEEDED + message: Too many requests diff --git a/src/modules/bmm/workflows/3-solutioning/create-api-spec/workflow.yaml b/src/modules/bmm/workflows/3-solutioning/create-api-spec/workflow.yaml new file mode 100644 index 00000000..2728385a --- /dev/null +++ b/src/modules/bmm/workflows/3-solutioning/create-api-spec/workflow.yaml @@ -0,0 +1,39 @@ +# API Design Workflow +name: create-api-spec +description: "Contract-first API design workflow producing OpenAPI 3.0+ specifications with mock server guidance and client SDK generation recommendations" +author: "BMAD" +version: "1.0.0" + +# Configuration sources +config_source: "{project-root}/_bmad/bmm/config.yaml" +user_name: "{config_source}:user_name" +communication_language: "{config_source}:communication_language" +user_skill_level: "{config_source}:user_skill_level" +document_output_language: "{config_source}:document_output_language" +planning_artifacts: "{config_source}:planning_artifacts" +output_folder: "{planning_artifacts}" +date: system-generated + +# Workflow components +installed_path: "{project-root}/_bmad/bmm/workflows/3-solutioning/create-api-spec" +instructions: "{installed_path}/instructions.md" +template: "{installed_path}/openapi.template.yaml" +checklist: "{installed_path}/api-checklist.md" + +# Input references +prd_doc: "{planning_artifacts}/*prd*.md" +architecture_doc: "{planning_artifacts}/*architecture*.md" +project_context: "**/project-context.md" + +# Output +output_file: "{output_folder}/api-spec.yaml" +output_doc: "{output_folder}/api-design.md" + +# API styles supported +api_styles: + - rest # RESTful API + - graphql # GraphQL schema + - grpc # Protocol Buffers + - websocket # WebSocket events + +standalone: true