Zum Inhalt springen
OmniRoute source

Database Schema & Operations Guide (Deutsch)

OmniRoute hat sich aus mehreren Gründen für SQLite anstelle von PostgreSQL/MySQL entschieden:

Faktor SQLite PostgreSQL
Bereitstellung Eingebettet — kein separater Server Erfordert die Einrichtung eines Servers
Verschlüsselung Anwendungsebene (AES-256-GCM) Integrierte TDE
Leistung Schneller bei kleinen/mittleren Workloads Besser für sehr viele gleichzeitige Schreibvorgänge
Nebenläufigkeit WAL-Modus ermöglicht gleichzeitige Lesevorgänge Vollständiges MVCC
Sicherung Kopie einer einzelnen Datei pg_dump oder Dateisystem-Snapshot
Anwendungsfall Installation pro Benutzer, eingebettet Mandantenfähiges SaaS

Für Bereitstellungen mit einem Benutzer und einer einzelnen Instanz (der primäre Anwendungsfall von OmniRoute) ist SQLite einfacher und schneller.

core.ts öffnet die Datenbank im WAL-Modus (Write-Ahead Logging):

src/lib/db/core.ts
db.pragma("journal_mode = WAL");
db.pragma("busy_timeout = 2000");
db.pragma("synchronous = NORMAL");
db.pragma(`cache_size = -${DEFAULT_DATABASE_SETTINGS.optimization.cacheSize}`);

WAL ermöglicht gleichzeitige Lesevorgänge während Schreibvorgängen — wichtig für das Dashboard, das Abfragen ausführt, während Anfragen aufgezeichnet werden.

Die standardmäßige Cache-Größe beträgt 65.536 KiB (64 MiB). SQLite interpretiert einen negativen cache_size-Wert als ungefähre Obergrenze in KiB und weist Seiten nach Bedarf zu. Unter Einstellungen > System & Speicher > Cache-Größe werden Ganzzahlwerte von 1 bis 1.000.000 KiB akzeptiert; beim Speichern der Einstellung wird sie auf die aktive Datenbankverbindung angewendet, und OmniRoute stellt den gespeicherten Wert beim Start wieder her.


Die SQLite-Datei wird hier gespeichert:

Betriebssystem Pfad
Linux ~/.omniroute/storage.sqlite
macOS ~/.omniroute/storage.sqlite
Windows %USERPROFILE%\.omniroute\storage.sqlite
Docker /app/data/storage.sqlite (konfigurierbar über DATA_DIR)

Zugehörige Dateien:

  • storage.sqlite-wal — Write-Ahead-Log
  • storage.sqlite-shm — Shared-Memory-Datei
  • call_logs/ — Artefakte von Anfrage-Payloads (sofern aktiviert)

Speicherort überschreiben:

Terminal-Fenster
DATA_DIR=/custom/path omniroute

Die Datenbank von OmniRoute umfasst 110 TypeScript-Module auf oberster Ebene in src/lib/db/. Jedes Domänenmodul:

  • Ist für eine oder mehrere bestimmte Tabellen zuständig
  • Exportiert typisierte CRUD-Funktionen
  • Greift niemals auf die Tabellen eines anderen Moduls zu
  • Verwendet getDbInstance() aus core.ts, um auf die Datenbank zuzugreifen

OmniRoute verfügt über 110 TypeScript-Dateien auf oberster Ebene in src/lib/db/. Nachfolgend finden Sie eine Auswahl der Kernmodule; die vollständige Liste finden Sie in der Verzeichnisauflistung:

