---
name: project-iwrs-mongo
description: IWRS data kompletně v MongoDB studie — 8 hlavních kolekcí + 5 snapshot. MySQL je nyní read-only archiv. Pipeline IWRS/Patients/run_all.py + IWRS/Drugs/run_all.py píše přímo do Mongo.
metadata: 
  node_type: memory
  type: project
  originSessionId: 7e135172-3d69-4283-801f-d2450be664a9
---

**Vše IWRS migrováno do MongoDB databáze `studie`. MySQL je nyní read-only archiv.**

## Hlavní kolekce (upsert = aktuální stav)
- `iwrs_imports` — log běhů importu (sekvenční import_id)
- `iwrs_subject_summary` — `_id = "{study}:{subject}"`, sjednoceno pro obě studie (společná pole + study-specifická vedle)
- `iwrs_visits` — `_id = "{study}:{subject}:{irt_transaction_no|scheduled_date}:{desc}"`
- `iwrs_notifications` — `_id = pk` (IWRS unique), obsahuje text + medications[] + fields{} + PDF jako BinData
- `iwrs_shipments` — `_id = shipment_id`
- `iwrs_shipment_items` — `_id = "{shipment_id}:{medication_id}"`
- `iwrs_inventory` — `_id = "{site}:{medication_id}"`
- `iwrs_destruction` — `_id = "{basket_id}:{medication_id}"` (immutable)

## Snapshot kolekce (append-only s `import_id`)
`iwrs_subject_summary_snapshots`, `iwrs_visits_snapshots`, `iwrs_shipments_snapshots`, `iwrs_shipment_items_snapshots`, `iwrs_inventory_snapshots`. Notifications + destruction snapshoty nepotřebují (immutable).

## Struktura kódu
- [IWRS/common/mongo_writer.py](IWRS/common/mongo_writer.py) — sdílené helpers (to_str/to_int/to_date converters, get_db, ensure_indexes, log_import, bulk_upsert_with_snapshot, bulk_upsert_only)
- [IWRS/Patients/import_to_mongo.py](IWRS/Patients/import_to_mongo.py) — subject_summary + visits parser z XLSX
- [IWRS/Patients/import_notifications_to_mongo.py](IWRS/Patients/import_notifications_to_mongo.py) — PDF+JSON z disku rovnou do Mongo (parsuje text per typ, PDF jako BinData, přesun do Zpracováno/)
- [IWRS/Drugs/import_to_mongo.py](IWRS/Drugs/import_to_mongo.py) — shipments + items + inventory + destruction
- [IWRS/backfill_mysql_to_mongo.py](IWRS/backfill_mysql_to_mongo.py) — jednorázový backfill historie z MySQL (už proběhlo)
- [IWRS/Patients/parse_notifications_to_mongo.py](IWRS/Patients/parse_notifications_to_mongo.py) — starší parser MySQL→Mongo (parsery z něj reuse-uje `import_notifications_to_mongo.py`)

## Pipeline
- `IWRS/Patients/run_all.py`: download (Playwright) → `import_to_mongo.run()` (summary + visits) → `import_notifications_to_mongo.main()` (PDF/JSON → Mongo)
- `IWRS/Drugs/run_all.py`: download (Playwright) → `drugs_mongo.run()` (shipments + items + inventory + destruction)

**Why:** UCO3001 a MDD3003 mají hodně podobnou ale ne shodnou sadu polí (společných ~16, study-specifických ~14–17). Per-studie MySQL tabulky = schema sprawl při každé nové studii. Schemaless Mongo + sjednocení = přidání nové studie znamená jen nový parser, žádné DDL. Notifikace navíc obsahují lot/expirace/clinical response/audit trail, které XLSX reporty nemají.

**How to apply:** Pro nové analýzy/dotazy IWRS dat používej Mongo `studie.iwrs_*`. MySQL `studie.iwrs_*` nech být (read-only). Po nějaké době ověření lze MySQL IWRS tabulky dropnout. Související: [[project-edc-mongo]] — stejný Mongo server, stejný snapshot pattern.

**Známé limity parseru notifikací:**
- `Cohort` chybí u MDD3003 mimo `Screening` (v textu není)
- Když má klíč prázdnou hodnotu, parser vezme následující neprázdný řádek — občas v `fields` skončí název další sekce jako pseudohodnota (jen šum)
