# Contributing to OmniRoute Thank you for your interest in contributing! This guide covers everything you need to get started. --- ## Development Setup ### Prerequisites - **Node.js** 20+ (recommended: 22 LTS) - **npm** 10+ - **Git** ### Clone & Install ```bash git clone https://github.com/diegosouzapw/OmniRoute.git cd OmniRoute npm install ``` ### Environment Variables ```bash # Create your .env from the template cp .env.example .env # Generate required secrets echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env ``` Key variables for development: | Variable | Development Default | Description | | ---------------------- | ----------------------- | ------------------------- | | `PORT` | `3000` | Server port | | `NEXT_PUBLIC_BASE_URL` | `http://localhost:3000` | Base URL for frontend | | `JWT_SECRET` | (generate above) | JWT signing secret | | `INITIAL_PASSWORD` | `123456` | First login password | | `ENABLE_REQUEST_LOGS` | `false` | Enable debug request logs | ### Running Locally ```bash # Development mode (hot reload) npm run dev # Production build npm run build npm run start # Common port configuration PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev ``` Default URLs: - **Dashboard**: `http://localhost:3000/dashboard` - **API**: `http://localhost:3000/v1` --- ## Git Workflow > ⚠️ **NEVER commit directly to `main`.** Always use feature branches. ```bash git checkout -b feat/your-feature-name # ... make changes ... git commit -m "feat: describe your change" git push -u origin feat/your-feature-name # Open a Pull Request on GitHub ``` ### Branch Naming | Prefix | Purpose | | ----------- | ------------------------- | | `feat/` | New features | | `fix/` | Bug fixes | | `refactor/` | Code restructuring | | `docs/` | Documentation changes | | `test/` | Test additions/fixes | | `chore/` | Tooling, CI, dependencies | ### Commit Messages Follow [Conventional Commits](https://www.conventionalcommits.org/): ``` feat: add circuit breaker for provider calls fix: resolve JWT secret validation edge case docs: update SECURITY.md with PII protection test: add observability unit tests refactor(db): consolidate rate limit tables ``` Scopes: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`. --- ## Running Tests ```bash # All unit tests npm test npm run test:unit # Specific test suites npm run test:security # Security tests npm run test:fixes # Fix verification tests # With coverage npm run test:coverage # E2E tests (requires Playwright) npm run test:e2e # Lint + format check npm run lint npm run check ``` Current test status: **368+ unit tests** covering: - Provider translators and format conversion - Rate limiting, circuit breaker, and resilience - Semantic cache, idempotency, progress tracking - Database operations and schema - OAuth flows and authentication - API endpoint validation --- ## Code Style - **ESLint** — Run `npm run lint` before committing - **Prettier** — Auto-formatted via `lint-staged` on commit - **TypeScript** — All `src/` code uses `.ts`/`.tsx`; document with TSDoc (`@param`, `@returns`, `@throws`) - **No `eval()`** — ESLint enforces `no-eval`, `no-implied-eval`, `no-new-func` - **Zod validation** — Use Zod schemas for API input validation --- ## Project Structure ``` src/ # TypeScript (.ts / .tsx) ├── app/ # Next.js App Router │ ├── (dashboard)/ # Dashboard pages (.tsx) │ ├── api/ # API routes (.ts) │ └── login/ # Auth pages (.tsx) ├── domain/ # Domain types and response helpers (.ts) ├── lib/ # Core business logic (.ts) │ ├── db/ # SQLite database layer │ ├── oauth/ # OAuth services per provider │ ├── cacheLayer.ts # LRU cache │ ├── semanticCache.ts # Semantic response cache │ ├── idempotencyLayer.ts # Request deduplication │ └── localDb.ts # Settings facade (LowDB for config, SQLite for domain data) ├── shared/ │ ├── components/ # React components (.tsx) │ ├── middleware/ # Correlation IDs, etc. │ ├── utils/ # Circuit breaker, sanitizer, etc. │ └── validation/ # Zod schemas └── sse/ # SSE chat handlers (.ts) open-sse/ # @omniroute/open-sse workspace (JavaScript) ├── handlers/ # chatCore.js — main request handler ├── services/ # Rate limit, fallback ├── translators/ # Format converters (OpenAI ↔ Claude ↔ Gemini) └── utils/ # Progress tracker, stream helpers tests/ ├── unit/ # Node.js test runner (.test.mjs) └── e2e/ # Playwright tests docs/ # Documentation ├── USER_GUIDE.md # Provider setup, CLI integration ├── API_REFERENCE.md # All endpoints ├── TROUBLESHOOTING.md # Common issues ├── ARCHITECTURE.md # System architecture └── adr/ # Architecture Decision Records ``` --- ## Adding a New Provider ### Step 1: OAuth Service (if using OAuth) Create `src/lib/oauth/services/your-provider.ts` extending `OAuthService`: ```typescript import { OAuthService } from "../OAuthService"; export class YourProviderService extends OAuthService { constructor() { super({ name: "your-provider", authUrl: "https://provider.com/oauth/authorize", tokenUrl: "https://provider.com/oauth/token", clientId: "...", scopes: ["..."], }); } } ``` ### Step 2: Register Provider Add to `src/lib/oauth/providers.ts`: ```typescript import { YourProviderService } from "./services/your-provider"; // Add to the providers map ``` ### Step 3: Add Constants Add provider constants in `src/lib/providerConstants.ts`: - Provider prefix (e.g., `yp/`) - Default models - Pricing info ### Step 4: Add Translator (if non-OpenAI format) Create translator in `open-sse/translators/` if the provider uses a custom API format. ### Step 5: Add Timeout Add request timeout configuration in `src/shared/utils/requestTimeout.ts`. ### Step 6: Add Tests Write unit tests in `tests/unit/` covering at minimum: - Provider registration - Request/response translation - Error handling --- ## Pull Request Checklist - [ ] Tests pass (`npm test`) - [ ] Linting passes (`npm run lint`) - [ ] Build succeeds (`npm run build`) - [ ] TypeScript types added for new public functions and interfaces - [ ] No hardcoded secrets or fallback values - [ ] CHANGELOG updated (if user-facing change) - [ ] Documentation updated (if applicable) --- ## Releasing When a new GitHub Release is created (e.g. `v0.4.0`), the package is **automatically published to npm** via GitHub Actions: ```bash gh release create v0.4.0 --title "v0.4.0" --generate-notes ``` --- ## Getting Help - **Architecture**: See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) - **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) - **ADRs**: See `docs/adr/` for architectural decision records