boilerplate

📁 manastalukdar/claude-devstudio 📅 5 days ago
3
总安装量
2
周安装量
#60558
全站排名
安装命令
npx skills add https://github.com/manastalukdar/claude-devstudio --skill boilerplate

Agent 安装分布

opencode 2
gemini-cli 2
claude-code 2
github-copilot 2
codex 2
kimi-cli 2

Skill 文档

Framework Boilerplate Generator

I’ll generate framework-specific boilerplate code following best practices and conventions for React, Vue, Next.js, Express, FastAPI, Django, and more.

Arguments: $ARGUMENTS – component/route/model name and type

Supported Frameworks:

  • Frontend: React, Vue, Next.js, Angular, Svelte
  • Backend: Express, Fastify, NestJS, FastAPI, Django
  • Full-stack: Next.js, Remix, SvelteKit

Token Optimization

This skill uses multiple optimization strategies to minimize token usage while maintaining comprehensive boilerplate generation:

1. Framework Detection Caching (400 token savings)

Pattern: Cache framework detection results to avoid repeated file system checks

# Cache file: .boilerplate-framework.cache
# Format: framework_name
# TTL: 24 hours (framework rarely changes)

if [ -f ".boilerplate-framework.cache" ] && [ $(($(date +%s) - $(stat -c %Y .boilerplate-framework.cache))) -lt 86400 ]; then
    FRAMEWORK=$(cat .boilerplate-framework.cache)
    # 20 tokens vs 420 tokens for full detection
else
    FRAMEWORK=$(detect_framework)  # Full detection (420 tokens)
    echo "$FRAMEWORK" > .boilerplate-framework.cache
fi

Savings:

  • Cached: ~20 tokens (read cache file)
  • Uncached: ~420 tokens (package.json/requirements.txt checks, multiple Grep operations)
  • 400 token savings (95%) for subsequent runs

2. Template Library Approach (2,500 token savings)

Pattern: Use comprehensive pre-defined templates instead of LLM-generated code

# Instead of: LLM-generated boilerplate (3,000+ tokens)
# Use: Template library (500 tokens)

# Template files stored in skill
TEMPLATE_DIR="templates/$FRAMEWORK"

generate_component() {
    local component_name="$1"
    local template_file="$TEMPLATE_DIR/component.template.tsx"

    # Simple variable substitution (100 tokens)
    sed "s/\${COMPONENT_NAME}/$component_name/g" "$template_file"
}

Savings:

  • Template-based: ~500 tokens (file read + substitution)
  • LLM-generated: ~3,000 tokens (full code generation with analysis)
  • 2,500 token savings (83%) per component

3. Grep-Based Configuration Detection (300 token savings)

Pattern: Use Grep to detect project configuration instead of reading files

# Instead of: Read package.json/requirements.txt fully (500 tokens)
# Use: Grep for specific patterns (200 tokens)

# Detect React
HAS_REACT=$(grep -q "\"react\":" package.json && echo "true" || echo "false")

# Detect TypeScript
HAS_TS=$(grep -q "\"typescript\":" package.json && echo "true" || echo "false")

# Detect testing framework
HAS_JEST=$(grep -q "\"jest\":" package.json && echo "true" || echo "false")

Savings:

  • Grep approach: ~200 tokens (pattern matching)
  • Full file read: ~500 tokens (read and parse JSON)
  • 300 token savings (60%)

4. Incremental Scaffolding (1,200 token savings)

Pattern: Generate only requested component type, not entire feature

# Instead of: Full feature scaffolding (4,000+ tokens)
# - Component + styles + tests + stories + types
# Generate: Only component (800 tokens)

case $COMPONENT_TYPE in
    component)
        generate_component "$COMPONENT_NAME"  # 800 tokens
        ;;
    route)
        generate_route "$COMPONENT_NAME"  # 900 tokens
        ;;
    full)
        generate_component "$COMPONENT_NAME"
        generate_styles "$COMPONENT_NAME"
        generate_tests "$COMPONENT_NAME"
        generate_types "$COMPONENT_NAME"  # 4,000 tokens
        ;;
