This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
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.
# 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 coveragesrc/
├── 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
-
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).
-
Security Model:
- Admin authentication: Bearer token (
ADMIN_TOKENenv var) - API key authentication: Client keys hashed with bcrypt, verified on proxy requests
- Upstream keys: Encrypted at rest with Fernet (
ENCRYPTION_KEYenv var)
- Admin authentication: Bearer token (
-
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 -
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
-
Database: PostgreSQL with Drizzle ORM. Schema defined in
src/lib/db/schema.ts.
# 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# 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- 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
- Create route in
src/app/api/admin/{endpoint}/route.ts - Add service logic in
src/lib/services/ - Update types in
src/types/api.tsif needed - Write tests in
tests/
- Create route in
src/app/[locale]/(dashboard)/ - Add translations in
src/messages/{en,zh}.json - Create components in
src/components/ - Add API hooks using TanStack Query patterns from
src/hooks/