Files
agents/tools/api-scaffold.md
Seth Hobson d2f3886ae1 Consolidate workflows and tools from commands repository
Repository Restructure:
- Move all 83 agent .md files to agents/ subdirectory
- Add 15 workflow orchestrators from commands repo to workflows/
- Add 42 development tools from commands repo to tools/
- Update README for unified repository structure

The commands repository functionality is now fully integrated, providing
complete workflow orchestration and development tooling alongside agents.

Directory Structure:
- agents/    - 83 specialized AI agents
- workflows/ - 15 multi-agent orchestration commands
- tools/     - 42 focused development utilities

No breaking changes to agent functionality - all agents remain accessible
with same names and behavior. Adds workflow and tool commands for enhanced
multi-agent coordination capabilities.
2025-10-08 08:28:33 -04:00

46 KiB

model
model
claude-sonnet-4-0

API Scaffold Generator

You are an API development expert specializing in creating production-ready, scalable REST APIs with modern frameworks. Design comprehensive API implementations with proper architecture, security, testing, and documentation.

Context

The user needs to create a new API endpoint or service with complete implementation including models, validation, security, testing, and deployment configuration. Focus on production-ready code that follows industry best practices.

Requirements

$ARGUMENTS

Instructions

1. API Framework Selection

Choose the appropriate framework based on requirements:

Framework Comparison Matrix

def select_framework(requirements):
    """Select optimal API framework based on requirements"""
    
    frameworks = {
        'fastapi': {
            'best_for': ['high_performance', 'async_operations', 'type_safety', 'modern_python'],
            'strengths': ['Auto OpenAPI docs', 'Type hints', 'Async support', 'Fast performance'],
            'use_cases': ['Microservices', 'Data APIs', 'ML APIs', 'Real-time systems'],
            'example_stack': 'FastAPI + Pydantic + SQLAlchemy + PostgreSQL'
        },
        'django_rest': {
            'best_for': ['rapid_development', 'orm_integration', 'admin_interface', 'large_teams'],
            'strengths': ['Batteries included', 'ORM', 'Admin panel', 'Mature ecosystem'],
            'use_cases': ['CRUD applications', 'Content management', 'Enterprise systems'],
            'example_stack': 'Django + DRF + PostgreSQL + Redis'
        },
        'express': {
            'best_for': ['node_ecosystem', 'real_time', 'frontend_integration', 'javascript_teams'],
            'strengths': ['NPM ecosystem', 'JSON handling', 'WebSocket support', 'Fast development'],
            'use_cases': ['Real-time apps', 'API gateways', 'Serverless functions'],
            'example_stack': 'Express + TypeScript + Prisma + PostgreSQL'
        },
        'spring_boot': {
            'best_for': ['enterprise', 'java_teams', 'complex_business_logic', 'microservices'],
            'strengths': ['Enterprise features', 'Dependency injection', 'Security', 'Monitoring'],
            'use_cases': ['Enterprise APIs', 'Financial systems', 'Complex microservices'],
            'example_stack': 'Spring Boot + JPA + PostgreSQL + Redis'
        }
    }
    
    # Selection logic based on requirements
    if 'high_performance' in requirements:
        return frameworks['fastapi']
    elif 'enterprise' in requirements:
        return frameworks['spring_boot']
    elif 'rapid_development' in requirements:
        return frameworks['django_rest']
    elif 'real_time' in requirements:
        return frameworks['express']
    
    return frameworks['fastapi']  # Default recommendation

2. FastAPI Implementation

Complete FastAPI API implementation:

Project Structure

project/
├── app/
│   ├── __init__.py
│   ├── main.py
│   ├── core/
│   │   ├── config.py
│   │   ├── security.py
│   │   └── database.py
│   ├── api/
│   │   ├── __init__.py
│   │   ├── deps.py
│   │   └── v1/
│   │       ├── __init__.py
│   │       ├── endpoints/
│   │       │   ├── users.py
│   │       │   └── items.py
│   │       └── api.py
│   ├── models/
│   │   ├── __init__.py
│   │   ├── user.py
│   │   └── item.py
│   ├── schemas/
│   │   ├── __init__.py
│   │   ├── user.py
│   │   └── item.py
│   ├── services/
│   │   ├── __init__.py
│   │   ├── user_service.py
│   │   └── item_service.py
│   └── tests/
│       ├── conftest.py
│       ├── test_users.py
│       └── test_items.py
├── alembic/
├── requirements.txt
├── Dockerfile
└── docker-compose.yml

Core Configuration

# app/core/config.py
from pydantic import BaseSettings, validator
from typing import Optional, Dict, Any
import secrets

