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
| 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)
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)