esac

Savings:

  • Component only: ~800 tokens
  • Full feature: ~4,000 tokens
  • 1,200 token savings (75%) when generating single component

5. Early Exit for Existing Components (90% savings)

Pattern: Check if component already exists before generating

# Quick check: Does component exist?
case $FRAMEWORK in
    react)
        component_path="src/components/${COMPONENT_NAME}/${COMPONENT_NAME}.tsx"
        ;;
    nextjs)
        component_path="app/${COMPONENT_NAME}/page.tsx"
        ;;
esac

if [ -f "$component_path" ]; then
    echo "⚠️  Component $COMPONENT_NAME already exists at $component_path"
    read -p "Overwrite? (y/n): " confirm
    if [ "$confirm" != "y" ]; then
        echo "✓ Keeping existing component"
        exit 0  # 200 tokens total
    fi
fi

# Otherwise: Full generation (3,500+ tokens)

Savings:

  • Existing component: ~200 tokens (early exit)
  • Full generation: ~3,500+ tokens
  • 3,300+ token savings (94%) when component exists

6. Framework-Specific Template Caching (800 token savings)

Pattern: Cache loaded templates per framework

# Cache file: .boilerplate-templates-${FRAMEWORK}.cache
# Contains pre-loaded templates for the framework
# TTL: 24 hours

load_templates() {
    local cache_file=".boilerplate-templates-${FRAMEWORK}.cache"

    if [ -f "$cache_file" ]; then
        source "$cache_file"  # 150 tokens
        return
    fi

    # Load all templates for framework (950 tokens)
    case $FRAMEWORK in
        react)
            TEMPLATE_COMPONENT=$(cat templates/react/component.tsx)
            TEMPLATE_TEST=$(cat templates/react/test.tsx)
            TEMPLATE_STYLES=$(cat templates/react/styles.css)
            ;;
        nextjs)
            TEMPLATE_PAGE=$(cat templates/nextjs/page.tsx)
            TEMPLATE_API=$(cat templates/nextjs/api-route.ts)
            ;;
    esac

    declare -p TEMPLATE_* > "$cache_file"
}

Savings:

  • Cached templates: ~150 tokens
  • Load templates: ~950 tokens (multiple file reads)
  • 800 token savings (84%) for subsequent runs

7. Component Inventory Tracking (400 token savings)

Pattern: Track generated components to avoid duplicates

# Cache file: .boilerplate-generated.cache
# Format: framework:component_type:component_name:file_path
# TTL: Session-based (cleared manually)

is_component_generated() {
    local component_name="$1"
    local component_type="$2"
    grep -q "^$FRAMEWORK:$component_type:$component_name:" .boilerplate-generated.cache 2>/dev/null
}

# Track generated components
if ! is_component_generated "$COMPONENT_NAME" "$COMPONENT_TYPE"; then
    generate_boilerplate
    echo "$FRAMEWORK:$COMPONENT_TYPE:$COMPONENT_NAME:$component_path" >> .boilerplate-generated.cache
else
    echo "  ✓ $COMPONENT_NAME already generated"
fi

Savings:

  • Skip duplicate: ~50 tokens (cache check)
  • Generate new: ~450 tokens (template processing)
  • 400 token savings (89%) for duplicate prevention

8. Test File Generation Optimization (600 token savings)

Pattern: Generate minimal test boilerplate with placeholders

# Instead of: Comprehensive test suite (1,200 tokens)
# Use: Minimal test template with TODOs (600 tokens)

generate_minimal_test() {
    local component_name="$1"

    cat <<EOF
import { render, screen } from '@testing-library/react';
import { ${component_name} } from './${component_name}';

describe('${component_name}', () => {
  it('renders without crashing', () => {
    render(<${component_name} />);
  });

  // TODO: Add more tests
});
EOF
}