class Settings(BaseSettings):
    API_V1_STR: str = "/api/v1"
    SECRET_KEY: str = secrets.token_urlsafe(32)
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8  # 8 days
    SERVER_NAME: str = "localhost"
    SERVER_HOST: str = "0.0.0.0"
    
    # Database
    POSTGRES_SERVER: str = "localhost"
    POSTGRES_USER: str = "postgres"
    POSTGRES_PASSWORD: str = ""
    POSTGRES_DB: str = "app"
    DATABASE_URL: Optional[str] = None
    
    @validator("DATABASE_URL", pre=True)
    def assemble_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any:
        if isinstance(v, str):
            return v
        return f"postgresql://{values.get('POSTGRES_USER')}:{values.get('POSTGRES_PASSWORD')}@{values.get('POSTGRES_SERVER')}/{values.get('POSTGRES_DB')}"
    
    # Redis
    REDIS_URL: str = "redis://localhost:6379"
    
    # Security
    BACKEND_CORS_ORIGINS: list = ["http://localhost:3000", "http://localhost:8000"]
    
    # Rate Limiting
    RATE_LIMIT_REQUESTS: int = 100
    RATE_LIMIT_WINDOW: int = 60
    
    # Monitoring
    SENTRY_DSN: Optional[str] = None
    LOG_LEVEL: str = "INFO"
    
    class Config:
        env_file = ".env"

settings = Settings()

Database Setup

# app/core/database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool
import redis

from app.core.config import settings

# PostgreSQL
engine = create_engine(
    settings.DATABASE_URL,
    poolclass=StaticPool,
    pool_size=20,
    max_overflow=30,
    pool_pre_ping=True,
    echo=settings.LOG_LEVEL == "DEBUG"
)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

# Redis
redis_client = redis.from_url(settings.REDIS_URL, decode_responses=True)

def get_db():
    """Dependency to get database session"""
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

def get_redis():
    """Dependency to get Redis connection"""
    return redis_client

Security Implementation

# app/core/security.py
from datetime import datetime, timedelta
from typing import Optional
import jwt
from passlib.context import CryptContext
from fastapi import HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials

from app.core.config import settings

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
security = HTTPBearer()

def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    """Create JWT access token"""
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
    
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm="HS256")
    return encoded_jwt

def verify_token(credentials: HTTPAuthorizationCredentials) -> dict:
    """Verify JWT token"""
    try:
        payload = jwt.decode(
            credentials.credentials, 
            settings.SECRET_KEY, 
            algorithms=["HS256"]
        )
        username: str = payload.get("sub")
        if username is None:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Could not validate credentials",
                headers={"WWW-Authenticate": "Bearer"},
            )
        return payload
    except jwt.PyJWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Could not validate credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )

def verify_password(plain_password: str, hashed_password: str) -> bool:
    """Verify password against hash"""
    return pwd_context.verify(plain_password, hashed_password)

def get_password_hash(password: str) -> str:
    """Generate password hash"""
    return pwd_context.hash(password)

Models Implementation

# app/models/user.py
from sqlalchemy import Column, Integer, String, Boolean, DateTime, Text
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship

from app.core.database import Base

class User(Base):
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True, index=True)
    email = Column(String, unique=True, index=True, nullable=False)
    username = Column(String, unique=True, index=True, nullable=False)
    hashed_password = Column(String, nullable=False)
    full_name = Column(String)
    is_active = Column(Boolean, default=True)
    is_superuser = Column(Boolean, default=False)
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    updated_at = Column(DateTime(timezone=True), onupdate=func.now())
    
    # Relationships
    items = relationship("Item", back_populates="owner")

# app/models/item.py
from sqlalchemy import Column, Integer, String, Boolean, DateTime, Text, ForeignKey
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship

from app.core.database import Base

class Item(Base):
    __tablename__ = "items"
    
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String, index=True, nullable=False)
    description = Column(Text)
    is_active = Column(Boolean, default=True)
    owner_id = Column(Integer, ForeignKey("users.id"))
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    updated_at = Column(DateTime(timezone=True), onupdate=func.now())
    
    # Relationships
    owner = relationship("User", back_populates="items")

Pydantic Schemas

# app/schemas/user.py
from pydantic import BaseModel, EmailStr, validator
from typing import Optional
from datetime import datetime

class UserBase(BaseModel):
    email: EmailStr
    username: str
    full_name: Optional[str] = None

class UserCreate(UserBase):
    password: str
    
    @validator('password')
    def validate_password(cls, v):
        if len(v) < 8:
            raise ValueError('Password must be at least 8 characters')
        return v

class UserUpdate(BaseModel):
    email: Optional[EmailStr] = None
    username: Optional[str] = None
    full_name: Optional[str] = None
    is_active: Optional[bool] = None

class UserInDB(UserBase):
    id: int
    is_active: bool
    is_superuser: bool
    created_at: datetime
    updated_at: Optional[datetime]
    
    class Config:
        orm_mode = True

class User(UserInDB):
    pass

# app/schemas/item.py
from pydantic import BaseModel, validator
from typing import Optional
from datetime import datetime

class ItemBase(BaseModel):
    title: str
    description: Optional[str] = None

