Jean-Luc Makiola b95071a95e
Some checks failed
CI / ci (push) Failing after 24s
ci: manueller checkout statt actions/checkout
actions/checkout@v4 ist eine node-action; python:3.12-slim hat kein node
installiert -> 'exec: node not found'. ersatz durch git clone analog
release.yml.
2026-05-07 15:59:24 +02:00

rag-ingestor

Microservice der Dateien aus Nextcloud (Documents/THB/Studium/) in Qdrant indexiert. Embeddings via Ollama.

Endpoints

  • POST /webhook (Header X-Webhook-Secret): Nextcloud-Event-Empfang (created / updated / deleted).
  • POST /bulk-import (Header X-Webhook-Secret): Body {"path": "..."} → rekursiver Re-Index. Bulk-Pipeline-Stages laufen mit Concurrency 4 (siehe BULK_CONCURRENCY in app/bulk.py).
  • GET /health: Liveness-Probe.

Webhook-Payload-Format

Der Service erwartet ein vorgeformtes JSON. Nextcloud-Roh-Events werden nicht direkt akzeptiert — sie müssen via Flow-Webhook in dieses Schema übersetzt werden:

{
  "event_type": "created",
  "file_path": "Documents/THB/Studium/2.Semester/Databases/DBS1.pdf",
  "file_name": "DBS1.pdf"
}

event_type{"created", "updated", "deleted"}. Auth via Header X-Webhook-Secret, der mit WEBHOOK_SECRET aus der Konfiguration übereinstimmen muss.

Beispielaufruf:

curl -X POST http://localhost:8000/webhook \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Secret: $WEBHOOK_SECRET" \
  -d '{"event_type": "created", "file_path": "Documents/THB/Studium/2.Semester/Databases/DBS1.pdf", "file_name": "DBS1.pdf"}'

Erwartete Ordnerstruktur

Documents/THB/Studium/<N>.Semester/<Fach>/[<Unterordner>]/<datei>

Unterstützte Dateitypen: .pdf, .md, .docx, .xlsx (XLSX wird nur als Filename indexiert, kein Inhalt).

Konfiguration

Siehe .env.example. Alle Werte über Env-Vars, kein Config-File.

Lokale Entwicklung

uv sync
uv run pytest
uv run uvicorn app.main:app --reload

Deployment

Image bauen und in Coolify neben Qdrant + Ollama deployen:

docker build -f docker/Dockerfile -t rag-ingestor .

Tests

uv run pytest -v

Tests deckt Pure-Logic ab (Metadata-Parser, Chunker, Extractors, Auth, Pipeline-Orchestrierung mit gemockten externen Services). Keine Integration-Tests gegen echte Ollama/Qdrant/WebDAV-Instanzen.

Recovery-Runbook

Einbettungs-Modell oder -Dimension geändert

Beim Boot crasht der Service mit qdrant collection ... dimension mismatch, falls die existierende Collection eine andere Vektor-Dimension hat als das aktuelle Embedding-Modell. Dies ist Absicht (Fail-Fast). Vorgehen:

  1. Collection in Qdrant manuell droppen:
    curl -X DELETE "$QDRANT_URL/collections/$QDRANT_COLLECTION"
    
  2. Service neu starten — Lifespan legt die Collection mit der neuen Dimension an.
  3. Bulk-Import auf den Studium-Root anstoßen, um alle Inhalte neu zu indexieren:
    curl -X POST http://localhost:8000/bulk-import \
      -H "Content-Type: application/json" \
      -H "X-Webhook-Secret: $WEBHOOK_SECRET" \
      -d '{"path": "Documents/THB/Studium"}'
    

Webhook-Ausfall / fehlende In-Flight-Jobs nach Crash

Der Service hat keinen persistenten Job-Store; In-Flight-BackgroundTasks gehen bei Crash verloren. Recovery erfolgt über den Bulk-Import-Endpoint auf den betroffenen Pfad (siehe oben).

Ein einzelnes File neu indexieren

Webhook mit event_type: "updated" an /webhook POSTen — alte Chunks werden via delete_by_filter(file_path) entfernt, dann frisch indexiert.

Description
Nextcloud → Qdrant RAG ingestion service
Readme 241 KiB
v0.2.0 Latest
2026-05-18 20:15:57 +00:00
Languages
Python 99.2%
Dockerfile 0.8%