# OmniRoute Database Migrations and Domain Module Structure: Complete Developer Guide

> Explore OmniRoute's 84 SQLite database migrations and clean architecture domain module structure. Understand schema evolution and business logic organization in this developer guide.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: developer-guide
- Published: 2026-08-16

---

**OmniRoute manages database schema evolution through 84 version-controlled SQLite migrations in `src/lib/db/migrations/` and organizes business logic into clean-architecture domain modules under `src/domain/`.**

This guide examines how OmniRoute's migration system and domain layer work together to provide a reliable foundation for LLM routing, quota management, and provider resilience. We'll analyze the actual source code from the `release/v3.8.50` branch to understand the schema design patterns and domain module implementation.

## How OmniRoute Database Migrations Work

The migration system in OmniRoute follows a strict **lexical ordering convention** that ensures deterministic schema evolution across all deployment nodes.

### Migration File Naming and Location

All migrations reside in `src/lib/db/migrations/` and use the pattern `###_description.sql`:

```bash
src/lib/db/migrations/
├── 001_initial_schema.sql
├── 002_mcp_a2a_tables.sql
├── 003_provider_node_custom_paths.sql
...
├── 088_quota_groups.sql
├── 093_proxy_enable_toggles.sql
└── 126_reasoning_routing_rules.sql

```

The three-digit numeric prefix controls execution order. Gaps in numbering are intentional, allowing future migrations to insert between existing versions without renaming files.

### Key Migrations by Feature Area

From the 84 migration files in the current release, these core migrations establish OmniRoute's data model:

| Migration | Tables/Features Created |
|-----------|------------------------|
| [`001_initial_schema.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/001_initial_schema.sql) | `providers`, `api_keys`, `model_capability_overrides`, foundational routing tables |
| [`002_mcp_a2a_tables.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/002_mcp_a2a_tables.sql) | MCP/A2A messaging framework tables |
| [`003_provider_node_custom_paths.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/003_provider_node_custom_paths.sql) | Provider-specific path routing configuration |
| [`010_model_combo_mappings.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/010_model_combo_mappings.sql) | `combo_call_log_targets`, `combo_sort_order` for multi-model routing |
| [`014_unified_log_artifacts.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/014_unified_log_artifacts.sql) | Consolidated observability schema |
| [`025_call_logs_summary_storage.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/025_call_logs_summary_storage.sql) | Optimized call log aggregation |
| [`040_oneproxy_proxy_fields.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/040_oneproxy_proxy_fields.sql) | One-proxy abstraction layer |
| [`058_command_code_auth_sessions.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/058_command_code_auth_sessions.sql) | Command-code session authentication |
| [`070_webhooks_kind_metadata.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/070_webhooks_kind_metadata.sql) | Webhook `kind` and metadata extensions |
| [`079_provider_plans.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/079_provider_plans.sql) | Provider plan configuration tables |
| [`088_quota_groups.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/088_quota_groups.sql) | `quota_pools`, `quota_groups`, `quota_consumption` tables |
| [`093_proxy_enable_toggles.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/093_proxy_enable_toggles.sql) | Per-provider proxy activation flags |
| [`126_reasoning_routing_rules.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/126_reasoning_routing_rules.sql) | Latest reasoning engine routing rules |

### Migration Runner Implementation

The [`src/lib/db/migrationRunner.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/migrationRunner.ts) file implements transactional, idempotent schema upgrades:

```ts
import { runMigrations } from '@/lib/db/migrationRunner';

async function initDatabase() {
  await runMigrations();
}
initDatabase();

```

The runner executes each migration within a **SQLite transaction** and records progress in the `schema_migrations` table. This design guarantees:

- **Atomicity**: Failed migrations roll back completely
- **Idempotency**: Applied migrations are skipped on subsequent runs
- **Cluster convergence**: All nodes reach identical schema states

## OmniRoute Domain Module Architecture

Domain modules in `src/domain/` implement **clean architecture principles**, isolating business logic from infrastructure concerns. Each module operates on tables defined by the migration layer.

### Core Domain Files and Responsibilities

#### [`src/domain/types.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/domain/types.ts) — Shared TypeScript Interfaces

Defines the contracts used across all domain modules, including request/response shapes and internal model types. This file establishes type safety between the database layer and business logic.

#### [`src/domain/policyEngine.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/domain/policyEngine.ts) — Request Validation

Evaluates cost rules, lock-out policies, and fallback strategies before dispatch:

```ts
import { evaluatePolicy } from '@/domain/policyEngine';
import { getDbInstance } from '@/lib/db/core';

async function canProceed(request) {
  const db = getDbInstance();
  const result = await evaluatePolicy(db, request);
  return result.allowed;
}

```

The policy engine queries tables established by migrations `001`, `058`, and `126` to make routing decisions.

#### [`src/domain/comboResolver.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/domain/comboResolver.ts) — Multi-Model Routing

Resolves "combo" requests into ordered target model lists using `combo_call_log_targets` and `combo_sort_order` tables (migration `010`).

#### [`src/domain/quotaCache.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/domain/quotaCache.ts) — Rate Limit Enforcement

Reads from migration `088`'s quota tables to enforce limits:

- `quota_pools` — Aggregate capacity allocation
- `quota_groups` — Per-tenant or per-key groupings
- `quota_consumption` — Real-time usage tracking