class ItemCreate(ItemBase):
    @validator('title')
    def validate_title(cls, v):
        if len(v.strip()) < 3:
            raise ValueError('Title must be at least 3 characters')
        return v.strip()

class ItemUpdate(BaseModel):
    title: Optional[str] = None
    description: Optional[str] = None
    is_active: Optional[bool] = None

class ItemInDB(ItemBase):
    id: int
    is_active: bool
    owner_id: int
    created_at: datetime
    updated_at: Optional[datetime]
    
    class Config:
        orm_mode = True

class Item(ItemInDB):
    pass

Service Layer

# app/services/user_service.py
from typing import Optional, List
from sqlalchemy.orm import Session
from fastapi import HTTPException, status

from app.models.user import User
from app.schemas.user import UserCreate, UserUpdate
from app.core.security import get_password_hash, verify_password

class UserService:
    def __init__(self, db: Session):
        self.db = db
    
    def get_user(self, user_id: int) -> Optional[User]:
        """Get user by ID"""
        return self.db.query(User).filter(User.id == user_id).first()
    
    def get_user_by_email(self, email: str) -> Optional[User]:
        """Get user by email"""
        return self.db.query(User).filter(User.email == email).first()
    
    def get_users(self, skip: int = 0, limit: int = 100) -> List[User]:
        """Get list of users"""
        return self.db.query(User).offset(skip).limit(limit).all()
    
    def create_user(self, user_create: UserCreate) -> User:
        """Create new user"""
        # Check if user exists
        if self.get_user_by_email(user_create.email):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Email already registered"
            )
        
        # Create user
        hashed_password = get_password_hash(user_create.password)
        db_user = User(
            email=user_create.email,
            username=user_create.username,
            full_name=user_create.full_name,
            hashed_password=hashed_password
        )
        self.db.add(db_user)
        self.db.commit()
        self.db.refresh(db_user)
        return db_user
    
    def update_user(self, user_id: int, user_update: UserUpdate) -> User:
        """Update user"""
        db_user = self.get_user(user_id)
        if not db_user:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="User not found"
            )
        
        update_data = user_update.dict(exclude_unset=True)
        for field, value in update_data.items():
            setattr(db_user, field, value)
        
        self.db.commit()
        self.db.refresh(db_user)
        return db_user
    
    def authenticate_user(self, email: str, password: str) -> Optional[User]:
        """Authenticate user"""
        user = self.get_user_by_email(email)
        if not user or not verify_password(password, user.hashed_password):
            return None
        return user

Rate Limiting Middleware

# app/core/rate_limiting.py
import time
from typing import Callable
from fastapi import Request, HTTPException, status
from fastapi.responses import JSONResponse
import redis

from app.core.config import settings
from app.core.database import get_redis

class RateLimiter:
    def __init__(self, redis_client: redis.Redis):
        self.redis = redis_client
        self.requests = settings.RATE_LIMIT_REQUESTS
        self.window = settings.RATE_LIMIT_WINDOW
    
    async def __call__(self, request: Request, call_next: Callable):
        # Get client identifier
        client_ip = request.client.host
        user_id = getattr(request.state, 'user_id', None)
        key = f"rate_limit:{user_id or client_ip}"
        
        # Check rate limit
        current = self.redis.get(key)
        if current is None:
            # First request in window
            self.redis.setex(key, self.window, 1)
        else:
            current = int(current)
            if current >= self.requests:
                raise HTTPException(
                    status_code=status.HTTP_429_TOO_MANY_REQUESTS,
                    detail=f"Rate limit exceeded. Try again in {self.redis.ttl(key)} seconds",
                    headers={"Retry-After": str(self.redis.ttl(key))}
                )
            self.redis.incr(key)
        
        response = await call_next(request)
        
        # Add rate limit headers
        remaining = max(0, self.requests - int(self.redis.get(key) or 0))
        response.headers["X-RateLimit-Limit"] = str(self.requests)
        response.headers["X-RateLimit-Remaining"] = str(remaining)
        response.headers["X-RateLimit-Reset"] = str(int(time.time()) + self.redis.ttl(key))
        
        return response

API Endpoints

# app/api/v1/endpoints/users.py
from typing import List
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session

from app.core.database import get_db
from app.core.security import verify_token, security
from app.schemas.user import User, UserCreate, UserUpdate
from app.services.user_service import UserService

router = APIRouter()

@router.post("/", response_model=User, status_code=status.HTTP_201_CREATED)
async def create_user(
    user_create: UserCreate,
    db: Session = Depends(get_db)
):
    """Create new user"""
    service = UserService(db)
    return service.create_user(user_create)

@router.get("/me", response_model=User)
async def get_current_user(
    token: dict = Depends(verify_token),
    db: Session = Depends(get_db)
):
    """Get current user profile"""
    service = UserService(db)
    user = service.get_user_by_email(token["sub"])
    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="User not found"
        )
    return user

