--- name: pyeco-powerbricks description: "PowerBricks — visual query builder per colleghi ICR non tecnici, seme di progetto dormiente (zero codice scritto, cartella originale eliminata da PYTHON/ il 04/08/2026)" metadata: type: project --- Query builder visuale (Blockly, stile Scratch) che traduce blocchi in SQL su DuckDB/Parquet, per colleghi non tecnici. Nato come seme di progetto (metà luglio 2026, modulo `PYTHON/MyICR_Suite/app/modules/powerbricks/`, eliminato il 04/08/2026, commit `9937a81` nel repo `MyICR_Suite`) e da allora effettivamente costruito — prototipo reale in `sandbox/powerbricks/` (vedi sezioni sotto per la storia completa). **Materiale grezzo originale eliminato (10/08/2026)**: la copia raw salvata in migrazione (`PowerBricks-raw/` — specifica ufficiale, dizionario dati NL, skill `/nlquery`) è stata rimossa dall'archivio. Non era più riferimento attivo: il suo contenuto è ormai superato da due cose reali costruite nel frattempo — il prototipo `sandbox/powerbricks/` (proprio `CLAUDE.md` come fonte di verità aggiornata: 5 domini, stack pywebview, perno su Anagrafica non più fisso) e mcp-query/"PowerBricks LLM" (conoscenza di dominio in [[data-expert]], non nel vecchio dizionario NL). Lo skill `/nlquery` era comunque già morto (path interno rotto verso `datawarehouse/`, mai esistita). - **Posizionamento strategico** (chi sa cosa, rischio AllRights, ruoli): [[lavoro-progetti-strumenti]], paragrafo PowerBricks. - **Business logic dati as-is**: [[data-expert]] — non l'architettura app, quella è in `sandbox/powerbricks/CLAUDE.md`. ## Discrepanza nota — risolta il 06/08/2026 `agenda.md` (file sciolto in `PYTHON/`, recuperato e poi eliminato il 04/08/2026) conteneva un'idea di dominio di partenza **dinamico** ("il sistema suggerisce quello con più filtri attivi, l'utente può sovrascrivere tra anagrafica/emesso/diritti/boxoffice") — diversa dal perno **fisso** su Anagrafica della specifica ufficiale (`PowerBricks_Specifiche.md` §4). Verificato con Mauro (04/08/2026): non era una decisione deliberata di rivedere la specifica, "probabilmente riflessioni in tempi diversi" mai confrontate col documento ufficiale — trattato come corrente finché non deciso altrimenti. **Deciso esplicitamente il 06/08/2026**: Mauro ha rimosso il vincolo del perno fisso — vedi sezione "Consultazione standalone" più sotto per il dettaglio. Non è il dominio dinamico di `agenda.md` (nessun "suggerimento" automatico di quale dominio usare): più semplicemente, ogni tabella satellite può essere consultata **da sola**, senza dover comunque passare da Anagrafica. Altro dettaglio da `agenda.md`, non nella specifica ufficiale, di stato incerto (idea viva o superata? non verificato): - **Output base**: una lista di `rifer` passata a Linker, che renderizza autonomamente le informazioni associate. ## Doppia modalità blocchi + pseudo-linguaggio — confermata idea viva (04/08/2026) `[CONFERMATO]` — GUI a blocchi per l'utente base + pseudo-linguaggio testuale generato in parallelo, sincronizzato, per l'utente avanzato (modificare l'uno aggiorna l'altro) — parentesi tonde per l'ordine di esecuzione (es. `(emesso AND diritti) OR anagrafica`). Era già in `agenda.md` (30/07 circa) ma segnata "stato incerto" — Mauro ci è arrivato di nuovo in modo indipendente il 04/08/2026 ragionando sul problema dei blocchi che diventano ingombranti con query complesse: non è un'idea abbandonata, è il suo pensiero corrente. **Perché risolve un problema reale**: i blocchi visuali (Blockly) funzionano bene per composizioni semplici ma scalano male con 3+ domini incatenati e filtri incrociati (l'albero diventa grande e annidato quanto una query SQL, solo più lento da comporre col mouse). Pattern collaudato altrove, non speculativo — Power Query in Excel fa esattamente questo (passi visuali ↔ editor avanzato in linguaggio M): chi resta sul caso semplice non tocca mai il testo, chi ha una domanda complessa scrive direttamente. Vantaggio aggiuntivo per il pubblico ICR: uno pseudo-linguaggio con parentesi è più vicino all'alfabetizzazione da formula Excel (che molti colleghi già hanno) che alla programmazione vera — punto intermedio tra "troppo tecnico" e "troppo limitato". **Vocabolario di partenza**: le regole interpretative che i colleghi userebbero naturalmente (es. "film italiano" → `tipologia='FILM'` + `paesi_produzione1/2/3='I'`) sono ormai quelle vive in [[data-expert]] (il vecchio dizionario NL del ramo raw, superato, è stato rimosso il 10/08/2026) — riusabile come lessico per progettare la palette di blocchi/le parole chiave dello pseudo-linguaggio, senza reinventare da zero cosa intendono i colleghi per "prime time" o "film italiano". ## Strategia di partenza — prototipo minimo, due passi (04/08/2026) `[CONFERMATO]` — prima di affrontare i 4 domini, salire per gradi: 1. **Solo Anagrafica, zero join** — valida il meccanismo base dell'interfaccia (trascinamento campi, composizione filtri, risultati) senza nessuna complessità sopra. 2. **+ Emesso**, primo dominio vero aggiunto — non boxoffice (scartato: tabella marginale nel lavoro reale ICR, dati cinema tangenziali al cuore diritti/palinsesto; un prototipo che funziona su una tabella che nessuno usa non dimostra granché). Emesso porta con sé un problema reale da affrontare subito, non rimandabile: relazione **1:molti** con Anagrafica (un prodotto/edizione può avere decine/centinaia di righe, una per trasmissione, anche a distanza di anni) — quindi tre forme diverse della stessa domanda ("quando è andato in onda"): prima emissione, ultima emissione, tutte le emissioni. Richiede una scelta di aggregazione (min/max/nessuna) che l'interfaccia deve esporre esplicitamente — non un dettaglio rimandabile, perché la stessa scelta si ripresenterà identica con Diritti (un prodotto può avere più contratti nel tempo). Vale la pena progettarla bene una volta qui. Diritti resta per un terzo giro, quando l'interfaccia avrà già dimostrato di reggere sia il caso base sia la scelta di aggregazione. Risponde parzialmente alla domanda "che perimetro ha la v1" sotto — non definitiva, ma un punto di partenza concreto. **Decisione di design (05/08/2026) — colore dei blocchi per dominio**: quando si aggiungeranno Emesso/Diritti/Boxoffice, ogni dominio avrà la propria famiglia di colori per i blocchi (non tutti rossi come oggi solo-Anagrafica) — aiuta a distinguere a colpo d'occhio la provenienza di un blocco quando più domini convivranno nello stesso canvas. Non ancora implementato (oggi esiste solo Anagrafica): da definire in dettaglio quando si costruisce il passo 2. ## Prototipo passo 1 — in corso (05/08/2026) `[CONFERMATO]` — sandbox creata in `Dropbox/adrian/sandbox/powerbricks/` (repo principale `adrian`, non sotto `PYTHON/` — scrivibile anche da Nave, sync via Dropbox+git). Commit `6cad2b5`. **Stack effettivo, allineato a MediaTrack** (non quello ipotizzato nelle prime bozze di questa conversazione, poi corrette): Flask + `pywebview` (finestra desktop nativa, non browser) + DuckDB in-memory + Blockly nel frontend. Stesso pattern di `PYTHON/MyICR_Suite/app/modules/mediatrack/run.py`, dichiarato modello di riferimento in `MyICR_Suite/CLAUDE.md`. **Dati**: legge davvero `PYTHON/MyICR_Suite/local_db/parquet/prodotti.parquet` (226.431 righe, sola lettura, path relativo `../../PYTHON/...` — stesso su Nave e Ufficio) — non un mock. Campi esposti nel passo 1: `prodotto`, `titolo_italiano`, `titolo_originale`, `anno_produzione`, `tipologia`, `genere1`, `paesi_produzione1`, `veg`, `durata`. **Verificato da Nave**: backend Flask/DuckDB testato end-to-end via `test_client()` (filtri equals/contains/gt/gte su dati reali, validazione campo non valido → 400) — funziona. **Non ancora verificato**: il meccanismo a blocchi Blockly nel browser/finestra pywebview — Nave è headless, serve un display reale (PC ufficio, o sessione con GUI) per aprire `python run.py` e trascinare i blocchi davvero. **Aggiornamento 05/08/2026 — validato**: Mauro ha lanciato `run.bat` su PC ufficio, la finestra pywebview si apre correttamente (commit `b325739` per il bat di lancio). Meccanismo base considerato confermato. **Decisione 05/08/2026 — fase di test prima di Emesso**: Mauro ha voluto approfondire limiti e potenzialità della sola Anagrafica prima di passare al passo 2 (espressività filtri, tenuta con molti campi/filtri, usabilità dei blocchi con query complesse — "un po' tutto"). Ampliato di conseguenza il prototipo (commit `7c5b582`): blocco `pb_gruppo` AND/OR annidabile (prima solo AND flat), operatori estesi (`not_equals`, `contains`, `between`, `is_null`/`is_not_null`), tutti i 25 campi di `prodotti.parquet` filtrabili (prima 9). Verificato su dati reali via `test_client()` da Nave prima del test umano. **Esito test umano su Ufficio (05/08/2026)**: Mauro ha provato di persona i nuovi blocchi (gruppi annidati inclusi) — giudizio: **"va MOLTO bene, mi sembra sia la strada giusta"**. Non una semplice conferma funzionale come il primo giro (`run.bat` che apre la finestra): qui il meccanismo a blocchi è stato messo sotto sforzo con query più elaborate e ha retto bene, secondo l'uso reale che ne farebbe un collega. **Tre tentativi sull'output selezionabile, tutti scartati (05/08/2026)**: checkbox HTML → doppio elenco stile Access con frecce → blocco Blockly nativo (`field_checkbox`) + categorie toolbox. Giudizio di Mauro: "stai complicando inutilmente" — rollback a `git checkout 7c5b582 --` (output tornato a SELECT fissa) per fermarsi e riflettere prima di continuare a iterare da soli. **Riflessione che ha rimesso in discussione Blockly stesso**: la fatica nel far entrare la selezione output nel linguaggio a blocchi ha fatto notare a Mauro (Access power-user da una vita) che il modello mentale giusto per i colleghi non è il suo — e che Blockly porta con sé la metafora "blocchi di programmazione per bambini" (eredità Scratch/App Inventor/Code.org), non quella di un filtro per un pubblico alfabetizzato su Excel. Confronto MS Access / Power BI: entrambi risolvono la selezione campi con **un pannello dedicato e persistente**, separato dal canvas di composizione della logica (Access: trascina campi in una griglia QBE; Power BI: checkbox in un pannello Campi fisso) — non un widget minore infilato dentro il flusso. **Tentativo intermedio (05/08/2026) — WHERE su jQuery QueryBuilder, poi scartato**: libreria MIT dedicata a righe campo/operatore/valore + gruppi AND/OR annidabili (via CDN, jQuery+Bootstrap 5, nessun build step) — risolveva bene il disagio "blocchi da bambini". Ma **feedback di Mauro**: con QueryBuilder l'effetto "PowerBricks" (l'identità visiva a mattoncini che dà il nome al prodotto) si perdeva completamente — un compromesso peggiore del problema che si voleva risolvere. Commit `ea40579`. **Secondo tentativo (05/08/2026) — Blockly con renderer Zelos, poi anche questo accantonato**: tornato Blockly per la WHERE con renderer Zelos (Scratch/MakeCode, blocchi più chunky) per mitigare il disagio "programmazione per bambini" senza perdere l'identità a mattoncini. Commit `b94c84e`. Valutati anche i limiti reali di Blockly in questo giro: nessun vincolo di licenza/manutenzione (Apache 2.0, Google), unico limite non aggirabile l'accessibilità (drag&drop mouse-centrico, tastiera sperimentale, no screen reader) — non bloccante per un tool interno. **Reset esplicito (05/08/2026)**: dopo tutto questo andirivieni (output selezionabile in tre forme, poi QueryBuilder, poi Zelos), Mauro ha chiesto di **ripartire esattamente dalla versione "molto convinto"** invece di continuare a iterare sulle varianti successive. Ripristinato `git checkout 7c5b582 --`: stato identico al commit validato con entusiasmo — gruppi AND/OR annidati, tutti i 25 campi filtrabili, Blockly renderer default, output a SELECT fissa (nessuna selezione campi). Commit `488c56d`. **Tutto il lavoro su output/QueryBuilder/Zelos è accantonato**, non in backlog da riprendere automaticamente — se si riaffronta il tema, si riparte con occhi diversi, non dagli ultimi tentativi fatti oggi. **Soluzione trovata (05/08/2026) — modale a doppio click, VALIDATA**: ripartendo dal punto "molto convinto", nuova idea per l'output: doppio click sul blocco "Query Anagrafica" apre un modale HTML col doppio elenco disponibili/selezionati (frecce sposta/riordina) — il canvas Blockly resta pulito, solo filtri, identità "a mattoncini" intatta; la selezione si salva su `block.data` (serializzato automaticamente da Blockly, nessuna persistenza custom). Meccanica: estensione Blockly `pb_query_output_modal` con listener DOM `dblclick` su `block.getSvgRoot()`. Commit `9611e5d`. **Mauro ha testato su Ufficio e confermato: "il meccanismo mi piace"** — validato, non solo funzionante. **Stato complessivo passo 1**: sia il meccanismo filtri (blocchi + gruppi AND/OR) sia la selezione output (modale a doppio click) sono ora validati con convinzione da Mauro. Nessuna azione pendente sul frontend. **Prossimo passo concreto**: passo 2 — aggiungere Emesso, affrontare la scelta di aggregazione prima/ultima/tutte (relazione 1:molti con Anagrafica, vedi sezione sopra) — oppure ulteriori test sull'Anagrafica se Mauro preferisce continuare a esplorare prima di allargare il perimetro. ## Passo 2 — Emesso, prima implementazione (05/08/2026) `[CONFERMATO]` — implementato come previsto: blocco `pb_emesso` (join su `prodotto`+`edizione`, LEFT JOIN sempre) con dropdown aggregazione prima/ultima/tutte. Per prima/ultima uso una window function che restituisce la riga intera dell'emissione (non solo la data) — scelta più utile del semplice MIN/MAX. "Tutte" cambia la cardinalità del risultato (una riga per emissione). Nessun filtro sui campi Emesso in questo giro, solo aggregazione + output selezionabile (stesso modale a doppio click del passo 1, generalizzato per riusarlo su entrambi i blocchi). Verificato su dati reali da Nave: query sotto il secondo anche con la window function su 8,8M righe di `emesso.parquet`. Dettaglio tecnico completo in `sandbox/powerbricks/CLAUDE.md`, sezione "Passo 2 — Emesso". **Colore dominio**: seguendo la decisione di design già registrata sopra, `pb_emesso` è ambra/oro (`#F9A825`) — un solo blocco per ora, distinto dal rosso di Anagrafica; una famiglia completa (medio/chiaro) si definirà quando arriveranno altri blocchi Emesso-specifici (es. filtri). **Validato su Ufficio (05/08/2026)**: Mauro ha provato il blocco Emesso di persona — "Molto bene". Tag `powerbricks-checkpoint-emesso-05082026` sul commit validato. **Richiesta successiva (05/08/2026) — Emesso reso flessibile quanto Anagrafica**: subito dopo la validazione, Mauro ha chiesto che Emesso avesse WHERE oltre a SELECT (fin lì solo aggregazione + campi in output). Aggiunti `pb_filtro_emesso`/`pb_gruppo_emesso` (stessa logica di `pb_filtro`/`pb_gruppo`), agganciati in un nuovo slot filtri dentro `pb_emesso`. Backend generalizzato per tabella (`_build_filtro`/`_build_where` parametrici su `fields_dict`/`table_alias` invece di hardcoded su Anagrafica). I filtri Emesso si applicano dentro la subquery, prima di scegliere prima/ultima emissione. Dettaglio tecnico completo in `sandbox/powerbricks/CLAUDE.md`. Verificato su dati reali da Nave. **Sganciamento `pb_query`/`pb_emesso` (05/08/2026)**: Mauro ha corretto l'impostazione — non voleva `pb_emesso` nidificato dentro `pb_query` (slot "Emesso opzionale"), ma **due blocchi container indipendenti sulla lavagna**, "Query Anagrafica" e "Query Emesso", che viaggiano separati. La join resta implicita (fissa su `prodotto`+`edizione`, nessuna scelta esplicita) — Mauro ha segnalato che in futuro potrebbe arrivare un blocco "ponte" per definire il tipo di join, ma non è una priorità ora. Backend invariato (join implicita già uguale), solo il frontend cambia: `getEmessoConfig(workspace)` cerca `pb_emesso` ovunque sulla lavagna invece di leggerlo da uno slot annidato. **Spunto valutato e accantonato — gruppo AND/OR agnostico**: Mauro ha chiesto se il blocco "gruppo" potesse essere unico per tutti i domini (colore neutro) invece di duplicato (`pb_gruppo`/`pb_gruppo_emesso`). Risposta: tecnicamente possibile, ma la duplicazione oggi non è decorativa — è ciò che garantisce via `check` Blockly che un gruppo Anagrafica non finisca nello slot Emesso (o viceversa), impedendolo all'incastro invece di scoprirlo come errore a runtime. Un blocco generico romperebbe questa garanzia, a meno di un check dinamico (più codice). **Deciso: restare semplice**, due blocchi distinti, non implementato. **Rinomina + aggregazione rimandata (05/08/2026)**: Mauro ha chiarito che i blocchi si chiamano meglio "Tabella Anagrafica"/"Tabella Emesso" (dichiarano una tabella, non una query completa) e che l'aggregazione (prima/ultima/tutte) va tenuta separata dal blocco tabella — sarà un blocco a sé in uno step successivo, non integrata in "Tabella Emesso". Rinominati i blocchi, rimosso il dropdown aggregazione dal frontend; il backend resta pronto (default "tutte" quando l'aggregazione non è specificata, la logica prima/ultima via window function è invariata in attesa del futuro blocco). **Gotcha reale trovato da Mauro testando (05/08/2026) — LEFT JOIN nascondeva il filtro Emesso**: con LEFT JOIN sempre attiva, un filtro su Emesso (es. rete=I1) non restringeva i prodotti Anagrafica — chi non corrispondeva usciva comunque, solo con le colonne Emesso a NULL. Fix: INNER JOIN quando ci sono filtri Emesso (un filtro deve restringere), LEFT quando non ce ne sono (Emesso arricchisce senza restringere). Verificato su dati reali (tipologia=FILM): senza filtri 471.494 righe (52.215 NULL, LEFT corretto); con rete=I1, 30.690 righe zero NULL (INNER corretto). **Blocco ponte esplicito `pb_join` (05/08/2026)**: la regola automatica sopra non copriva un caso legittimo — "mostrami tutti i prodotti, e se disponibile mostrami solo l'emissione su rete X" (LEFT + filtro solo per la visualizzazione). Aggiunto un blocco indipendente e facoltativo "Join Anagrafica ↔ Emesso" con tendina Automatico/LEFT forzato/INNER forzato, colore neutro grigio (è un ponte tra domini, non appartiene a una tabella). Se assente, vale la regola automatica di prima. Verificato tutti e tre i casi su dati reali, conteggi coerenti tra loro. **Stato attuale**: due domini (Anagrafica, Emesso) entrambi con WHERE+SELECT completi, blocchi "Tabella" container indipendenti, join di default automatica (INNER-se-filtri-altrimenti-LEFT) con possibilità di forzarla esplicitamente via `pb_join`, nessuna aggregazione nel frontend (rimandata). **Non ancora testato visivamente su Ufficio** il blocco ponte. ## Terzo dominio implementato: Boxoffice, non Diritti (06/08/2026) `[CONFERMATO]` — la strategia originale (sezione sopra, 04/08/2026) aveva scartato Boxoffice esplicitamente ("tabella marginale nel lavoro reale ICR") a favore di Diritti come terzo dominio. Mauro è tornato sulla decisione il 06/08/2026 chiedendo di aggiungerlo comunque, motivazione tecnica più che strategica ("è semplice") — confermata sui dati: relazione **1:1** su `prodotto` (39.771 righe = 39.771 prodotti distinti, nessun duplicato), quindi senza il problema di aggregazione prima/ultima/tutte che rende Emesso (e in futuro Diritti, stessa relazione 1:molti) più costoso da modellare. Non un abbandono di Diritti — resta il prossimo dominio "vero" da affrontare, questo è stato un giro laterale a basso costo. Dettaglio tecnico completo in `sandbox/powerbricks/CLAUDE.md`, sezione "Terzo dominio — Boxoffice". **Stato dopo questa aggiunta**: tre domini nel prototipo (Anagrafica, Emesso, Boxoffice), tutti con WHERE+SELECT completi, ognuno con blocco ponte facoltativo per forzare LEFT/INNER contro Anagrafica. Toolbox riorganizzato in categorie native Blockly per dominio (vedi sotto) proprio in vista di questa crescita. ## Toolbox a categorie invece di lista piatta (06/08/2026) `[CONFERMATO]` — con l'aggiunta di Emesso il toolbox flat (tutti i blocchi di tutti i domini sempre visibili) ha iniziato a mostrare il limite anticipato: con 3-4 domini diventa un elenco lungo da scorrere. Discusse alcune opzioni con Mauro (pannello di selezione tabella a monte, due pannelli custom sincronizzati) prima di convergere su una soluzione nativa Blockly: il **category toolbox** (stesso pattern "Logic/Loops/Math" dei playground ufficiali) è già di fatto un sistema a due pannelli — elenco categorie colorate a sinistra, flyout a comparsa coi blocchi della categoria selezionata — senza costruire nulla di custom. Aggiunto anche un bottone "Seleziona campi output..." dentro ogni flyout (via `registerButtonCallback` nativo), stessa modale del doppio click sul blocco ma più scopribile per chi non sa che il doppio click esiste. Dettaglio tecnico in `sandbox/powerbricks/CLAUDE.md`. ## Quarto dominio implementato: Diritti, solo campi grezzi (06/08/2026) `[CONFERMATO]` — il dominio "vero" rimandato dopo il giro laterale su Boxoffice (sezione sopra). La specifica ufficiale segnala che Diritti non è un semplice JOIN come gli altri tre: titolarità %, passaggi residui, first-run/re-run e inibizioni sono logica di business derivata, non chiavi relazionali — "il cuore del valore" del progetto secondo il documento originale. Risponde parzialmente a una delle domande aperte del vecchio dossier Elon sotto ("dove si ferma la logica diritti nella prima versione — farla tutta subito rischia di non finire mai"): questo giro si è fermato deliberatamente ai soli campi grezzi del contratto (18 campi: distributore, percentuali, passaggi, decorrenza/scadenza, causale, inibizioni), join 1:molti su prodotto+edizione senza aggregazione, escludendo esplicitamente le 45 colonne `*_WIN_1..9` (nove finestre storiche per riga) che sono il materiale grezzo della logica derivata — quella resta un layer a sé, non affrontato in questo giro. Stesso principio "prototipo minimo" già usato per Emesso/Boxoffice. Trovato e corretto nello stesso giro un bug preesistente nel pannello pseudo-lingua: i filtri Boxoffice (aggiunti nel giro precedente) non comparivano nell'anteprima testuale pur funzionando correttamente nella query vera — percorso di codice separato non aggiornato quando Boxoffice fu aggiunto. Verificato su dati reali da Nave (SQL diretto, `test_client()`, `playwright` headless) — **non ancora testato visivamente** su Ufficio. Dettaglio tecnico completo in `sandbox/powerbricks/CLAUDE.md`, sezione "Quarto dominio — Diritti". **Bug reale segnalato da Mauro testando su Ufficio (06/08/2026)**: filtrare `decr` con un confronto (`gte`) falliva — le colonne data erano tipizzate `"string"` (equals/contains soltanto), non `"date"` (che abilita anche i confronti). Stesso bug presente anche su `data_emissione` (Emesso) e `data_debutto` (Boxoffice), non specifico di Diritti — corretto per tutti e tre insieme con un nuovo tipo `"date"` nel motore filtri. Nessuna modifica frontend necessaria (la tendina operatori era già generica). ## Quinto dominio implementato: Gemma, join tramite IMDb (06/08/2026) `[CONFERMATO]` — Mauro ha chiesto di aggiungere `gemma.parquet` (dataset di tracking acquisizioni/screener, livello "pre-prodotto", non da OnAir come gli altri parquet) con un vincolo esplicito: il join va fatto tramite **codice IMDb**, non tramite `A_CODICE_PRODOTTO` (che pure esiste ma copre solo il 9,5% delle righe). Percorso di join a catena: `gemma.A_COD_IMDB` → `imdb.riferimento_imdb` → `imdb.codice` = `prodotti.prodotto`. Verificato e accettato un fan-out reale (`imdb.riferimento_imdb` non è univoco, fino a 41 codici interni per lo stesso ID IMDb) — stesso principio già applicato ai fan-out di Emesso/Diritti, non filtrato/deduplicato in questo primo giro. Tutti i 58 campi (meno la chiave di join) esposti come "Tabella Gemma", stesso schema minimale degli altri domini. Verificato da Nave (SQL a più stadi, `test_client()`, `playwright` headless con screenshot) — **non ancora testato visivamente** su Ufficio. Dettaglio tecnico completo in `sandbox/powerbricks/CLAUDE.md`, sezione "Quinto dominio — Gemma". ## Idea valutata e non implementata — "superblocco" a C per il join (06/08/2026) Spunto di Mauro: invece del blocco ponte anonimo (pallino grigio), un blocco a forma di "C" che contenga visivamente le due tabelle unite, con la scelta di join incorporata. Idea respinta per un motivo strutturale, non estetico: in Blockly un blocco può stare dentro un solo genitore alla volta, ma oggi Anagrafica si unisce **contemporaneamente** a Emesso/Boxoffice/Diritti/Gemma nella stessa query — un contenitore fisico costringerebbe a duplicare "Tabella Anagrafica" dentro ogni C, oppure tornerebbe al modello "una tabella dentro l'altra" già scartato il 05/08 per lo stesso motivo di rigidità. Deciso di lasciare il modello attuale (tabelle indipendenti + blocco ponte) invariato. ## Consultazione standalone — Anagrafica non più obbligatoria (06/08/2026) `[CONFERMATO]` — nato dalla discussione sul superblocco a C sopra: parlando di Gemma (il cui legame con Anagrafica è già debole, solo 9,5% di copertura) Mauro ha notato che non serve sempre passare da Anagrafica, ed esteso subito il ragionamento a tutte le tabelle: "anche le altre tabelle potrebbero venire consultate AS IS". Rimuove esplicitamente il perno fisso su Anagrafica della specifica ufficiale (§4) — vedi "Discrepanza nota" sopra, ora risolta. **Scope confermato con Mauro**: solo consultazione a **tabella singola** — una tabella satellite alla volta, letta così com'è, utile per "fare una verifica su una tabella". Non include combinare due tabelle satellite tra loro senza Anagrafica (richiederebbe chiavi di join dirette tra coppie di satelliti, oggi non definite — tema a sé se servirà in futuro). Se sulla lavagna non c'è "Tabella Anagrafica" ma c'è esattamente una tabella satellite, quella diventa la fonte diretta della query, saltando la logica che esiste solo per il legame con Anagrafica (aggregazione di Emesso, risoluzione IMDb di Gemma). Con più di una tabella satellite e nessuna Anagrafica, errore esplicito invece di un comportamento indovinato. Verificato con `test_client()` e `playwright` headless (tabella singola, caso ambiguo, lavagna vuota). Dettaglio tecnico completo in `sandbox/powerbricks/CLAUDE.md`, sezione "Consultazione standalone". ## Idea per il futuro — "PowerBricksLLM", versione vocale via voice-chat (06/08/2026, non implementata — voice-chat smantellato 12/08/2026) Spunto di Mauro collegando il lavoro della mattina su voice-chat (dialogo vocale con questa sessione, validato end-to-end) a PowerBricks: interrogare i dati in linguaggio naturale a voce invece che a blocchi. Già anticipato in `sandbox/voice-chat/CLAUDE.md` ("propedeutico a un'eventuale versione vocale di PowerBricks ma non ancora collegato") — non un'idea nuova, solo il momento in cui è stata nominata esplicitamente come prossimo passo. **Punto chiarito da Mauro, tecnicamente corretto**: questa versione **non userebbe Blockly** — i blocchi visuali servono per l'utente non tecnico che compone filtri a mano; un'interrogazione vocale in linguaggio naturale salterebbe l'interfaccia a blocchi e userebbe solo la **logica di business sottostante** (schema campi, regole WHERE/JOIN già in `backend/server.py`, motore DuckDB sui parquet). Il pezzo tecnicamente più semplice non sarebbe nemmeno un livello NL→blocchi separato (i "due binari" del ramo NL sperimentale, vedi [[data-expert]]): la sessione Claude Code che già risponde a voice-chat potrebbe interpretare la domanda e chiamare direttamente `/api/query` (endpoint già esistente), senza intermediari. **Deciso: non ora** — si resta sul prototipo a blocchi, questa resta un'idea per un secondo giro futuro. ## Idea per il futuro — Backpack per cluster di filtri riutilizzabili (06/08/2026, non implementata) Spunto di Mauro dopo aver notato la funzione nativa "Backpack" di Blockly (zaino in cui trascinare blocchi da riusare dopo — non è nel core `blockly_compressed.js` già in uso qui, è un plugin a parte `@blockly/workspace-backpack`). Idea: permettere di salvare un cluster di filtri assemblati (es. "film italiano" = `tipologia=FILM` + `paesi_produzione1=I`, vocabolario già mappato in [[data-expert]]) per riutilizzarlo senza ricostruirlo da zero ogni volta. **Da tenere presente, non da implementare ora** — nessuna decisione su quando/se riprenderla. ## Prossimo passo (thread aperto 06/08/2026 sera, da riprendere) — griglia risultati Excel-style, PyQt6 Spunto di Mauro guardando avanti a "domani" (venerdì): sostituire `results_grid.py` (oggi un semplice `QTableWidget` statico, senza ordinamento né filtro) con una griglia risultati vera, Excel-style — ordinamento + filtro per colonna, pensata da subito per essere **riusabile in più punti**, non cucita a un solo posto. **Ricognizione fatta la sera del 06/08 su cosa esiste già in MyICR_Suite** (per non reinventare qualcosa di già pronto): nessun pezzo esistente fa sia ordinamento sia filtro insieme in modo riusabile. - **Ordinamento**: c'è un vero componente condiviso, `app/widgets/detail_table_base.py` (`DetailTableBase(QTableWidget)`) — header cliccabili, sort su DataFrame pandas, già adottato da `dash_em_pivot` (mentre `dash_diritti` ha ancora la versione duplicata pre-refactor). - **Filtro stile Excel** (per colonna, sui dati già caricati, non una nuova query): esiste **solo** dentro Linker (`linker/src/gui/gemma_sheet.py` + `filter_bar.py`), architettura diversa (`QAbstractTableModel` + header custom + `FilterBar`), mai resa un pezzo condiviso. - MediaTrack (web) e Frank sono più semplici ancora (solo ordinamento manuale o niente). **Correzione a una mia imprecisione della stessa sera**: avevo detto "coerenza con lo stack usato ovunque nell'app (Linker, dashboard)" come se tutto fosse PyQt6 — non è così. **MediaTrack è Flask+pywebview+JavaScript vanilla, esattamente come PowerBricks**, non PyQt6. L'ecosistema ha due famiglie di stack distinte, non una sola: Flask+pywebview+JS (MediaTrack, PowerBricks) vs PyQt6 nativo (Linker, dashboard di `app/features/`). "Restare coerenti con lo stack" non è quindi un argomento a favore netto di PyQt6 per la griglia di PowerBricks — PowerBricks *stesso* è già nella famiglia web (il canvas Blockly), e la griglia risultati oggi è PyQt6 solo perché aperta come processo separato (pywebview e PyQt6 non condividono lo stesso loop eventi), non per una scelta di design deliberata. **Valutata l'alternativa web**: si era considerato di uscire dal PyQt6-per-la-griglia usando una libreria JS matura dentro la stessa finestra pywebview — Tabulator (gratis, MIT, niente paywall sulle funzioni Excel-style, coerente col "niente build step" già in uso per Blockly) o AG Grid Community (bundle UMD senza bundler, ordinamento multi-colonna/filtri base/ virtualizzazione gratis, solo il filtro a checkbox stile Excel vero è Enterprise — stessa conclusione di Tabulator sul punto). Il vantaggio concreto: Adrian può verificare una UI web con Playwright anche da Nave headless (pattern nato col prototipo voice-chat, smantellato 12/08/2026 — vedi "Pattern riconosciuti" in `memory/MEMORY.md`; sezione "Consultazione standalone" sopra), cosa che non può fare altrettanto facilmente con PyQt6 nativo (serve un display reale o `xvfb`, non ancora testato). **Framing risolto la sera del 06/08/2026 (voce, via voice-chat)**: invece di decidere la domanda grande ("dovremmo unificare tutto l'ecosistema su un solo stack?" — sollevata da Mauro dopo un giro di parere con Claude.ai su MediaTrack, poi accantonata come questione a sé, troppo grande per essere risolta di riflesso), Mauro ha semplificato: **PowerBricks è sperimentazione, quindi si costruisce la griglia migliore possibile lì, senza vincolarsi in anticipo alla tecnologia** — "se ci convince la utilizzeremo e la estenderemo [altrove], per ora ci limitiamo a PowerBricks". Quindi **né PyQt6 né web sono scartati a priori** per domani: la scelta si fa guardando cosa dà davvero il miglior risultato per questo prototipo, non per coerenza con il resto dell'ecosistema — quella domanda resta aperta e si riaffronta solo se/quando il risultato convince abbastanza da voler estendere il pattern. **Punto di partenza per quando si riprende**: valutare concretamente le due strade (PyQt6 in stile `DetailTableBase`+`FilterBar`/`gemma_sheet.py` di Linker, oppure Tabulator/AG Grid dentro la finestra pywebview esistente di PowerBricks) prima di scrivere codice — non ancora scoped in dettaglio, da fare quando si riprende il lavoro. ## Griglia risultati — decisione e implementazione (07/08/2026, validata) `[CONFERMATO]` — thread ripreso lo stesso giorno. Prima di scegliere una tecnologia, Mauro ha inquadrato l'obiettivo di fondo: la griglia Linker (MyICR, ex VBA) è il perno storico di molti punti dell'ecosistema — una riga per prodotto che riassume anagrafica+diritti+emesso+ boxoffice+Gemma. Punti chiave del framing: (1) solo la componente di **visualizzazione**, il **gestionale/data-entry resta esplicitamente fuori scope** per ora; (2) PowerBricks non è un vicolo cieco — a tendere confluirà in MyICR, quindi la griglia costruita qui è candidata a diventare il **componente condiviso** riusabile, non usa-e-getta; (3) la versione VBA originale era statica (colonne/posizioni fisse, drill-down limitato) — l'obiettivo ora è una griglia unica, avanzata, riusabile in più punti, per agevolare manutenzione e coerenza UX. **Valutazione PyQt6 vs web, poi Tabulator vs AG Grid**: la scoperta di Playwright (05-06/08) aveva sollevato il dubbio se riaprire la domanda grande "tutto web?" — risolto: Playwright è solo un vantaggio di verifica per Adrian, non tocca i tre vincoli reali (niente diritti admin sui client, fluidità su migliaia di record, ricchezza Excel-like) che avevano giustificato PyQt6 per le griglie. La domanda giusta era più stretta: le librerie JS moderne coprono ormai quei vincoli? Verificato (ricerca web): sì su performance (entrambe virtualizzate, gestiscono migliaia/centinaia di migliaia di righe) e su installazione (nessuna, girano nella finestra pywebview già esistente). Sul punto decisivo — funzionalità Excel-like — differenza netta: **AG Grid Community** (gratis) non include il filtro a checkbox multi-selezione stile Excel ("Set Filter"), row grouping né master/detail: tutti **Enterprise**, $999/dev/anno. **Tabulator** (MIT, nessun tier a pagamento) ha row grouping/tree nativi gratis, e il filtro multi-select si costruisce sopra `headerFilter: 'select'` con `multiselect: true` (pattern documentato). Scelto **Tabulator** — copre meglio l'ambizione "Excel-like" senza sorprese a pagamento future, e riduce il rischio di lock-in (nessun muro Enterprise dietro l'angolo; la griglia resta comunque solo uno strato di presentazione sopra l'API `/api/query`, sostituibile a basso costo se servisse). Editing di cella nativo confermato disponibile (non preclude un futuro capitolo gestionale, anche se oggi non usato). **Implementazione**: componente standalone `sandbox/datagrid/` (`src/datagrid.js`, wrapper Tabulator con API `initGrid(target, options)`, nessuna dipendenza da PowerBricks — vedi `sandbox/datagrid/CLAUDE.md`), consumato da PowerBricks via una seconda static route Flask (niente copia). Sostituisce `results_grid.py` (PyQt6, processo separato): ora i risultati si aprono in una **seconda finestra pywebview** (stesso processo, nessun conflitto di loop eventi — il vincolo PyQt6/pywebview non si applica più a un componente puro JS). Dettaglio tecnico completo in `sandbox/powerbricks/CLAUDE.md`, sezione "Griglia risultati — migrata da PyQt6 a datagrid web". **Validato da Mauro su Ufficio (07/08/2026)**: "funziona perfettamente e il risultato mi sembra molto gradevole" — stesso `run.bat` di sempre, nessun passo di installazione manuale (requirements.txt si allinea da solo, Tabulator via CDN come già Blockly). Prima vera verifica visiva della griglia risultati (PyQt6 non era mai stato testato a schermo). ## Cluster Anagrafica Linker — trovato e replicato, campi derivati aggiunti (07/08/2026) `[CONFERMATO]` — Mauro ha chiesto di trovare il cluster di campi anagrafici che Linker mostra in griglia ("stesso cluster Excel-style" citato più sopra). Trovato in `PYTHON/MyICR_Suite/app/modules/linker/src/gui/column_defs.py` (dict `FIELDS`, intestazione arancione): 14 campi — `RIFER, IMDB, TIPOL, TI, TO, ANNO, PAESE, GENERE, EPIS, DURATA, SUPERSERIE, VEG, REGISTA, ATTORI`. Confermato via screenshot reale di Mauro (griglia Linker aperta su Ufficio) — corrispondenza esatta, nessuna discrepanza tra codice e schermo. 11 dei 14 erano già disponibili in PowerBricks (`prodotti.parquet`); mancavano `IMDB`/`REGISTA`/ `ATTORI`. **Decisione presa insieme**: niente "Tabella Cast" standalone (`cast.parquet` ha fan-out pesante su `prodotto`, fino a 1.369 righe — Mauro ha notato da solo che sarebbe stato lo stesso problema di aggregazione già visto con Emesso/Diritti, senza un bisogno reale). Aggiunti invece `imdb_codice`/`regista`/`attori` come **campi derivati dentro Anagrafica**, stessa logica di `v_custom_anagr` in Linker (riletta 1:1, non reinventata) — dettaglio tecnico completo in `sandbox/powerbricks/CLAUDE.md`. Verificato sullo stesso prodotto dello screenshot condiviso (3096645, "LIFE OF THE PARTY"): output identico a Linker (`tt5619332`, "BEN FALCONE", "MELISSA MCCARTHY, MATT WALSH, MOLLY GORDON"). **Nota per il futuro**: Mauro ha osservato che REGISTA/ATTORI sono di fatto "cluster calcolati" (riassunto pre-aggregato di più righe cast) — stessa idea del cluster di campi discussa più sopra, applicata dentro un singolo campo invece che a un set di campi. Un domani potrebbero fare drill verso il dettaglio cast grezzo filtrato per ruolo. Non implementato, solo annotato. **Label leggibili stile Linker**, stesso giro: le tendine campo e la griglia risultati ora mostrano le label di `column_defs.py` (es. `titolo_italiano` → `TI`) dove la corrispondenza è certa (Anagrafica, Diritti, Emesso, Boxoffice) — Gemma esclusa deliberatamente, mapping valutazioni troppo incerto per essere indovinato. Dettaglio in `sandbox/powerbricks/CLAUDE.md`. **Default output Anagrafica = cluster Linker (07/08/2026)**: un blocco "Tabella Anagrafica" mai toccato nel modale ora produce di default i 14 campi del cluster (stesso ordine di `column_defs.py`), non più tutti i 28 disponibili — richiesta esplicita di Mauro ("consideriamo solo i campi presenti nel foglio Linker da visualizzare, stesso ordine"). Dettaglio in `sandbox/powerbricks/CLAUDE.md`. ## Idea per il futuro — modalità standard/avanzata (07/08/2026, solo concetti, non scoped) Riflessione nata dal cluster Anagrafica appena implementato sopra, non ancora tradotta in lavoro concreto — Mauro ha chiesto esplicitamente di restare sul teorico per ora ("da pensarci", "solo concetti"). Riassunto dei concetti emersi, in ordine: 1. **Due modalità d'uso**: standard (solo cluster, tabelle "non necessarie" nascoste — es. `cast.parquet` grezzo mai esposto) vs avanzata (tutto grezzo, tabelle satellite come oggi, join/aggregazione espliciti). Il toolbox Blockly è già a categorie: filtrare quali categorie mostrare in base alla modalità è tecnicamente leggero, non un redesign. 2. **Non è un interruttore, è una doppia rappresentazione per dominio**: alcuni domini (Boxoffice, forse Emesso) potrebbero dover esistere sia come cluster incorporato in Anagrafica (standard) sia come tabella joinable a sé (avanzata) — costo di manutenzione reale, non solo una UI da nascondere/mostrare. 3. **Stesso meccanismo già in uso per REGISTA/ATTORI/IMDB, generalizzato**: quei tre campi sono la prima istanza concreta del pattern "N righe → 1 valore per prodotto". La modalità standard applicherebbe lo stesso pattern a ogni dominio satellite, non solo a quelli già fatti. 4. **Si aggancia al blocco aggregazione Emesso rimandato** (prima/ultima/tutte, mai costruito): in modalità standard non servirebbe come scelta esposta all'utente — basterebbe una regola fissa hardcoded (es. "ultima emissione", coerente con cosa mostra oggi Linker), stesso principio con cui regista è già "il primo FRE per progr_cast" senza che l'utente scelga nulla. Il blocco esplicito resterebbe solo in modalità avanzata. 5. **Il cluster si applica anche al WHERE, non solo al SELECT**: filtri guidati/semplificati invece di campo+operatore grezzo (es. un blocco "Nazionalità = Italiana" invece di `paesi_produzione1 contiene 'I'`). Si aggancia a due thread già esistenti mai implementati: il vocabolario in [[data-expert]] (già segnalato altrove come riusabile per la palette senza reinventare) come base semantica per i cluster WHERE, e l'idea "Backpack per cluster di filtri riutilizzabili" (sezione sopra, 06/08) come lo strumento con cui un utente avanzato potrebbe *creare* nuovi cluster WHERE da promuovere poi in standard. 6. **Diritti — corretto il 08/09/2026, era sbagliato**: si pensava servisse la logica derivata (first-run/re-run, inibizioni) prima di poter fare un cluster Diritti per la modalità standard — non è vero. **Precedente già in uso in Linker** (Mauro): mostrare una riga **arbitraria** (es. la prima) **più un indicatore che ce ne sono altre** ("1 di N"), nessuna pretesa di sapere quale sia quella "giusta". Non richiede nessuna logica di business — è anzi il caso **più facile** dei quattro dei domini satellite, buildabile subito. La logica derivata resta un problema a sé (serve a chi vuole sapere davvero qual è il contratto corretto), ma non blocca più la modalità standard: quella può mostrare l'ambiguità onestamente invece di aspettare di risolverla. Stesso principio applicabile a qualunque dominio senza una regola di collasso certa (non solo Diritti). 7. **Wizard**: Mauro ha suggerito che la modalità standard potrebbe usare un flusso guidato a passi (pattern già presente in altre parti di MyICR, non ancora individuato/ricercato da Adrian) invece del canvas libero Blockly — coerente col rendere esplicite le regole dietro un cluster (mostrare cosa cerca davvero un filtro guidato, non nasconderlo del tutto). Prossimo passo naturale quando si vorrà concretizzare: cercare i wizard esistenti in MyICR_Suite per riusare un linguaggio UI familiare invece di inventarne uno nuovo. 8. **Tendina filtro allineata all'output selezionato (07/08/2026)**: idea più semplice del filtro-per-label proposto inizialmente da Adrian (poi corretta da Mauro) — la tendina `FIELD` di un blocco filtro rispecchierebbe dinamicamente l'elenco corrente del modale "Campi da mostrare in output" del blocco Tabella gemello, non un elenco fisso per dominio. Gemma (nessun cluster, default "tutti i campi" in output) mostrerebbe di riflesso tutti i campi anche nel filtro — nessuna eccezione da gestire caso per caso. **Trade-off segnalato**: oggi si può filtrare su un campo senza doverlo mostrare in output (es. filtrare `tipologia=FILM` senza metterlo in colonna) — allineare le due liste toglierebbe questa possibilità. Probabilmente un bene in modalità standard (più guidato), una limitazione in avanzata. **Tecnicamente**: le tendine `FIELD` oggi sono statiche (fissate al caricamento pagina) — diventerebbero dinamiche per istanza di blocco, lette da `block.data` del blocco Tabella al momento dell'apertura, pattern non ancora esistente nel codice. Non implementato, solo segnato come punto su cui tornare. 9. **(08/09/2026) Il controllo LEFT/INNER forzato è concettualmente "modalità avanzata"**, non dovrebbe esistere in standard — nato testando il debug NL (test 4: "tutti i prodotti, e se disponibile l'incasso boxoffice sopra 1 milione", un caso costruito apposta per esercitare il meccanismo, non la traduzione naturale di una richiesta reale — un utente vero che chiede "prodotti con incasso sopra 1 milione" si aspetta l'INNER di default, non il LEFT). In modalità standard l'etichetta sulla linea di join mostrerebbe **sempre e solo "Automatico"** — anche se sotto sotto il sistema risolve concretamente a LEFT o INNER a seconda dei filtri, la distinzione resta implicita, non esposta né modificabile dall'utente standard. Solo in modalità avanzata comparirebbe il vero valore risolto e la possibilità di cliccarlo per cambiarlo (comportamento attuale, oggi l'unica modalità esistente). Si aggancia al punto 1 sopra (due modalità, non solo nascondere tabelle/campi — anche nascondere/bloccare controlli come questo). 10. **(08/09/2026) Meccanica concreta per "1 di N" — righe espandibili stile Excel**: Mauro propone che il drill (punto 6 sopra) non sia un popup separato ma un **"+" nella griglia risultati** che espande righe aggiuntive per lo stesso prodotto (le altre righe Diritti corrispondenti) — le colonne che non cambiano tra un contratto e l'altro (tutto ciò che è "del prodotto", non "del contratto specifico": Anagrafica, Emesso...) restano **vuote** nelle righe espanse invece di ripetere lo stesso valore, così si vede subito quali colonne sono per-prodotto e quali per-riga-di-dettaglio. **Tecnicamente già nel perimetro scelto**: `Tabulator` (il componente `datagrid`, vedi "Griglia risultati" sopra) è stato scelto il 07/08 anche per il row grouping/tree nativo gratis (motivo esplicito della scelta su AG Grid Community, che lo ha solo a pagamento) — nessuna libreria nuova, solo una funzionalità di Tabulator non ancora usata. Non implementato, solo la meccanica pensata. Nessuna decisione presa, nessun lavoro iniziato — solo la mappa dei concetti perché non vada persa quando si vorrà riprendere il tema. ## Sessione conclusa (07/08/2026 sera) — riaperta la domanda grande "smantellare PyQt6 in MyICR" `[NON SCOPED]` — Mauro ha chiuso la sessione di oggi su PowerBricks (griglia web, stile Linker, cluster Anagrafica, tutte le rifiniture — vedi sezioni sopra) dichiarando l'obiettivo "pienamente raggiunto", ed è tornato di sua iniziativa sulla domanda che era stata esplicitamente rimandata il 06/08/2026 ("PowerBricks è sperimentazione... si riaffronta solo se il risultato convince abbastanza da voler estendere il pattern" — vedi sezione "Griglia risultati — migrata da PyQt6 a datagrid web" in `sandbox/powerbricks/CLAUDE.md`): **oggi il risultato l'ha convinto**, ipotesi esplicita "potremo smantellare in tutto MyICR PyQt6 e uniformare il tutto". Punto di attrito da affrontare quando si riprende: `MyICR_Suite/CLAUDE.md` dichiara oggi "Linker resta PyQt6 — funziona, nessun rimpianto" come principio architetturale esplicito, non solo inerzia — riaprire la domanda significa mettere in discussione quel principio, non solo valutare una tecnologia. Non affrontato stasera (Mauro esausto, ha chiesto esplicitamente di fermarsi) — solo registrato perché il thread non vada perso. Nessuna analisi, nessuna decisione, nessun lavoro iniziato: da riprendere con calma, probabilmente meglio in una sessione dedicata (non di coda a un'altra giornata lunga) dato il peso della domanda. **Idea collegata, stesso momento**: se la domanda PyQt6-vs-web diventa reale, Mauro ha ipotizzato un **agente dedicato a MyICR**, garante del funzionamento complessivo e della coerenza tecnologica tra le sezioni — diverso da `expert-data`/`expert-flussi` (quelli coprono i dati, non l'architettura applicativa). Compito più di giudizio che di lookup: non "quali dati ci sono" ma "questo modulo sta divergendo dal pattern degli altri, o è una deroga legittima". **(30/08/2026)**: se costruito, partire da un esperto/sentinella persistente (container), non da un subagente — preferenza generale di Mauro, vedi `archivio/Adrian/feedback/feedback_no_subagenti_preferenza_container.md`. Anche questo non approfondito, solo annotato accanto al thread sopra perché collegato — da scoparlo insieme quando si riprende. **Terzo elemento collegato, stessa sera — Costituzione aggiornata**: la discussione ha portato a un vero cambiamento immediato (non solo un'idea parcheggiata): `CLAUDE.md` v1.85 ammette ora la scrittura in `PYTHON/` da Nave quando Mauro supervisiona in diretta via `/remote_control` (prima "mai, solo istanza ufficio"). Motivato inizialmente da Playwright (chiude il gap di verifica solo per il codice web-style, non per PyQt6), poi **rinforzato da un motivo indipendente**: rischio che Direzione Sistemi (IT aziendale) blocchi o monitori VSCode/Claude Code sul PC ufficio in futuro — Nave è macchina personale di Mauro fuori dal perimetro IT aziendale, `/remote_control` è solo una pagina web nel browser, più difficile da bloccare selettivamente rispetto a un'installazione locale. I due motivi vanno tenuti distinti: uno regge anche se l'altro decadesse (es. se il vantaggio di verifica Playwright non bastasse più per qualche ragione, il vantaggio di resilienza contro un'eventuale stretta IT resterebbe comunque valido). Nessuno spostamento attivo del lavoro deciso oltre l'aggiornamento della regola — solo la motivazione registrata per quando si riprenderà il tema. ## Domande aperte non ancora affrontate (da `PowerBricks_dossier.md`, dossier Elon 13/07/2026, recuperato e poi eliminato il 04/08/2026 — nessuna risposta trovata né nell'archivio né nella specifica ufficiale) - Perimetro della v1: quali dei 4 domini entrano subito, quali no. - Dove si ferma la logica diritti nella prima versione — è il pezzo più costoso, farla tutta subito rischia di non finire mai. - Se e quando PowerBricks toccherà il territorio AllRights — decisione strategica, non tecnica. - Cosa rende "fatto bene" questo progetto, dato che non è stato commissionato da nessuno e quindi nessuno darà il criterio di completamento dall'esterno. ## Scorporo da MyICR_Suite — superato dagli eventi Spunto emerso il 04/08/2026: dato che la specifica dichiarava PowerBricks come consumer esterno del layer semantico ("lo usa come dipendenza, non lo ingloba"), scorporarlo in una cartella propria sotto `PYTHON/` (coerente con "un repo per progetto") aveva senso concettuale. Nel frattempo, stesso giorno, Mauro ha deciso di eliminare la cartella del tutto invece di scorporarla — quindi la domanda non si pone più nei termini originali: non c'è più nulla da scorporare da MyICR_Suite. Se e quando l'implementazione ripartirà, ripartirà da zero, e a quel punto la scelta "modulo dentro MyICR_Suite vs progetto a sé sotto `PYTHON/`" si potrà fare direttamente in partenza, senza vincoli ereditati. ## Anagrafica sempre implicita per Emesso/Boxoffice/Diritti — revisione della standalone (08/09/2026) `[CONFERMATO]` — nato testando il debug NL (vedi sotto): Mauro ha notato che nel test 3 (solo "Tabella Emesso" sulla lavagna) il blocco "Tabella Anagrafica" compariva comunque, vuoto e visivamente slegato da Emesso — nessun segnale sul canvas che le due tabelle fossero in join (la join è logica invisibile lato backend). Ragionandoci insieme è emerso che il problema di fondo non è visivo ma di modello: oggi "assenza del blocco Anagrafica" significa "modalità standalone" (deciso 06/08, per il caso Gemma — legame debole, 9,5% di copertura). Per Emesso/Boxoffice/Diritti quella semantica non ha lo stesso senso: sono tutti a chiave diretta su prodotto+edizione, quasi sempre si vuole comunque Anagrafica insieme. **Nuova regola**: per Emesso/Boxoffice/Diritti (non Gemma), la presenza di uno qualsiasi di questi tre domini sulla lavagna fa **sempre** passare la query dal percorso unificato ancorato ad Anagrafica — mai più modalità standalone in automatico per omissione. Se "Tabella Anagrafica" non è fisicamente sul canvas, si usano comunque le sue colonne di default (nessun filtro proprio); la sua presenza/assenza ora conta solo per eventuali filtri/colonne extra su Anagrafica, non più per decidere il percorso di query. **Nessuna via d'uscita costruita per tornare alla vecchia standalone** su questi tre domini — valutata e scartata (Mauro: "non ho un bisogno reale oggi") coerente col principio di non costruire per un bisogno ipotetico; se servirà davvero in futuro, rientra nel concetto "modalità avanzata" già parcheggiato (sezione sopra), non prima. **Gemma resta l'eccezione dichiarata**: comportamento standalone invariato (assenza di Anagrafica + solo Gemma → grezza come oggi) — il suo legame debole con Anagrafica (fan-out via catena IMDb, 9,5% di copertura diretta) è il motivo originale per cui la standalone esiste, resta valido solo lì. **"Esegui query" auto-completa il canvas per trasparenza** (idea di Mauro): se il percorso unificato gira ma "Tabella Anagrafica" non è ancora sulla lavagna, il frontend la aggiunge visivamente prima di eseguire — quello che si vede sul canvas coincide sempre con quello che è girato davvero, niente di implicito/nascosto. Risolve il problema visivo di partenza (blocco Emesso "slegato") alla radice invece che con un indicatore aggiuntivo (linea disegnata, scartata come idea intermedia — non più necessaria con questa modifica). **Effetto collaterale positivo**: sparisce anche il caso speciale "due o più satelliti senza Anagrafica → errore esplicito" (era tra i 7 test NL progressivi, il numero 7) — diventa semplicemente il caso normale "più domini, join automatica", nessuna gestione a parte. **Non ancora implementato** — decisione presa, implementazione da fare (backend: la modalità standalone/`_execute_standalone_query` per Emesso/Boxoffice/Diritti va rimossa dal percorso di scelta frontend; frontend: `getQueryPayload` non deve più cercare "Tabella Anagrafica" come condizione per il percorso unificato su questi tre domini, più l'auto-completamento del canvas su "Esegui query"). ### Blocchi ponte (`pb_join`) rimossi — tendina di join dentro il blocco tabella stesso `[CONFERMATO]` — stesso giro di ragionamento sopra: Mauro ha notato che anche i blocchi ponte (`pb_join`/`pb_join_boxoffice`/`pb_join_diritti`/`pb_join_gemma`, categoria "Strumenti") sono fluttuanti e slegati visivamente esattamente come lo era "Tabella Anagrafica" — capisci a quale dominio si riferiscono solo leggendo l'etichetta del blocco, nessuna connessione grafica. Valutata un'alternativa più ambiziosa (linea/etichetta disegnata via overlay SVG tra i blocchi in relazione, cliccabile per cambiare il tipo di join, stile diagramma ER/Access) e scartata: rischio concreto di non essere fluida quanto il drag nativo di Blockly (un secondo sistema di rendering sopra quello nativo, da verificare su display reale per saperlo con certezza) più la complessità di un'interazione aggiuntiva da inventare — costo/rischio non giustificato ora che il problema più fastidioso (perché serve Anagrafica) è già risolto dall'auto-completamento. **Deciso invece**: la scelta Automatico/LEFT forzato/INNER forzato diventa una tendina (`field_dropdown`) **dentro lo stesso blocco "Tabella Emesso"/"Tabella Boxoffice"/"Tabella Diritti"/"Tabella Gemma"** — nessun blocco ponte separato, nessuna categoria "Strumenti" nel toolbox. Il backend non cambia (`join_type` nel payload resta identico, solo la UI che lo produce cambia). Vale per **tutti e quattro** i domini (Gemma inclusa) — è un miglioramento di UI ortogonale alla domanda standalone-vs-sempre-Anagrafica, che invece resta diversa solo per Gemma (vedi sopra). **Non ancora implementato**, da fare insieme al punto sopra (stesso giro di modifiche). ## Join Anagrafica↔Emesso ridotta a solo "prodotto" (08/09/2026) `[CONFERMATO]` — nato testando il debug NL (test 5/5b): il default `edizione=1` su Anagrafica (sezione sopra, stesso giorno) ha un effetto collaterale sulla join Emesso, che richiedeva match anche su `edizione` — un prodotto con le emissioni reali registrate sotto un'edizione diversa da 1 (caso reale trovato: prodotto 3073191, 28.455 emissioni tutte sotto edizione 2/3, zero sotto edizione 1) risultava "mai andato in onda" nell'output, mentre in realtà lo era. Discussione: da un lato edizioni diverse possono avere durate/tagli diversi (VM16/VM14, colorizzata), quindi "quale edizione è andata in onda" è informazione vera, non un dettaglio tecnico. Dall'altro, per un primo giro, la semplicità vince — Mauro ha deciso di trattare "prodotto" come l'unità che conta per la storia di trasmissione, non l'edizione specifica. **Scope: solo Emesso** — Boxoffice è già a chiave solo-`prodotto` (nessuna modifica), Diritti resta su prodotto+edizione (non toccato, non richiesto). Materia di affinamento futuro se servirà davvero ("campo di fine tuning", Mauro) — non riaprire senza un caso reale che lo richieda. **Implementazione**: `_build_emesso_join()` — `ON` della join ridotto a solo `prodotto` (prima anche `edizione`); la `PARTITION BY` della window function per l'aggregazione prima/ultima (non ancora esposta in frontend) allineata allo stesso principio, per non lasciare un'inconsistenza silenziosa per quando quel blocco verrà costruito. ## Direzione confermata (28/08/2026) — PyQt6 verrà smantellato, condizionato `[CONFERMATO]` — la domanda grande riaperta il 07/08/2026 ("potremo smantellare in tutto MyICR PyQt6 e uniformare il tutto") non è più solo un'ipotesi lasciata in sospeso: Mauro ha dichiarato la direzione esplicitamente, con una condizione chiara — **PyQt6 verrà smantellato, a patto che la griglia risultati stile Linker di PowerBricks (Tabulator, vedi "Griglia risultati — decisione e implementazione" sopra) regga bene alla prova d'uso**, ed eventualmente da lì generalizzata al resto dell'ecosistema (Linker stesso, `dash_diritti`, le altre dashboard PyQt6 di `app/features/`). Non ancora una decisione operativa da eseguire — resta condizionata a una verifica non ancora fatta (quanto "regge bene" la griglia Tabulator su usi reali, non solo il test di validazione del 07/08) e al lavoro di generalizzazione stesso, non scoped. Ma il principio guida per il futuro è ora chiaro: non è più "se", è "quando, ammesso che la griglia dimostri di reggere". Segnalato anche in `memory/MEMORY.md` (thread PowerBricks) e collegato a [[project_pseudo_os_artifact]] (ArkOS), dove Mauro ha nel frattempo espresso l'idea di portare versioni ridotte degli applicativi MyICR/MediaTrack come app a uso personale — quella direzione presuppone implicitamente lo stesso spostamento verso stack web invece di PyQt6 nativo. Vedi [[_i_lavoro-python-ecosistema|lavoro-python-ecosistema]] per il quadro d'insieme.