#### [`src/domain/modelAvailability.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/domain/modelAvailability.ts) — Capability Filtering

Checks whether models can handle specific requests by querying:

- `model_capability_overrides` (migration `001`)
- `model_intelligence` (migration `001`)

```ts
import { getModelOverrides } from '@/domain/modelAvailability';
import { getDbInstance } from '@/lib/db/core';

async function listOverrides(modelId: string) {
  const db = getDbInstance();
  return await getModelOverrides(db, modelId);
}

```

### Resilience Domain Modules

OmniRoute implements a **three-layer resilience mechanism** across dedicated domain modules:

| Module | Purpose | Migration Dependencies |
|--------|---------|------------------------|
| [`fallbackPolicy.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/fallbackPolicy.ts) | Provider fallback chain selection | `provider_breaker_state` |
| [`lockoutPolicy.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/lockoutPolicy.ts) | Model-level lockout enforcement | `connection_runtime_state` |

These modules operate on circuit breaker and cooldown tables introduced in earlier migrations.

### Assessment and Self-Healing Framework

The `src/domain/assessment/` subdirectory contains:

- [`selfHealer.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/selfHealer.ts) — Automated recovery from routing failures
- Categorization logic for audit table analysis

These utilities operate on audit schema generated by [`assessment_migration.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/assessment_migration.sql).

## How Migrations and Domain Modules Integrate

The architecture enforces a **unidirectional dependency**: domain modules import from `src/lib/db/` but migrations never reference domain code.

### Schema-to-Code Mapping Example

Migration [`088_quota_groups.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/088_quota_groups.sql) creates quota tables → [`quotaCache.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/quotaCache.ts) provides typed access:

```

Migration Layer (DDL)          Domain Layer (Business Logic)
─────────────────────          ─────────────────────────────
quota_groups  ───────────────>  quotaCache.ts
quota_pools   ───────────────>    ├── getPoolCapacity()
quota_consumption ───────────>    ├── consumeQuota()
                                  └── checkGroupLimits()

```

### Adding New Features: Developer Workflow

When extending OmniRoute, the typical pattern is:

1. **Create migration** in `src/lib/db/migrations/###_feature_name.sql`
2. **Update domain types** in [`src/domain/types.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/domain/types.ts) if new entities are introduced
3. **Implement domain module** or extend existing module in `src/domain/`
4. **Export public API** from domain module for use by handlers and executors

## Migration Best Practices from OmniRoute Source

The `release/v3.8.50` codebase demonstrates several schema evolution patterns:

- **Additive changes only**: No migrations drop columns or tables; deprecation happens in domain logic
- **Index creation**: Separate from table creation, often in dedicated migrations for large tables
- **Data transformations**: Some migrations include `INSERT ... SELECT` statements to populate new columns from existing data
- **Feature flags**: Migrations `093` and later introduce toggles that domain modules check at runtime

## Summary

- **84 SQLite migrations** in `src/lib/db/migrations/` define OmniRoute's schema, numbered `001` through `126` with intentional gaps for future insertions
- **Migration runner** ([`src/lib/db/migrationRunner.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/migrationRunner.ts)) executes files transactionally and tracks state in `schema_migrations`
- **Domain modules** in `src/domain/` implement clean architecture with zero dependencies on the migration layer
- **Core modules**: [`policyEngine.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/policyEngine.ts), [`comboResolver.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/comboResolver.ts), [`quotaCache.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/quotaCache.ts), [`modelAvailability.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/modelAvailability.ts), [`fallbackPolicy.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/fallbackPolicy.ts), [`lockoutPolicy.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/lockoutPolicy.ts)
- **Resilience pattern**: Three-layer circuit breaker implemented across [`fallbackPolicy.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/fallbackPolicy.ts) and [`lockoutPolicy.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/lockoutPolicy.ts)
- **Assessment framework**: Self-healing utilities in `src/domain/assessment/` operate on migration-generated audit tables

## Frequently Asked Questions

### Where are OmniRoute database migrations stored?

All migrations live in `src/lib/db/migrations/` and follow the `###_description.sql` naming pattern. The three-digit prefix ensures lexical execution order. The current release contains 84 migration files ranging from [`001_initial_schema.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/001_initial_schema.sql) to [`126_reasoning_routing_rules.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/126_reasoning_routing_rules.sql).

### How does the migration runner ensure schema consistency across nodes?

The [`migrationRunner.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/migrationRunner.ts) executes each migration within a SQLite transaction and records the applied version in the `schema_migrations` table. On startup, nodes compare their recorded version against available migrations and apply only pending changes. This guarantees all cluster members converge on identical schema states.

### What tables support OmniRoute's quota and rate limiting system?

Migration [`088_quota_groups.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/088_quota_groups.sql) introduced `quota_pools`, `quota_groups`, and `quota_consumption` tables. The [`quotaCache.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/quotaCache.ts) domain module provides typed access to these tables, implementing per-key and per-provider limit enforcement with configurable pool capacities.

### How do domain modules access database tables without tight coupling?

Domain modules import database connections through [`src/lib/db/core.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/core.ts) and use TypeScript interfaces from [`src/domain/types.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/domain/types.ts). The architecture enforces clean separation: migrations define schema (DDL), domain modules implement business logic (DML), and neither layer imports from the other.