@router.get("/{user_id}", response_model=User)
async def get_user(
    user_id: int,
    db: Session = Depends(get_db),
    token: dict = Depends(verify_token)
):
    """Get user by ID"""
    service = UserService(db)
    user = service.get_user(user_id)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="User not found"
        )
    return user

@router.put("/{user_id}", response_model=User)
async def update_user(
    user_id: int,
    user_update: UserUpdate,
    db: Session = Depends(get_db),
    token: dict = Depends(verify_token)
):
    """Update user"""
    service = UserService(db)
    return service.update_user(user_id, user_update)

@router.get("/", response_model=List[User])
async def list_users(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db),
    token: dict = Depends(verify_token)
):
    """List users"""
    service = UserService(db)
    return service.get_users(skip=skip, limit=limit)

Main Application

# app/main.py
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.responses import JSONResponse
import logging
import time
import uuid

from app.core.config import settings
from app.core.rate_limiting import RateLimiter
from app.core.database import get_redis
from app.api.v1.api import api_router

# Configure logging
logging.basicConfig(
    level=getattr(logging, settings.LOG_LEVEL),
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)

# Create FastAPI app
app = FastAPI(
    title="Production API",
    description="A production-ready API with FastAPI",
    version="1.0.0",
    openapi_url=f"{settings.API_V1_STR}/openapi.json"
)

# Middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.BACKEND_CORS_ORIGINS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

app.add_middleware(
    TrustedHostMiddleware,
    allowed_hosts=["localhost", "127.0.0.1", settings.SERVER_NAME]
)

# Rate limiting middleware
rate_limiter = RateLimiter(get_redis())
app.middleware("http")(rate_limiter)

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    """Add processing time and correlation ID"""
    correlation_id = str(uuid.uuid4())
    request.state.correlation_id = correlation_id
    
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    
    response.headers["X-Process-Time"] = str(process_time)
    response.headers["X-Correlation-ID"] = correlation_id
    return response

@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    """Global exception handler"""
    correlation_id = getattr(request.state, 'correlation_id', 'unknown')
    
    logger.error(
        f"Unhandled exception: {exc}",
        extra={"correlation_id": correlation_id, "path": request.url.path}
    )
    
    return JSONResponse(
        status_code=500,
        content={
            "detail": "Internal server error",
            "correlation_id": correlation_id
        }
    )

# Include routers
app.include_router(api_router, prefix=settings.API_V1_STR)

@app.get("/health")
async def health_check():
    """Health check endpoint"""
    return {"status": "healthy", "timestamp": time.time()}

@app.get("/")
async def root():
    """Root endpoint"""
    return {"message": "Welcome to the Production API"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "app.main:app",
        host=settings.SERVER_HOST,
        port=8000,
        reload=True
    )

3. Express.js Implementation

Complete Express.js TypeScript implementation:

Project Structure & Setup

// package.json
{
  "name": "express-api",
  "version": "1.0.0",
  "scripts": {
    "dev": "nodemon src/index.ts",
    "build": "tsc",
    "start": "node dist/index.js",
    "test": "jest",
    "test:watch": "jest --watch"
  },
  "dependencies": {
    "express": "^4.18.2",
    "express-rate-limit": "^6.10.0",
    "helmet": "^7.0.0",
    "cors": "^2.8.5",
    "compression": "^1.7.4",
    "morgan": "^1.10.0",
    "joi": "^17.9.2",
    "jsonwebtoken": "^9.0.2",
    "bcryptjs": "^2.4.3",
    "prisma": "^5.1.0",
    "@prisma/client": "^5.1.0",
    "redis": "^4.6.7",
    "winston": "^3.10.0"
  },
  "devDependencies": {
    "@types/express": "^4.17.17",
    "@types/node": "^20.4.5",
    "typescript": "^5.1.6",
    "nodemon": "^3.0.1",
    "jest": "^29.6.1",
    "@types/jest": "^29.5.3",
    "supertest": "^6.3.3"
  }
}

// src/types/index.ts
export interface User {
  id: string;
  email: string;
  username: string;
  fullName?: string;
  isActive: boolean;
  createdAt: Date;
  updatedAt: Date;
}

export interface CreateUserRequest {
  email: string;
  username: string;
  password: string;
  fullName?: string;
}

export interface AuthTokenPayload {
  userId: string;
  email: string;
  iat: number;
  exp: number;
}

// src/config/index.ts
import { config as dotenvConfig } from 'dotenv';

dotenvConfig();

export const config = {
  port: parseInt(process.env.PORT || '3000'),
  jwtSecret: process.env.JWT_SECRET || 'your-secret-key',
  jwtExpiresIn: process.env.JWT_EXPIRES_IN || '7d',
  redisUrl: process.env.REDIS_URL || 'redis://localhost:6379',
  databaseUrl: process.env.DATABASE_URL || 'postgresql://user:pass@localhost:5432/db',
  nodeEnv: process.env.NODE_ENV || 'development',
  corsOrigins: process.env.CORS_ORIGINS?.split(',') || ['http://localhost:3000'],
  rateLimitMax: parseInt(process.env.RATE_LIMIT_MAX || '100'),
  rateLimitWindow: parseInt(process.env.RATE_LIMIT_WINDOW_MS || '900000'), // 15 minutes
};

