# jnj_tower_ingest v1.2.0 **Soubor:** `jnj_tower_ingest_v1.2.py` **Datum:** 2026-06-10 **Autor:** vladimir.buzalka **Běží:** Docker kontejner `python-runner` na Unraid Tower (192.168.1.76), u MongoDB. ## Co to je Sjednocený **Tower-side ingest** JNJ e-mailů — tři fáze v jednom běhu (cron `*/5`): | Fáze | Co dělá | |---|---| | **1. PARSE** | `.msg` z `/mnt/JNJEMAILS` → tělo do Mongo `emaily."vbuzalka@its.jnj.com"`. Inkrementálně přes mtime watermark (`parse_state`). | | **2. SYNC** | nejnovější SQLite (read-only) → zrcadlo `jnj_messages` + `jnj_folder`/stav do `emaily`. Watermark `updated_at` + `last_db` + **NULL-safe** (viz níže). | | **3. ENRICH** | sdílený `5_enrich_fulltext_emails --mailbox vbuzalka@its.jnj.com` → PG fulltext. Jen když parse přidal nové dokumenty. | Pořadí **parse → sync → enrich**. Klíč = Internet Message-ID = Mongo `_id`. ## NULL-safe sync (v1.2 — oprava nesouladu Sent) **Problém:** na JNJ stroji běží vedle `jnj_mailbox_sync` i starý **`inbox_full_sync`**, který zapisuje řádky do SQLite s **`updated_at = NULL`** (stará schémata to pole neměla). Domácí sync přitom filtroval `WHERE updated_at > watermark`, a v SQL je `NULL > x = false` → **všechny NULL řádky tiše vypadly** (měly tělo v Mongu, ale nikdy nedostaly `jnj_folder`). Týkalo se 69 400 ze 70 060 řádků. **Oprava:** sync teď bere i řádky s `updated_at IS NULL`, které ještě **nejsou** v `jnj_messages` (zpracují se právě jednou; už zrcadlené NULL řádky se levně přeskočí). Nic se už tiše nezahodí. `last_db` short-circuit zůstává (nezměněná SQLite = okamžitý no-op). **Kořen na JNJ straně (mimo tento skript):** ideálně vyřadit/nahradit naplánovaný `inbox_full_sync` za `jnj_mailbox_sync --mode capture` (nastavuje `updated_at`). ## Argumenty `--dry-run`, `--full`, `--limit N`, `--reindex`, `--force` (sync: ignoruj last_db), `--parse-only` / `--sync-only` / `--enrich-only`, `--no-enrich`, `--enrich-always`. ## Spouštění ```bash docker exec python-runner python3 /scripts/jnj_tower_ingest_v1.2.py # cron docker exec -it python-runner python3 /scripts/jnj_tower_ingest_v1.2.py --dry-run docker exec python-runner python3 /scripts/jnj_tower_ingest_v1.2.py --sync-only --full # backfill ``` ## Plánování Unraid User Scripts `jnj_state_sync` (cron `*/5`) → wrapper s `flock` volá v1.2. Log jen reálná práce → `/mnt/user/Scripts/logs/jnj_tower_ingest.log`. ## Revert `jnj_tower_ingest_v1.1.py` (bez NULL-safe), `_v1.0.py` (bez enrich), `parse_emails_tower_v1.3.py`, `sync_jnj_state_v1.0.py` zůstávají v `/scripts/`. ## Historie verzí - **1.0.0** — sjednocení parse + sync (mtime watermark). - **1.1.0** — + fáze ENRICH (sdílený `5_enrich --mailbox`). - **1.2.0** — SYNC NULL-safe: bere i `updated_at IS NULL` řádky (jinak je watermark filtr tiše zahazoval → maily měly tělo, ale ne `jnj_folder`). + jednorázový `--full` backfill.