Diary RAG System - Documentation

Das Crumbforest Diary RAG System ist jetzt vollstΓ€ndig integriert! Kinder kΓΆnnen Tagebuch-EintrΓ€ge erstellen, die automatisch indexiert und durchsuchbar gemacht werden.

🎯 Was wurde implementiert?

1. Database Schema

Neue Tabellen (compose/init/04_diary_schema.sql):
- children - Kinder/Nutzer mit Access Tokens
- diary_entries - Tagebuch-EintrΓ€ge
- audit_log - GDPR-konforme Audit-Logs

Erweiterte Tabelle:
- post_vectors - Neue Spalten: post_type, child_id

2. Pydantic Models

Neue Models (app/models/rag_models.py):
- DiaryIndexRequest / DiaryIndexResponse
- DiarySearchRequest / DiarySearchResponse
- DiaryAskRequest / DiaryAskResponse
- DiarySearchResult

3. API Endpoints

Neuer Router (app/routers/diary_rag.py):
- POST /api/diary/index - Indexiert Tagebuch-Eintrag
- POST /api/diary/search - Semantic Search im Tagebuch
- POST /api/diary/ask - RAG Query (Q&A)
- GET /api/diary/{child_id}/status - Indexing-Status

4. Integration Test

Test-Suite (tests/test_integration.py):
- Kompletter End-to-End Test
- PHP -> FastAPI -> Qdrant Flow
- Alle 6 Schritte validiert

πŸ“‹ API Endpoints

1. Index Diary Entry

POST /api/diary/index
Content-Type: application/json

{
  "entry_id": 1,
  "child_id": 1,
  "content": "# Heute im Wald\n\nIch habe einen Igel gesehen!",
  "provider": "openai"
}

Response:

{
  "status": "success",
  "entry_id": 1,
  "child_id": 1,
  "chunks": 3,
  "collection": "diary_child_1",
  "provider": "openai"
}

2. Search Diary

POST /api/diary/search
Content-Type: application/json

{
  "child_id": 1,
  "query": "Igel",
  "provider": "openai",
  "limit": 5
}

Response:

{
  "results": [
    {
      "entry_id": 1,
      "content": "Ich habe einen Igel gesehen...",
      "score": 0.95,
      "created_at": "2025-01-15T10:30:00"
    }
  ],
  "query": "Igel",
  "child_id": 1,
  "provider": "openai"
}

3. RAG Query (Ask)

POST /api/diary/ask
Content-Type: application/json

{
  "child_id": 1,
  "question": "Was habe ich im Wald gesehen?",
  "provider": "openai",
  "context_limit": 3
}

Response:

{
  "answer": "Du hast einen Igel im Wald gesehen. Du warst mit deinem Papa spazieren...",
  "question": "Was habe ich im Wald gesehen?",
  "child_id": 1,
  "sources": [
    {
      "entry_id": 1,
      "content": "Ich war heute mit Papa im Wald...",
      "score": 0.95,
      "created_at": "2025-01-15T10:30:00"
    }
  ],
  "provider": "openai",
  "model": "gpt-4o-mini"
}

4. Get Status

GET /api/diary/1/status

Response:

{
  "child_id": 1,
  "total_entries": 5,
  "indexed_entries": 5,
  "total_vectors": 15,
  "last_indexed": "2025-01-15T10:30:00",
  "collection_name": "diary_child_1"
}

πŸ”§ Setup & Deployment

1. Environment Variables

FΓΌge zu .env hinzu:

# AI Provider API Keys (mindestens einen)
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
OPENROUTER_API_KEY=sk-or-...

# Default Providers
DEFAULT_EMBEDDING_PROVIDER=openai
DEFAULT_COMPLETION_PROVIDER=openai

2. Database Migration

# Starte Docker Compose neu, um die neuen Tabellen zu erstellen
cd compose
docker compose down
docker compose up --build

# Alternativ: FΓΌhre das Schema-Update manuell aus
docker compose exec -T db sh -lc \
  'mariadb -u"$MARIADB_USER" -p"$MARIADB_PASSWORD" "$MARIADB_DATABASE"' \
  < compose/init/04_diary_schema.sql

3. Verify Installation

# Health Check
curl http://localhost:8000/health

# List all routes
curl http://localhost:8000/__routes | grep diary

# Check providers
curl http://localhost:8000/admin/rag/providers

πŸ§ͺ Testing

Run Integration Test

# Stelle sicher, dass Docker Compose lΓ€uft
cd compose && docker compose up -d

# Setze API Key (mindestens einen)
export OPENAI_API_KEY=sk-...

# FΓΌhre Test aus
python tests/test_integration.py

Erwartete Ausgabe:

