# RAG & Daten-Management Spezifikation

## Übersicht

Admin-Frontend für die Verwaltung von Trainingsdaten und RAG-Systemen in BreakPilot.

**Location**: `/admin/docs` → Tab "Daten & RAG"
**Backend**: `klausur-service` (Port 8086)
**Storage**: MinIO (persistentes Docker Volume `minio_data`)
**Vector DB**: Qdrant (Port 6333)

## Datenmodell

### Zwei Datentypen mit unterschiedlichen Regeln

| Typ | Quelle | Training erlaubt | Isolation | Collection |
|-----|--------|------------------|-----------|------------|
| **Landes-Daten** | NiBiS, andere Bundesländer | ✅ Ja | Pro Bundesland | `bp_{bundesland}_{usecase}` |
| **Lehrer-Daten** | Lehrer-Upload (BYOEH) | ❌ Nein | Pro Tenant (Schule/Lehrer) | `bp_eh` (verschlüsselt) |

### Bundesland-Codes (ISO 3166-2:DE)

```
NI = Niedersachsen    BY = Bayern         BW = Baden-Württemberg
NW = Nordrhein-Westf. HE = Hessen         SN = Sachsen
BE = Berlin           HH = Hamburg        SH = Schleswig-Holstein
BB = Brandenburg      MV = Meckl.-Vorp.   ST = Sachsen-Anhalt
TH = Thüringen        RP = Rheinland-Pfalz SL = Saarland
HB = Bremen
```

### Use Cases (RAG-Sammlungen)

| Use Case | Collection Pattern | Beschreibung |
|----------|-------------------|--------------|
| Klausurkorrektur | `bp_{bl}_klausur` | Erwartungshorizonte für Abitur |
| Zeugnisgenerator | `bp_{bl}_zeugnis` | Textbausteine für Zeugnisse |
| Lehrplan | `bp_{bl}_lehrplan` | Kerncurricula, Rahmenrichtlinien |

Beispiel: `bp_ni_klausur` = Niedersachsen Klausurkorrektur

## MinIO Bucket-Struktur

```
breakpilot-rag/
├── landes-daten/
│   ├── ni/                          # Niedersachsen
│   │   ├── klausur/
│   │   │   ├── 2016/
│   │   │   │   ├── manifest.json
│   │   │   │   └── *.pdf
│   │   │   ├── 2017/
│   │   │   ├── ...
│   │   │   └── 2025/
│   │   └── zeugnis/
│   ├── by/                          # Bayern
│   └── .../
│
└── lehrer-daten/                    # BYOEH - verschlüsselt
    └── {tenant_id}/
        └── {lehrer_id}/
            └── *.pdf.enc
```

## Qdrant Schema

### Landes-Daten Collection (z.B. `bp_ni_klausur`)

```json
{
  "id": "uuid-v5-from-string",
  "vector": [384 dimensions],
  "payload": {
    "original_id": "nibis_2024_deutsch_ea_1_abc123_chunk_0",
    "doc_id": "nibis_2024_deutsch_ea_1_abc123",
    "chunk_index": 0,
    "text": "Der Erwartungshorizont...",
    "year": 2024,
    "subject": "Deutsch",
    "niveau": "eA",
    "task_number": 1,
    "doc_type": "EWH",
    "bundesland": "NI",
    "source": "nibis",
    "training_allowed": true,
    "minio_path": "landes-daten/ni/klausur/2024/2024_Deutsch_eA_I_EWH.pdf"
  }
}
```

### Lehrer-Daten Collection (`bp_eh`)

```json
{
  "id": "uuid",
  "vector": [384 dimensions],
  "payload": {
    "tenant_id": "schule_123",
    "eh_id": "eh_abc",
    "chunk_index": 0,
    "subject": "deutsch",
    "encrypted_content": "base64...",
    "training_allowed": false
  }
}
```

## Frontend-Komponenten

### 1. Sammlungen-Übersicht (`/admin/rag/collections`)

