[{"data":1,"prerenderedAt":1368},["ShallowReactive",2],{"project-agenthub":3,"related-agenthub":360},{"id":4,"title":5,"body":6,"date":343,"description":344,"extension":345,"featured":346,"image":347,"meta":348,"navigation":349,"order":350,"path":351,"sector":352,"seo":353,"stem":354,"tech":355,"type":358,"__hash__":359},"progetti\u002Fprogetti\u002Fagenthub.md","AgentHub",{"type":7,"value":8,"toc":324},"minimark",[9,14,23,26,42,46,53,58,61,81,85,88,108,111,115,122,142,146,149,175,179,182,208,212,238,245,249,253,256,289,292,296,299,303,310,317],[10,11,13],"h2",{"id":12},"la-sfida","La sfida",[15,16,17,18,22],"p",{},"Dopo il successo di SalesInsight, la stessa PMI del settore arredamento ha posto una nuova sfida: ",[19,20,21],"strong",{},"la rete agenti lavorava ancora con strumenti frammentati",". Ogni agente gestiva i propri clienti con un mix di Excel, email, note sul telefono e memoria. Non esisteva un sistema unico per pianificare le visite, consultare lo storico, preparare offerte o raccogliere ordini.",[15,24,25],{},"Il direttore commerciale voleva una piattaforma unica che:",[27,28,29,33,36,39],"ul",{},[30,31,32],"li",{},"Centralizzasse tutte le informazioni sui clienti",[30,34,35],{},"Fornisse agli agenti dati per preparare le visite (cosa ha comprato il cliente, quando, quanto)",[30,37,38],{},"Suggerisse opportunità commerciali (riordini previsti, cross-selling)",[30,40,41],{},"Permettesse di raccogliere ordini direttamente sul campo",[10,43,45],{"id":44},"la-soluzione","La soluzione",[15,47,48,49,52],{},"Ho progettato AgentHub come un ",[19,50,51],{},"CRM modulare"," con 5 moduli che coprono l'intero ciclo commerciale:",[54,55,57],"h3",{"id":56},"modulo-1-crm-base","Modulo 1: CRM Base",[15,59,60],{},"Il fondamento di tutto. Ogni agente ha la sua dashboard con:",[27,62,63,69,75],{},[30,64,65,68],{},[19,66,67],{},"Calendario visite"," con pianificazione settimanale",[30,70,71,74],{},[19,72,73],{},"Scheda cliente completa",": dati anagrafici, storico interazioni, note, allegati",[30,76,77,80],{},[19,78,79],{},"Dashboard personale",": KPI del mese, visite effettuate, ordini raccolti, target vs. effettivo",[54,82,84],{"id":83},"modulo-2-bi-integrata","Modulo 2: BI Integrata",[15,86,87],{},"Qui entra in gioco l'esperienza maturata con SalesInsight e DataVision. Ogni scheda cliente include:",[27,89,90,96,102],{},[30,91,92,95],{},[19,93,94],{},"Profilo interessi",": quali famiglie di prodotto compra, con che frequenza, quali ha smesso di comprare",[30,97,98,101],{},[19,99,100],{},"Analytics zona",": performance dell'agente nella sua area, confronto con la media",[30,103,104,107],{},[19,105,106],{},"Score clienti A\u002FB\u002FC\u002FD",": classificazione automatica basata su 5 dimensioni (fatturato, frequenza, margine, trend, potenziale)",[15,109,110],{},"Lo score viene calcolato con un algoritmo che ho sviluppato analizzando i pattern storici di acquisto. Non è machine learning   è business logic raffinata, comprensibile e spiegabile al management.",[54,112,114],{"id":113},"modulo-3-predittivo","Modulo 3: Predittivo",[15,116,117,118,121],{},"Il modulo più innovativo. Basandosi sulla ",[19,119,120],{},"frequenza storica di acquisto per famiglia prodotto",", il sistema:",[27,123,124,130,136],{},[30,125,126,129],{},[19,127,128],{},"Prevede i riordini",": \"Il cliente X ha comprato la famiglia Y ogni 45 giorni. L'ultimo acquisto è stato 40 giorni fa. Probabilmente riordinerà questa settimana.\"",[30,131,132,135],{},[19,133,134],{},"Genera suggerimenti pre-visita",": prima di ogni visita, l'agente riceve un riepilogo con le opportunità (riordini previsti, prodotti da proporre in cross-selling, articoli in promozione)",[30,137,138,141],{},[19,139,140],{},"Invia alert",": quando un cliente atteso non ordina nel tempo previsto, il sistema segnala l'anomalia",[54,143,145],{"id":144},"modulo-4-catalogo-digitale","Modulo 4: Catalogo Digitale",[15,147,148],{},"Gli agenti non portano più cataloghi cartacei. Il catalogo digitale offre:",[27,150,151,157,163,169],{},[30,152,153,156],{},[19,154,155],{},"Filtri avanzati"," per famiglia, materiale, fascia prezzo, disponibilità",[30,158,159,162],{},[19,160,161],{},"Schede prodotto"," con immagini, specifiche tecniche, listino",[30,164,165,168],{},[19,166,167],{},"Galleria installazioni",": foto dei prodotti installati presso altri clienti (con autorizzazione)   un potente strumento di vendita",[30,170,171,174],{},[19,172,173],{},"Generazione PDF personalizzato",": l'agente seleziona i prodotti e genera un catalogo su misura per il cliente",[54,176,178],{"id":177},"modulo-5-raccolta-ordini-mobile","Modulo 5: Raccolta Ordini Mobile",[15,180,181],{},"L'ultimo anello della catena. L'agente può:",[27,183,184,191,198,205],{},[30,185,186,187,190],{},"Aggiungere prodotti al ",[19,188,189],{},"carrello"," direttamente dal catalogo",[30,192,193,194,197],{},"Applicare ",[19,195,196],{},"sconti"," (con soglie configurabili per ruolo   l'agente può scontare fino al X%, il responsabile fino al Y%)",[30,199,200,201,204],{},"Generare il ",[19,202,203],{},"PDF di conferma d'ordine"," con firma del cliente",[30,206,207],{},"Inviare l'ordine al gestionale per la lavorazione",[10,209,211],{"id":210},"architettura-tecnica","Architettura tecnica",[27,213,214,220,226,232],{},[30,215,216,219],{},[19,217,218],{},"Frontend",": Vue.js 3 con Composition API, progettato mobile-first per l'uso da tablet",[30,221,222,225],{},[19,223,224],{},"Database primario",": MongoDB per i dati CRM (documenti flessibili, ideali per schede cliente con struttura variabile)",[30,227,228,231],{},[19,229,230],{},"Database ERP",": SQL Server per i dati storici (fatturato, ordini, anagrafica prodotti)   letto in sola lettura",[30,233,234,237],{},[19,235,236],{},"TypeScript"," end-to-end per type safety e manutenibilità",[15,239,240,241,244],{},"La scelta di ",[19,242,243],{},"MongoDB"," per il CRM è stata strategica: le schede cliente hanno campi variabili (note, preferenze, allegati), i documenti embedded (storico visite, interazioni) crescono nel tempo, e la flessibilità dello schema permette di aggiungere funzionalità senza migrazioni invasive.",[10,246,248],{"id":247},"funzionalità-chiave-nel-dettaglio","Funzionalità chiave nel dettaglio",[54,250,252],{"id":251},"rating-clienti-su-5-dimensioni","Rating clienti su 5 dimensioni",[15,254,255],{},"Ho sviluppato un sistema di scoring che valuta ogni cliente su:",[257,258,259,265,271,277,283],"ol",{},[30,260,261,264],{},[19,262,263],{},"Fatturato"," (peso 30%): quanto compra in valore assoluto",[30,266,267,270],{},[19,268,269],{},"Frequenza"," (peso 25%): con quale regolarità ordina",[30,272,273,276],{},[19,274,275],{},"Margine"," (peso 20%): quanto margine genera",[30,278,279,282],{},[19,280,281],{},"Trend"," (peso 15%): sta crescendo o calando rispetto all'anno precedente",[30,284,285,288],{},[19,286,287],{},"Potenziale"," (peso 10%): quanto potrebbe comprare in base alla sua tipologia e zona",[15,290,291],{},"Il risultato è una classificazione A\u002FB\u002FC\u002FD che aiuta l'agente a prioritizzare il tempo: i clienti A meritano una visita mensile, i D possono aspettare.",[54,293,295],{"id":294},"cross-selling-automatico","Cross-selling automatico",[15,297,298],{},"Analizzando i pattern di acquisto di clienti simili, il sistema identifica prodotti che il cliente non ha mai comprato ma che clienti con il suo profilo acquistano regolarmente. Queste opportunità vengono presentate come suggerimenti durante la preparazione della visita.",[10,300,302],{"id":301},"lezioni-apprese","Lezioni apprese",[15,304,305,306,309],{},"AgentHub mi ha insegnato che ",[19,307,308],{},"il CRM non è software   è un cambiamento di processo",". La sfida più grande non è stata tecnica, ma di change management: convincere agenti esperti (con 20+ anni di esperienza) a cambiare il loro modo di lavorare.",[15,311,312,313,316],{},"La soluzione? ",[19,314,315],{},"Partire dal valore immediato",". Ho lanciato prima il modulo predittivo (suggerimenti pre-visita), perché gli agenti vedevano subito il beneficio: \"Ah, questo cliente non compra da 2 mesi? Vero, lo chiamo\". Una volta convinti del valore, l'adozione degli altri moduli è stata naturale.",[15,318,319,320,323],{},"Dal punto di vista tecnico, la combinazione ",[19,321,322],{},"MongoDB + SQL Server"," si è rivelata vincente. MongoDB per i dati dinamici del CRM, SQL Server (in sola lettura) per i dati storici dell'ERP. Due database, due scopi diversi, zero conflitti.",{"title":325,"searchDepth":326,"depth":326,"links":327},"",2,[328,329,337,338,342],{"id":12,"depth":326,"text":13},{"id":44,"depth":326,"text":45,"children":330},[331,333,334,335,336],{"id":56,"depth":332,"text":57},3,{"id":83,"depth":332,"text":84},{"id":113,"depth":332,"text":114},{"id":144,"depth":332,"text":145},{"id":177,"depth":332,"text":178},{"id":210,"depth":326,"text":211},{"id":247,"depth":326,"text":248,"children":339},[340,341],{"id":251,"depth":332,"text":252},{"id":294,"depth":332,"text":295},{"id":301,"depth":326,"text":302},"2024","CRM modulare per rete agenti con BI integrata, previsione riordini e catalogo digitale. 5 moduli per gestire l'intero ciclo commerciale dalla visita all'ordine.","md",false,"\u002Fimages\u002Fprojects\u002Fagenthub.jpg",{},true,5,"\u002Fprogetti\u002Fagenthub","Arredamento \u002F Produzione",{"title":5,"description":344},"progetti\u002Fagenthub",[356,243,357,236],"Vue.js 3","SQL Server","CRM","09nOos_uzyQaXGVQ7AF9i5_akqreYJqVBwRnu9JSA64",[361,528,728,950,1150],{"id":362,"title":363,"body":364,"date":343,"description":516,"extension":345,"featured":349,"image":517,"meta":518,"navigation":349,"order":519,"path":520,"sector":521,"seo":522,"stem":523,"tech":524,"type":526,"__hash__":527},"progetti\u002Fprogetti\u002Fsafetrack.md","SafeTrack",{"type":7,"value":365,"toc":505},[366,368,371,374,376,379,382,386,393,405,409,412,426,429,433,440,444,451,462,466,469,489,491,498],[10,367,13],{"id":12},[15,369,370],{},"Un'azienda del settore antincendio e sicurezza nel Sud Italia gestiva tutta la manutenzione   estintori, impianti antincendio, DAE   su carta. Gli operatori uscivano al mattino con fogli stampati, compilavano a mano i report di intervento, tornavano in ufficio e qualcuno li inseriva nel sistema. Un processo che funzionava, certo. Ma funzionava male.",[15,372,373],{},"I problemi erano evidenti: errori di trascrizione, ritardi nella rendicontazione, nessuna visibilità in tempo reale su chi stava facendo cosa. Il management vedeva i dati solo a fine settimana. E quando un cliente chiedeva lo storico degli interventi, servivano ore per ricostruirlo.",[10,375,45],{"id":44},[15,377,378],{},"Ho progettato e sviluppato SafeTrack, un'app mobile nativa che accompagna l'operatore in ogni fase del lavoro quotidiano. L'idea era semplice: l'operatore apre l'app, vede la sua lista lavoro, prende in carico gli interventi, li completa e tutto si sincronizza automaticamente con il backoffice.",[15,380,381],{},"Ma la semplicità d'uso nasconde una complessità tecnica significativa.",[54,383,385],{"id":384},"architettura-offline-first","Architettura offline-first",[15,387,388,389,392],{},"Gli operatori lavorano spesso in seminterrati, garage, capannoni   posti dove il segnale è un lusso. Per questo ho scelto un'architettura ",[19,390,391],{},"offline-first",": l'app funziona completamente senza connessione. I dati vengono scaricati all'inizio della giornata, gli interventi vengono registrati localmente e la sincronizzazione avviene quando il dispositivo torna online.",[15,394,395,396,400,401,404],{},"Ho utilizzato ",[397,398,399],"code",{},"AsyncStorage"," per i dati operativi e ",[397,402,403],{},"SecureStore"," per i token JWT, garantendo sia la persistenza che la sicurezza.",[54,406,408],{"id":407},"due-workflow-distinti","Due workflow distinti",[15,410,411],{},"Il sistema gestisce due workflow principali:",[27,413,414,420],{},[30,415,416,419],{},[19,417,418],{},"Prelievo",": l'operatore preleva il dispositivo (estintore, DAE, ecc.), lo porta in laboratorio, esegue la manutenzione e lo riconsegna",[30,421,422,425],{},[19,423,424],{},"SulPosto",": l'operatore esegue la manutenzione direttamente presso il cliente",[15,427,428],{},"Ogni workflow ha i suoi stati, le sue validazioni e le sue regole. Ho implementato una macchina a stati che gestisce le transizioni e impedisce operazioni non valide.",[54,430,432],{"id":431},"gestione-gerarchica-a-3-livelli","Gestione gerarchica a 3 livelli",[15,434,435,436,439],{},"I dispositivi sono organizzati in una gerarchia a tre livelli: ",[19,437,438],{},"Categoria → Tipologia → Dispositivo",". Questa struttura permette di navigare rapidamente tra migliaia di dispositivi e di applicare regole di manutenzione specifiche per ogni tipologia.",[10,441,443],{"id":442},"stack-tecnico","Stack tecnico",[15,445,446,447,450],{},"Il backend è costruito su ",[19,448,449],{},"Strapi 5"," con autenticazione JWT. Ho scelto Strapi perché offre un'API REST completa out-of-the-box e un pannello di amministrazione che il backoffice può usare direttamente.",[15,452,453,454,457,458,461],{},"Il frontend è ",[19,455,456],{},"React Native"," con ",[19,459,460],{},"Expo SDK 54",", TypeScript come linguaggio principale. La scelta di Expo ha accelerato enormemente lo sviluppo e il deployment su entrambe le piattaforme (iOS e Android).",[10,463,465],{"id":464},"risultati","Risultati",[15,467,468],{},"I numeri parlano chiaro:",[27,470,471,477,483],{},[30,472,473,476],{},[19,474,475],{},"-70% tempi di rendicontazione",": quello che prima richiedeva ore di data entry manuale ora è automatico",[30,478,479,482],{},[19,480,481],{},"Eliminazione completa della gestione cartacea",": niente più fogli stampati, niente più errori di trascrizione",[30,484,485,488],{},[19,486,487],{},"Visibilità real-time dal backoffice",": il management vede in tempo reale lo stato degli interventi, senza aspettare fine giornata",[10,490,302],{"id":301},[15,492,493,494,497],{},"SafeTrack è stata la mia prima app mobile in produzione con architettura offline-first. La lezione più importante? ",[19,495,496],{},"La sincronizzazione dei dati è il problema più difficile da risolvere",". Non è sufficiente salvare i dati localmente e inviarli quando c'è rete   bisogna gestire i conflitti, i retry, i timeout. Ho sviluppato un sistema di coda con retry exponential backoff che ha reso il processo robusto e affidabile.",[15,499,500,501,504],{},"Un'altra lezione: ",[19,502,503],{},"Expo SDK 54 è maturo per la produzione",". I tempi di sviluppo rispetto a React Native CLI sono drasticamente inferiori, e la qualità del risultato è identica.",{"title":325,"searchDepth":326,"depth":326,"links":506},[507,508,513,514,515],{"id":12,"depth":326,"text":13},{"id":44,"depth":326,"text":45,"children":509},[510,511,512],{"id":384,"depth":332,"text":385},{"id":407,"depth":332,"text":408},{"id":431,"depth":332,"text":432},{"id":442,"depth":326,"text":443},{"id":464,"depth":326,"text":465},{"id":301,"depth":326,"text":302},"App mobile per la gestione della manutenzione antincendio. Offline-first con React Native ed Expo, ha eliminato la gestione cartacea e ridotto i tempi di rendicontazione del 70%.","\u002Fimages\u002Fprojects\u002Fsafetrack.jpg",{},1,"\u002Fprogetti\u002Fsafetrack","Antincendio \u002F Sicurezza",{"title":363,"description":516},"progetti\u002Fsafetrack",[456,460,236,449,525,399,403],"JWT Auth","Mobile App","PhoCOUoCKtZkUOcq3EHbPxOVtxxfQxJ-5jX1b_KIURI",{"id":529,"title":530,"body":531,"date":717,"description":718,"extension":345,"featured":349,"image":719,"meta":720,"navigation":349,"order":326,"path":721,"sector":722,"seo":723,"stem":724,"tech":725,"type":726,"__hash__":727},"progetti\u002Fprogetti\u002Fmuseumplay.md","MuseumPlay",{"type":7,"value":532,"toc":705},[533,535,538,553,557,564,568,571,575,578,598,601,605,608,619,623,634,638,679,683,690,692,699],[10,534,13],{"id":12},[15,536,537],{},"Una software house partner mi ha coinvolto su un progetto ambizioso: una piattaforma di gamification culturale per musei italiani, commissionata tramite il Ministero della Cultura. L'obiettivo era rendere l'esperienza museale più coinvolgente per i visitatori attraverso missioni, giochi e contenuti interattivi accessibili da smartphone.",[15,539,540,541,544,545,548,549,552],{},"Le sfide tecniche erano molteplici: l'app doveva funzionare ",[19,542,543],{},"offline"," (i musei spesso hanno connettività scarsa), essere ",[19,546,547],{},"multi-tenant"," (ogni museo è un'istanza indipendente con i propri contenuti), supportare ",[19,550,551],{},"più lingue"," e offrire un'esperienza mobile-first fluida e performante   il tutto senza richiedere l'installazione di un'app nativa.",[10,554,556],{"id":555},"la-soluzione-una-pwa-mobile-first","La soluzione: una PWA mobile-first",[15,558,559,560,563],{},"Ho scelto di realizzare MuseumPlay come ",[19,561,562],{},"Progressive Web App",". Una PWA offre il meglio dei due mondi: si usa come un sito web (nessuna installazione richiesta, accessibile da QR code all'ingresso del museo) ma funziona come un'app nativa (funzionalità offline, notifiche, installazione opzionale sulla home screen).",[54,565,567],{"id":566},"architettura-multi-tenant","Architettura multi-tenant",[15,569,570],{},"Ogni museo ha la propria istanza di MuseumPlay con contenuti, missioni, mappe e stili personalizzati. Ho progettato un'architettura multi-tenant dove la base di codice è unica, ma la configurazione per museo è completamente indipendente. Questo significa che aggiungere un nuovo museo al sistema richiede solo configurazione, non sviluppo.",[54,572,574],{"id":573},"flusso-di-autenticazione-progressivo","Flusso di autenticazione progressivo",[15,576,577],{},"Ho implementato un flusso di autenticazione a tre livelli, pensato per non creare attrito:",[257,579,580,586,592],{},[30,581,582,585],{},[19,583,584],{},"Guest",": il visitatore inizia a esplorare senza registrarsi",[30,587,588,591],{},[19,589,590],{},"OTP",": per sbloccare funzionalità avanzate, basta un codice via SMS",[30,593,594,597],{},[19,595,596],{},"Registrazione completa",": per salvare i progressi e partecipare alle classifiche",[15,599,600],{},"Questo approccio progressivo massimizza il coinvolgimento: il visitatore non deve compilare un form prima ancora di capire cosa offre l'app.",[54,602,604],{"id":603},"sistema-di-missioni-e-gamification","Sistema di missioni e gamification",[15,606,607],{},"Il cuore di MuseumPlay è il sistema di missioni. Ogni museo configura percorsi tematici con tappe, giochi, quiz e contenuti multimediali. Ho implementato il progress tracking completo: il visitatore vede il suo avanzamento in tempo reale, sblocca reward e può confrontarsi con gli altri visitatori.",[15,609,610,611,614,615,618],{},"Le mappe interattive sono costruite con ",[19,612,613],{},"Leaflet",", con layer personalizzati per ogni museo. Le animazioni di feedback (completamento missione, reward sbloccato) usano ",[19,616,617],{},"Motion.dev"," per un'esperienza fluida e soddisfacente.",[54,620,622],{"id":621},"funzionalità-offline-con-service-worker","Funzionalità offline con Service Worker",[15,624,625,626,629,630,633],{},"Ho configurato ",[19,627,628],{},"Workbox"," tramite ",[397,631,632],{},"vite-plugin-pwa"," per gestire il caching strategico delle risorse. I contenuti del museo vengono pre-cachati quando il visitatore ha connessione, così può continuare a esplorare anche quando perde il segnale. Le interazioni (risposte ai quiz, completamento missioni) vengono salvate localmente e sincronizzate appena la connessione torna disponibile.",[10,635,637],{"id":636},"stack-tecnico-nel-dettaglio","Stack tecnico nel dettaglio",[27,639,640,649,655,661,667,673],{},[30,641,642,644,645,648],{},[19,643,356],{}," con Composition API e ",[19,646,647],{},"Vite"," per un'esperienza di sviluppo velocissima",[30,650,651,654],{},[19,652,653],{},"Pinia"," per lo state management (sessione utente, progressi, dati museo)",[30,656,657,660],{},[19,658,659],{},"Tailwind CSS 4"," per lo styling   con design token personalizzabili per museo",[30,662,663,666],{},[19,664,665],{},"vue-i18n"," per l'internazionalizzazione (italiano, inglese, con struttura predisposta per altre lingue)",[30,668,669,672],{},[19,670,671],{},"Zod"," per la validazione dei dati in ingresso   fondamentale per la robustezza di un'app multi-tenant",[30,674,675,678],{},[19,676,677],{},"GitLab CI\u002FCD"," su istanza self-hosted, accessibile via VPN Tailscale",[10,680,682],{"id":681},"processo-di-sviluppo","Processo di sviluppo",[15,684,685,686,689],{},"Il progetto ha richiesto un piano di sviluppo strutturato su ",[19,687,688],{},"144-181 giorni",", con milestone ben definite. La gestione è avvenuta interamente su GitLab self-hosted del partner, con accesso tramite VPN. Ho lavorato in sprint di 2 settimane con demo al termine di ciascuno, coinvolgendo sia il partner che i referenti istituzionali.",[10,691,302],{"id":301},[15,693,694,695,698],{},"La lezione più grande di MuseumPlay? ",[19,696,697],{},"La multicanalità come vincolo architetturale",". Progettare un sistema multi-tenant non è solo una questione di database separati   è una mentalità che permea ogni decisione, dallo stile CSS al routing, dalla gestione degli asset alla configurazione del Service Worker.",[15,700,701,702,704],{},"Ho anche imparato l'importanza di ",[19,703,671],{}," come guardia in ingresso: in un sistema dove i dati arrivano da configurazioni diverse per ogni museo, avere una validazione rigorosa ha evitato decine di bug in produzione.",{"title":325,"searchDepth":326,"depth":326,"links":706},[707,708,714,715,716],{"id":12,"depth":326,"text":13},{"id":555,"depth":326,"text":556,"children":709},[710,711,712,713],{"id":566,"depth":332,"text":567},{"id":573,"depth":332,"text":574},{"id":603,"depth":332,"text":604},{"id":621,"depth":332,"text":622},{"id":636,"depth":326,"text":637},{"id":681,"depth":326,"text":682},{"id":301,"depth":326,"text":302},"2025","Progressive Web App per la gamification culturale nei musei italiani. Architettura multi-tenant, funzionalità offline e sistema di missioni interattive per un progetto del Ministero della Cultura.","\u002Fimages\u002Fprojects\u002Fmuseumplay.jpg",{},"\u002Fprogetti\u002Fmuseumplay","Cultura \u002F Pubblica Amministrazione",{"title":530,"description":718},"progetti\u002Fmuseumplay",[356,647,653,659,613,617,628,665,671,677],"PWA","MD1jxYWSeZxXBkfqKNetmmuOhsSBQ0JiU2ydQbddqIo",{"id":729,"title":730,"body":731,"date":930,"description":931,"extension":345,"featured":349,"image":932,"meta":933,"navigation":349,"order":332,"path":934,"sector":935,"seo":936,"stem":937,"tech":938,"type":948,"__hash__":949},"progetti\u002Fprogetti\u002Fdatavision.md","DataVision",{"type":7,"value":732,"toc":917},[733,735,742,745,747,750,754,761,765,768,772,779,783,790,794,805,828,830,833,864,867,869,872,898,900,907,914],[10,734,13],{"id":12},[15,736,737,738,741],{},"Un'azienda di distribuzione nel settore sicurezza industriale aveva un problema molto comune nelle PMI italiane: ",[19,739,740],{},"i dati c'erano, ma nessuno riusciva a usarli",". Il gestionale ERP conteneva anni di dati su vendite, clienti, magazzino, agenti   ma estrarre un report significava chiedere all'ufficio IT, aspettare giorni e ricevere un file Excel con migliaia di righe incomprensibili.",[15,743,744],{},"Il management prendeva decisioni sulla base di sensazioni. Gli agenti non sapevano quali clienti stavano calando. Il magazzino ordinava a occhio. I dati erano lì, ma erano invisibili.",[10,746,45],{"id":44},[15,748,749],{},"Ho progettato e realizzato DataVision, una piattaforma BI completa che trasforma i dati dell'ERP aziendale in dashboard interattive, accessibili da browser. Ogni ruolo aziendale ha la sua vista: agenti, responsabili warehouse, management, direzione.",[54,751,753],{"id":752},"dashboard-venduto-con-drill-down","Dashboard Venduto con drill-down",[15,755,756,757,760],{},"La dashboard principale mostra l'andamento delle vendite con filtri per periodo, agente, zona, categoria prodotto. Ma il vero valore è nel ",[19,758,759],{},"drill-down",": dal totale del venduto si può scendere fino alla singola fattura, passando per cliente, famiglia prodotto, articolo. Il management non deve più chiedere \"perché quel numero è così\"   può scoprirlo da solo.",[54,762,764],{"id":763},"controllo-fido-con-alert","Controllo fido con alert",[15,766,767],{},"Ho implementato un sistema di monitoraggio del fido clienti con alert automatici. Quando un cliente si avvicina o supera il limite, il sistema invia notifiche al responsabile commerciale e all'agente. Questo ha ridotto drasticamente i ritardi nei pagamenti.",[54,769,771],{"id":770},"sistema-premi-agenti","Sistema premi agenti",[15,773,774,775,778],{},"Uno dei moduli più complessi: il sistema di calcolo premi per la rete agenti. La logica di business richiede il ",[19,776,777],{},"calcolo con anti double-counting","   ogni vendita viene attribuita una sola volta, anche quando più regole di premialità si sovrappongono. Ho implementato un motore di regole configurabile che il management può modificare senza intervento tecnico.",[54,780,782],{"id":781},"valutazione-magazzino","Valutazione magazzino",[15,784,785,786,789],{},"Il modulo warehouse calcola l'",[19,787,788],{},"indice di rotazione"," per ogni articolo, identifica le scorte ferme e suggerisce i riordini. I dati vengono aggiornati quotidianamente tramite pipeline ETL automatizzate.",[54,791,793],{"id":792},"integrazione-ai","Integrazione AI",[15,795,796,797,800,801,804],{},"Ho integrato le API di ",[19,798,799],{},"OpenAI"," e ",[19,802,803],{},"Claude"," per aggiungere un layer di intelligenza all'analisi. Il sistema può:",[27,806,807,814,821],{},[30,808,809,810,813],{},"Generare ",[19,811,812],{},"analisi testuali"," a partire dai dati (es. \"Il fatturato zona Nord è calato del 12% rispetto al trimestre precedente, principalmente a causa del cliente X\")",[30,815,816,817,820],{},"Identificare ",[19,818,819],{},"pattern anomali"," nei dati di vendita",[30,822,823,824,827],{},"Suggerire ",[19,825,826],{},"azioni correttive"," basate sui trend",[10,829,211],{"id":210},[15,831,832],{},"La piattaforma si compone di diversi layer:",[27,834,835,840,846,852,858],{},[30,836,837,839],{},[19,838,218],{},": Vue.js 3 con Composition API per le dashboard interattive",[30,841,842,845],{},[19,843,844],{},"ETL Layer",": Node-RED e n8n per l'estrazione, trasformazione e caricamento dei dati dall'ERP (SQL Server) al database operativo (MySQL)",[30,847,848,851],{},[19,849,850],{},"BI Engine",": Power BI per i report embedded, con misure DAX avanzate per calcoli complessi (YoY, running totals, ranking)",[30,853,854,857],{},[19,855,856],{},"AI Layer",": API OpenAI\u002FClaude per analisi predittive e generazione insights",[30,859,860,863],{},[19,861,862],{},"Infrastructure",": Docker per il deployment, GitHub Actions per la CI\u002FCD",[15,865,866],{},"I flussi ETL girano ogni notte, aggiornando i dati operativi. I dashboard sono sempre aggiornati alla giornata precedente, con alcuni KPI refreshati in near-real-time.",[10,868,465],{"id":464},[15,870,871],{},"I numeri che mi rendono più orgoglioso:",[27,873,874,880,886,892],{},[30,875,876,879],{},[19,877,878],{},"-40% tempi di estrazione dati",": quello che prima richiedeva ore di lavoro manuale ora è accessibile in un clic",[30,881,882,885],{},[19,883,884],{},"Analisi bancaria da 3 ore a 20 secondi",": un report che richiedeva mezza giornata di lavoro ora è istantaneo",[30,887,888,891],{},[19,889,890],{},"40+ utenti attivi",": dagli agenti alla direzione, tutta l'azienda usa DataVision quotidianamente",[30,893,894,897],{},[19,895,896],{},"Autonomia operativa",": il management prende decisioni basate sui dati, senza dipendere dall'ufficio IT",[10,899,302],{"id":301},[15,901,902,903,906],{},"DataVision mi ha insegnato che ",[19,904,905],{},"la BI non è una questione di tecnologia, ma di traduzione",". Il mio lavoro non è stato costruire dashboard   è stato capire le domande che il management si pone e tradurle in visualizzazioni comprensibili.",[15,908,909,910,913],{},"Ho anche imparato il valore di ",[19,911,912],{},"Node-RED e n8n come acceleratori",": per le pipeline ETL, queste piattaforme low-code permettono di iterare velocemente e di coinvolgere anche figure non tecniche nella definizione dei flussi.",[15,915,916],{},"L'integrazione AI è stata la parte più innovativa. Non ho cercato di sostituire l'analisi umana   ho dato agli analisti uno strumento in più per interpretare i dati. Il risultato è che le riunioni commerciali sono diventate più brevi e più focalizzate.",{"title":325,"searchDepth":326,"depth":326,"links":918},[919,920,927,928,929],{"id":12,"depth":326,"text":13},{"id":44,"depth":326,"text":45,"children":921},[922,923,924,925,926],{"id":752,"depth":332,"text":753},{"id":763,"depth":332,"text":764},{"id":770,"depth":332,"text":771},{"id":781,"depth":332,"text":782},{"id":792,"depth":332,"text":793},{"id":210,"depth":326,"text":211},{"id":464,"depth":326,"text":465},{"id":301,"depth":326,"text":302},"2023","Piattaforma di Business Intelligence completa con dashboard per agenti, warehouse e direzione. Integrazione AI per analisi predittive, usata quotidianamente da oltre 40 utenti.","\u002Fimages\u002Fprojects\u002Fdatavision.jpg",{},"\u002Fprogetti\u002Fdatavision","Distribuzione \u002F Sicurezza industriale",{"title":730,"description":931},"progetti\u002Fdatavision",[356,939,940,357,941,942,943,944,945,946,947],"Node-RED","n8n","MySQL","Power BI","DAX","OpenAI API","Claude API","Docker","GitHub Actions","BI Dashboard","JprSV2IFbZmzZxKZO98qTrYI5sn6BSCVdMUzBLXRMBQ",{"id":951,"title":952,"body":953,"date":930,"description":1141,"extension":345,"featured":346,"image":1142,"meta":1143,"navigation":349,"order":1144,"path":1145,"sector":352,"seo":1146,"stem":1147,"tech":1148,"type":948,"__hash__":1149},"progetti\u002Fprogetti\u002Fsalesinsight.md","SalesInsight",{"type":7,"value":954,"toc":1130},[955,957,964,971,973,980,984,987,994,997,1001,1010,1016,1020,1026,1052,1055,1059,1083,1085,1111,1113,1120,1127],[10,956,13],{"id":12},[15,958,959,960,963],{},"Una PMI produttrice nel settore arredamento aveva un problema ricorrente: ",[19,961,962],{},"ogni mese, il reparto amministrativo dedicava 15-20 ore all'estrazione di report commerciali",". L'ERP aziendale (basato su SQL Server) conteneva tutti i dati, ma non aveva un modulo di reportistica decente. Il risultato? Export in Excel, pivot table manuali, invio via email. E quando il direttore commerciale chiedeva un dato aggiornato a metà mese, doveva aspettare.",[15,965,966,967,970],{},"La direzione voleva una cosa semplice: ",[19,968,969],{},"vedere il fatturato in tempo reale",", con filtri per periodo, cliente e agente. Senza chiedere all'ufficio ogni volta.",[10,972,45],{"id":44},[15,974,975,976,979],{},"Ho progettato SalesInsight come una dashboard web leggera, collegata direttamente al database dell'ERP aziendale. L'idea era chiara: ",[19,977,978],{},"non duplicare i dati, ma leggerli dove sono",".",[54,981,983],{"id":982},"architettura-zero-trust-con-tailscale","Architettura zero-trust con Tailscale",[15,985,986],{},"Il database SQL Server dell'azienda è on-premise, dietro un firewall. La cosa tradizionale sarebbe stata aprire una porta, configurare un reverse proxy, gestire certificati SSL... e introdurre un rischio di sicurezza significativo.",[15,988,989,990,993],{},"Ho scelto un approccio diverso: ",[19,991,992],{},"Tailscale VPN",". Ogni nodo della rete (il server della dashboard, il server aziendale) si registra sulla rete Tailscale e comunica attraverso un tunnel crittografato punto-punto. Zero porte aperte, zero configurazione firewall, zero rischi.",[15,995,996],{},"Il server della dashboard gira su un VPS e si connette al SQL Server aziendale come se fosse sulla rete locale. Nessun dato transita in chiaro, nessuna porta esposta su Internet.",[54,998,1000],{"id":999},"backend-expresstypescript","Backend Express\u002FTypeScript",[15,1002,1003,1004,800,1007,1009],{},"Il backend è un'API REST costruita con ",[19,1005,1006],{},"Express",[19,1008,236],{},". Le query al SQL Server sono ottimizzate con viste materializzate e indici dedicati, per garantire tempi di risposta sotto il secondo anche con query complesse su anni di dati.",[15,1011,1012,1013,1015],{},"I risultati delle query più pesanti vengono cachati in ",[19,1014,243],{}," (su Docker), con un sistema di invalidazione intelligente che refresha solo i dati modificati dall'ultimo aggiornamento.",[54,1017,1019],{"id":1018},"frontend-vuejs-3","Frontend Vue.js 3",[15,1021,1022,1023,1025],{},"La dashboard è costruita con ",[19,1024,356],{}," e Composition API. Le visualizzazioni principali includono:",[27,1027,1028,1034,1040,1046],{},[30,1029,1030,1033],{},[19,1031,1032],{},"Andamento fatturato"," nel tempo (giorno, settimana, mese, trimestre, anno)",[30,1035,1036,1039],{},[19,1037,1038],{},"Performance clienti",": classifica, confronto anno su anno, trend di crescita o calo",[30,1041,1042,1045],{},[19,1043,1044],{},"Performance agenti",": venduto per agente con target e scostamento",[30,1047,1048,1051],{},[19,1049,1050],{},"Confronto YoY",": ogni dato è sempre affiancato dal valore dell'anno precedente",[15,1053,1054],{},"L'interfaccia è progettata per essere usata dal direttore commerciale   non da un analista dati. Pochi filtri, visualizzazioni chiare, drill-down dove serve.",[54,1056,1058],{"id":1057},"deploy-e-infrastruttura","Deploy e infrastruttura",[27,1060,1061,1067,1073,1078],{},[30,1062,1063,1066],{},[19,1064,1065],{},"Nginx"," come reverse proxy",[30,1068,1069,1072],{},[19,1070,1071],{},"PM2"," per il process management del backend Node.js",[30,1074,1075,1077],{},[19,1076,947],{}," per la CI\u002FCD automatizzata",[30,1079,1080,1082],{},[19,1081,946],{}," per MongoDB e per l'ambiente di staging",[10,1084,465],{"id":464},[27,1086,1087,1093,1099,1105],{},[30,1088,1089,1092],{},[19,1090,1091],{},"Azzeramento tempi di estrazione report",": quelle 15-20 ore mensili di lavoro manuale non esistono più",[30,1094,1095,1098],{},[19,1096,1097],{},"ROI in 12 mesi",": il costo dello sviluppo è stato ripagato in un anno solo dal risparmio di tempo del reparto amministrativo",[30,1100,1101,1104],{},[19,1102,1103],{},"Autonomia completa",": la direzione commerciale accede ai dati in autonomia, senza dipendere dall'ufficio amministrativo",[30,1106,1107,1110],{},[19,1108,1109],{},"Dati sempre aggiornati",": il dashboard mostra i dati in near-real-time, non più report settimanali",[10,1112,302],{"id":301},[15,1114,1115,1116,1119],{},"SalesInsight mi ha insegnato il valore di ",[19,1117,1118],{},"Tailscale come soluzione per l'accesso remoto ai dati aziendali",". In molte PMI, i dati critici sono su server on-premise e non possono essere migrati al cloud per motivi normativi o di costi. Tailscale risolve questo problema in modo elegante e sicuro.",[15,1121,1122,1123,1126],{},"Un'altra lezione importante: ",[19,1124,1125],{},"non servono dashboard complesse per creare valore",". SalesInsight ha pochi schermi, pochi filtri, pochi grafici. Ma sono esattamente quelli che servono. La tentazione di aggiungere funzionalità è forte   resistere è la scelta giusta.",[15,1128,1129],{},"Questo progetto ha anche gettato le basi per AgentHub, il CRM per la rete agenti della stessa azienda. Il valore dimostrato da SalesInsight ha convinto la direzione a investire in una soluzione più ampia.",{"title":325,"searchDepth":326,"depth":326,"links":1131},[1132,1133,1139,1140],{"id":12,"depth":326,"text":13},{"id":44,"depth":326,"text":45,"children":1134},[1135,1136,1137,1138],{"id":982,"depth":332,"text":983},{"id":999,"depth":332,"text":1000},{"id":1018,"depth":332,"text":1019},{"id":1057,"depth":332,"text":1058},{"id":464,"depth":326,"text":465},{"id":301,"depth":326,"text":302},"Dashboard commerciale real-time collegata all'ERP aziendale via VPN zero-trust. Ha azzerato le 15-20 ore mensili di estrazione report manuali.","\u002Fimages\u002Fprojects\u002Fsalesinsight.jpg",{},4,"\u002Fprogetti\u002Fsalesinsight",{"title":952,"description":1141},"progetti\u002Fsalesinsight",[356,1006,236,243,946,992,357,1065,1071,947],"Q-i9dxO6VPQJc7ibkrzrVK7mOnQs_eskAImSDYPJHDM",{"id":4,"title":5,"body":1151,"date":343,"description":344,"extension":345,"featured":346,"image":347,"meta":1365,"navigation":349,"order":350,"path":351,"sector":352,"seo":1366,"stem":354,"tech":1367,"type":358,"__hash__":359},{"type":7,"value":1152,"toc":1349},[1153,1155,1159,1161,1171,1173,1177,1179,1181,1195,1197,1199,1213,1215,1217,1221,1235,1237,1239,1257,1259,1261,1277,1279,1297,1301,1303,1305,1307,1329,1331,1333,1335,1337,1341,1345],[10,1154,13],{"id":12},[15,1156,17,1157,22],{},[19,1158,21],{},[15,1160,25],{},[27,1162,1163,1165,1167,1169],{},[30,1164,32],{},[30,1166,35],{},[30,1168,38],{},[30,1170,41],{},[10,1172,45],{"id":44},[15,1174,48,1175,52],{},[19,1176,51],{},[54,1178,57],{"id":56},[15,1180,60],{},[27,1182,1183,1187,1191],{},[30,1184,1185,68],{},[19,1186,67],{},[30,1188,1189,74],{},[19,1190,73],{},[30,1192,1193,80],{},[19,1194,79],{},[54,1196,84],{"id":83},[15,1198,87],{},[27,1200,1201,1205,1209],{},[30,1202,1203,95],{},[19,1204,94],{},[30,1206,1207,101],{},[19,1208,100],{},[30,1210,1211,107],{},[19,1212,106],{},[15,1214,110],{},[54,1216,114],{"id":113},[15,1218,117,1219,121],{},[19,1220,120],{},[27,1222,1223,1227,1231],{},[30,1224,1225,129],{},[19,1226,128],{},[30,1228,1229,135],{},[19,1230,134],{},[30,1232,1233,141],{},[19,1234,140],{},[54,1236,145],{"id":144},[15,1238,148],{},[27,1240,1241,1245,1249,1253],{},[30,1242,1243,156],{},[19,1244,155],{},[30,1246,1247,162],{},[19,1248,161],{},[30,1250,1251,168],{},[19,1252,167],{},[30,1254,1255,174],{},[19,1256,173],{},[54,1258,178],{"id":177},[15,1260,181],{},[27,1262,1263,1267,1271,1275],{},[30,1264,186,1265,190],{},[19,1266,189],{},[30,1268,193,1269,197],{},[19,1270,196],{},[30,1272,200,1273,204],{},[19,1274,203],{},[30,1276,207],{},[10,1278,211],{"id":210},[27,1280,1281,1285,1289,1293],{},[30,1282,1283,219],{},[19,1284,218],{},[30,1286,1287,225],{},[19,1288,224],{},[30,1290,1291,231],{},[19,1292,230],{},[30,1294,1295,237],{},[19,1296,236],{},[15,1298,240,1299,244],{},[19,1300,243],{},[10,1302,248],{"id":247},[54,1304,252],{"id":251},[15,1306,255],{},[257,1308,1309,1313,1317,1321,1325],{},[30,1310,1311,264],{},[19,1312,263],{},[30,1314,1315,270],{},[19,1316,269],{},[30,1318,1319,276],{},[19,1320,275],{},[30,1322,1323,282],{},[19,1324,281],{},[30,1326,1327,288],{},[19,1328,287],{},[15,1330,291],{},[54,1332,295],{"id":294},[15,1334,298],{},[10,1336,302],{"id":301},[15,1338,305,1339,309],{},[19,1340,308],{},[15,1342,312,1343,316],{},[19,1344,315],{},[15,1346,319,1347,323],{},[19,1348,322],{},{"title":325,"searchDepth":326,"depth":326,"links":1350},[1351,1352,1359,1360,1364],{"id":12,"depth":326,"text":13},{"id":44,"depth":326,"text":45,"children":1353},[1354,1355,1356,1357,1358],{"id":56,"depth":332,"text":57},{"id":83,"depth":332,"text":84},{"id":113,"depth":332,"text":114},{"id":144,"depth":332,"text":145},{"id":177,"depth":332,"text":178},{"id":210,"depth":326,"text":211},{"id":247,"depth":326,"text":248,"children":1361},[1362,1363],{"id":251,"depth":332,"text":252},{"id":294,"depth":332,"text":295},{"id":301,"depth":326,"text":302},{},{"title":5,"description":344},[356,243,357,236],1776157867704]