Modul Tabellen Zuständigkeit
providers.ts provider_connections Registrierung und Anmeldedaten von Anbietern per OAuth/API-Schlüssel
models.ts key_value (Modelldaten) Modelldefinitionen, Fähigkeiten und Preise
combos.ts combos Konfigurationen und Reihenfolge des Combo-Routings
apiKeys.ts api_keys Lebenszyklus von API-Schlüsseln, Geltungsbereiche und Kontingentverfolgung
settings.ts key_value, api_keys, combos Systemkonfiguration und gemeinsam genutzter KV-Speicher
backup.ts — Operationen zum Exportieren und Importieren von Sicherungen
proxies.ts proxy_registry, proxy_assignments, provider_connections Proxy-Konfigurationen und Routing-Regeln
prompts.ts prompt_templates Wiederverwendbare Prompt-Vorlagen und Versionierung
webhooks.ts webhooks Ereignisgesteuerte Webhook-Abonnements und Protokolle
detailedLogs.ts request_detail_logs Audit-Protokollierung pro Anfrage (optional, hohes Volumen)
domainState.ts domain_* (5 Tabellen) Domänenbudgets, Leistungsschalter, Sperren, Fallback-Ketten und Kostenverlauf
registeredKeys.ts registered_keys, account_key_limits, provider_key_limits Zulässige API-Schlüssel für MCP/A2A
quotaSnapshots.ts quota_snapshots Historische Kontingentnutzung
modelComboMappings.ts model_combo_mappings Zuordnung von Modellen zu Combo-Standardeinstellungen
cliToolState.ts cli_tool_state CLI-spezifischer persistenter Zustand
encryption.ts — Hilfsfunktionen zum Ver- und Entschlüsseln von Feldern
readCache.ts — In-Memory-Cache für leseintensive Operationen
secrets.ts key_value (verschlüsselte Einträge) Verschlüsselte Speicherung geheimer Daten
stateReset.ts — Löschen/Zurücksetzen des Datenbankzustands für Tests
contextHandoffs.ts context_handoffs Sitzungskontext für die Übergabe zwischen Agenten
usage*.ts usage_history, call_logs, proxy_logs Nutzungsverfolgung
compression*.ts compression_settings, compression_combos Komprimierungskonfiguration

Eine zentrale Architekturregel lautet: Module greifen nicht direkt auf die Tabellen anderer Module zu. Um mit den Daten eines anderen Moduls zu arbeiten, importieren Sie die Funktion aus diesem Modul.

// ❌ FALSCH: direktes SQL aus einem anderen Modul
db.prepare("SELECT * FROM provider_connections").all();
// ✅ RICHTIG: Funktion des providers-Moduls verwenden
import { listProviders } from "@/lib/db/providers";
const providers = await listProviders();

Diese Regel wird bei Code-Reviews durchgesetzt — es gibt keine statische Prüfung, Verstöße werden jedoch beanstandet.


core.ts definiert die 17 Basistabellen in SCHEMA_SQL. Diese werden durch die Migration 001_initial_schema.sql erstellt und bilden das Kernschema.

Kerntabellen (in der initialen Migration erstellt)

Abschnitt betitelt „Kerntabellen (in der initialen Migration erstellt)“
Tabelle Zweck Schlüsselspalten
provider_connections Provider-Anmeldedaten (verschlüsselt) id, provider, auth_type, api_key, is_active
provider_nodes Routing-Informationen für Provider-Knoten id, type, name, base_url, created_at
key_value Allgemeiner KV-Speicher namespace, key, value
combos Definitionen von Routing-Kombinationen id, name, data, sort_order
api_keys API-Schlüssel für das Gateway id, name, key, machine_id, allowed_models
db_meta Datenbankmetadaten key, value
usage_history Datensätze zur Anfragenutzung id, provider, model, tokens_input, tokens_output, timestamp
call_logs Anfrage-Payloads und Antworten id, timestamp, status, model, provider, latency_ms
proxy_logs Protokolle von Proxy-Anfragen id, timestamp, proxy_type, status, provider
domain_fallback_chains Modell-zu-Provider-Ketten model, chain
domain_budgets Ausgabenbudgets pro Domäne api_key_id, daily_limit_usd, warning_threshold, reset_interval
domain_budget_reset_logs Verlauf der Budgetzurücksetzungen id, api_key_id, reset_interval, previous_spend, reset_at
domain_cost_history Kostenverfolgung pro Domäne id, api_key_id, cost, timestamp
domain_lockout_state Ratenbegrenzungsstatus der Domäne identifier, attempts, locked_until
domain_circuit_breakers Circuit-Breaker-Status pro Domäne name, state, failure_count, last_failure_time
semantic_cache Cache für LLM-Antworten id, signature, model, prompt_hash, response
quota_snapshots Historische Kontingent-Snapshots id, provider, connection_id, window_key, remaining_percentage

Zusätzliche Tabellen (durch spätere Migrationen hinzugefügt)

Abschnitt betitelt „Zusätzliche Tabellen (durch spätere Migrationen hinzugefügt)“

