# jnj_tower_ingest v1.1.0

**Soubor:** `jnj_tower_ingest_v1.1.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 dříve oddělené části v jednom běhu:

| Fáze | Dříve samostatně | Co dělá |
|---|---|---|
| **1. PARSE** | `parse_emails_tower_v1.3.py` | `.msg` z `/mnt/JNJEMAILS` → dokument v Mongo `emaily."vbuzalka@its.jnj.com"` (tělo, přílohy, hlavičky, MAPI). Inkrementálně přes **mtime watermark** (`jnj_sync_state`/`_id="parse_state"`). |
| **2. SYNC** | `sync_jnj_state_v1.0.py` | nejnovější SQLite (read-only) → zrcadlo `jnj_messages` + doplnění `jnj_folder`/stavu do `emaily`. Watermark `updated_at` + zkratka `last_db`. |
| **3. ENRICH** | `jnj_emails_to_fulltext_v1.0.py` | doindexuje JNJ schránku do **PG fulltextu** zavoláním **sdíleného** `5_enrich_fulltext_emails_vX.Y.py --mailbox vbuzalka@its.jnj.com` (stejný extractor jako Graph pipeline → konzistentní schéma). |

**Pořadí: parse → sync → enrich.** Čerstvě naparsovaný mail dostane v jednom běhu tělo
(parse) + cestu (sync) + fulltext (enrich). Klíč všude = Internet Message-ID = Mongo `_id`.

## Inkrementálnost (cron každých 5 min)

- **PARSE** — jen `.msg` s `mtime > parse_state.last_parse_mtime`. 1. běh = seed dle
  filename v Mongu, pak čistě mtime. `--full` reparsuje vše. Indexy jen při full/seed/`--reindex`.
- **SYNC** — watermark `updated_at` + zkratka `last_db` (stejná SQLite → no-op).
- **ENRICH** — spustí se **jen když parse přidal nové dokumenty** (jinak přeskočí — JNJ
  stejně enrichuje hlavní Graph pipeline v 6:00/18:00). Verze enrich se **auto-detekuje**
  (nejnovější `/scripts/5_enrich_fulltext_emails_v*.py`). `--no-enrich` vypne,
  `--enrich-always` vynutí.

Tři nezávislé události (nová `.msg` / nová `.db` / nové doc pro PG) → skript udělá jen to,
co má práci; jinak levný no-op.

## Vztah ke Graph pipeline

Hlavní `0_run_pipeline` (Graph API) zpracovává schránky buzalka.cz a **JNJ přeskakuje**
(`SKIP_MAILBOXES`, žádné API). JNJ řeší tenhle skript přes `.msg`. Obě cesty ústí do téhož
Monga `emaily` a přes **sdílený `5_enrich`** do téhož PG `MongoEmaily.emails`. Servisní
kolekce `jnj_messages` + `jnj_sync_state` jsou v enrich `NON_MAILBOX_COLLECTIONS`
(nejsou schránky → nejdou do PG).

## Argumenty

| Argument | Význam |
|---|---|
| `--dry-run` | nic nezapíše, jen plán všech fází |
| `--full` | parse: reparsuj vše; sync: ignoruj watermark; enrich: vynuť |
| `--limit N` | max N souborů (parse) / řádků (sync) |
| `--reindex` | vynutí indexy po parse |
| `--force` | sync: ignoruj `last_db` |
| `--parse-only` / `--sync-only` / `--enrich-only` | jen daná fáze |
| `--no-enrich` | přeskoč enrich |
| `--enrich-always` | spusť enrich i bez nových dokumentů |

## Spouštění

```bash
docker exec -it python-runner python3 /scripts/jnj_tower_ingest_v1.1.py --dry-run
docker exec python-runner python3 /scripts/jnj_tower_ingest_v1.1.py          # cron
docker exec -it python-runner python3 /scripts/jnj_tower_ingest_v1.1.py --enrich-only
```

## Plánování (HOTOVO)

Unraid User Scripts úloha `jnj_state_sync` (cron `*/5 * * * *`) — wrapper s `flock` volá
`docker exec python-runner python3 /scripts/jnj_tower_ingest_v1.1.py`. Loguje jen reálnou
práci/chyby do `/mnt/user/Scripts/logs/jnj_tower_ingest.log`
(grep `Zapisuji|PARSE hotovo|SYNC hotovo|ENRICH hotovo|CHYBA|Traceback`).

## Revert

`jnj_tower_ingest_v1.0.py` (bez enrich) + `parse_emails_tower_v1.3.py` +
`sync_jnj_state_v1.0.py` zůstávají v `/scripts/` jako pojistka. Návrat = přepsat wrapper
zpět. `jnj_emails_to_fulltext` přesunut do Trash (nahrazen fází 3).

## Historie verzí

- **1.0.0** 2026-06-10 — sjednocení parse + sync (mtime watermark, pořadí parse→sync).
- **1.1.0** 2026-06-10 — + fáze ENRICH (sdílený `5_enrich --mailbox`, auto-detekce verze,
  jen při nových dokumentech). Nahrazuje `jnj_emails_to_fulltext_v1.0`.