```
┌─────────────────────────────────────────────────────────────────┐
│ Daten & RAG                                                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Sammlungen                                          [+ Neu]     │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │ 📚 Niedersachsen - Klausurkorrektur                     │    │
│  │    bp_ni_klausur | 630 Docs | 4.521 Chunks | 2016-2025  │    │
│  │    [Suchen] [Indexieren] [Details]                      │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │ 📚 Niedersachsen - Zeugnisgenerator                     │    │
│  │    bp_ni_zeugnis | 0 Docs | Leer                        │    │
│  │    [Suchen] [Indexieren] [Details]                      │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

### 2. Upload-Bereich (`/admin/rag/upload`)

```
┌─────────────────────────────────────────────────────────────────┐
│ Dokumente hochladen                                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Ziel-Sammlung:  [Niedersachsen - Klausurkorrektur ▼]           │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                                                         │    │
│  │     📁 ZIP-Datei oder Ordner hierher ziehen            │    │
│  │                                                         │    │
│  │              oder [Dateien auswählen]                   │    │
│  │                                                         │    │
│  │     Unterstützt: .zip, .pdf, Ordner                    │    │
│  │                                                         │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│  Upload-Queue:                                                   │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │ ✅ 2018.zip - 45 PDFs erkannt                          │    │
│  │ ⏳ 2019.zip - Wird analysiert...                       │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│  [Hochladen & Indexieren]                                        │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

### 3. Ingestion-Status (`/admin/rag/ingestion`)

```
┌─────────────────────────────────────────────────────────────────┐
│ Ingestion Status                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Aktueller Job: Niedersachsen Klausur 2024                      │
│  ████████████████████░░░░░░░░░░  65% (412/630 Docs)             │
│  Chunks: 2.891 | Fehler: 3 | ETA: 4:32                          │
│  [Pausieren] [Abbrechen]                                         │
│                                                                  │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  Letzte Jobs:                                                    │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │ ✅ 09.01.2025 15:30 - NI Klausur 2024 - 128 Chunks     │    │
│  │ ✅ 09.01.2025 14:00 - NI Klausur 2017 - 890 Chunks     │    │
│  │ ❌ 08.01.2025 10:15 - BY Klausur - Fehler: Timeout     │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

### 4. Suche & Qualitätstest (`/admin/rag/search`)

```
┌─────────────────────────────────────────────────────────────────┐
│ RAG Suche & Qualitätstest                                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Sammlung: [Niedersachsen - Klausurkorrektur ▼]                 │
│                                                                  │
│  Query: [Analyse eines Gedichts von Rilke                    ]  │
│                                                                  │
│  Filter:                                                         │
│  Jahr: [Alle ▼]  Fach: [Deutsch ▼]  Niveau: [eA ▼]             │
│                                                                  │
│  [🔍 Suchen]                                                     │
│                                                                  │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  Ergebnisse (3):                                    Latenz: 45ms │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │ #1 | Score: 0.847 | 2024 Deutsch eA Aufgabe 2          │    │
│  │                                                         │    │
│  │ "...Die Analyse des Rilke-Gedichts soll folgende       │    │
│  │ Aspekte berücksichtigen: Aufbau, Bildsprache..."       │    │
│  │                                                         │    │
│  │ Relevanz: [⭐⭐⭐⭐⭐] [⭐⭐⭐⭐] [⭐⭐⭐] [⭐⭐] [⭐]       │    │
│  │ Notizen: [Optional: Warum relevant/nicht relevant?   ] │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

### 5. Metriken-Dashboard (`/admin/rag/metrics`)