Nachfolgende Migrationen fügen unter anderem folgende Tabellen hinzu:

  • cli_tool_state (Migration 011) — Status des CLI-Tools
  • mcp_*-Tabellen — MCP-Server-Audit
  • a2a_*-Tabellen — A2A-Aufgabenstatus
  • usage_*-Tabellen — Nutzungsverfolgung
  • plugin_*-Tabellen — Plugin-System
  • skill_executions — Ausführungsverlauf von Skills
  • memory_*-Tabellen — Speichersystem
  • compression_*-Tabellen — Komprimierungssystem
  • webhook_*-Tabellen — Webhook-Zustellungsprotokoll
  • acp_*-Tabellen — Agent Client Protocol
  • oneproxy_*-Tabellen — 1proxy-Marktplatz
  • proxy_assignments — Bindungen des Proxy-Gültigkeitsbereichs
  • detailed_call_artifacts — Metadaten zu Artefakten von Aufrufprotokollen
  • quota_alert_history — Audit von Kontingentwarnungen
  • command_code_auth_sessions — Command Code-OAuth-Sitzungen

Die vollständige Liste mit über 30 Tabellen befindet sich in src/lib/db/migrations/.


OmniRoute verwendet versionierte, idempotente Migrationen in src/lib/db/migrations/. Jede Migration ist eine einzelne SQL-Datei mit dem Namen NNN_description.sql.

001_initial_schema.sql
002_mcp_a2a_tables.sql
003_provider_node_custom_paths.sql
...
021_combo_call_log_targets.sql

Beim Start führt migrationRunner.ts folgende Schritte aus:

  1. Erstellt die Tabelle _omniroute_migrations, falls sie nicht existiert
  2. Fragt bereits angewendete Migrationen ab
  3. Wendet alle neuen Migrationen der Reihe nach an, jeweils innerhalb einer Transaktion
  4. Zeichnet jede angewendete Migration mit einem Zeitstempel auf
// src/lib/db/migrationRunner.ts (vereinfacht)
export async function runMigrations(db: SqliteDatabase, migrationsDir: string) {
const applied = getAppliedMigrations(db);
const available = readMigrationFiles(migrationsDir);
for (const migration of available) {
if (applied.includes(migration.id)) continue;
db.transaction(() => {
db.exec(migration.sql);
recordAppliedMigration(db, migration.id);
})();
}
}

Migrationen müssen idempotent sein — eine zweimalige Ausführung sollte keine Auswirkungen haben:

-- 004_proxy_registry.sql
CREATE TABLE IF NOT EXISTS proxy_registry (
id TEXT PRIMARY KEY,
host TEXT NOT NULL,
port INTEGER NOT NULL,
...
);

Verwenden Sie großzügig die Klauseln IF NOT EXISTS, IF EXISTS und OR IGNORE / OR REPLACE.

  1. Nächste Nummer ermitteln: ls src/lib/db/migrations/ | tail -1
  2. Datei erstellen: NNN_my_change.sql
  3. Sicheres DDL verwenden: CREATE TABLE IF NOT EXISTS, ALTER TABLE ... ADD COLUMN
  4. Daten sorgfältig nachpflegen: Verwenden Sie UPDATE ... WHERE ..., um vorhandene Zeilen zu berücksichtigen
  5. An einer Kopie testen: Führen Sie niemals ungetestete Migrationen in der Produktion aus

Beispiel:

-- 022_add_combo_priority.sql
ALTER TABLE combos ADD COLUMN priority INTEGER DEFAULT 100;
UPDATE combos SET priority = 100 WHERE priority IS NULL;
CREATE INDEX IF NOT EXISTS idx_combos_priority ON combos(priority);

Nicht abwärtskompatible Änderungen (z. B. das Löschen von Spalten) sind problematisch. OmniRoute unterstützt KEIN Downgrade — sobald eine Migration angewendet wurde, ist die Schemaänderung dauerhaft. Planen Sie entsprechend.


Sensible Felder (API-Schlüssel, OAuth-Token, Verbindungszeichenfolgen) werden im Ruhezustand mit AES-256-GCM verschlüsselt.

// src/lib/db/encryption.ts (vereinfacht)
const key = deriveKeyFromPassphrase(passphrase, salt);
const iv = randomBytes(12);
const cipher = createCipheriv("aes-256-gcm", key, iv);
const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);
const authTag = cipher.getAuthTag();
return { encrypted, iv, authTag };
  • provider_connections.api_key — auf Anwendungsebene verschlüsselt
  • provider_connections.access_token, refresh_token, id_token — auf Anwendungsebene verschlüsselt
  • key_value-Einträge mit namespace = "secrets" — auf Anwendungsebene verschlüsselt
  • proxy_registry.auth — auf Anwendungsebene verschlüsselt (falls vorhanden)

