# Operator guide ## Run locally ```bash make install make run ``` The API defaults to `127.0.0.1:8010` and `./sbom-nexus.db`. SQLite schema is created automatically for local development. For PostgreSQL, migrate before starting the API: ```bash export SBOM_NEXUS_DATABASE_URL='postgresql+psycopg://user:password@host/sbom_nexus' make migrate make run ``` Production deployments should mount a Secret and set `SBOM_NEXUS_DATABASE_URL_FILE` to its `url` file rather than exposing the DSN in a manifest or command argument. The same file setting is consumed by both Alembic and the API process. PostgreSQL never auto-creates tables unless `SBOM_NEXUS_AUTO_CREATE=1` is set explicitly. Normal production operation must use Alembic. ## Register and ingest a repository ```bash curl -X PUT http://127.0.0.1:8010/repositories/example \ -H 'Content-Type: application/json' \ -d '{"checkout_path":"/srv/repos/example","active":true}' curl -X POST http://127.0.0.1:8010/sbom/example/ingest ``` The ingest response is terminal: `ingested`, or `skipped` with one of `no-checkout`, `no-manifest`, or `ingest-error`. A skip advances queue fairness but does not advance `last_success_at`. ## Inspect catch-up ```bash curl -s 'http://127.0.0.1:8010/sbom/catch-up?limit=3' | python3 -m json.tool ``` The default stale threshold is 30 days. Override it globally with `SBOM_NEXUS_STALE_DAYS` or per query with `stale_days` during controlled operation. ## Import State Hub history Synchronize the minimum repository identity/path projection first. This command does not call an ingest endpoint or create an SBOM snapshot: ```bash uv run python scripts/sync_repository_projections.py \ --source-url http://127.0.0.1:8000 \ --target-url http://127.0.0.1:8010 \ --host-id bnt-lap001 \ --dry-run ``` Remove `--dry-run` only after the target is deployed. The apply path upserts all active and inactive records, then reads them back and fails on a missing or mismatched active/path projection. Extra target rows are reported but retained. Run a read-only preview first: ```bash uv run python scripts/import_state_hub.py --dry-run ``` Then run against a backed-up Nexus database: ```bash uv run python scripts/import_state_hub.py \ --source-url http://127.0.0.1:8000 \ --target-url http://127.0.0.1:8010 ``` Imports are idempotent on the State Hub snapshot UUID. Before cutover, compare the source/target repository, snapshot, and entry counts described in the extraction review. The command fails unless every legacy snapshot id, repository, timestamp, entry count, licence group, and direct-production copyleft count reconciles. ## Current production limitations - Authentication and authorization are not yet integrated. - Structured operational metrics, backup/restore proof, and retention policy are required before authority cutover. - State Hub and Repo Manager callers have not yet been retargeted.