Files

3.6 KiB

PanoramaContacts — CLAUDE.md

Účel adresáře

Import kontaktů středisek (site contacts) z exportů systému PANORAMA (CTMS) do MySQL a jejich zobrazení ve Streamlit web reportu. Filtruje pouze záznamy pro Czechia. Aktuálně pokryté protokoly:

Protocol ID TA
77242113UCO3001 Immunology
42847922MDD3003 Neuroscience

Soubory

Soubor Účel
import_CZ_contacts.py Import xlsx → MySQL
webreport.py Streamlit web report
run_webreport.py PyCharm launcher (streamlit run webreport.py)
sql/create_CTMS_contacts.sql DDL tabulky CTMS_contacts
SourceData/*.xlsx PANORAMA Dashboard exporty (zdrojová data)
filter_state.json Automaticky ukládaný stav filtrů (generuje app)

MySQL

  • Host: 192.168.1.76:3306 · DB: studie · Tabulka: CTMS_contacts
  • Sheet v xlsx: Site Contacts, header na řádku 6 (0-based index 5)

Klíčové sloupce tabulky

Sloupec Typ Poznámka
file_date DATE Z dcterms:created v docProps/core.xml xlsx
imported_at DATETIME Auto timestamp importu
protocol_id VARCHAR(20) Identifikátor studie
site_id VARCHAR(15) Středisko (např. DD5-CZ10006)
contact_role VARCHAR(50) Role kontaktu (PI, Study Coordinator, …)
contact_start_date DATE Začátek platnosti kontaktu
contact_end_date DATE Konec platnosti — NULL = stále aktivní
email VARCHAR(100) Hlavní e-mail

import_CZ_contacts.py

  • Zpracuje všechny *.xlsx v SourceData/
  • Přeskočí soubory, jejichž file_date ≠ dnešní datum (UTC)
  • Přepis: DELETE + INSERT podle (file_date, protocol_id, country_name)
  • clean_value() převede NaN / NaT / Timestamp na typy přijatelné MySQL driverem

webreport.py — Streamlit app

Filtry (sidebar)

Filtr Widget Logika options
Střediska radio Aktivní / Neaktivní / Všechna
Protokol selectbox Z celé DB
Role multiselect Filtrováno dle protokolu + aktivní/neaktivní
Site multiselect Filtrováno dle protokolu + aktivní/neaktivní
Hledání text_input Fulltext přes všechny sloupce řádku

Logika filtru Střediska

Hodnota Site podmínka End Date podmínka
Aktivní site_id v ACTIVE_SITES contact_end_date IS NULL
Neaktivní site_id NOT v ACTIVE_SITES bez omezení
Všechna bez omezení bez omezení

Aktivní střediska (ACTIVE_SITES)

"77242113UCO3001": {
    "DD5-CZ10001", "DD5-CZ10003", "DD5-CZ10006", "DD5-CZ10009",
    "DD5-CZ10010", "DD5-CZ10012", "DD5-CZ10013", "DD5-CZ10015",
    "DD5-CZ10016", "DD5-CZ10020", "DD5-CZ10021", "DD5-CZ10022",
}
"42847922MDD3003": {
    "S10-CZ10004", "S10-CZ10008", "S10-CZ10011", "S10-CZ10012",
}

Perzistence filtrů

  • Stav se ukládá do filter_state.json při každé změně filtru (on_change=save_filter_state)
  • Načítá se jednou za session přes flag filters_initialized v st.session_state
  • Při načítání se hodnoty validují vůči aktuálním options (ochrana před zastaralými daty)

Clipboard tlačítko

  • Knihovna pyperclip — kopíruje přímo do Windows clipboardu ze serverové strany
  • Formát: Jméno Příjmení <email@domain.cz>; …
  • Reaguje na aktuálně zobrazené (filtrované) záznamy

Cache

  • @st.cache_data(ttl=300) — data se drží 5 minut
  • Tlačítko 🔄 Obnovit data volá st.cache_data.clear() + st.rerun()

Závislosti (venv)

mysql-connector-python
pandas
openpyxl
streamlit
pyperclip