--- name: PowerBricks-appunti description: "Appunti rapidi PowerBricks — stato corrente, prossimi passi, cose da sistemare. Consultazione veloce per Mauro; il dettaglio/motivazioni stanno in PowerBricks.md." metadata: type: project --- # PowerBricks — appunti rapidi *Aggiornato: 09/09/2026. Per la storia completa/motivazioni: [[PowerBricks|PowerBricks.md]] (stesso cartella). Dettaglio tecnico: `sandbox/powerbricks/CLAUDE.md`.* **Da dove riprendere**: il modale di dettaglio per riga (sostituto del vecchio albero Diritti, generalizzabile a Emesso/Gemma) **non è ancora deciso** — Mauro non è ancora convinto della forma (09/09/2026). Nel frattempo l'albero inline Diritti è stato **rimosso** (vista flat, nessun sostituto per ora) — vedi sezione dedicata sotto. ## Rimosso (09/09/2026) — albero espandibile Diritti Tolto sia backend (`_group_diritti_rows`, blocco raggruppamento in `_execute_query`) sia frontend (`treeOptions`, ramo `if(tree)` in `results.html`) — vista Diritti torna flat, ogni riga singola. Motivo: confermato che l'albero regge un solo dominio moltiplicato per volta, non la combinazione (es. Emesso+Diritti insieme). Nessun sostituto ancora — il modale di dettaglio resta da disegnare quando Mauro ha più chiarezza sulla forma. Implementato da `gemello-ufficio` (commit `0472cc7`), contratto backend verificato su dati reali (80 righe, 15 gruppi con fan-out, tutte piatte), test visivo Playwright da Nave confermato (58 righe renderizzate, zero elementi tree nel DOM, zero errori console). Chiuso. ## Direzione confermata **PyQt6 verrà smantellato in MyICR**, a patto che la griglia risultati Tabulator di PowerBricks regga bene alla prova d'uso reale — non è "se", è "quando". Verifica non ancora fatta formalmente. ## Stato attuale - 5 domini implementati e funzionanti: Anagrafica, Emesso, Boxoffice, Diritti, Gemma - Griglia risultati (Tabulator) validata da Mauro su Ufficio — "funziona perfettamente" - Cluster campi stile Linker replicato in Anagrafica (14 campi, stesso ordine) ## Prossimi passi decisi (08/09/2026) 1. **Carrello — salvare/ricaricare query** — **fatto e validato (08/09/2026)**: implementato da `gemello-ufficio` (backend `/api/carrello`+`carrello.json`, frontend modale toolbar), committato da Adrian (`6c93cc2`), **verificato visivamente da Mauro su Ufficio — "funziona benissimo"**. Chiuso. 2. **Debug NL→PowerBricks** (solo interno, mai esposto agli utenti): Mauro scrive una richiesta in linguaggio naturale, Adrian prova a ricostruirla come blocchi PowerBricks (usando il vocabolario di dominio in `data-expert`) per vedere se il sistema regge o cosa manca. Si appoggia sullo stesso meccanismo di caricamento JSON del carrello — da fare dopo. ## Fatto (08/09/2026) — join sempre implicita + linea visuale (non più tendina) Percorso completo, tutto validato: 1. Anagrafica sempre implicita per Emesso/Boxoffice/Diritti (Gemma eccezione), auto-completamento anticipato a "appena aggiungi un satellite" (non più solo all'esecuzione). 2. Blocchi ponte (`pb_join`) rimossi, sostituiti da una **linea disegnata** tra Anagrafica e ogni satellite in join (non la tendina inizialmente prevista — provata dal vivo da Mauro, "più che accettabile" nonostante il ridisegno non sia perfettamente fluido). 3. Tendina JOIN nascosta dai blocchi (ridondante, l'etichetta sulla linea gestisce lo switch) — blocchi tabella ora puliti, solo nome + filtri. Implementato da `gemello-ufficio`, ogni passo revisionato + verificato visivamente da Adrian (Playwright headless su Nave). Un bug reale trovato e corretto strada facendo (loop di redraw infinito su eventi pan/zoom). Un incidente di sync Dropbox (stesso pattern del 07/09, nuova variante "Responding ma sync fermo" — vedi `gemello-nave/archivio/conoscenza-nave.md`) risolto con restart. **Chiuso**, nessuna azione pendente. Dettaglio completo in `PowerBricks.md`. ## Fatto (08/09/2026) — righe espandibili stile Excel per Diritti, ma da riconsiderare Committata e **confermata funzionante da Mauro** ("perfetto"): quando un prodotto ha più righe diritto, riga padre (prima, arbitraria — principio Linker) + "+" che espande le altre (Tabulator `dataTree`), icona spostata sulla prima colonna Diritti su richiesta. **Ripensata subito dopo, stesso giorno**: provando a estendere lo stesso meccanismo a Emesso (dove la riga padre sarebbe "l'ultima emissione", non arbitraria) è emerso un limite reale — l'albero inline regge solo quando **un unico dominio** si moltiplica per volta; con Emesso e Diritti moltiplicati insieme nella stessa query (caso comune, PowerBricks combina domini di proposito) servirebbe un albero a due livelli, soluzione mal posta più che complicata. **Deciso: dismettere l'albero inline**, passare a un **bottone per riga che apre un modale con il dettaglio** (stesso pattern già in uso su Linker) — uno indipendente per dominio, nessun conflitto quando ne coesistono più di uno. **Non ancora implementato** — prossimo passo quando si riprende: buttare giù la spec (backend: endpoint dettaglio on-demand invece di embeddare tutto nella risposta principale; frontend: bottone+modale, generalizzabile a Diritti/Emesso/Gemma). L'albero Diritti resta nel codice per ora (funzionante, non rimosso), da disfare quando il modale sarà pronto a sostituirlo. ## Cose da sistemare / non ancora fatte - **(10/09) Carrello — query pubbliche/private, catalogo condiviso tra colleghi, idea non scoped**: oggi il carrello (`sandbox/powerbricks/carrello.json`) non ha alcun concetto di utente — è un unico file, "condiviso" tra Nave/Ufficio solo per effetto collaterale del path Dropbox, zero login/identità in MyICR_Suite, zero lock su scritture concorrenti. Approccio leggero proposto da Adrian (non costruire un sistema di login vero): taggare ogni query salvata con `owner` (nome utente Windows, gratis, nessuna autenticazione da gestire) + `scope: private|public` — frontend mostra sempre le public di tutti + le private solo del proprio owner. Il problema di fondo da affrontare insieme (oggi assente per caso, un catalogo condiviso lo farebbe emergere davvero): scritture concorrenti multi-utente senza lock. Non scoped, solo registrato. - **(10/09) Query "SQL diretto" nel carrello, senza rappresentazione a blocchi — idea di Mauro, non scoped**: PowerBricks a regime dovrebbe coprire qualsiasi richiesta, ma senza esplicitare ai colleghi che dietro c'è una LLM. Per le query troppo complesse per i blocchi, niente vieta che Adrian costruisca la query direttamente nell'editor testuale e la carichi nel carrello come **query di tipo speciale**: eseguibile ma senza controparte Blockly/visuale — stesso principio di MS Access, dove una query costruita in "Vista SQL" può non essere rappresentabile in griglia QBE e resta comunque eseguibile. Copre il caso limite (richiesta reale troppo complessa per i blocchi attuali) senza dover ammettere l'uso di un LLM: dal punto di vista del collega è solo "una query nel carrello", indistinguibile nell'uso da una costruita a blocchi — solo non editabile visivamente. Si collega alla decisione già presa sull'editor testuale interattivo (percorso di esecuzione separato testo/blocchi, sezione sotto) — qui si estende lo stesso principio: una query può nascere *solo* testuale, senza mai avere avuto uno stato Blockly. **Visualizzazione nel carrello (confermata da Mauro)**: distinguerle visivamente dalle query a blocchi, es. con un prefisso "SQL" nel nome/etichetta — non per rivelare l'uso di una LLM, solo per segnalare a chi la esegue che è un tipo speciale non modificabile a blocchi. **Uso come segnale di roadmap (Mauro, 10/09)**: l'accumulo di query SQL dirette nel tempo serve anche a capire quali funzioni/pattern vale la pena promuovere a blocco vero — un backlog che emerge dall'uso reale (pattern che si ripetono tra query diverse) invece di essere indovinato a priori. Non scoped, solo registrato. - **(09/09) Vista SQL in dialetto Access nell'editor testuale, non scoped**: Mauro crede molto in PowerBricks a tendere ("diventerà anche mio sistema per elaborazioni" — quando arriva una richiesta, si valuterà insieme se PowerBricks regge). Vorrebbe che il pannello editor testuale (oggi mostra solo la pseudo-lingua leggibile) potesse mostrare anche il **SQL vero**, in **dialetto MS Access** — non solo per leggerlo: **esiste già un DB Access reale con le tabelle SQLite collegate**, **confermato e chiarito con `expert-flussi`**: la pipeline (`sqlite_mirror.py`, step [5] settimanale di `run_weekly.bat` su wincoarcapp01, stessa cadenza di `emesso.parquet`) genera **solo** `I:\SOFTWARE\PYTHON_SRV\sqlite_layer2\mirror_l2.sqlite` (rigenerato da zero ogni volta, 12 tabelle full — emesso, emesso_enrich, reti_cluster, osservatorio, imdb, scelte_rete, boxoffice, prodotti, diritti_enrich, diritti, cast, gemma — con `_id` surrogata dove serve per compatibilità ODBC). Il file **`mirror_l2.accdb`** (stessa cartella) è costruito **manualmente da Mauro**, tabelle collegate via ODBC allo `.sqlite` — non generato/mantenuto dalla pipeline, si aggiorna da solo quando apre le tabelle collegate (lettura live via ODBC). Quindi il SQL tradotto sarebbe **eseguibile per davvero** lì — un confronto incrociato vero, non solo lettura. Per questo la fedeltà sintattica al dialetto Access conta (join con parentesi annidate, `IIF`, date tra `#...#`, campi tra `[...]`) — non basta un'approssimazione leggibile. Approccio consigliato da Adrian: prima SQL generico/standard (utile da solo, più vicino a quanto DuckDB già costruisce internamente), la traduzione al dialetto Access come passo successivo sopra quello. Non scoped, solo registrato. - **(09/09) Aggregazione vera (GROUP BY), idea forte, UX corretta da Mauro, non scoped**: Mauro vuole poter raggruppare risultati con funzioni di aggregazione (somma/conteggio/media), non solo filtrare. Esempio concreto: "ore emissione di C5 raggruppate per tipologia" — filtro `rete=C5`, `GROUP BY tipologia`, `SUM(durata)`. Risultato con una riga per gruppo, non per record. **UX preferita da Mauro (non un nuovo tipo di blocco)**: pattern Access, riusare il **modale di selezione campi già esistente** (doppio click su `pb_query`/blocchi dominio) aggiungendo per ogni campo selezionato un menu "ruolo" — Raggruppa per / Somma / Conteggio / Media / ecc. — invece di un blocco Blockly dedicato. Più semplice da costruire (riusa UI esistente) e più familiare per chi conosce Access. Supporto backend per query di aggregazione: DuckDB lo gestisce nativamente, nessun problema lato motore. **Possibile unificazione con "prima/ultima emissione" — non confermata, da ripensare**: ipotesi emersa in conversazione (non l'idea originale di Mauro con "campo trascinato", che restava non del tutto catturata): "prima"/"ultima" come altre due opzioni nello stesso menu per campo (Raggruppa per / Somma / Conteggio / Media / Primo / Ultimo), come le funzioni "Primo"/"Ultimo" di Access. Mauro: "non era così che intendevo ma forse regge, da pensare" — quindi **non confermata**, solo un'alternativa plausibile da riprendere insieme al resto quando si progetta per davvero, non l'idea originale del "campo trascinato" (che resta da chiarire meglio a quel punto). **Ulteriore variabile per il futuro (Mauro)**: se un giorno arrivano campi custom/calcolati (non solo i campi grezzi fissi di oggi), il meccanismo di raggruppamento dovrà reggere anche quelli — altro motivo per non fissare il design ora. Non scoped, solo registrato. - **(09/09) Subquery / risultati a catena — idea forte, non scoped**: Mauro propone di poter usare il risultato di una query come base ("macroblocco") per una query successiva — es. step 1 "film italiani con diritti in essere", step 2 "di questi, incasso > X". Equivalente concettuale a una CTE SQL — risolverebbe anche il limite che ha bloccato l'albero Diritti (un solo dominio moltiplicato per query, mai la combinazione). Approccio tecnico preferito da Adrian: non SQL annidato vero, ma materializzare le chiavi (prodotto+edizione, già la chiave di join ovunque) del primo risultato e riusarle come filtro `IN (...)` nello step successivo — coerente col motore attuale, nessuna riscrittura. Visivamente vicino al carrello esistente (query salvata), ma usabile come **input**, non solo output. Pezzo di lavoro reale, non piccolo — non scoped, solo registrato come direzione promettente. - **(09/09) Editor SQL/pseudo-codice — reso interattivo, design deciso, non implementato**: oggi il pannello testuale è solo output (si aggiorna dai blocchi, non modificabile). Idea di Mauro: renderlo editabile con validazione sintattica preventiva. Sul "riflesso sui blocchi" (testo→blocchi), deciso di **non** fare una sincronizzazione bidirezionale piena (rischio di loop, parser complesso) — invece un **percorso di esecuzione separato**: il testo modificato si esegue per conto suo ("Esegui" dal testo), i blocchi restano fermi all'ultima configurazione visuale, un indicatore visivo segnala il disallineamento; tornando a toccare i blocchi il testo si rigenera da loro come oggi, l'edit manuale si perde. Non prioritario ora, solo registrato per quando si riprende. - **(08/09) Tendina JOIN visibile anche nel pannello del cestino** — stessa causa del bug flyout già corretto (terza lavagna Blockly separata, il cestino ha la sua). Bassa priorità, cosmetico. - **(08/09) Cancellazione blocchi poco intuitiva** (Mauro, dopo aver provato cestino/tasto destro) — meccanismi nativi Blockly (drag sul cestino, "Cancella N blocchi" da tasto destro), funzionano ma non scoperti facilmente. Lasciato così per ora, non prioritario — da rivedere se emerge di nuovo. - **(08/09) Limite 5000 righe su `/api/open_grid` senza avviso di troncamento** — trovato testando i debug NL: una query che supera 5000 risultati mostra solo le prime 5000 in griglia senza nessun indicatore "N di M totali". Rischio: un utente può pensare di vedere tutti i dati mentre in realtà sono troncati. Da aggiungere: conteggio totale + avviso esplicito quando si tronca. - Verifica "regge bene alla prova d'uso" della griglia Tabulator — non ancora un test formale, solo la validazione iniziale del 07/08. - Blocco Gemma — verificato solo da Nave (SQL/Playwright), non ancora a schermo su Ufficio. - Idea "modalità standard/avanzata" — solo concetti, non scoped (vedi `PowerBricks.md` per il dettaglio). - Domanda grande "generalizzare Tabulator al resto di MyICR" (Linker, `dash_diritti`) — non scoped, dipende dalla verifica sopra.