feat(harness): persist server sessions in postgres

This commit is contained in:
User
2026-07-16 17:31:04 +02:00
parent 8f0154eb9e
commit 5dbb91390f
12 changed files with 1057 additions and 3 deletions
+33
View File
@@ -9,6 +9,39 @@ from tht.cli.schema_cmd import _load_config_or_exit
session_app = typer.Typer(help="Sessioni (directory artefatti)")
@session_app.command("migrate")
def migrate_cmd(
database_url: str = typer.Option(
..., "--database-url", envvar="THT_SESSIONS_ADMIN_URL", help="Admin PostgreSQL URL."
),
status_only: bool = typer.Option(False, "--status", help="Inspect without applying."),
json_output: bool = typer.Option(False, "--json", help="Emit pristine JSON."),
) -> None:
"""Apply or inspect the private PostgreSQL session schema migrations."""
from tht.session.postgres_repository import MigrationError, migrate, migration_status
try:
status = migration_status(database_url) if status_only else migrate(database_url)
except (MigrationError, ValueError) as exc:
if json_output:
typer.echo(json.dumps({"error": str(exc)}, sort_keys=True))
else:
typer.echo(f"ERROR: {exc}", err=True)
raise typer.Exit(code=1) from None
payload = {
"applied": [item.version for item in status.applied],
"drifted": [item.version for item in status.drifted],
"pending": [item.version for item in status.pending],
}
if json_output:
typer.echo(json.dumps(payload, sort_keys=True))
else:
typer.echo(
f"Applied: {len(status.applied)}; pending: {len(status.pending)}; "
f"drifted: {len(status.drifted)}"
)
def session_dir(cfg, session_id: str) -> Path:
return cfg.paths.sessions / session_id