Server
FastAPI service backing the cq remote store.
Development
From the repository root:
make setup-server-backend # uv sync
make dev-api # run against a local SQLite DB
make test-server-backend # pytest
make lint-server-backend # pre-commit (ruff, ty, uv lock check)Database migrations (Alembic)
Alembic owns the schema. The server runs alembic upgrade head on every start, before opening the store; any schema change must land as a new migration in alembic/versions/.
The runner (cq_server.migrations.run_migrations) is restart-safe in three cases:
New database — applies the baseline migration and writes
alembic_version.Database with existing data but no
alembic_version— stamps the baseline revision without re-running its DDL, then applies any later migrations. No data touched.Already-managed database —
upgrade headis a no-op when nothing is pending.
Database URL
Resolution lives in cq_server.core.config.Settings.resolved_database_url and is the single source of truth for alembic/env.py, the migration runner, and the Database engine wrapper. Precedence:
CQ_DATABASE_URL— used verbatim. SQLite URLs (sqlite:///<path>) work today;postgresql+psycopg://...is reserved for the Postgres backend and currently raisesNotImplementedErrorat startup pointing at the Phase 2 implementation issue (#312).CQ_DB_PATH— wrapped assqlite:///<path>. The SQLite shortcut for single-instance deployments; supported alongsideCQ_DATABASE_URL.Default —
sqlite:////data/cq.db.
Rollback
Migrations are forward-only. If a new migration causes a bad deploy, redeploy the previous server image; if its head is older than the alembic_version row on disk, Alembic raises its standard "Can't locate revision" error from command.upgrade and the server refuses to start — the safeguard against silently downgrading data. To recover, either redeploy the version that wrote the newer alembic_version, or hand-write a downgrade migration before redeploying the older image.
Local development
Alembic is invoked from server/backend/, so paths resolve relative to it:
The full environment-variable table for self-hosters lives in DEVELOPMENT.md.
Semantic search
Semantic similarity search is disabled by default. It activates only when TOKEN_EMBEDDING_URL is set and the semsearch optional extra is installed.
Installation
The extra installs sqlite-vec, numpy, and httpx.
Environment variables
TOKEN_EMBEDDING_URL
to enable
—
Base URL of the encoderfile embedding service. When this variable is set and the semsearch extra is installed, every insert/update writes an embedding row and query modulates relevance by cosine distance.
SEMSEARCH_EMBEDDING_DIM
no
768
Dimensionality of the embedding vectors. Must match the model served at TOKEN_EMBEDDING_URL.
Embedding service contract
The server calls:
Expected response:
The server averages across all returned embeddings to produce a single vector.
Disabled-by-default behaviour
When TOKEN_EMBEDDING_URL is unset (or the semsearch extra is not installed) semsearch.is_enabled() returns False and all semsearch code-paths are short-circuited; behaviour matches the non-semsearch baseline exactly.
Last updated