// src/middleware/validation.ts
import { Request, Response, NextFunction } from 'express';
import Joi from 'joi';

export const validateRequest = (schema: Joi.ObjectSchema) => {
  return (req: Request, res: Response, next: NextFunction) => {
    const { error } = schema.validate(req.body);
    
    if (error) {
      return res.status(400).json({
        success: false,
        message: 'Validation error',
        details: error.details.map(detail => ({
          field: detail.path.join('.'),
          message: detail.message
        }))
      });
    }
    
    next();
  };
};

// Validation schemas
export const userSchemas = {
  create: Joi.object({
    email: Joi.string().email().required(),
    username: Joi.string().alphanum().min(3).max(30).required(),
    password: Joi.string().min(8).required(),
    fullName: Joi.string().max(100).optional()
  }),
  
  update: Joi.object({
    email: Joi.string().email().optional(),
    username: Joi.string().alphanum().min(3).max(30).optional(),
    fullName: Joi.string().max(100).optional(),
    isActive: Joi.boolean().optional()
  })
};

// src/middleware/auth.ts
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import { config } from '../config';
import { AuthTokenPayload } from '../types';

declare global {
  namespace Express {
    interface Request {
      user?: AuthTokenPayload;
    }
  }
}

export const authenticateToken = (req: Request, res: Response, next: NextFunction) => {
  const authHeader = req.headers.authorization;
  const token = authHeader && authHeader.split(' ')[1];

  if (!token) {
    return res.status(401).json({
      success: false,
      message: 'Access token required'
    });
  }

  try {
    const decoded = jwt.verify(token, config.jwtSecret) as AuthTokenPayload;
    req.user = decoded;
    next();
  } catch (error) {
    return res.status(403).json({
      success: false,
      message: 'Invalid or expired token'
    });
  }
};

// src/services/userService.ts
import { PrismaClient } from '@prisma/client';
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { config } from '../config';
import { CreateUserRequest, User } from '../types';

const prisma = new PrismaClient();

export class UserService {
  async createUser(userData: CreateUserRequest): Promise<User> {
    // Check if user exists
    const existingUser = await prisma.user.findFirst({
      where: {
        OR: [
          { email: userData.email },
          { username: userData.username }
        ]
      }
    });

    if (existingUser) {
      throw new Error('User with this email or username already exists');
    }

    // Hash password
    const hashedPassword = await bcrypt.hash(userData.password, 12);

    // Create user
    const user = await prisma.user.create({
      data: {
        email: userData.email,
        username: userData.username,
        fullName: userData.fullName,
        hashedPassword,
        isActive: true
      }
    });

    // Remove password from response
    const { hashedPassword: _, ...userWithoutPassword } = user;
    return userWithoutPassword as User;
  }

  async getUserById(id: string): Promise<User | null> {
    const user = await prisma.user.findUnique({
      where: { id },
      select: {
        id: true,
        email: true,
        username: true,
        fullName: true,
        isActive: true,
        createdAt: true,
        updatedAt: true
      }
    });

    return user;
  }

  async authenticateUser(email: string, password: string): Promise<string | null> {
    const user = await prisma.user.findUnique({
      where: { email }
    });

    if (!user || !await bcrypt.compare(password, user.hashedPassword)) {
      return null;
    }

    const token = jwt.sign(
      { userId: user.id, email: user.email },
      config.jwtSecret,
      { expiresIn: config.jwtExpiresIn }
    );

    return token;
  }

  async getUsers(skip = 0, take = 10): Promise<User[]> {
    return await prisma.user.findMany({
      skip,
      take,
      select: {
        id: true,
        email: true,
        username: true,
        fullName: true,
        isActive: true,
        createdAt: true,
        updatedAt: true
      }
    });
  }
}

// src/controllers/userController.ts
import { Request, Response } from 'express';
import { UserService } from '../services/userService';
import { logger } from '../utils/logger';

const userService = new UserService();

export class UserController {
  async createUser(req: Request, res: Response) {
    try {
      const user = await userService.createUser(req.body);
      
      logger.info('User created successfully', { userId: user.id });
      
      res.status(201).json({
        success: true,
        message: 'User created successfully',
        data: user
      });
    } catch (error) {
      logger.error('Error creating user', { error: error.message });
      
      res.status(400).json({
        success: false,
        message: error.message || 'Failed to create user'
      });
    }
  }