============================================================
Crumbforest Integration Test
PHP <-> FastAPI <-> Qdrant
============================================================
βœ“ API is healthy
βœ“ Connected to database
βœ“ Cleaned up test data

=== Step 1: Create Child ===
βœ“ Created child with ID: 1

=== Step 2: Create Diary Entry ===
βœ“ Created diary entry with ID: 1

=== Step 3: Index Diary Entry ===
βœ“ Indexed successfully:
  - Status: success
  - Chunks: 3
  - Collection: diary_child_1
  - Provider: openai

=== Step 4: Search Diary ===
βœ“ Search successful:
  - Query: Igel
  - Results: 1

=== Step 5: RAG Query (Ask Question) ===
βœ“ RAG query successful:
  - Answer: Du hast einen Igel im Wald gesehen...

=== Step 6: Check Indexing Status ===
βœ“ Status: All entries indexed

============================================================
βœ“ ALL TESTS PASSED!
============================================================
Wuuuuhuuu! πŸ’š

πŸ”— PHP Integration

PHP FastAPI Client

Nutze die existierende class.fastapi.php:

<?php
require_once 'classes/class.fastapi.php';

$api = new FastAPIClient('http://fastapi:8000');

// Index diary entry
$response = $api->post('/api/diary/index', [
    'entry_id' => $entry_id,
    'child_id' => $child_id,
    'content' => $diary_content,
    'provider' => 'openai'
]);

if ($response['success']) {
    echo "Indexed successfully!";
}

// Search diary
$results = $api->post('/api/diary/search', [
    'child_id' => $child_id,
    'query' => 'Igel',
    'provider' => 'openai',
    'limit' => 5
]);

// RAG query
$answer = $api->post('/api/diary/ask', [
    'child_id' => $child_id,
    'question' => 'Was habe ich im Wald gesehen?',
    'provider' => 'openai'
]);

πŸ“Š Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  PHP (8080) β”‚
β”‚             β”‚
β”‚ - Children  β”‚
β”‚ - Diary     β”‚
β”‚ - Tokens    β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β”‚ HTTP POST
       β”‚
       v
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ FastAPI (8000)  │────► β”‚ Qdrant:6333  β”‚
β”‚                 β”‚      β”‚              β”‚
β”‚ - RAG Service   β”‚      β”‚ Collections: β”‚
β”‚ - Embedding     β”‚      β”‚ - diary_1    β”‚
β”‚ - Provider      β”‚      β”‚ - diary_2    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚ - diary_N    β”‚
          β”‚              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚
          v
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  MariaDB:3306   β”‚
β”‚                 β”‚
β”‚ - children      β”‚
β”‚ - diary_entries β”‚
β”‚ - post_vectors  β”‚
β”‚ - audit_log     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ” Security & GDPR

Audit Logging

Alle Aktionen werden in audit_log protokolliert:
- diary_indexed - Eintrag wurde indexiert
- diary_searched - Tagebuch wurde durchsucht
- diary_rag_query - RAG Query wurde ausgefΓΌhrt

Data Isolation

  • Jedes Kind hat seine eigene Qdrant Collection: diary_child_{id}
  • Keine Cross-Child Zugriffe mΓΆglich
  • Token-basierter Zugriff ΓΌber QR-Codes

GDPR Compliance

  • Immutable Audit Log (INSERT ONLY)
  • Metadata als JSON fΓΌr FlexibilitΓ€t
  • CASCADE DELETE auf Kind-Ebene

🎨 Providers

UnterstΓΌtzte Provider

  1. OpenAI - text-embedding-3-small + gpt-4o-mini
  2. Claude - Voyage AI embeddings + Claude Sonnet
  3. OpenRouter - Flexible multi-provider

Provider wechseln

# In allen Requests:
{
  "provider": "claude"  # oder "openai", "openrouter"
}

πŸš€ Next Steps

1. PHP Integration

  • Erstelle php/api/diary/create.php
  • Integriere FastAPI-Aufruf nach Diary Creation
  • FΓΌge Background-Worker fΓΌr Batch-Indexing hinzu

2. UI Features

  • Admin Dashboard fΓΌr Diary Stats
  • Kind-spezifische RAG Query Page
  • Token-generierung fΓΌr Kinder

3. Advanced Features

  • Multi-lingual Diary Support
  • Emotion Detection
  • Automatic Tagging
  • Export als PDF

πŸ“ž Support

Bei Fragen oder Problemen:
1. Check logs: docker compose logs -f app
2. Verify DB: docker compose exec db mariadb -u crumb -p
3. Test Qdrant: curl http://localhost:6333/collections


Wuuuuhuuu! Das Diary RAG System ist fertig! πŸ’š