Skip to content

Contributing

This guide covers how to set up a development environment, run the test suite, and contribute code to Gatewyse. These are internal contribution guidelines for team members working on the product.

Development Setup

Prerequisites

  • Node.js 24.0.0 or later
  • pnpm 10.0.0 or later
  • Docker and Docker Compose (for MongoDB, Redis, and integration tests)

Clone and Install

Terminal window
git clone <repository-url>
cd ai-gateway
pnpm install

Start Infrastructure

Launch MongoDB and Redis using Docker Compose:

Terminal window
docker compose -f docker/docker-compose.yml up -d

This starts:

  • MongoDB on port 27017 (with initialization script at docker/mongo-init.js)
  • Redis on port 6379

Build the Shared and License Packages

The shared package must be built before other packages, since they depend on its compiled output. The license package must be built before the server, because the server’s tsconfig resolves @ai-gateway/license from ../license/dist:

Terminal window
pnpm build:shared
pnpm --filter @ai-gateway/license build
pnpm build:server

Start Development Servers

Run all services in development mode:

Terminal window
pnpm dev

Or run them individually:

Terminal window
pnpm dev:server # Express API on port 3000
pnpm dev:worker # BullMQ worker
pnpm dev:admin # Nuxt admin dashboard on port 3001

Running Tests

The project has four test tiers with approximately 1074 total tests. Counts are grep-based estimates (it(/test( matches) and the exact totals shift slightly with describe.each and table-driven cases — run the suites if you need ground-truth numbers.

Unit Tests (~854 tests)

Fast, isolated tests with no external dependencies:

Terminal window
pnpm test:unit

Unit tests are located in tests/unit/ and use Jest. They cover services, adapters, utilities, and middleware.

Integration Tests (46 tests)

Tests that require MongoDB and Redis:

Terminal window
# Start test infrastructure
pnpm test:integration:up
# Run integration tests
pnpm test:integration
# Tear down test infrastructure
pnpm test:integration:down

Integration tests use docker/docker-compose.test.yml with isolated test databases. They run sequentially (--runInBand) to avoid port conflicts.

End-to-End Tests (~174 tests)

Playwright tests for the admin dashboard:

Terminal window
pnpm --filter @ai-gateway/admin test:e2e

E2E tests are located in packages/admin/e2e/ and test the full admin dashboard UI with mocked API responses. The admin runs in SPA mode (ssr: false), so Pinia auth state is in-memory and page.goto resets state.

Navigation in E2E tests uses sidebar clicks rather than direct URL navigation to match real user behavior.

Smoke Tests (6 phases)

Live tests against a running server:

Terminal window
npx tsx tests/smoke/run.ts

Smoke tests run in six sequential phases:

  1. Infrastructure — Verify server health, MongoDB, and Redis connectivity
  2. Authentication — Test login, token refresh, and API key validation
  3. CRUD — Test admin API resource management (tenants, users, providers, models, etc.)
  4. Gateway Setup — Configure providers and routing for live testing
  5. Live Gateway — Send actual requests through configured providers
  6. Advanced — Test semantic cache, budget enforcement, and guard pipeline

Configuration is in tests/smoke/.env.smoke.

Code Structure

Package Conventions

packages/
+-- shared/src/
| +-- types/ # TypeScript interfaces and type definitions
| +-- schemas/ # Zod validation schemas
| +-- utils/ # Shared utility functions
| +-- errors/ # AppError class and error codes
+-- server/src/
| +-- config/ # Environment, Redis, and database configuration
| +-- middleware/ # Express middleware (auth, rate limiting, etc.)
| +-- models/ # Mongoose models and schemas
| +-- providers/ # Provider adapter implementations (38 adapters)
| +-- routes/ # Express route handlers
| +-- services/ # Business logic services
| +-- utils/ # Server-specific utilities
+-- worker/src/ # BullMQ job processors
+-- admin/
+-- app/ # Nuxt 4 application (pages, components, stores)
+-- e2e/ # Playwright E2E tests

Development Pattern

The codebase follows a layered pattern for new features:

  1. Types — Define interfaces in packages/shared/src/types/
  2. Zod Schema — Add validation schemas in packages/shared/src/schemas/
  3. Model — Create Mongoose model in packages/server/src/models/
  4. Service — Implement business logic in packages/server/src/services/
  5. Route — Add Express routes in packages/server/src/routes/
  6. Tests — Write unit tests in tests/unit/, integration tests in tests/integration/

Linting and Formatting

Terminal window
pnpm lint # ESLint with auto-fix
pnpm format # Prettier formatting
pnpm typecheck # TypeScript type checking across all packages

CI Pipeline

GitHub Actions runs the following on every pull request:

  1. Lint — ESLint checks
  2. Typecheck — TypeScript compilation
  3. Build — Full monorepo build
  4. Unit Tests — All ~854 unit tests
  5. Integration Tests — All 46 integration tests with Docker services

PR Process

  1. Create a feature branch from main.
  2. Make your changes following the development pattern above.
  3. Ensure all tests pass locally: pnpm lint && pnpm typecheck && pnpm test:unit.
  4. Write tests for new functionality. Aim to cover both success and error paths.
  5. Open a pull request against main with a clear description of the change.
  6. CI must pass before merge.

Commit Message Style

Use conventional commit format:

  • feat: — New feature
  • fix: — Bug fix
  • refactor: — Code restructuring without behavior change
  • test: — Adding or updating tests
  • docs: — Documentation changes
  • chore: — Build, CI, dependency updates

Next Steps