diff --git a/scripts/bootstrap_qdrant_plans.py b/scripts/bootstrap_qdrant_plans.py new file mode 100644 index 0000000..36f42e1 --- /dev/null +++ b/scripts/bootstrap_qdrant_plans.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Idempotenter Bootstrap für Qdrant-Collections rund um Pläne. +- Legt fehlende Collections NICHT neu an (wir erwarten, dass der erste Upsert sie erzeugt) +- Legt fehlende Payload-Indizes als KEYWORD an (wo sinnvoll) +- Zeitfelder: bleiben textuell (ISO8601); optional kann created_at_ts später ergänzt werden + +Start: + pip install qdrant-client --upgrade + python3 scripts/bootstrap_qdrant_plans.py +""" +import os +from qdrant_client import QdrantClient +from qdrant_client.models import PayloadSchemaType + +QDRANT_HOST = os.getenv("QDRANT_HOST", "localhost") +QDRANT_PORT = int(os.getenv("QDRANT_PORT", "6333")) + +PLANS = os.getenv("PLAN_COLLECTION") or os.getenv("QDRANT_COLLECTION_PLANS", "plans") +TEMPLATES = os.getenv("PLAN_TEMPLATE_COLLECTION", "plan_templates") +SESSIONS = os.getenv("PLAN_SESSION_COLLECTION", "plan_sessions") + +INDEX_SPECS = { + TEMPLATES: [ + ("discipline", PayloadSchemaType.KEYWORD), + ("age_group", PayloadSchemaType.KEYWORD), + ("target_group", PayloadSchemaType.KEYWORD), + ("sections.name", PayloadSchemaType.KEYWORD), + ("goals", PayloadSchemaType.KEYWORD), + ], + PLANS: [ + ("discipline", PayloadSchemaType.KEYWORD), + ("age_group", PayloadSchemaType.KEYWORD), + ("target_group", PayloadSchemaType.KEYWORD), + ("sections.name", PayloadSchemaType.KEYWORD), + ("goals", PayloadSchemaType.KEYWORD), + ("created_by", PayloadSchemaType.KEYWORD), + ("created_at", PayloadSchemaType.KEYWORD), + ("fingerprint", PayloadSchemaType.KEYWORD), + ("title", PayloadSchemaType.KEYWORD) + ], + SESSIONS: [ + ("plan_id", PayloadSchemaType.KEYWORD), + ("executed_at", PayloadSchemaType.KEYWORD), + ("coach", PayloadSchemaType.KEYWORD), + ("group_label", PayloadSchemaType.KEYWORD) + ], +} + + +def _create_indexes(client: QdrantClient, collection: str, specs): + # Prüfe, ob Collection existiert (wir erwarten sie). Falls nicht, Hinweis, aber nicht fatal. + try: + client.get_collection(collection) + print(f"[Bootstrap] Collection '{collection}' ok.") + except Exception as e: + print(f"[Bootstrap] WARN: Collection '{collection}' nicht gefunden (wird beim ersten Upsert erstellt). Details: {e}") + return + + for field, schema in specs: + try: + client.create_payload_index(collection_name=collection, field_name=field, field_schema=schema) + print(f"[Bootstrap] Index created: {collection}.{field} ({schema})") + except Exception as e: + print(f"[Bootstrap] Index exists or skipped: {collection}.{field} -> {e}") + + +def main(): + client = QdrantClient(host=QDRANT_HOST, port=QDRANT_PORT) + for coll, specs in INDEX_SPECS.items(): + _create_indexes(client, coll, specs) + print("[Bootstrap] done.") + + +if __name__ == "__main__": + main() \ No newline at end of file