"""Create the `chunks` collection — the Qdrant analogue of `alembic upgrade head`. uv run python -m src.cli.qdrant_bootstrap A deployment step, deliberately not part of the FastAPI lifespan: collection creation is DDL, which ADR-0009 keeps out of application startup for Postgres and ADR-0012 keeps out of it for LangGraph's `.setup()`. See `src/infrastructure/qdrant/collection.py` for the full reasoning. Idempotent and safe to re-run. Exits non-zero if an existing collection diverges from the pinned schema, rather than leaving a silently degraded sparse index behind. """ import asyncio import sys import structlog from src.config import Settings from src.infrastructure.observability.logging import configure_logging from src.infrastructure.qdrant.client import create_client from src.infrastructure.qdrant.collection import ( CollectionSchemaMismatchError, ensure_chunks_collection, ) logger = structlog.get_logger(__name__) async def bootstrap(settings: Settings | None = None) -> int: resolved = settings or Settings() configure_logging(resolved.logging, resolved.app) client = create_client(resolved.qdrant) try: created = await ensure_chunks_collection(client, collection=resolved.qdrant.collection) except CollectionSchemaMismatchError as exc: logger.error("qdrant.bootstrap.schema_mismatch", error=str(exc)) return 1 finally: await client.close() logger.info( "qdrant.bootstrap.completed", collection=resolved.qdrant.collection, created=created ) return 0 def main() -> None: sys.exit(asyncio.run(bootstrap())) if __name__ == "__main__": main()