```
┌─────────────────────────────────────────────────────────────────┐
│ RAG Qualitätsmetriken                                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Zeitraum: [Letzte 7 Tage ▼]  Sammlung: [Alle ▼]               │
│                                                                  │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ Precision@5  │  │ Recall@10    │  │ MRR          │          │
│  │    0.78      │  │    0.85      │  │   0.72       │          │
│  │   ↑ +5%      │  │   ↑ +3%      │  │   ↓ -2%      │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
│                                                                  │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ Avg Latency  │  │ Bewertungen  │  │ Fehlerrate   │          │
│  │    52ms      │  │    127       │  │   0.3%       │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
│                                                                  │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  Score-Verteilung:                                               │
│  0.9+ ████████████████ 23%                                      │
│  0.7+ ████████████████████████████ 41%                          │
│  0.5+ ████████████████████ 28%                                  │
│  <0.5 ██████ 8%                                                 │
│                                                                  │
│  [Export CSV] [Detailbericht]                                    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

## API Endpoints

### Collections API

```
GET    /api/v1/admin/rag/collections
POST   /api/v1/admin/rag/collections
GET    /api/v1/admin/rag/collections/{id}
DELETE /api/v1/admin/rag/collections/{id}
GET    /api/v1/admin/rag/collections/{id}/stats
```

### Upload API

```
POST   /api/v1/admin/rag/upload
       Content-Type: multipart/form-data
       - file: ZIP oder PDF
       - collection_id: string
       - metadata: JSON (optional)

POST   /api/v1/admin/rag/upload/folder
       - Für Ordner-Upload (WebKitDirectory)
```

### Ingestion API

```
POST   /api/v1/admin/rag/ingest
       - collection_id: string
       - filters: {year?, subject?, doc_type?}

GET    /api/v1/admin/rag/ingest/status
GET    /api/v1/admin/rag/ingest/history
POST   /api/v1/admin/rag/ingest/cancel
```

### Search API

```
POST   /api/v1/admin/rag/search
       - query: string
       - collection_id: string
       - filters: {year?, subject?, niveau?}
       - limit: int

POST   /api/v1/admin/rag/search/feedback
       - result_id: string
       - rating: 1-5
       - notes: string (optional)
```

### Metrics API

```
GET    /api/v1/admin/rag/metrics
       - collection_id?: string
       - from_date?: date
       - to_date?: date

GET    /api/v1/admin/rag/metrics/export
       - format: csv|json
```

## Embedding-Konfiguration

```python
# Default: Lokale Embeddings (kein API-Key nötig)
EMBEDDING_BACKEND = "local"
LOCAL_EMBEDDING_MODEL = "all-MiniLM-L6-v2"
VECTOR_DIMENSIONS = 384

# Optional: OpenAI (für Produktion)
EMBEDDING_BACKEND = "openai"
EMBEDDING_MODEL = "text-embedding-3-small"
VECTOR_DIMENSIONS = 1536
```

## Datenpersistenz

### Docker Volumes (WICHTIG - nicht löschen!)

```yaml
volumes:
  minio_data:        # Alle hochgeladenen Dokumente
  qdrant_data:       # Alle Vektoren und Embeddings
  postgres_data:     # Metadaten, Bewertungen, History
```

### Backup-Strategie

```bash
# MinIO Backup
docker exec breakpilot-pwa-minio mc mirror /data /backup

# Qdrant Backup
curl -X POST http://localhost:6333/collections/bp_ni_klausur/snapshots