Savings:

  • Minimal test: ~200 tokens (basic structure)
  • Comprehensive test: ~800 tokens (multiple test cases)
  • 600 token savings (75%)
  • Users can expand tests as needed

9. Real-World Token Usage Distribution

Typical Scenarios:

  1. First Run – Single Component (2,000-3,000 tokens)

    • Framework detection: 420 tokens
    • Load templates: 950 tokens
    • Generate component: 800 tokens
    • Generate test: 200 tokens
    • Generate styles: 150 tokens
    • Total: ~2,520 tokens
  2. Subsequent Run – Same Framework (800-1,500 tokens)

    • Framework detection (cached): 20 tokens
    • Load templates (cached): 150 tokens
    • Generate component: 800 tokens
    • Generate test: 200 tokens
    • Total: ~1,170 tokens
  3. Component Exists (150-250 tokens)

    • Framework detection (cached): 20 tokens
    • Check existing: 100 tokens
    • Early exit: 50 tokens
    • Total: ~170 tokens
  4. Full Feature Scaffold (4,000-6,000 tokens)

    • Framework detection: 420 tokens
    • Load templates: 950 tokens
    • Generate component: 800 tokens
    • Generate test: 800 tokens
    • Generate styles: 150 tokens
    • Generate types: 400 tokens
    • Generate story: 300 tokens
    • Total: ~3,820 tokens
  5. API Route Only (600-1,000 tokens)

    • Framework detection (cached): 20 tokens
    • Load API template: 150 tokens
    • Generate route: 600 tokens
    • Total: ~770 tokens

Expected Token Savings:

  • Average 53% reduction from baseline (3,000 → 1,400 tokens)
  • 94% reduction when component already exists
  • Aggregate savings: 1,500-2,000 tokens per boilerplate generation

Optimization Summary

Strategy Savings When Applied
Framework detection caching 400 tokens (95%) Subsequent runs
Template library approach 2,500 tokens (83%) Always
Grep-based config detection 300 tokens (60%) Always
Incremental scaffolding 1,200 tokens (75%) Component-only generation
Early exit for existing 3,300 tokens (94%) Component exists
Template caching 800 tokens (84%) Subsequent runs
Component inventory 400 tokens (89%) Duplicate prevention
Minimal test generation 600 tokens (75%) Test files

Key Insight: The template library approach combined with framework caching provides 50-60% token reduction while maintaining production-ready boilerplate quality. Early exit patterns provide 94% savings when components already exist.

Phase 1: Framework Detection

#!/bin/bash
# Detect project framework

echo "=== Detecting Framework ==="
echo ""

detect_framework() {
    if [ -f "package.json" ]; then
        if grep -q "\"react\"" package.json; then
            if grep -q "\"next\"" package.json; then
                echo "nextjs"
            else
                echo "react"
            fi
        elif grep -q "\"vue\"" package.json; then
            echo "vue"
        elif grep -q "\"@angular/core\"" package.json; then
            echo "angular"
        elif grep -q "\"svelte\"" package.json; then
            echo "svelte"
        elif grep -q "\"express\"" package.json; then
            echo "express"
        elif grep -q "\"fastify\"" package.json; then
            echo "fastify"
        elif grep -q "\"@nestjs/core\"" package.json; then
            echo "nestjs"
        fi
    elif [ -f "requirements.txt" ]; then
        if grep -q "fastapi" requirements.txt; then
            echo "fastapi"
        elif grep -q "django" requirements.txt; then
            echo "django"
        elif grep -q "flask" requirements.txt; then
            echo "flask"
        fi
    fi
}

FRAMEWORK=$(detect_framework)

if [ -z "$FRAMEWORK" ]; then
    echo "❌ No supported framework detected"
    echo ""
    echo "Supported frameworks:"
    echo "  Frontend: React, Vue, Next.js, Angular, Svelte"
    echo "  Backend: Express, Fastify, NestJS, FastAPI, Django, Flask"
    exit 1