Der Verschlüsselungsschlüssel wird aus einer Passphrase (festgelegt über die Umgebungsvariable STORAGE_ENCRYPTION_KEY) und einem Salt (in der Datenbank gespeichert) abgeleitet. Beide sind erforderlich, um Daten zu entschlüsseln.

Terminal-Fenster
# Eine sichere Passphrase generieren
openssl rand -hex 32
# In .env festlegen
STORAGE_ENCRYPTION_KEY=<your-key>

Kritisch: Der Verlust des Verschlüsselungsschlüssels bedeutet, dass der Zugriff auf alle verschlüsselten Daten verloren geht. Sichern Sie den Schlüssel getrennt von der Datenbank.

Aus Leistungsgründen werden folgende Daten im Klartext gespeichert:

  • Anzeigenamen der Anbieter
  • Modelldefinitionen (bereits öffentlich)
  • Routingregeln
  • Nutzungsdatensätze (keine personenbezogenen Daten)

OmniRoute verwendet migrateLegacyEncryptedString(), um zwei Verschlüsselungsverfahren transparent zu handhaben:

  • Legacy (vor v3.5.0): XOR-basierte „Verschlüsselung“ (keine echte Kryptografie)
  • Aktuell: AES-256-GCM mit korrektem IV und Authentifizierungs-Tag

Die Migrationshilfsfunktion erkennt das Legacy-Format und verschlüsselt die Daten beim ersten Lesen mit dem neuen Verfahren erneut. Das bedeutet, dass Sie eine alte Datenbank aktualisieren können, ohne Zugangsdaten zu verlieren.


Für häufig gelesene Daten (Modelle, Anbieter, Einstellungen) stellt readCache.ts einen In-Memory-Cache bereit:

// Beim Start zwischengespeichert, beim Schreiben invalidiert
const providers = await getCachedProviders(); // Schnell, im Arbeitsspeicher
const fresh = await listProviders(); // Langsam, greift auf die DB zu
Zwischengespeicherte Entität Cache-Schlüssel TTL
models models:v1 Bis zum Schreibvorgang
provider_connections providers:v1 Bis zum Schreibvorgang
settings settings:v1 Bis zum Schreibvorgang
combos combos:v1 Bis zum Schreibvorgang

Der Cache wird bei jedem Schreibvorgang in die entsprechende Tabelle invalidiert.


Terminal-Fenster
# CLI verwenden, um eine lokale Sicherung zu erstellen
omniroute backup create --name pre-migration
# Oder über die API
curl -X PUT http://localhost:20128/api/db-backups \
-H "Authorization: Bearer $MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "pre-migration"}'

Die Sicherungsdatei enthält:

  • Alle DB-Tabellen (als JSON serialisiert)
  • Aufrufprotokoll-Artefakte (Base64-kodiert, optional)
  • Einstellungen + Geheimnisse (verschlüsselt)
  • Plugin-Konfiguration
Terminal-Fenster
# Über die CLI
omniroute restore pre-migration
# Über die API
curl -X POST http://localhost:20128/api/db-backups/restore \
-H "Authorization: Bearer $MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "pre-migration"}'

Warnung: Die Wiederherstellung überschreibt die gesamte DB. Stoppen Sie zuerst alle Clients.

Terminal-Fenster
# Automatisierte tägliche Sicherungen über die CLI aktivieren
omniroute backup auto enable --cron "0 2 * * *" --retention 7

Der Zeitplan wird serverseitig durch einen Hintergrundjob ausgeführt, der standardmäßig alle 30 Sekunden aktiv wird und den Cron-Ausdruck anhand der lokalen Serverzeit auswertet.

Variable Standardwert Beschreibung
OMNIROUTE_BACKUP_SCHEDULE_JOB_INTERVAL_MS 30000 Intervall in ms (min. 5000). Muss kürzer als 60 s sein, damit die passende Cron-Minute zuverlässig getroffen wird.

Für eine Sicherung einer laufenden DB ohne Ausfallzeit:

Terminal-Fenster
sqlite3 ~/.omniroute/storage.sqlite ".backup /backups/omniroute-hot.db"

Hierbei wird die Online-Backup-API von SQLite verwendet — die Ausführung ist sicher, während OmniRoute läuft.


WAL ist standardmäßig aktiviert. Für schreibintensive Workloads sollten Sie Folgendes in Betracht ziehen:

