--- aliases: ["MyICR Suite"] type: progetto --- # CLAUDE.md — MyICR_Suite **Versione:** v12 **Ultimo aggiornamento:** 2026-07-02 Suite applicativa ICR — dashboard TV, Linker, MediaTrack. Architettura: Flask API layer + HTML/JS/CSS frontend + PyQt6 per moduli tabellari Excel-like. ## Moduli [[app/modules/linker/CLAUDE|Linker]] · [[app/modules/mediatrack/CLAUDE|MediaTrack]] · [[app/modules/powerbricks/CLAUDE|PowerBricks]] > Contesto specifico per modulo nei rispettivi CLAUDE.md: > - `app/modules/linker/CLAUDE.md` > - `app/modules/mediatrack/CLAUDE.md` > - `app/modules/powerbricks/CLAUDE.md` --- ## Regola architetturale fondamentale: NO MS Access **MyICR_Suite non deve usare MS Access (pyodbc, .accdb, ODBC driver) come sorgente dati.** - Tutte le sorgenti dati: **DuckDB + Parquet** o **SQLite** - `CUSTOM_ANAGR_ORIZ` e tabelle simili → join DuckDB sui Parquet di DataHub_v2 - Tabelle con scritture → SQLite sidecar - Linker: migrazione completata (2026-04-29) --- ## Stack tecnologico - **Python 3.11.9** embedded standalone (`python\`) - **Flask** — unico API layer - **DuckDB** — query in-memory sui Parquet DataHub_v2 - **SQLite** — dati locali con scritture (mediatrack.db, linker.db) - **PyQt6 == 6.7.0 PINNED** — solo per moduli tabellari Excel-like - **Parquet DataHub_v2** — fonte di verità per tutti i dati TV --- ## Struttura directory ``` app/ modules/ linker/ — PyQt6, tabellare Excel-like mediatrack/ — Flask + HTML, MediaTrack dashboard/ — Flask + HTML, dashboard diritti/tipologie/em_pivot powerbricks/ — Visual Query Builder + NL Query frank_jobs/ — bat eseguiti da Frank daemon (usare path locali C:\PYTHON_LOCAL\...) launcher_src/ — bootstrap + sync shared_db sync_db/ — mediatrack.db, altri DB SQLite sincronizzati local_db/ — dati locali (posters, cache) ``` --- ## Sorgenti dati | Dato | Sorgente | Note | |---|---|---| | Prodotti TV | `DataHub_v2/parquet/prodotti.parquet` | weekly | | Diritti | `DataHub_v2/parquet/diritti.parquet` | weekly — solo FREE/Analogico-DVB-T; colonne date tipo DATE nativo | | Emesso | `DataHub_v2/parquet/emesso.parquet` | weekly | | IMDB | `DataHub_v2/parquet/imdb.parquet` | weekly | | Cast | `DataHub_v2/parquet/cast.parquet` | weekly | | Gemma | `DataHub_v2/parquet/gemma.parquet` | daily | | Osservatorio | `DataHub_v2/parquet/osservatorio.parquet` | daily | | MediaTrack | `sync_db/mediatrack.db` (SQLite) | aggiornato da OMDB Batch Enrich | | CUSTOM_ANAGR_ORIZ | join DuckDB sui Parquet | implementato in `parquet_db.py` → `v_custom_anagr` | --- ## Sync mediatrack.db — protocollo (2026-05-18) **Server = fonte di verità.** DB server: `I:\SOFTWARE\PYTHON_SRV\sync_db\mediatrack.db` **Funzione principale:** `pull_and_preserve_local()` in `launcher_src/shared_db_sync.py` - Chiamata al bootstrap (una volta sola all'avvio) - Sequenza: snapshot locale → pull server → merge locale on top → push se ci sono aggiunte - Il server vince sui record già esistenti - I record nuovi in locale vengono preservati e pushati **Background push:** ogni 5 minuti via timer + al quit dell'app. --- ## frank_jobs I bat in `frank_jobs/` vengono eseguiti dal daemon Frank (background, no drive mappati). **Usare sempre path locali** `C:\PYTHON_LOCAL\MyICR_Suite\...` — mai UNC o `I:\`. --- ## Gotcha: DFS e path di rete `\\mediaset.it\share\Indirizzo_Controllo_Risorse` è un namespace DFS con repliche fuori sync dal 17/03/2026. **Non usare mai UNC nel codice.** | Contesto | Path da usare | |---|---| | Deploy manuale | `I:\SOFTWARE\PYTHON_SRV\PYTHON_LOCAL\MyICR_Suite\` | | Bootstrap runtime (SERVER_ROOT) | derivato da `sys.argv[0]` — non hardcodato | | DB server sync (`config.json`) | `I:\SOFTWARE\PYTHON_SRV\sync_db\mediatrack.db` | | Frank jobs / daemon | `C:\PYTHON_LOCAL\MyICR_Suite\...` (locale) | | Codice applicativo runtime | `C:\PYTHON_LOCAL\MyICR_Suite\...` (locale) | ```python _script_dir = Path(sys.argv[0]).resolve().parent SERVER_ROOT = _script_dir if _script_dir != LOCAL_ROOT else Path(r"I:\SOFTWARE\PYTHON_SRV\PYTHON_LOCAL\MyICR_Suite") ```