Skip to content

Latest commit

 

History

History
160 lines (127 loc) · 6.34 KB

File metadata and controls

160 lines (127 loc) · 6.34 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

AutoRouter is an AI API Gateway providing API Key distribution, multi-upstream routing, and request management. It's a Next.js fullstack application with API Routes for the backend.

Development Commands

# Install dependencies
pnpm install

# Run development server
pnpm dev

# Build
pnpm build

# Database commands (Drizzle ORM)
pnpm db:generate    # Generate migrations from schema changes
pnpm db:migrate     # Apply migrations
pnpm db:push        # Push schema directly (development)
pnpm db:studio      # Open Drizzle Studio

# Linting & formatting
pnpm lint           # ESLint
pnpm format         # Prettier format
pnpm format:check   # Check formatting
pnpm exec tsc --noEmit  # Type checking

# Testing
pnpm test           # Run tests (watch mode)
pnpm test:run       # Run tests once
pnpm test:run --coverage  # Run with coverage

Architecture

Project Structure

src/
├── app/
│   ├── api/                 # Next.js API Routes (backend)
│   │   ├── admin/           # Admin API endpoints
│   │   │   ├── keys/        # API key management
│   │   │   ├── upstreams/   # Upstream management
│   │   │   ├── circuit-breakers/  # Circuit breaker management
│   │   │   ├── stats/       # Statistics endpoints
│   │   │   └── logs/        # Request logs
│   │   ├── proxy/v1/        # AI proxy endpoint
│   │   └── health/          # Health check
│   ├── [locale]/            # Internationalized routes (next-intl)
│   │   ├── (auth)/          # Login page (route group)
│   │   └── (dashboard)/     # Protected dashboard pages
│   └── layout.tsx           # Root layout with providers
├── components/              # React components (shadcn/ui based)
├── hooks/                   # Custom React hooks (TanStack Query)
├── lib/
│   ├── db/                  # Database (Drizzle ORM)
│   │   ├── schema.ts        # Table definitions
│   │   └── index.ts         # Database client
│   ├── services/            # Business logic
│   │   ├── key-manager.ts   # API key CRUD
│   │   ├── upstream-service.ts  # Upstream service (re-exports from focused modules)
│   │   ├── upstream-crud.ts     # Upstream database CRUD operations
│   │   ├── upstream-connection-tester.ts  # Upstream connection testing
│   │   ├── upstream-ssrf-validator.ts     # SSRF protection (IP/URL/DNS validation)
│   │   ├── proxy-client.ts  # HTTP proxy with SSE support
│   │   ├── request-logger.ts    # Request logging
│   │   ├── stats-service.ts     # Statistics aggregation
│   │   ├── circuit-breaker.ts   # Circuit breaker state machine
│   │   ├── load-balancer.ts     # Load balancing strategies
│   │   ├── model-router.ts      # Model-based auto routing
│   │   └── health-checker.ts    # Health monitoring
│   └── utils/               # Utility functions
│       ├── auth.ts          # Authentication (bcrypt)
│       ├── encryption.ts    # Fernet encryption
│       └── config.ts        # Environment configuration
├── i18n/                    # next-intl configuration
├── messages/                # Translation JSON files (en, zh)
├── providers/               # React context providers
└── types/                   # TypeScript type definitions

Key Architectural Patterns

  1. Upstream Management: Upstreams (AI providers like OpenAI, Anthropic) stored in PostgreSQL database. Runtime selection via model-based auto-routing (e.g., gpt-_ → openai group, claude-_ → anthropic group).

  2. Security Model:

    • Admin authentication: Bearer token (ADMIN_TOKEN env var)
    • API key authentication: Client keys hashed with bcrypt, verified on proxy requests
    • Upstream keys: Encrypted at rest with Fernet (ENCRYPTION_KEY env var)
  3. Proxy Flow: /api/proxy/v1/* receives requests → validates API key → extracts model from request body → routes to upstream group based on model prefix → selects upstream → forwards via proxy-client → logs request → returns SSE stream or response

  4. Failover & Circuit Breaker: Automatic failover with circuit breaker pattern:

    • Circuit Breaker States: CLOSED (normal), OPEN (failing), HALF_OPEN (probing)
    • Auto-failover: On timeout/5xx errors, retry with next available upstream
    • Health Monitoring: Background health checks mark upstreams healthy/unhealthy
    • Decision Logging: Failover attempts logged with error type and timestamp
    • Admin Control: API endpoints to force circuit breaker open/closed
  5. Database: PostgreSQL with Drizzle ORM. Schema defined in src/lib/db/schema.ts.

Configuration

Environment Variables (.env)

# Required
DATABASE_URL=postgresql://user:password@localhost:5432/autorouter
ENCRYPTION_KEY=<base64-32-bytes>  # Generate: node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
ADMIN_TOKEN=<admin-token>         # Admin API authentication

# Optional
ALLOW_KEY_REVEAL=false            # Allow revealing API keys
LOG_RETENTION_DAYS=90             # Request log retention
CORS_ORIGINS=http://localhost:3000

Docker Deployment

# Build and run with docker-compose
docker-compose up -d

# Or build manually
docker build -t autorouter .
docker run -p 3000:3000 \
  -e DATABASE_URL=postgresql://... \
  -e ENCRYPTION_KEY=... \
  -e ADMIN_TOKEN=... \
  autorouter

Code Quality Standards

  • TypeScript: ESLint + Prettier, strict mode
  • Database: Drizzle ORM with typed schema
  • Testing: Vitest for unit tests
  • CI: GitHub Actions run lint and test workflows on all PRs

Common Development Tasks

Adding a New API Endpoint

  1. Create route in src/app/api/admin/{endpoint}/route.ts
  2. Add service logic in src/lib/services/
  3. Update types in src/types/api.ts if needed
  4. Write tests in tests/

Adding a New Frontend Page

  1. Create route in src/app/[locale]/(dashboard)/
  2. Add translations in src/messages/{en,zh}.json
  3. Create components in src/components/
  4. Add API hooks using TanStack Query patterns from src/hooks/