  async getUser(req: Request, res: Response) {
    try {
      const { id } = req.params;
      const user = await userService.getUserById(id);

      if (!user) {
        return res.status(404).json({
          success: false,
          message: 'User not found'
        });
      }

      res.json({
        success: true,
        data: user
      });
    } catch (error) {
      logger.error('Error fetching user', { error: error.message });
      
      res.status(500).json({
        success: false,
        message: 'Internal server error'
      });
    }
  }

  async getCurrentUser(req: Request, res: Response) {
    try {
      const user = await userService.getUserById(req.user!.userId);

      if (!user) {
        return res.status(404).json({
          success: false,
          message: 'User not found'
        });
      }

      res.json({
        success: true,
        data: user
      });
    } catch (error) {
      logger.error('Error fetching current user', { error: error.message });
      
      res.status(500).json({
        success: false,
        message: 'Internal server error'
      });
    }
  }

  async loginUser(req: Request, res: Response) {
    try {
      const { email, password } = req.body;
      const token = await userService.authenticateUser(email, password);

      if (!token) {
        return res.status(401).json({
          success: false,
          message: 'Invalid email or password'
        });
      }

      res.json({
        success: true,
        message: 'Login successful',
        data: { token }
      });
    } catch (error) {
      logger.error('Error during login', { error: error.message });
      
      res.status(500).json({
        success: false,
        message: 'Internal server error'
      });
    }
  }
}

4. Testing Implementation

Comprehensive testing setup:

FastAPI Tests

# tests/conftest.py
import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool

from app.main import app
from app.core.database import Base, get_db
from app.core.config import settings

# Test database
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(
    SQLALCHEMY_DATABASE_URL,
    connect_args={"check_same_thread": False},
    poolclass=StaticPool,
)
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

def override_get_db():
    try:
        db = TestingSessionLocal()
        yield db
    finally:
        db.close()

app.dependency_overrides[get_db] = override_get_db

@pytest.fixture(scope="session")
def db_engine():
    Base.metadata.create_all(bind=engine)
    yield engine
    Base.metadata.drop_all(bind=engine)

@pytest.fixture(scope="function")
def db_session(db_engine):
    connection = db_engine.connect()
    transaction = connection.begin()
    session = TestingSessionLocal(bind=connection)
    
    yield session
    
    session.close()
    transaction.rollback()
    connection.close()

@pytest.fixture(scope="module")
def client():
    with TestClient(app) as test_client:
        yield test_client

# tests/test_users.py
import pytest
from fastapi.testclient import TestClient

def test_create_user(client: TestClient):
    """Test user creation"""
    user_data = {
        "email": "test@example.com",
        "username": "testuser",
        "password": "testpassword123",
        "full_name": "Test User"
    }
    
    response = client.post("/api/v1/users/", json=user_data)
    assert response.status_code == 201
    
    data = response.json()
    assert data["email"] == user_data["email"]
    assert data["username"] == user_data["username"]
    assert "id" in data
    assert "hashed_password" not in data

def test_create_user_duplicate_email(client: TestClient):
    """Test creating user with duplicate email"""
    user_data = {
        "email": "duplicate@example.com",
        "username": "user1",
        "password": "password123"
    }
    
    # Create first user
    response1 = client.post("/api/v1/users/", json=user_data)
    assert response1.status_code == 201
    
    # Try to create second user with same email
    user_data["username"] = "user2"
    response2 = client.post("/api/v1/users/", json=user_data)
    assert response2.status_code == 400
    assert "already registered" in response2.json()["detail"]

def test_get_user_unauthorized(client: TestClient):
    """Test accessing protected endpoint without token"""
    response = client.get("/api/v1/users/me")
    assert response.status_code == 401

@pytest.mark.asyncio
async def test_user_authentication_flow(client: TestClient):
    """Test complete authentication flow"""
    # Create user
    user_data = {
        "email": "auth@example.com",
        "username": "authuser",
        "password": "authpassword123"
    }
    
    create_response = client.post("/api/v1/users/", json=user_data)
    assert create_response.status_code == 201
    
    # Login
    login_data = {
        "email": user_data["email"],
        "password": user_data["password"]
    }
    login_response = client.post("/api/v1/auth/login", json=login_data)
    assert login_response.status_code == 200
    
    token = login_response.json()["access_token"]
    
    # Access protected endpoint
    headers = {"Authorization": f"Bearer {token}"}
    profile_response = client.get("/api/v1/users/me", headers=headers)
    assert profile_response.status_code == 200
    
    profile_data = profile_response.json()
    assert profile_data["email"] == user_data["email"]

5. Deployment Configuration

Docker Configuration

# Dockerfile (FastAPI)
FROM python:3.11-slim

WORKDIR /app

# Install system dependencies
RUN apt-get update && apt-get install -y \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# Install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application
COPY . .

# Create non-root user
RUN adduser --disabled-password --gecos '' appuser
RUN chown -R appuser:appuser /app
USER appuser

# Health check
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
    CMD curl -f http://localhost:8000/health || exit 1

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Docker Compose