fi

echo "✓ Detected framework: $FRAMEWORK"

# Parse arguments
COMPONENT_NAME="${1:-MyComponent}"
COMPONENT_TYPE="${2:-component}"

echo "  Name: $COMPONENT_NAME"
echo "  Type: $COMPONENT_TYPE"

Phase 2: React Component Boilerplate

// React component with TypeScript
import React, { useState, useEffect } from 'react';
import styles from './${COMPONENT_NAME}.module.css';

/**
 * Props for ${COMPONENT_NAME} component
 */
interface ${COMPONENT_NAME}Props {
  /**
   * Component title
   */
  title?: string;

  /**
   * Additional CSS classes
   */
  className?: string;

  /**
   * Event handler when component is clicked
   */
  onClick?: () => void;
}

/**
 * ${COMPONENT_NAME} component
 *
 * @example
 * ```tsx
 * <${COMPONENT_NAME} title="Hello" onClick={() => console.log('clicked')} />
 * ```
 */
export const ${COMPONENT_NAME}: React.FC<${COMPONENT_NAME}Props> = ({
  title = 'Default Title',
  className,
  onClick,
}) => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // Component mounted
    console.log('${COMPONENT_NAME} mounted');

    return () => {
      // Component unmounted
      console.log('${COMPONENT_NAME} unmounted');
    };
  }, []);

  const handleClick = () => {
    setCount((prev) => prev + 1);
    onClick?.();
  };

  return (
    <div className={`${styles.container} ${className || ''}`}>
      <h2>{title}</h2>
      <p>Count: {count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default ${COMPONENT_NAME};
/* ${COMPONENT_NAME}.module.css */
.container {
  padding: 1rem;
  border: 1px solid #ddd;
  border-radius: 8px;
}

.container h2 {
  margin: 0 0 1rem 0;
  font-size: 1.5rem;
}

.container button {
  padding: 0.5rem 1rem;
  background-color: #0070f3;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.container button:hover {
  background-color: #0051cc;
}
// ${COMPONENT_NAME}.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { ${COMPONENT_NAME} } from './${COMPONENT_NAME}';

describe('${COMPONENT_NAME}', () => {
  it('renders with default props', () => {
    render(<${COMPONENT_NAME} />);
    expect(screen.getByText('Default Title')).toBeInTheDocument();
  });

  it('renders with custom title', () => {
    render(<${COMPONENT_NAME} title="Custom Title" />);
    expect(screen.getByText('Custom Title')).toBeInTheDocument();
  });

  it('increments count on button click', () => {
    render(<${COMPONENT_NAME} />);
    const button = screen.getByRole('button', { name: /increment/i });

    expect(screen.getByText('Count: 0')).toBeInTheDocument();
    fireEvent.click(button);
    expect(screen.getByText('Count: 1')).toBeInTheDocument();
  });

  it('calls onClick handler when clicked', () => {
    const handleClick = jest.fn();
    render(<${COMPONENT_NAME} onClick={handleClick} />);

    const button = screen.getByRole('button', { name: /increment/i });
    fireEvent.click(button);

    expect(handleClick).toHaveBeenCalledTimes(1);
  });
});

Phase 3: Next.js Page/Route Boilerplate

// Next.js App Router page
import { Metadata } from 'next';
import { ${COMPONENT_NAME} } from '@/components/${COMPONENT_NAME}';

/**
 * Page metadata
 */
export const metadata: Metadata = {
  title: '${COMPONENT_NAME}',
  description: '${COMPONENT_NAME} page description',
};

/**
 * ${COMPONENT_NAME} page component
 */
export default async function ${COMPONENT_NAME}Page() {
  // Server-side data fetching
  const data = await fetchData();

  return (
    <div>
      <h1>${COMPONENT_NAME}</h1>
      <${COMPONENT_NAME} data={data} />
    </div>
  );
}

/**
 * Fetch data on the server
 */
async function fetchData() {
  // Fetch data from API or database
  const res = await fetch('https://api.example.com/data', {
    next: { revalidate: 3600 }, // Revalidate every hour
  });

  if (!res.ok) {
    throw new Error('Failed to fetch data');
  }

  return res.json();
}
// Next.js API Route
import { NextRequest, NextResponse } from 'next/server';

/**
 * GET /api/${COMPONENT_NAME}
 */
export async function GET(request: NextRequest) {
  try {
    // Get query parameters
    const searchParams = request.nextUrl.searchParams;
    const id = searchParams.get('id');

    // Fetch data
    const data = await fetchData(id);

    return NextResponse.json({
      success: true,
      data,
    });
  } catch (error) {
    console.error('${COMPONENT_NAME} GET error:', error);
    return NextResponse.json(
      { success: false, error: 'Internal server error' },
      { status: 500 }
    );
  }
}

/**
 * POST /api/${COMPONENT_NAME}
 */
export async function POST(request: NextRequest) {
  try {
    const body = await request.json();

    // Validate request body
    if (!body.name) {
      return NextResponse.json(
        { success: false, error: 'Name is required' },
        { status: 400 }
      );
    }

    // Process data
    const result = await createData(body);

    return NextResponse.json({
      success: true,
      data: result,
    }, { status: 201 });
  } catch (error) {
    console.error('${COMPONENT_NAME} POST error:', error);
    return NextResponse.json(
      { success: false, error: 'Internal server error' },
      { status: 500 }
    );
  }
}

Phase 4: Express Route Boilerplate

// Express route handler
import { Router, Request, Response, NextFunction } from 'express';
import { body, param, validationResult } from 'express-validator';

const router = Router();

/**
 * ${COMPONENT_NAME} interface
 */
interface ${COMPONENT_NAME} {
  id: string;
  name: string;
  createdAt: Date;
}

/**
 * GET /api/${COMPONENT_NAME}
 * List all ${COMPONENT_NAME}s
 */
router.get(
  '/',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { page = 1, limit = 10, search } = req.query;

      // Fetch data from database
      const items = await db.${COMPONENT_NAME}.findMany({
        where: search ? { name: { contains: search as string } } : {},
        skip: (Number(page) - 1) * Number(limit),
        take: Number(limit),
      });

      const total = await db.${COMPONENT_NAME}.count();

      res.json({
        data: items,
        pagination: {
          page: Number(page),
          limit: Number(limit),
          total,
          totalPages: Math.ceil(total / Number(limit)),
        },
      });
    } catch (error) {
      next(error);
    }
  }
);

