--- doc_type: technical_reference audience: developer, architect scope: database, qdrant, schema, agentic_validation status: active version: 4.5.8 context: "Exakte Definition der Datenmodelle (Payloads) in Qdrant und Index-Anforderungen. Berücksichtigt WP-14 Modularisierung, WP-15b Multi-Hashes und WP-24c Phase 3 Agentic Edge Validation (candidate: Präfix, verified Status)." --- # Technisches Datenmodell (Qdrant Schema) ## 1. Collections & Namenskonvention Mindnet speichert Daten in drei getrennten Qdrant-Collections. Der Prefix ist via ENV `COLLECTION_PREFIX` konfigurierbar (Default: `mindnet`). Die Auflösung erfolgt zentral über `app.core.database.collection_names`. Das System nutzt folgende drei Collections: * `{prefix}_notes`: Metadaten der Dateien. * `{prefix}_chunks`: Vektorisierte Textsegmente. * `{prefix}_edges`: Gerichtete Graph-Kanten. --- ## 2. Note Payload (`mindnet_notes`) Repräsentiert die Metadaten einer Markdown-Datei (1:1 Beziehung). **JSON-Schema:** ```json { "note_id": "string (keyword)", // UUIDv5 (deterministisch via NAMESPACE_URL) "title": "string (text)", // Titel aus Frontmatter "type": "string (keyword)", // Logischer Typ (z.B. 'project', 'concept') "status": "string (keyword)", // Lifecycle: 'stable', 'active', 'draft', 'system' (WP-22) "retriever_weight": "float", // Effektive Wichtigkeit (Frontmatter > Type > Default) "chunk_profile": "string", // Effektives Profil (Frontmatter > Type > Default) "edge_defaults": ["string"], // Liste der aktiven Default-Kanten "tags": ["string"], // Liste von Tags aus Frontmatter "aliases": ["string"], // Synonyme für Discovery (WP-11) "created": "string (iso-date)", // Erstellungsdatum "updated": "integer", // Timestamp (File Modification Time) "fulltext": "string (no-index)", // Gesamter Text (nur für Recovery/Export) // Multi-Hash für flexible Change Detection (WP-15b) "hashes": { "body:parsed:canonical": "string", // Hash nur über den Text-Body "full:parsed:canonical": "string" // Hash über Text + Metadaten (Tags, Title, Config) } } ``` **Erforderliche Indizes:** Es müssen Payload-Indizes für folgende Felder existieren: * `note_id` * `type` * `status` * `tags` --- ## 3. Chunk Payload (`mindnet_chunks`) Die atomare Sucheinheit. Enthält den Vektor. **Vektor-Konfiguration:** * Modell: `nomic-embed-text` (via Ollama oder Cloud) * Dimension: **768** * Metrik: Cosine Similarity **JSON-Schema:** ```json { "chunk_id": "string (keyword)", // Format: UUIDv5 aus {note_id}#c{index} "note_id": "string (keyword)", // Foreign Key zur Note "type": "string (keyword)", // Kopie aus Note (Denormalisiert für Filterung) "text": "string (text)", // Reintext für Anzeige (ohne Overlap) "window": "string (text)", // Text + Overlap (Basis für Embedding) "ord": "integer", // Laufende Nummer (1..N) für Sortierung "retriever_weight": "float", // Geerbt von Note (für schnelles Re-Ranking) "chunk_profile": "string", // Geerbt von Note (für Debugging/Filtering) "neighbors_prev": ["string"], // ID des Vorgängers (Linked List) "neighbors_next": ["string"], // ID des Nachfolgers "section": "string", // Pfad/Überschrift, zu der der Chunk gehört "source_path": "string" // Relativer Pfad zur Datei } ``` **Erforderliche Indizes:** Es müssen Payload-Indizes für folgende Felder existieren: * `note_id` * `chunk_id` * `type` --- ## 4. Edge Payload (`mindnet_edges`) Gerichtete Kanten zwischen Knoten. Stark erweitert in v2.6 für Provenienz-Tracking. Seit v2.9.1 unterstützt das System **Section-basierte Links** (`[[Note#Section]]`), die in `target_id` und `target_section` aufgeteilt werden. **JSON-Schema:** ```json { "edge_id": "string (keyword)", // Deterministischer Hash aus (src, dst, kind, variant) // variant = target_section (erlaubt Multigraph für Sections) "source_id": "string (keyword)", // Chunk-ID (Start) "target_id": "string (keyword)", // Chunk-ID oder Note-Titel (bei Unresolved) // WICHTIG: Enthält NUR den Note-Namen, KEINE Section-Info "target_section": "string (keyword)", // Optional: Abschnitts-Name (z.B. "P3 – Disziplin") // Wird aus [[Note#Section]] extrahiert "kind": "string (keyword)", // Beziehungsart (z.B. 'depends_on') "scope": "string (keyword)", // Immer 'chunk' (Legacy-Support: 'note') "note_id": "string (keyword)", // Owner Note ID (Ursprung der Kante) // Provenance & Quality (WP03/WP15/WP-24c) "provenance": "keyword", // 'explicit', 'explicit:note_zone', 'explicit:callout', 'rule', 'semantic_ai', 'structure', 'candidate:...' (vor Phase 3) "rule_id": "string (keyword)", // Traceability: 'inline:rel', 'explicit:wikilink', 'candidate:...' (vor Phase 3), 'explicit' (nach Phase 3 VERIFIED) "confidence": "float", // Vertrauenswürdigkeit (0.0 - 1.0) "scope": "string (keyword)", // 'chunk' (Standard) oder 'note' (Note-Scope Zonen) - WP-24c v4.2.0 "virtual": "boolean (optional)" // true für automatisch generierte Spiegelkanten (Invers-Logik) - WP-24c v4.5.8 } ``` **Section-Support (WP-15c):** * Links wie `[[Note#Section]]` werden in `target_id="Note"` und `target_section="Section"` aufgeteilt. * **Self-Links:** `[[#Section]]` wird zu `target_id="current_note_id"` und `target_section="Section"` aufgelöst. * Die Edge-ID enthält die Section als `variant`, sodass mehrere Kanten zwischen denselben Knoten existieren können, wenn sie auf verschiedene Sections zeigen (Multigraph-Modus). * Semantische Deduplizierung basiert auf `src->tgt:kind@sec` Key, um "Phantom-Knoten" zu vermeiden. * **Metadaten-Persistenz:** `target_section`, `provenance` und `confidence` werden durchgängig im In-Memory Subgraph und Datenbank-Adapter erhalten. **Phase 3 Validierung (WP-24c v4.5.8):** * **candidate: Präfix:** Kanten mit `candidate:` in `rule_id` oder `provenance` durchlaufen Phase 3 Validierung * **Vor Validierung:** `provenance: "candidate:global_pool"` oder `rule_id: "candidate:..."` * **Nach VERIFIED:** `candidate:` Präfix wird entfernt, Kante wird persistiert * **Nach REJECTED:** Kante wird **nicht** in die Datenbank geschrieben (verhindert "Geister-Verknüpfungen") * **Wichtig:** Nur Kanten ohne `candidate:` Präfix werden im Graph persistiert **Note-Scope vs. Chunk-Scope (WP-24c v4.2.0):** * **Chunk-Scope (`scope: "chunk"`):** Standard, `source_id = chunk_id` (z.B. `note-id#c00`) * **Note-Scope (`scope: "note"`):** Aus Note-Scope Zonen, `source_id = note_id` (nicht `chunk_id`) * **Phase 3 Kontext-Optimierung:** Note-Scope nutzt `note_summary`/`note_text`, Chunk-Scope nutzt spezifischen Chunk-Text **Automatische Spiegelkanten (WP-24c v4.5.8):** * **virtual: true:** Markiert automatisch generierte Invers-Kanten (Spiegelkanten) * **Provenance:** `structure` (System-generiert, geschützt durch Provenance Firewall) * **Confidence:** Leicht gedämpft (`original * 0.9`) im Vergleich zu expliziten Kanten **Erforderliche Indizes:** Es müssen Payload-Indizes für folgende Felder existieren: * `source_id` * `target_id` * `target_section` (neu: Keyword-Index für Section-basierte Filterung) * `kind` * `scope` * `note_id` ```