PRAGMA wal_autocheckpoint = 1000; -- Checkpoint alle 1000 Seiten
PRAGMA journal_size_limit = 67108864; -- WAL-Obergrenze von 64 MB

Wichtige Indizes für die Leistung (werden durch Migrationen automatisch erstellt):

  • idx_models_provider — Modellsuche nach Anbieter
  • idx_combo_targets_combo_id — Erweiterung von Kombinationszielen
  • idx_usage_history_api_key_timestamp — Nutzungsanalysen
  • idx_quota_snapshots_api_key_window — Kontingentverfolgung
  • idx_call_logs_timestamp — Abfragen von Aufrufprotokollen

Um einen neuen Index hinzuzufügen, erstellen Sie eine Migration:

-- 023_add_my_index.sql
CREATE INDEX IF NOT EXISTS idx_my_table_my_column ON my_table(my_column);

Für sehr große Datenbanken (>10 GB) kann die Speicherabbildung über ein SQLite-Pragma angepasst werden:

-- Über SQLite-Pragma festlegen (in core.ts oder zur Laufzeit anpassen)
PRAGMA mmap_size = 268435456; -- 256 MB

Lang laufende OmniRoute-Instanzen profitieren von einem gelegentlichen VACUUM:

Terminal-Fenster
sqlite3 ~/.omniroute/storage.sqlite "VACUUM;"

Führen Sie dies monatlich in Zeitfenstern mit geringem Datenverkehr aus. (Der WAL-Modus reduziert die Notwendigkeit, beseitigt sie jedoch nicht vollständig.)


src/lib/db/healthCheck.ts stellt Integritätsdiagnosen auf Datenbankebene bereit:

Beide HTTP-Methoden erfordern eine Authentifizierung (andernfalls 401). GET führt nur eine Diagnose durch; POST führt dieselbe Prüfung mit aktiviertem autoRepair aus.

Terminal-Fenster
GET /api/db/health # diagnostizieren
POST /api/db/health # diagnostizieren + reparieren

Die Antwort ist das von runDbHealthCheck() erzeugte DbHealthCheckResult (src/lib/db/healthCheck.ts):

{
"isHealthy": false,
"issues": [
{
"type": "broken_reference",
"table": "domain_budgets",
"description": "Domänenbudgets verwiesen auf API-Schlüssel, die nicht mehr existieren.",
"count": 2
}
],
"repairedCount": 0,
"backupCreated": false,
"autoRepair": false,
"checkedAt": "2026-08-18T09:00:00.000Z",
"driver": { "name": "better-sqlite3", "degraded": false }
}
Feld Bedeutung
isHealthy true, wenn issues leer ist. driver hat niemals Einfluss darauf.
issues[].type Einer der Werte integrity_check_failed, broken_reference, stale_snapshot, invalid_state.
repairedCount Während dieses Durchlaufs reparierte Zeilen; immer 0, wenn autoRepair den Wert false hat.
backupCreated Gibt an, ob vor der Reparatur eine Sicherung erstellt wurde.
checkedAt ISO-Zeitstempel, der für den Durchlauf und jeden dabei geschriebenen Reparaturhinweis identisch ist.
driver.name SQLite-Treiber, der die geprüfte Datenbank bereitstellt.
driver.degraded true, wenn Schreibvorgänge nicht dauerhaft durch die Datenbankdatei gesichert werden — beim WASM-Fallback sql.js (Persistenz der gesamten Datei) oder bei einer In-Memory-Datenbank.

Dieselbe Nutzlast wird vom MCP-Tool omniroute_db_health_check zurückgegeben.

Führen Sie PRAGMA integrity_check aus, um Beschädigungen zu erkennen:

Terminal-Fenster
sqlite3 ~/.omniroute/storage.sqlite "PRAGMA integrity_check;"
# Sollte Folgendes ausgeben: ok

Wenn etwas anderes als ok zurückgegeben wird, beenden Sie die Verwendung der Datenbank sofort und stellen Sie sie aus einer Sicherung wieder her.


Die -wal-Datei fehlt, aber -shm und die Hauptdatenbank sind intakt:

Terminal-Fenster
# Wird beim nächsten Öffnen automatisch wiederhergestellt
omniroute

Falls SQLite keine automatische Wiederherstellung durchführen kann:

Terminal-Fenster
sqlite3 ~/.omniroute/storage.sqlite ".recover" > recovered.sql
sqlite3 recovered.db < recovered.sql
mv recovered.db ~/.omniroute/storage.sqlite