/**
 * GET /api/${COMPONENT_NAME}/:id
 * Get ${COMPONENT_NAME} by ID
 */
router.get(
  '/:id',
  param('id').isUUID(),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
      }

      const item = await db.${COMPONENT_NAME}.findUnique({
        where: { id: req.params.id },
      });

      if (!item) {
        return res.status(404).json({ error: '${COMPONENT_NAME} not found' });
      }

      res.json({ data: item });
    } catch (error) {
      next(error);
    }
  }
);

/**
 * POST /api/${COMPONENT_NAME}
 * Create new ${COMPONENT_NAME}
 */
router.post(
  '/',
  body('name').isString().trim().isLength({ min: 1, max: 255 }),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
      }

      const item = await db.${COMPONENT_NAME}.create({
        data: {
          name: req.body.name,
        },
      });

      res.status(201).json({ data: item });
    } catch (error) {
      next(error);
    }
  }
);

/**
 * PUT /api/${COMPONENT_NAME}/:id
 * Update ${COMPONENT_NAME}
 */
router.put(
  '/:id',
  param('id').isUUID(),
  body('name').isString().trim().isLength({ min: 1, max: 255 }),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
      }

      const item = await db.${COMPONENT_NAME}.update({
        where: { id: req.params.id },
        data: { name: req.body.name },
      });

      res.json({ data: item });
    } catch (error) {
      next(error);
    }
  }
);

