Mac-Worker: - /api/summarize, /api/protocol, /api/preload akzeptieren optionales model-Feld → überschreibt den .env-Default pro Call, kein Restart nötig - /api/models listet die lokal verfügbaren Ollama-Modelle + Default LXC: - User.default_model + Job.model (Migration für SQLite) - /api/auth/me liefert default_model, PATCH speichert ihn sofort - /api/mac/models proxiet die Liste an die UI - Pipeline reicht job.model an Mac-Worker durch; leer = Worker-Default - create_job & reprocess akzeptieren model-Override - Snapshot-Meta nutzt job.model (genauer als /health-Snapshot) UI: - Header-Dropdown "Modell:" neben "Profil:" — sofort-speichert User-Default - Jeder Job zeigt sein Modell als Tag (lila); leer bedeutet Worker-Default - Reprocess öffnet einen Modal-Picker (statt simplem confirm), Auswahl aller verfügbaren Modelle inkl. "Worker-Default" Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
81 lines
3.5 KiB
Python
81 lines
3.5 KiB
Python
"""Leichte In-Place-Migrationen für SQLite (kein Alembic).
|
|
|
|
Wird beim App-Start nach create_all() ausgeführt. Idempotent.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from sqlalchemy import text
|
|
from sqlmodel import Session
|
|
|
|
from app.core.db import engine
|
|
|
|
log = logging.getLogger("voice-agent.migrate")
|
|
|
|
|
|
def _existing_columns(conn, table: str) -> set[str]:
|
|
rows = conn.execute(text(f"PRAGMA table_info({table})")).all()
|
|
return {r[1] for r in rows} # row[1] = column name
|
|
|
|
|
|
def run_migrations() -> None:
|
|
with engine.begin() as conn:
|
|
# 1) Job.owner_id Spalte nachrüsten, falls die Tabelle aus alter Version kommt.
|
|
cols = _existing_columns(conn, "job")
|
|
if "owner_id" not in cols:
|
|
log.info("Migration: füge job.owner_id hinzu")
|
|
conn.execute(text("ALTER TABLE job ADD COLUMN owner_id INTEGER"))
|
|
conn.execute(text("CREATE INDEX IF NOT EXISTS ix_job_owner_id ON job(owner_id)"))
|
|
|
|
# 2) Job.profile Spalte nachrüsten (Profil-System).
|
|
cols = _existing_columns(conn, "job")
|
|
if "profile" not in cols:
|
|
log.info("Migration: füge job.profile hinzu (default 'meeting')")
|
|
conn.execute(text("ALTER TABLE job ADD COLUMN profile VARCHAR DEFAULT 'meeting'"))
|
|
|
|
# 3) User.default_profile nachrüsten.
|
|
user_cols = _existing_columns(conn, "user")
|
|
if user_cols and "default_profile" not in user_cols:
|
|
log.info("Migration: füge user.default_profile hinzu (default 'meeting')")
|
|
conn.execute(text("ALTER TABLE user ADD COLUMN default_profile VARCHAR DEFAULT 'meeting'"))
|
|
|
|
# 4) Job.pdf_path nachrüsten (PDF-Export zusätzlich zu DOCX).
|
|
cols = _existing_columns(conn, "job")
|
|
if "pdf_path" not in cols:
|
|
log.info("Migration: füge job.pdf_path hinzu")
|
|
conn.execute(text("ALTER TABLE job ADD COLUMN pdf_path VARCHAR DEFAULT ''"))
|
|
|
|
# 5) Diagnose-Felder: step_started_at, last_heartbeat_at
|
|
cols = _existing_columns(conn, "job")
|
|
if "step_started_at" not in cols:
|
|
log.info("Migration: füge job.step_started_at hinzu")
|
|
conn.execute(text("ALTER TABLE job ADD COLUMN step_started_at DATETIME"))
|
|
if "last_heartbeat_at" not in cols:
|
|
log.info("Migration: füge job.last_heartbeat_at hinzu")
|
|
conn.execute(text("ALTER TABLE job ADD COLUMN last_heartbeat_at DATETIME"))
|
|
|
|
# 6) Modell-Auswahl: user.default_model + job.model
|
|
user_cols = _existing_columns(conn, "user")
|
|
if user_cols and "default_model" not in user_cols:
|
|
log.info("Migration: füge user.default_model hinzu (leer = Worker-Default)")
|
|
conn.execute(text("ALTER TABLE user ADD COLUMN default_model VARCHAR DEFAULT ''"))
|
|
cols = _existing_columns(conn, "job")
|
|
if "model" not in cols:
|
|
log.info("Migration: füge job.model hinzu (leer = Worker-Default)")
|
|
conn.execute(text("ALTER TABLE job ADD COLUMN model VARCHAR DEFAULT ''"))
|
|
|
|
|
|
def assign_orphan_jobs_to(user_id: int) -> int:
|
|
"""Weist alle Jobs ohne owner_id dem angegebenen User zu. Gibt Anzahl zurück."""
|
|
with Session(engine) as session:
|
|
result = session.execute(
|
|
text("UPDATE job SET owner_id = :uid WHERE owner_id IS NULL"),
|
|
{"uid": user_id},
|
|
)
|
|
session.commit()
|
|
n = result.rowcount or 0
|
|
if n:
|
|
log.info("Migration: %d Bestand-Jobs an user_id=%d zugeordnet", n, user_id)
|
|
return n
|