Skip to content

Run locally

Run these commands from the repository root:

cd apps/quicklookup
cp .env.example .env
docker compose -f docker-compose.test.yml up -d
uv sync --frozen --extra test --extra docs
uv run --extra docs mkdocs build --strict
uv run python manage.py migrate
uv run python manage.py seed_uom_catalog
uv run python manage.py sync_ctx_adapters
uv run uvicorn quicklookup.asgi:application --host 127.0.0.1 --port 8090

Run uv run python manage.py run_publication_worker in another terminal. Open http://127.0.0.1:8090/admin/ for the admin and /docs/ for this site.

Run unit tests while the development catalogue is in use. The contract and integration suites flush the Compose PostgreSQL schema and must use a disposable database.

Preserve the databases

docker compose down stops the stack and keeps its named volumes. Do not use down -v when the PostgreSQL or ClickHouse contents must survive. Starting the same Compose project reattaches those volumes.

The integration suite uses the configured Compose PostgreSQL database and flushes the QuickLookup schema. Do not run it while the local UI or another user depends on that catalogue. A volume surviving Docker cleanup does not mean its container, network, or Compose project name survived; inspect the configured volumes before recreating services.

After an intentional test run, these commands reconstruct only the standard UOM and CTX service catalogue from checked-in definitions and the live FDW inventory:

uv run python manage.py migrate
uv run python manage.py seed_uom_catalog
uv run python manage.py sync_ctx_adapters
uv run python manage.py run_publication_worker --once

Run the worker again while ClickHouse projection records remain pending. Customer-created definitions and catalogue grants are not reconstructed by those commands; restore them from a PostgreSQL backup. ClickHouse data volumes are independent, but rows are usable only when their PostgreSQL definitions and grants also exist.

When an upgrade changes the canonical CTX-owned path grammar, stop the API and worker, drain pending projections and observation copies, then use the existing recoverable identity cutover:

uv run python manage.py migrate_gid_namespace --normalize-current-ctx
uv run python manage.py migrate_gid_namespace --normalize-current-ctx --apply \
  --backup-dir /private/tmp/NEW-private-backup-directory
uv run python manage.py migrate_gid_namespace --project
uv run python manage.py sync_ctx_adapters
uv run python manage.py audit_series_families --fail-on-blockers

The preview is read-only. Apply copies affected ClickHouse rows, retains their old identities, creates compatibility aliases, corrects dependent immutable publication heads, and refuses to run without a new PostgreSQL backup directory. A repeated preview must report no matching identities before writers restart.

For a deployed, data-bearing catalogue, scale the API and worker to zero through GitOps, disable the post-sync catalogue job, and run the maintenance image with QUICKLOOKUP_DB_APPLICATION_NAME=quicklookup-maintenance plus --normalize-current-ctx --deployed-maintenance --apply. The command refuses to start while any API/worker database session named by QUICKLOOKUP_DB_WRITER_APPLICATION_NAME remains.

Verify /healthz, /readyz, the admin catalogue counts, and the publication backlog before using the restored stack. Then run one stored ClickHouse query and one CTX FDW query with a representative token.

The same maintenance command repairs family identities created before the canonical /families/ grammar. Preview first, then use a new backup directory for apply:

uv run python manage.py migrate_gid_namespace --normalize-series-families
uv run python manage.py migrate_gid_namespace --normalize-series-families --apply \
  --backup-dir /private/tmp/NEW-private-backup-directory
uv run python manage.py sync_ctx_adapters
uv run python manage.py sync_trading_economics
uv run python manage.py audit_series_families --fail-on-blockers

This mode is limited to the known legacy CTX and Trading Economics family generators. It creates one-hop aliases and corrected immutable heads; the reconciliations then assign the canonical family contracts.