/**
 * DELETE /api/${COMPONENT_NAME}/:id
 * Delete ${COMPONENT_NAME}
 */
router.delete(
  '/:id',
  param('id').isUUID(),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
      }

      await db.${COMPONENT_NAME}.delete({
        where: { id: req.params.id },
      });

      res.status(204).send();
    } catch (error) {
      next(error);
    }
  }
);

export default router;

Phase 5: FastAPI Route Boilerplate

# FastAPI route handler
from fastapi import APIRouter, HTTPException, Query, Path
from pydantic import BaseModel, Field
from typing import List, Optional
from datetime import datetime
import uuid

router = APIRouter(
    prefix="/api/${COMPONENT_NAME}",
    tags=["${COMPONENT_NAME}"],
)

class ${COMPONENT_NAME}Base(BaseModel):
    """Base ${COMPONENT_NAME} schema"""
    name: str = Field(..., min_length=1, max_length=255)

class ${COMPONENT_NAME}Create(${COMPONENT_NAME}Base):
    """Schema for creating ${COMPONENT_NAME}"""
    pass

class ${COMPONENT_NAME}Update(${COMPONENT_NAME}Base):
    """Schema for updating ${COMPONENT_NAME}"""
    name: Optional[str] = Field(None, min_length=1, max_length=255)

class ${COMPONENT_NAME}InDB(${COMPONENT_NAME}Base):
    """Schema for ${COMPONENT_NAME} in database"""
    id: str
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True

class PaginatedResponse(BaseModel):
    """Paginated response schema"""
    data: List[${COMPONENT_NAME}InDB]
    total: int
    page: int
    page_size: int
    total_pages: int

@router.get("/", response_model=PaginatedResponse)
async def list_${COMPONENT_NAME}s(
    page: int = Query(1, ge=1),
    page_size: int = Query(10, ge=1, le=100),
    search: Optional[str] = None,
):
    """
    List all ${COMPONENT_NAME}s with pagination

    Args:
        page: Page number (default: 1)
        page_size: Items per page (default: 10, max: 100)
        search: Optional search query

    Returns:
        Paginated list of ${COMPONENT_NAME}s
    """
    try:
        # Query database
        skip = (page - 1) * page_size
        query = db.query(${COMPONENT_NAME})

        if search:
            query = query.filter(${COMPONENT_NAME}.name.contains(search))

        total = query.count()
        items = query.offset(skip).limit(page_size).all()

        return PaginatedResponse(
            data=items,
            total=total,
            page=page,
            page_size=page_size,
            total_pages=(total + page_size - 1) // page_size,
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/{id}", response_model=${COMPONENT_NAME}InDB)
async def get_${COMPONENT_NAME}(
    id: str = Path(..., description="${COMPONENT_NAME} ID"),
):
    """
    Get ${COMPONENT_NAME} by ID

    Args:
        id: ${COMPONENT_NAME} unique identifier

    Returns:
        ${COMPONENT_NAME} object

    Raises:
        HTTPException: 404 if ${COMPONENT_NAME} not found
    """
    item = db.query(${COMPONENT_NAME}).filter(${COMPONENT_NAME}.id == id).first()

    if not item:
        raise HTTPException(status_code=404, detail="${COMPONENT_NAME} not found")

    return item

@router.post("/", response_model=${COMPONENT_NAME}InDB, status_code=201)
async def create_${COMPONENT_NAME}(
    data: ${COMPONENT_NAME}Create,
):
    """
    Create new ${COMPONENT_NAME}

    Args:
        data: ${COMPONENT_NAME} creation data

    Returns:
        Created ${COMPONENT_NAME} object
    """
    try:
        item = ${COMPONENT_NAME}(
            id=str(uuid.uuid4()),
            name=data.name,
            created_at=datetime.utcnow(),
            updated_at=datetime.utcnow(),
        )
        db.add(item)
        db.commit()
        db.refresh(item)
        return item
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))