# Postgres Backup (bereits implementiert)
# Läuft automatisch täglich um 2 Uhr
```

## Implementierungsreihenfolge

1. ✅ Backend: Basis-Ingestion (nibis_ingestion.py)
2. ✅ Backend: Lokale Embeddings (sentence-transformers)
3. ✅ Backend: MinIO-Integration (minio_storage.py)
4. ✅ Backend: Collections API (admin_api.py)
5. ✅ Backend: Upload API mit ZIP-Support
6. ✅ Backend: Metrics API mit PostgreSQL (metrics_db.py)
7. ✅ Frontend: Sammlungen-Übersicht
8. ✅ Frontend: Upload-Bereich (Drag & Drop)
9. ✅ Frontend: Ingestion-Status
10. ✅ Frontend: Suche & Qualitätstest (mit Stern-Bewertungen)
11. ✅ Frontend: Metriken-Dashboard

## Technologie-Stack

- **Frontend**: Next.js 15 (`/website/app/admin/rag/page.tsx`)
- **Backend**: FastAPI (`klausur-service/backend/`)
- **Vector DB**: Qdrant v1.7.4 (384-dim Vektoren)
- **Object Storage**: MinIO (S3-kompatibel)
- **Embeddings**: sentence-transformers `all-MiniLM-L6-v2`
- **Metrics DB**: PostgreSQL 16

## Entwickler-Dokumentation

### Projektstruktur

```
klausur-service/
├── backend/
│   ├── main.py              # FastAPI App + BYOEH Endpoints
│   ├── admin_api.py         # RAG Admin API (Upload, Search, Metrics)
│   ├── nibis_ingestion.py   # NiBiS Dokument-Ingestion Pipeline
│   ├── eh_pipeline.py       # Chunking, Embeddings, Encryption
│   ├── qdrant_service.py    # Qdrant Client + Search
│   ├── minio_storage.py     # MinIO S3 Storage
│   ├── metrics_db.py        # PostgreSQL Metrics
│   ├── requirements.txt     # Python Dependencies
│   └── tests/
│       └── test_rag_admin.py
└── docs/
    └── RAG-Admin-Spec.md    # Diese Datei
```

### Schnellstart für Entwickler

```bash
# 1. Services starten
cd /path/to/breakpilot-pwa
docker-compose up -d qdrant minio postgres

# 2. Dependencies installieren
cd klausur-service/backend
pip install -r requirements.txt

# 3. Service starten
python -m uvicorn main:app --port 8086 --reload

# 4. RAG-Services initialisieren (erstellt Bucket + Tabellen)
curl -X POST http://localhost:8086/api/v1/admin/rag/init
```

### API-Referenz (Implementiert)

#### NiBiS Ingestion
```
GET  /api/v1/admin/nibis/discover       # Dokumente finden
POST /api/v1/admin/nibis/ingest         # Indexierung starten
GET  /api/v1/admin/nibis/status         # Status abfragen
GET  /api/v1/admin/nibis/stats          # Statistiken
POST /api/v1/admin/nibis/search         # Semantische Suche
GET  /api/v1/admin/nibis/collections    # Qdrant Collections
```

#### RAG Upload & Storage
```
POST /api/v1/admin/rag/upload           # ZIP/PDF hochladen
GET  /api/v1/admin/rag/upload/history   # Upload-Verlauf
GET  /api/v1/admin/rag/storage/stats    # MinIO Statistiken
```

#### Metrics & Feedback
```
GET  /api/v1/admin/rag/metrics          # Qualitätsmetriken
POST /api/v1/admin/rag/search/feedback  # Bewertung abgeben
POST /api/v1/admin/rag/init             # Services initialisieren
```

### Umgebungsvariablen

```bash
# Qdrant
QDRANT_URL=http://localhost:6333

# MinIO
MINIO_ENDPOINT=localhost:9000
MINIO_ACCESS_KEY=breakpilot
MINIO_SECRET_KEY=breakpilot123
MINIO_BUCKET=breakpilot-rag

# PostgreSQL
DATABASE_URL=postgres://breakpilot:breakpilot123@localhost:5432/breakpilot_db

# Embeddings
EMBEDDING_BACKEND=local
LOCAL_EMBEDDING_MODEL=all-MiniLM-L6-v2
```

### Aktuelle Indexierungs-Statistik

- **Dokumente**: 579 Erwartungshorizonte (NiBiS)
- **Chunks**: 7.352
- **Jahre**: 2016, 2017, 2024, 2025
- **Fächer**: Deutsch, Englisch, Mathematik, Physik, Chemie, Biologie, Geschichte, Politik-Wirtschaft, Erdkunde, Sport, Kunst, Musik, Latein, Informatik, Ev. Religion, Kath. Religion, Werte und Normen, etc.
- **Collection**: `bp_nibis_eh`
- **Vektor-Dimensionen**: 384