# docker-compose.yml
version: '3.8'

services:
  api:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://postgres:password@db:5432/appdb
      - REDIS_URL=redis://redis:6379
    depends_on:
      - db
      - redis
    volumes:
      - ./app:/app/app
    restart: unless-stopped

  db:
    image: postgres:15
    environment:
      - POSTGRES_DB=appdb
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "5432:5432"
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - api
    restart: unless-stopped

volumes:
  postgres_data:
  redis_data:

6. CI/CD Pipeline

GitHub Actions Workflow

# .github/workflows/api.yml
name: API CI/CD

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  test:
    runs-on: ubuntu-latest
    
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: test_db
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432
      
      redis:
        image: redis:7
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 6379:6379

    steps:
    - uses: actions/checkout@v4
    
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.11'
    
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
        pip install -r requirements-dev.txt
    
    - name: Run linting
      run: |
        flake8 app tests
        black --check app tests
        isort --check-only app tests
    
    - name: Run type checking
      run: mypy app
    
    - name: Run security scan
      run: bandit -r app
    
    - name: Run tests
      env:
        DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_db
        REDIS_URL: redis://localhost:6379
      run: |
        pytest tests/ -v --cov=app --cov-report=xml
    
    - name: Upload coverage
      uses: codecov/codecov-action@v3
      with:
        file: ./coverage.xml

  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.event_name == 'push'
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3
    
    - name: Log in to Container Registry
      uses: docker/login-action@v3
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}
    
    - name: Extract metadata
      id: meta
      uses: docker/metadata-action@v5
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
        tags: |
          type=ref,event=branch
          type=ref,event=pr
          type=sha
    
    - name: Build and push Docker image
      uses: docker/build-push-action@v5
      with:
        context: .
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=gha
        cache-to: type=gha,mode=max

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    
    steps:
    - name: Deploy to staging
      run: |
        echo "Deploying to staging environment"
        # Add deployment commands here

7. Monitoring and Observability

Prometheus Metrics

# app/core/metrics.py
from prometheus_client import Counter, Histogram, Gauge, generate_latest
from fastapi import Request
import time

# Metrics
REQUEST_COUNT = Counter(
    'http_requests_total',
    'Total HTTP requests',
    ['method', 'endpoint', 'status']
)

REQUEST_DURATION = Histogram(
    'http_request_duration_seconds',
    'HTTP request duration',
    ['method', 'endpoint']
)

ACTIVE_CONNECTIONS = Gauge(
    'active_connections',
    'Active connections'
)

async def record_metrics(request: Request, call_next):
    """Record metrics for each request"""
    start_time = time.time()
    
    ACTIVE_CONNECTIONS.inc()
    
    try:
        response = await call_next(request)
        
        # Record metrics
        REQUEST_COUNT.labels(
            method=request.method,
            endpoint=request.url.path,
            status=response.status_code
        ).inc()
        
        REQUEST_DURATION.labels(
            method=request.method,
            endpoint=request.url.path
        ).observe(time.time() - start_time)
        
        return response
    
    finally:
        ACTIVE_CONNECTIONS.dec()

@app.get("/metrics")
async def metrics():
    """Prometheus metrics endpoint"""
    return Response(
        generate_latest(),
        media_type="text/plain"
    )

Cross-Command Integration

This command integrates seamlessly with other Claude Code commands to create complete development workflows:

1. Complete API Development Workflow

Standard Development Pipeline:

# 1. Start with API scaffold
/api-scaffold "User management API with FastAPI, PostgreSQL, and JWT auth"

# 2. Set up comprehensive testing
/test-harness "FastAPI API with unit, integration, and load testing using pytest and locust"

# 3. Security validation
/security-scan "FastAPI application with authentication endpoints"

# 4. Container optimization
/docker-optimize "FastAPI application with PostgreSQL and Redis dependencies"

# 5. Kubernetes deployment
/k8s-manifest "FastAPI microservice with PostgreSQL, Redis, and ingress"

# 6. Frontend integration (if needed)
/frontend-optimize "React application connecting to FastAPI backend"

2. Database-First Development

When starting with existing data:

# 1. Handle database migrations first
/db-migrate "PostgreSQL schema migration from legacy system to modern structure"

# 2. Generate API based on migrated schema
/api-scaffold "REST API for migrated PostgreSQL schema with auto-generated models"

# 3. Continue with standard pipeline...

3. Microservices Architecture

For distributed systems:

# Generate multiple related APIs
/api-scaffold "User service with authentication and profile management"
/api-scaffold "Order service with payment processing and inventory"
/api-scaffold "Notification service with email and push notifications"

# Containerize all services
/docker-optimize "Microservices architecture with service discovery"

# Deploy as distributed system
/k8s-manifest "Microservices deployment with service mesh and monitoring"

4. Integration with Generated Code

Test Integration Setup:

