Standalone Shonar Desktop: vendor portable sources + local engine; decouple from ~/Projects/Shonar

- shared/ = portable Android-origin sources vendored from deferred/desktop-server
  (app/build.gradle.kts srcDir repointed; PlaybackController.kt excluded as Android-only)
- backend/ = bundled-lite engine (SQLite + inline queue); .venv symlinked from the
  old checkout, PYTHONPATH pins THIS backend's code over any editable install
- repoRoot() resolves this project dir (env SHONAR_REPO still wins); desktop-dev.sh
  watches shared/ + backend/
- Verified: :app:compileKotlin + :app:test green (23 tests); engine boots on :8010,
  self-migrates, /healthz ok
This commit is contained in:
avi 2026-09-14 17:14:54 -05:00
commit 76c867fca4
136 changed files with 21099 additions and 0 deletions

View file

@ -0,0 +1,33 @@
"""Programmatic schema migrations for the bundled desktop engine.
Server deployments run ``alembic upgrade head`` in their deploy flow;
the desktop app owns its SQLite file end-to-end, so the API applies
migrations itself at startup (``SHONAR_AUTO_MIGRATE=1``).
"""
from __future__ import annotations
import asyncio
import logging
from pathlib import Path
from alembic import command
from alembic.config import Config
logger = logging.getLogger("shonar.migrate")
# backend/ dir: migrations/ + alembic.ini live here relative to this file.
_BACKEND_DIR = Path(__file__).resolve().parents[2]
async def upgrade_head(database_url: str) -> None:
"""Run 'alembic upgrade head' for `database_url` without blocking the loop."""
def _run() -> None:
cfg = Config(str(_BACKEND_DIR / "alembic.ini"))
cfg.set_main_option("script_location", str(_BACKEND_DIR / "migrations"))
cfg.set_main_option("sqlalchemy.url", database_url)
command.upgrade(cfg, "head")
await asyncio.to_thread(_run)
logger.info("database schema migrated to head")