Aus einer Sicherung wiederherstellen:

Terminal-Fenster
omniroute sync pull --merge # oder: omniroute backup restore &lt;backup-id&gt;

Ohne den Schlüssel ist keine Wiederherstellung möglich. Die verschlüsselten Felder sind nicht lesbar. Fügen Sie alle Anbieter manuell mit neuen Zugangsdaten erneut hinzu.

Gegenmaßnahme: Sichern Sie den Verschlüsselungsschlüssel stets separat, idealerweise in einem Passwortmanager oder KMS.

SQLite gibt SQLITE_FULL-Fehler zurück. Geben Sie Speicherplatz frei und führen Sie anschließend Folgendes aus:

Terminal-Fenster
# WAL-Checkpoint durchführen, um Speicherplatz freizugeben
sqlite3 ~/.omniroute/storage.sqlite "PRAGMA wal_checkpoint(TRUNCATE);"

Terminal-Fenster
sqlite3 ~/.omniroute/storage.sqlite "SELECT * FROM api_keys LIMIT 5;"
Terminal-Fenster
sqlite3 ~/.omniroute/storage.sqlite <<EOF
SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';
EOF
Terminal-Fenster
# Zuerst OmniRoute beenden
omniroute stop
# Datenbankdatei löschen
rm ~/.omniroute/storage.sqlite*
# Neu starten (erstellt eine leere Datenbank)
omniroute

Für ein selektives Zurücksetzen (Anbieter beibehalten, Nutzungsdaten löschen):

Terminal-Fenster
DELETE FROM usage_history WHERE timestamp < datetime('now', '-30 day');
DELETE FROM call_logs WHERE timestamp < datetime('now', '-30 day');
DELETE FROM proxy_logs WHERE timestamp < datetime('now', '-30 day');
Terminal-Fenster
sqlite3 ~/.omniroute/storage.sqlite <<EOF
.mode csv
.output api_keys.csv
SELECT * FROM api_keys;
EOF

Ein anderer Prozess hält eine Schreibsperre. Sie können:

  • Warten, bis der andere Prozess abgeschlossen ist (mit lsof | grep storage.sqlite prüfen)
  • Den anderen Prozess beenden
  • OmniRoute neu starten, falls das Problem weiterhin besteht

Ein Domänenmodul verletzt die referenzielle Integrität. Prüfen Sie Folgendes:

  • Verwaiste Zeilen in abhängigen Tabellen
  • Kaskadierende Löschvorgänge, die nicht weitergegeben wurden
  • Eine kürzlich durchgeführte Migration, die einen Fremdschlüssel geändert hat

Führen Sie PRAGMA foreign_key_check; aus, um Verletzungen zu finden.

Die speicherabgebildete Ein-/Ausgabe von SQLite überschreitet das Betriebssystemlimit. Reduzieren Sie sie über ein SQLite-Pragma:

PRAGMA mmap_size = 134217728; -- 128MB anstelle von 256MB

Oder deaktivieren Sie sie:

PRAGMA mmap_size = 0;

“Migration während der Ausführung fehlgeschlagen”

Abschnitt betitelt „“Migration während der Ausführung fehlgeschlagen”“

Die Migration wurde innerhalb einer Transaktion ausgeführt und sollte daher zurückgesetzt worden sein. Falls nicht:

  1. OmniRoute beenden (weitere Versuche verhindern)
  2. Datenbankstatus prüfen mit sqlite3
  3. Unvollständige Migration manuell korrigieren
  4. OmniRoute erneut ausführen (die Migration wird erneut versucht)

Um dies zu vermeiden, testen Sie Migrationen immer zuerst an einer Kopie.



OmniRoute-Quellcode (a58000c7685f)

HagiCode

HagiCode ist ein agentischer Coding-Arbeitsplatz mit strukturierten Workflows, Multi-Agent-Ausführung und Hero-Dungeon-Ansichten.

Mit einem intelligenteren, schnelleren und unterhaltsameren agentischen Workflow wird aus Ideen nutzbare Software.

HagiCode-Hauptoberfläche im hellen Design
  • SmartStrukturierte Workflows machen aus Absichten einen umsetzbaren Weg von der Idee bis zur Auslieferung.
  • EfficientMulti-Agent-Workflows führen Recherche, Umsetzung und Prüfung parallel aus.
  • FunHero Dungeon macht lange Coding-Sitzungen anschaulich und gemeinschaftlich.
HagiCode besuchen