{"queue_id": 57, "relative_path": "Solutions/HISTORICAL_IMPORT_VALIDATION.md", "title": "Historical Import Validation Report", "import_key": "4512912188cec0154d6f4d5fddca8ab792c0d1063700b99ab03057055708926c", "chunk_count": 23, "created_nodes": 24, "created_relationships": 45, "body": null, "chunks": [{"chunk_key": "389523bac24479c43dc64fdf2034bf98fbdcdf4c0896b945c85b01f8301a9eb0", "chunk_index": 0, "heading": "Historical Import Validation Report", "text": "# Historical Import Validation Report\n\n**Erstellt:** 2026-05-24\n**Autor:** AG (Claude Sonnet 4.6)\n**Status:** Abgeschlossen\n\n---", "text_hash": "3e4f65e493854e4effc452163d0d7080d17c28860b9a3a5e88db875da5633022"}, {"chunk_key": "934d2387dfbb00ab1540aac61698303a4d2d5209b1ee87ec3008b590c31ae471", "chunk_index": 1, "heading": "1. Ausgangslage", "text": "# Historical Import Validation Report\n\n**Erstellt:** 2026-05-24\n**Autor:** AG (Claude Sonnet 4.6)\n**Status:** Abgeschlossen\n\n---\n## 1. Ausgangslage", "text_hash": "a619e2a2cf01b77834504e6a52b057368bec9535fc29a6ff340a634236332613"}, {"chunk_key": "cba22006192d0d655a0ed3b699aab0c5c37716d0f95aa84d321e112663472d6b", "chunk_index": 2, "heading": "Verzeichnisse geprüft", "text": "## 1. Ausgangslage\n### Verzeichnisse geprüft\n\n| Pfad (Container) | Pfad (Host) | Status |\n|------------------|-------------|--------|\n| `/opt/data/gmail/raw/` | `/opt/struktur/hermes-carlo/data/gmail/raw/` | War leer — jetzt 25 Dateien |\n| `/opt/data/gmail/inbox_log.json` | `/opt/struktur/hermes-carlo/data/gmail/inbox_log.json` | 4 Einträge ohne Raw-Dateien |\n| `/opt/data/gmail/error_log.json` | `/opt/struktur/hermes-carlo/data/gmail/error_log.json` | Leer (`[]`) |", "text_hash": "d390947faa4a44470732976820be0d1c0a7bea809aca211ab635d33a9875caf1"}, {"chunk_key": "54548491ba1336f3328406b4106057fb41ca673543e76f09375a54d085c147ee", "chunk_index": 3, "heading": "Vorgefundene Probleme", "text": "_log.json` | 4 Einträge ohne Raw-Dateien |\n| `/opt/data/gmail/error_log.json` | `/opt/struktur/hermes-carlo/data/gmail/error_log.json` | Leer (`[]`) |\n### Vorgefundene Probleme\n\n1. **Raw-Dateien fehlten komplett**: Der Cron-Job `gmail_ingestion_01` war als LLM-Prompt implementiert. Der erste Lauf (2026-05-24 08:18) hatte einen unvollständigen Prompt — er setzte `processed`-Labels und schrieb `inbox_log.json`, erstellte aber **keine Raw-Dateien**.\n\n2. **Race Condition**: `processed`-Label wurde gesetzt, **bevor** Raw-Datei gespeichert wurde.\n\n3. **Kein `gmail_source_type` Feld**: Raw-Dateien hatten keine Klassifizierung der E-Mail-Quelle.\n\n4. **Label `historical_import` fehlte**: Kein Gmail-Label für historisch importierte Mails.\n\n5. **48+ historische E-Mails unverarbeitet**: Aus dem importierten lueftungsprofi.m@gmail.com-Konto.\n\n6. **1 E-Mail (Sicherheitswarnung) ohne inbox_log-Eintrag**: Wurde in einem früheren Lauf mit `processed` markiert, aber nicht geloggt.\n\n---", "text_hash": "2b50e99664630bb00e32e21bd88f8f7506cc8f40952208f193bcda8e0a01c3eb"}, {"chunk_key": "9c8682f1993fc0c9d2d0c66a68016ad35721f21effdb72dd3f6d5fd123c4190c", "chunk_index": 4, "heading": "2. Anzahl verarbeiteter Mails", "text": "m-Konto.\n\n6. **1 E-Mail (Sicherheitswarnung) ohne inbox_log-Eintrag**: Wurde in einem früheren Lauf mit `processed` markiert, aber nicht geloggt.\n\n---\n## 2. Anzahl verarbeiteter Mails", "text_hash": "e346225aa67aee9a9d77645cd8a6410415cc4a1f238be4242fe6f05991765729"}, {"chunk_key": "447372e6a4f8cda16ddf50e9a5d439ecbaccfa74d0b253a083eccfbe98c6e81f", "chunk_index": 5, "heading": "Verarbeitungs-Run 2026-05-24", "text": "## 2. Anzahl verarbeiteter Mails\n### Verarbeitungs-Run 2026-05-24\n\n| Phase | Anzahl |\n|-------|--------|\n| Retrofix (bereits-processed, fehlende Raw-Dateien) | 5 |\n| Neue historische Mails (Batch 1) | 20 |\n| **Gesamt Raw-Dateien nach Run** | **25** |\n| Noch ausstehend (nächste Cron-Läufe) | ~48 |", "text_hash": "72c0173508a93cfcb7bc7b8a025d6bf35510af1fc6ad2fe15c24332ca03b3a1a"}, {"chunk_key": "ab08e65c0ba25b44079e8a5a50073486247ce38890e54a3a3ca1af3c60390f15", "chunk_index": 6, "heading": "Aufschlüsselung nach `gmail_source_type`", "text": "w-Dateien) | 5 |\n| Neue historische Mails (Batch 1) | 20 |\n| **Gesamt Raw-Dateien nach Run** | **25** |\n| Noch ausstehend (nächste Cron-Läufe) | ~48 |\n### Aufschlüsselung nach `gmail_source_type`\n\n| Typ | Anzahl |\n|-----|--------|\n| `historical_import` | 20 |\n| `live_forward` | 5 |\n| `manual_forward` | 0 |\n\n---", "text_hash": "9e9984b261420677454c0445885b6be957243ac30c10d248d457fd4fea9a434d"}, {"chunk_key": "1ba67fa05ffc8a3d5a2c305e944daa5d1b2f5c52f147eee5b06576d4bf097857", "chunk_index": 7, "heading": "3. Raw-Dateien", "text": "üsselung nach `gmail_source_type`\n\n| Typ | Anzahl |\n|-----|--------|\n| `historical_import` | 20 |\n| `live_forward` | 5 |\n| `manual_forward` | 0 |\n\n---\n## 3. Raw-Dateien\n\n**Gesamtzahl:** 25 Dateien\n**Verzeichnis:** `/opt/data/gmail/raw/`\n**Namensschema:** `<gmail_message_id>.json`", "text_hash": "a732545b337d17a7bfa80299ece80ecfa991694a9d14e7230a61de07434bfaf0"}, {"chunk_key": "ee301d477dbeaae0d3e8a13d9afe848a7104b195d81e01f9dcafd466cbc51ab9", "chunk_index": 8, "heading": "Integritätsprüfung", "text": "## 3. Raw-Dateien\n\n**Gesamtzahl:** 25 Dateien\n**Verzeichnis:** `/opt/data/gmail/raw/`\n**Namensschema:** `<gmail_message_id>.json`\n### Integritätsprüfung\n\n| Prüfung | Ergebnis |\n|---------|----------|\n| Dateiname == `gmail_message_id` | ✅ Alle 25 korrekt |\n| Kein Overwrite existierender Raw-Dateien | ✅ `FileExistsError` wird geworfen |\n| Jede Raw-Datei hat inbox_log-Eintrag | ✅ 0 fehlende Einträge |\n| Jeder inbox_log-Eintrag hat Raw-Datei | ✅ 0 fehlende Raw-Dateien |\n| Duplikate in Raw-Dateien | ✅ 0 Duplikate |\n| Error-Log Einträge | ✅ 0 Fehler |\n\n---", "text_hash": "e81b45c22afcad4546bb7e2fcbc8f1662e2fba9962f7fa828714692f7081ea91"}, {"chunk_key": "8b95922cbd2133759f8f346daf7f9fd51a652a2e6d25f6eb5f735487d1446d65", "chunk_index": 9, "heading": "4. Duplikat-Erkennung", "text": "der inbox_log-Eintrag hat Raw-Datei | ✅ 0 fehlende Raw-Dateien |\n| Duplikate in Raw-Dateien | ✅ 0 Duplikate |\n| Error-Log Einträge | ✅ 0 Fehler |\n\n---\n## 4. Duplikat-Erkennung\n\nDie Duplikat-Erkennung erfolgt zweistufig:\n\n1. **Vor dem Speichern:** `raw_file_exists(message_id)` — prüft ob `raw/<message_id>.json` existiert\n2. **Beim Speichern:** `save_raw()` wirft `FileExistsError` wenn Datei bereits existiert\n\nBefund: **0 Duplikate** in den 25 Raw-Dateien gefunden.\n\n---", "text_hash": "e9a2987aae9e448565acbeff6469885046f30c08aa48f381c096218c0369db23"}, {"chunk_key": "a13cc304fd09ef6ee1b8fd3aba0b905e97bb843b4d5cd13ae9f298d0181a009e", "chunk_index": 10, "heading": "5. Fehlerfälle", "text": "2. **Beim Speichern:** `save_raw()` wirft `FileExistsError` wenn Datei bereits existiert\n\nBefund: **0 Duplikate** in den 25 Raw-Dateien gefunden.\n\n---\n## 5. Fehlerfälle\n\n**Keine Fehler** in diesem Lauf. Error-Log enthält `[]`.\n\n---", "text_hash": "793b0a05f2fced07bd2c7869e25c6f7f3e413fb5cd4ff92f0529675cc9872ab6"}, {"chunk_key": "b41eb5beb96da625ca505560f00338c1595ded14a814b23009561d38f61f0a20", "chunk_index": 11, "heading": "6. Gmail-Label `historical_import`", "text": "## 5. Fehlerfälle\n\n**Keine Fehler** in diesem Lauf. Error-Log enthält `[]`.\n\n---\n## 6. Gmail-Label `historical_import`\n\n- **Label-ID:** `Label_67`\n- **Erstellt:** 2026-05-24T13:19:00Z\n- **Sichtbarkeit:** `labelShow` / `messageListVisibility: show`\n- **Angewendet auf:** Alle 20 historischen Mails im ersten Batch\n\n**Regel:** Label wird gesetzt NACH erfolgreicher Raw-Speicherung — nie vorher.\n\n---", "text_hash": "11090b27b700e2a9b8a8a7ee3d8f889f000e0365473901a88acf58a0fa98f106"}, {"chunk_key": "0d06837fc1cda94160e83a67fe9c75cbad04d400e1daf8032d63fa1375923956", "chunk_index": 12, "heading": "7. Erkannte Risiken", "text": "\n- **Angewendet auf:** Alle 20 historischen Mails im ersten Batch\n\n**Regel:** Label wird gesetzt NACH erfolgreicher Raw-Speicherung — nie vorher.\n\n---\n## 7. Erkannte Risiken", "text_hash": "0af90ba7b921797617cad84bc26a003952e16d8e3e9c20992b4f1e85b568b651"}, {"chunk_key": "0236934a82219d9bae326f795e536baef041f00d3a14d7b981e7808ebfa87fb5", "chunk_index": 13, "heading": "Risiko 1: 48 ausstehende historische Mails", "text": "## 7. Erkannte Risiken\n### Risiko 1: 48 ausstehende historische Mails\n**Status:** Werden durch automatische Cron-Läufe (alle 15 Min, max 20 pro Lauf) verarbeitet.\n**Erwartung:** ~3 weitere Läufe bis vollständige Verarbeitung.", "text_hash": "a7f718703d5c958cde5202becb4274c28dd9ad836146361829b4e1426f9f919b"}, {"chunk_key": "2bf3af65c3fddce3d74e62b47a978b67269b6b5a4c5b135c95170fe9d0909fbf", "chunk_index": 14, "heading": "Risiko 2: Cron-Job bleibt LLM-Prompt-basiert", "text": "tus:** Werden durch automatische Cron-Läufe (alle 15 Min, max 20 pro Lauf) verarbeitet.\n**Erwartung:** ~3 weitere Läufe bis vollständige Verarbeitung.\n### Risiko 2: Cron-Job bleibt LLM-Prompt-basiert\n**Status:** Prompt wurde vereinfacht auf direkten Script-Aufruf.\n**Restrisiko:** LLM könnte das Script falsch aufrufen. Empfehlung: Langfristig auf `no_agent: true` + `script`-Feld umstellen.", "text_hash": "17c2ad1e9a1253dc434a9627182b7dbf261b4a539fb7f0764d0d0af4802c3676"}, {"chunk_key": "2d0ca7ae5c8639a6e98288d29ac2f2fbfd6eba7df74b2dc209dcecc7ed3fc946", "chunk_index": 15, "heading": "Risiko 3: OAuth-Token-Ablauf", "text": "direkten Script-Aufruf.\n**Restrisiko:** LLM könnte das Script falsch aufrufen. Empfehlung: Langfristig auf `no_agent: true` + `script`-Feld umstellen.\n### Risiko 3: OAuth-Token-Ablauf\n**Status:** Token läuft ab (kein festes Datum im Token bekannt).\n**Empfehlung:** Token-Erneuerungsstrategie definieren.", "text_hash": "61bb4392367c235f5d464477cc62fbba468370e2059ef6478f12c6a19446fc16"}, {"chunk_key": "0168138c54db011f52ed81b71aacf80c88a960f2c84bb7bba03d910197dd9ddf", "chunk_index": 16, "heading": "Risiko 4: Source-Type-Heuristik nicht 100% treffsicher", "text": "# Risiko 3: OAuth-Token-Ablauf\n**Status:** Token läuft ab (kein festes Datum im Token bekannt).\n**Empfehlung:** Token-Erneuerungsstrategie definieren.\n### Risiko 4: Source-Type-Heuristik nicht 100% treffsicher\n**Logik:**\n- `manual_forward`: Betreff beginnt mit \"Fwd:\" oder \"FW:\"\n- `historical_import`: Datum < 2026 ODER hat Nicht-System-Labels\n- `live_forward`: alles andere\n\n**Schwäche:** E-Mails aus 2026 mit Projekt-Labels würden als `historical_import` klassifiziert. In der Praxis kein Problem da neue Mails keine LPM-Projekt-Labels haben.\n\n---", "text_hash": "134a5bc7ea3eb59cf0b14ffb12930206ac439f44de9d8b910acc42884d71da2a"}, {"chunk_key": "fdbc74611455a5d4b1eb175e78228c190b235315c5863c187d6cd777f7f82933", "chunk_index": 17, "heading": "8. Beispielstruktur einer Raw-Mail", "text": "us 2026 mit Projekt-Labels würden als `historical_import` klassifiziert. In der Praxis kein Problem da neue Mails keine LPM-Projekt-Labels haben.\n\n---\n## 8. Beispielstruktur einer Raw-Mail\n\n```json\n{\n \"gmail_message_id\": \"19e5a035da1ee7f2\",\n \"gmail_thread_id\": \"19e5a035da1ee7f2\",\n \"import_timestamp\": \"2026-05-24T13:19:22Z\",\n \"gmail_source_type\": \"historical_import\",\n \"original_folder\": \"INBOX/! Aemter/Kooperationen/Mallorca Immobilien\",\n \"from_raw\": \"LPM <info@lueftungsprofi-mallorca.com>\",\n \"to_raw\": \"info@mallorca-immobilien.com\",\n \"subject\": \"Raumklima-Probleme rechtzeitig loesen – Verkaufsprozesse absichern\",\n \"date\": \"Tue, 5 Aug 2025 20:40:00 +0200\",\n \"body_raw\": \"Hallo Frau Langer,\\r\\n\\r\\ních bin Carlo Hammer...\",\n \"labels_at_import\": [\"INBOX/! Aemter/Kooperationen/Mallorca Immobilien\"],\n \"processing_status\": \"raw\"\n}\n```\n\n---", "text_hash": "78aa18222616f1bb35ce89c42e01493a0e2be83a627d2682b292956a31786803"}, {"chunk_key": "e8bef71e35241b46e6ba07dd8f5493e08936d89e4480410d79351c06835b232c", "chunk_index": 18, "heading": "9. Implementierte Änderungen", "text": "\\r\\n\\r\\ních bin Carlo Hammer...\",\n \"labels_at_import\": [\"INBOX/! Aemter/Kooperationen/Mallorca Immobilien\"],\n \"processing_status\": \"raw\"\n}\n```\n\n---\n## 9. Implementierte Änderungen", "text_hash": "9d0ce1491b84e076d2159586284dd63f3f76c8877daa0cdd1dae6bfab59f40c6"}, {"chunk_key": "6f257c7273acdcf3beb386c00c3ad81ec7612126448dd7e62fc8fefb6e52458b", "chunk_index": 19, "heading": "Neues Script: `/opt/data/gmail/gmail_ingest.py`", "text": "## 9. Implementierte Änderungen\n### Neues Script: `/opt/data/gmail/gmail_ingest.py`\n\nErsetzt den unzuverlässigen LLM-Prompt für die Raw-Ingestion. Funktionen:\n- `detect_source_type()` — bestimmt `gmail_source_type`\n- `save_raw()` — speichert Raw-Datei, niemals Overwrite\n- `retrofix_processed_mails()` — repariert fehlende Raw-Dateien\n- `create_historical_label()` — erstellt Gmail-Label via API\n- Fehlerbehandlung: `failed`-Label + error_log.json\n- Duplicate-Check: zweistufig (Datei-Existenz + FileExistsError)", "text_hash": "bd0c14172af3f19cf3aafe4a17e521baad155eea337db0a2186e27c5b0dc058f"}, {"chunk_key": "7f420ace70a955f6f853c60332559240d6358c16453babf56d4c331e1dc51849", "chunk_index": 20, "heading": "Cron-Job `gmail_ingestion_01` aktualisiert", "text": ")` — erstellt Gmail-Label via API\n- Fehlerbehandlung: `failed`-Label + error_log.json\n- Duplicate-Check: zweistufig (Datei-Existenz + FileExistsError)\n### Cron-Job `gmail_ingestion_01` aktualisiert\n\nNeuer Prompt ruft Script direkt auf:\n```\nFuehre aus: python3 /opt/data/gmail/gmail_ingest.py --max 20\n```", "text_hash": "1cf5439419cc1fd020db912d649c5e5cc8ccf4282b66170fe0ed711e2aa1315f"}, {"chunk_key": "2fdd39afa0233c3be545b24f0a9a3616ca9dea8a3f29538614d95a47ee7ee58f", "chunk_index": 21, "heading": "Retroaktive Raw-Dateien für 5 bereits-processed Mails", "text": " Cron-Job `gmail_ingestion_01` aktualisiert\n\nNeuer Prompt ruft Script direkt auf:\n```\nFuehre aus: python3 /opt/data/gmail/gmail_ingest.py --max 20\n```\n### Retroaktive Raw-Dateien für 5 bereits-processed Mails\n\nAlle 5 E-Mails aus dem ersten Lauf (08:18) haben jetzt Raw-Dateien.\n1 zusätzlicher Eintrag (Sicherheitswarnung) wurde in inbox_log.json ergänzt.\n\n---", "text_hash": "28596184dad7d600f85b0934955d84322c1e192552bea1ab9165e98196a924b7"}, {"chunk_key": "e7afa4d24ef2e96064069de14995f37756bd8f5cc0fc3b675f374bb9f87dd1db", "chunk_index": 22, "heading": "10. Unveränderliche Garantien (eingehalten)", "text": "\nAlle 5 E-Mails aus dem ersten Lauf (08:18) haben jetzt Raw-Dateien.\n1 zusätzlicher Eintrag (Sicherheitswarnung) wurde in inbox_log.json ergänzt.\n\n---\n## 10. Unveränderliche Garantien (eingehalten)\n\n- ✅ Keine Obsidian-Writes\n- ✅ Keine Graphiti-Writes\n- ✅ Keine automatische Projektzuordnung\n- ✅ Keine automatischen Contact-Merges\n- ✅ Original-E-Mails wurden nicht verändert\n- ✅ processed-Label wird erst nach erfolgreicher Raw-Speicherung gesetzt", "text_hash": "0f14f741919d12e860d585b528b25642478c9ef0c6cbce5b83bf92b1e491b9ad"}], "elapsed_s": 0.078}