# After running /api-scaffold, use this with /test-harness
test_config:
  api_base_url: "http://localhost:8000"
  test_database: "postgresql://test:test@localhost:5432/test_db"
  authentication:
    test_user: "test@example.com"
    test_password: "testpassword123"
  
  endpoints_to_test:
    - POST /api/v1/users/
    - POST /api/v1/auth/login
    - GET /api/v1/users/me
    - GET /api/v1/users/{id}

Security Scan Configuration:

# Configuration for /security-scan after API scaffold
security_scan:
  target: "localhost:8000"
  authentication_endpoints:
    - "/api/v1/auth/login"
    - "/api/v1/auth/refresh"
  protected_endpoints:
    - "/api/v1/users/me"
    - "/api/v1/users/{id}"
  vulnerability_tests:
    - jwt_token_validation
    - sql_injection
    - xss_prevention
    - rate_limiting

Docker Integration:

# Generated Dockerfile can be optimized with /docker-optimize
# Multi-stage build for FastAPI application
FROM python:3.11-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt

FROM python:3.11-slim as runtime
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Kubernetes Deployment:

# Use this configuration with /k8s-manifest
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api
        image: api:latest
        ports:
        - containerPort: 8000
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: api-secrets
              key: database-url
        - name: JWT_SECRET
          valueFrom:
            secretKeyRef:
              name: api-secrets
              key: jwt-secret
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8000
          initialDelaySeconds: 5
          periodSeconds: 5

5. CI/CD Pipeline Integration

Complete pipeline using multiple commands:

name: Full Stack CI/CD

on:
  push:
    branches: [main]

jobs:
  api-test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    
    # Test API (generated by /api-scaffold)
    - name: Run API tests
      run: |
        # Use test configuration from /test-harness
        pytest tests/ -v --cov=app
    
    # Security scan (from /security-scan)
    - name: Security scan
      run: |
        bandit -r app/
        safety check
    
    # Build optimized container (from /docker-optimize)
    - name: Build container
      run: |
        docker build -f Dockerfile.optimized -t api:${{ github.sha }} .
    
    # Deploy to Kubernetes (from /k8s-manifest)
    - name: Deploy to staging
      run: |
        kubectl apply -f k8s/staging/
        kubectl set image deployment/api-deployment api=api:${{ github.sha }}

6. Frontend-Backend Integration

When building full-stack applications:

# 1. Backend API
/api-scaffold "REST API with user management and data operations"

# 2. Frontend application
/frontend-optimize "React SPA with API integration, authentication, and state management"

# 3. Integration testing
/test-harness "End-to-end testing for React frontend and FastAPI backend"

# 4. Unified deployment
/k8s-manifest "Full-stack deployment with API, frontend, and database"

Frontend API Integration Code:

// Generated API client for frontend
// Use this pattern with /frontend-optimize
export class APIClient {
  private baseURL: string;
  private token: string | null = null;

  constructor(baseURL: string) {
    this.baseURL = baseURL;
  }

  setAuthToken(token: string) {
    this.token = token;
  }

  private async request<T>(
    endpoint: string, 
    options: RequestInit = {}
  ): Promise<T> {
    const url = `${this.baseURL}${endpoint}`;
    const headers = {
      'Content-Type': 'application/json',
      ...(this.token && { Authorization: `Bearer ${this.token}` }),
      ...options.headers,
    };

    const response = await fetch(url, {
      ...options,
      headers,
    });

    if (!response.ok) {
      throw new Error(`API Error: ${response.statusText}`);
    }

    return response.json();
  }

  // User management methods (matching API scaffold)
  async createUser(userData: CreateUserRequest): Promise<User> {
    return this.request<User>('/api/v1/users/', {
      method: 'POST',
      body: JSON.stringify(userData),
    });
  }

  async login(credentials: LoginRequest): Promise<AuthResponse> {
    return this.request<AuthResponse>('/api/v1/auth/login', {
      method: 'POST',
      body: JSON.stringify(credentials),
    });
  }

  async getCurrentUser(): Promise<User> {
    return this.request<User>('/api/v1/users/me');
  }
}

7. Monitoring and Observability Integration

Complete observability stack:

# After API deployment, add monitoring
/api-scaffold "Monitoring endpoints with Prometheus metrics and health checks"

# Use with Kubernetes monitoring
/k8s-manifest "Kubernetes deployment with Prometheus, Grafana, and alerting"

This integrated approach ensures all components work together seamlessly, creating a production-ready system with proper testing, security, deployment, and monitoring.

Validation Checklist

  • Framework selected based on requirements
  • Project structure follows best practices
  • Authentication and authorization implemented
  • Input validation and sanitization in place
  • Rate limiting configured
  • Error handling comprehensive
  • Logging and monitoring setup
  • Tests written and passing
  • Security measures implemented
  • API documentation generated
  • Deployment configuration ready
  • CI/CD pipeline configured

Focus on creating production-ready APIs with proper architecture, security, testing, and operational concerns addressed from the start.