@router.put("/{id}", response_model=${COMPONENT_NAME}InDB)
async def update_${COMPONENT_NAME}(
    id: str = Path(..., description="${COMPONENT_NAME} ID"),
    data: ${COMPONENT_NAME}Update = None,
):
    """
    Update ${COMPONENT_NAME}

    Args:
        id: ${COMPONENT_NAME} unique identifier
        data: Update data

    Returns:
        Updated ${COMPONENT_NAME} object

    Raises:
        HTTPException: 404 if ${COMPONENT_NAME} not found
    """
    item = db.query(${COMPONENT_NAME}).filter(${COMPONENT_NAME}.id == id).first()

    if not item:
        raise HTTPException(status_code=404, detail="${COMPONENT_NAME} not found")

    update_data = data.dict(exclude_unset=True)
    for key, value in update_data.items():
        setattr(item, key, value)

    item.updated_at = datetime.utcnow()
    db.commit()
    db.refresh(item)
    return item

@router.delete("/{id}", status_code=204)
async def delete_${COMPONENT_NAME}(
    id: str = Path(..., description="${COMPONENT_NAME} ID"),
):
    """
    Delete ${COMPONENT_NAME}

    Args:
        id: ${COMPONENT_NAME} unique identifier

    Raises:
        HTTPException: 404 if ${COMPONENT_NAME} not found
    """
    item = db.query(${COMPONENT_NAME}).filter(${COMPONENT_NAME}.id == id).first()

    if not item:
        raise HTTPException(status_code=404, detail="${COMPONENT_NAME} not found")

    db.delete(item)
    db.commit()
    return None

Summary

echo ""
echo "=== ✓ Boilerplate Generation Complete ==="
echo ""
echo "📁 Generated files for $FRAMEWORK:"

case $FRAMEWORK in
    react)
        echo "  - src/components/${COMPONENT_NAME}/${COMPONENT_NAME}.tsx"
        echo "  - src/components/${COMPONENT_NAME}/${COMPONENT_NAME}.module.css"
        echo "  - src/components/${COMPONENT_NAME}/${COMPONENT_NAME}.test.tsx"
        ;;
    nextjs)
        echo "  - app/${COMPONENT_NAME}/page.tsx"
        echo "  - app/api/${COMPONENT_NAME}/route.ts"
        ;;
    express)
        echo "  - src/routes/${COMPONENT_NAME}.routes.ts"
        echo "  - src/controllers/${COMPONENT_NAME}.controller.ts"
        ;;
    fastapi)
        echo "  - app/routes/${COMPONENT_NAME}.py"
        echo "  - app/schemas/${COMPONENT_NAME}.py"
        ;;
esac

echo ""
echo "✓ Includes:"
echo "  - TypeScript/type definitions"
echo "  - Input validation"
echo "  - Error handling"
echo "  - JSDoc/docstrings"
echo "  - Unit tests"
echo ""
echo "🚀 Next steps:"
echo "  1. Review and customize generated code"
echo "  2. Update business logic"
echo "  3. Add database integration"
echo "  4. Run tests: npm test"

Best Practices

Code Quality:

  • Follow framework conventions
  • Include comprehensive types
  • Add proper error handling
  • Write meaningful documentation

Integration Points:

  • /test – Generate tests for boilerplate
  • /scaffold – Complete feature scaffolding
  • /inline-docs – Add documentation

What I’ll Actually Do

  1. Detect framework – Identify project type
  2. Parse arguments – Component name and type
  3. Generate boilerplate – Framework-specific code
  4. Include tests – Unit/integration tests
  5. Add documentation – JSDoc/docstrings
  6. Follow conventions – Framework best practices

Important: I will NEVER add AI attribution.

Credits: Boilerplate patterns based on Create React App, Next.js, Express.js, FastAPI, and framework documentation best practices.