[{"data":1,"prerenderedAt":619},["ShallowReactive",2],{"featured-projects":3},[4,191,393],{"id":5,"title":6,"body":7,"date":175,"description":176,"extension":177,"featured":178,"image":179,"meta":180,"navigation":178,"order":181,"path":182,"sector":183,"seo":184,"stem":185,"tech":186,"type":189,"__hash__":190},"progetti\u002Fprogetti\u002Fsafetrack.md","SafeTrack",{"type":8,"value":9,"toc":161},"minimark",[10,15,19,22,26,29,32,37,45,57,61,64,80,83,87,94,98,105,116,120,123,143,147,154],[11,12,14],"h2",{"id":13},"la-sfida","La sfida",[16,17,18],"p",{},"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.",[16,20,21],{},"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.",[11,23,25],{"id":24},"la-soluzione","La soluzione",[16,27,28],{},"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.",[16,30,31],{},"Ma la semplicità d'uso nasconde una complessità tecnica significativa.",[33,34,36],"h3",{"id":35},"architettura-offline-first","Architettura offline-first",[16,38,39,40,44],{},"Gli operatori lavorano spesso in seminterrati, garage, capannoni   posti dove il segnale è un lusso. Per questo ho scelto un'architettura ",[41,42,43],"strong",{},"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.",[16,46,47,48,52,53,56],{},"Ho utilizzato ",[49,50,51],"code",{},"AsyncStorage"," per i dati operativi e ",[49,54,55],{},"SecureStore"," per i token JWT, garantendo sia la persistenza che la sicurezza.",[33,58,60],{"id":59},"due-workflow-distinti","Due workflow distinti",[16,62,63],{},"Il sistema gestisce due workflow principali:",[65,66,67,74],"ul",{},[68,69,70,73],"li",{},[41,71,72],{},"Prelievo",": l'operatore preleva il dispositivo (estintore, DAE, ecc.), lo porta in laboratorio, esegue la manutenzione e lo riconsegna",[68,75,76,79],{},[41,77,78],{},"SulPosto",": l'operatore esegue la manutenzione direttamente presso il cliente",[16,81,82],{},"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.",[33,84,86],{"id":85},"gestione-gerarchica-a-3-livelli","Gestione gerarchica a 3 livelli",[16,88,89,90,93],{},"I dispositivi sono organizzati in una gerarchia a tre livelli: ",[41,91,92],{},"Categoria → Tipologia → Dispositivo",". Questa struttura permette di navigare rapidamente tra migliaia di dispositivi e di applicare regole di manutenzione specifiche per ogni tipologia.",[11,95,97],{"id":96},"stack-tecnico","Stack tecnico",[16,99,100,101,104],{},"Il backend è costruito su ",[41,102,103],{},"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.",[16,106,107,108,111,112,115],{},"Il frontend è ",[41,109,110],{},"React Native"," con ",[41,113,114],{},"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).",[11,117,119],{"id":118},"risultati","Risultati",[16,121,122],{},"I numeri parlano chiaro:",[65,124,125,131,137],{},[68,126,127,130],{},[41,128,129],{},"-70% tempi di rendicontazione",": quello che prima richiedeva ore di data entry manuale ora è automatico",[68,132,133,136],{},[41,134,135],{},"Eliminazione completa della gestione cartacea",": niente più fogli stampati, niente più errori di trascrizione",[68,138,139,142],{},[41,140,141],{},"Visibilità real-time dal backoffice",": il management vede in tempo reale lo stato degli interventi, senza aspettare fine giornata",[11,144,146],{"id":145},"lezioni-apprese","Lezioni apprese",[16,148,149,150,153],{},"SafeTrack è stata la mia prima app mobile in produzione con architettura offline-first. La lezione più importante? ",[41,151,152],{},"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.",[16,155,156,157,160],{},"Un'altra lezione: ",[41,158,159],{},"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":162,"searchDepth":163,"depth":163,"links":164},"",2,[165,166,172,173,174],{"id":13,"depth":163,"text":14},{"id":24,"depth":163,"text":25,"children":167},[168,170,171],{"id":35,"depth":169,"text":36},3,{"id":59,"depth":169,"text":60},{"id":85,"depth":169,"text":86},{"id":96,"depth":163,"text":97},{"id":118,"depth":163,"text":119},{"id":145,"depth":163,"text":146},"2024","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%.","md",true,"\u002Fimages\u002Fprojects\u002Fsafetrack.jpg",{},1,"\u002Fprogetti\u002Fsafetrack","Antincendio \u002F Sicurezza",{"title":6,"description":176},"progetti\u002Fsafetrack",[110,114,187,103,188,51,55],"TypeScript","JWT Auth","Mobile App","PhoCOUoCKtZkUOcq3EHbPxOVtxxfQxJ-5jX1b_KIURI",{"id":192,"title":193,"body":194,"date":382,"description":383,"extension":177,"featured":178,"image":384,"meta":385,"navigation":178,"order":163,"path":386,"sector":387,"seo":388,"stem":389,"tech":390,"type":391,"__hash__":392},"progetti\u002Fprogetti\u002Fmuseumplay.md","MuseumPlay",{"type":8,"value":195,"toc":370},[196,198,201,216,220,227,231,234,238,241,262,265,269,272,283,287,298,302,344,348,355,357,364],[11,197,14],{"id":13},[16,199,200],{},"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.",[16,202,203,204,207,208,211,212,215],{},"Le sfide tecniche erano molteplici: l'app doveva funzionare ",[41,205,206],{},"offline"," (i musei spesso hanno connettività scarsa), essere ",[41,209,210],{},"multi-tenant"," (ogni museo è un'istanza indipendente con i propri contenuti), supportare ",[41,213,214],{},"più lingue"," e offrire un'esperienza mobile-first fluida e performante   il tutto senza richiedere l'installazione di un'app nativa.",[11,217,219],{"id":218},"la-soluzione-una-pwa-mobile-first","La soluzione: una PWA mobile-first",[16,221,222,223,226],{},"Ho scelto di realizzare MuseumPlay come ",[41,224,225],{},"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).",[33,228,230],{"id":229},"architettura-multi-tenant","Architettura multi-tenant",[16,232,233],{},"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.",[33,235,237],{"id":236},"flusso-di-autenticazione-progressivo","Flusso di autenticazione progressivo",[16,239,240],{},"Ho implementato un flusso di autenticazione a tre livelli, pensato per non creare attrito:",[242,243,244,250,256],"ol",{},[68,245,246,249],{},[41,247,248],{},"Guest",": il visitatore inizia a esplorare senza registrarsi",[68,251,252,255],{},[41,253,254],{},"OTP",": per sbloccare funzionalità avanzate, basta un codice via SMS",[68,257,258,261],{},[41,259,260],{},"Registrazione completa",": per salvare i progressi e partecipare alle classifiche",[16,263,264],{},"Questo approccio progressivo massimizza il coinvolgimento: il visitatore non deve compilare un form prima ancora di capire cosa offre l'app.",[33,266,268],{"id":267},"sistema-di-missioni-e-gamification","Sistema di missioni e gamification",[16,270,271],{},"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.",[16,273,274,275,278,279,282],{},"Le mappe interattive sono costruite con ",[41,276,277],{},"Leaflet",", con layer personalizzati per ogni museo. Le animazioni di feedback (completamento missione, reward sbloccato) usano ",[41,280,281],{},"Motion.dev"," per un'esperienza fluida e soddisfacente.",[33,284,286],{"id":285},"funzionalità-offline-con-service-worker","Funzionalità offline con Service Worker",[16,288,289,290,293,294,297],{},"Ho configurato ",[41,291,292],{},"Workbox"," tramite ",[49,295,296],{},"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.",[11,299,301],{"id":300},"stack-tecnico-nel-dettaglio","Stack tecnico nel dettaglio",[65,303,304,314,320,326,332,338],{},[68,305,306,309,310,313],{},[41,307,308],{},"Vue.js 3"," con Composition API e ",[41,311,312],{},"Vite"," per un'esperienza di sviluppo velocissima",[68,315,316,319],{},[41,317,318],{},"Pinia"," per lo state management (sessione utente, progressi, dati museo)",[68,321,322,325],{},[41,323,324],{},"Tailwind CSS 4"," per lo styling   con design token personalizzabili per museo",[68,327,328,331],{},[41,329,330],{},"vue-i18n"," per l'internazionalizzazione (italiano, inglese, con struttura predisposta per altre lingue)",[68,333,334,337],{},[41,335,336],{},"Zod"," per la validazione dei dati in ingresso   fondamentale per la robustezza di un'app multi-tenant",[68,339,340,343],{},[41,341,342],{},"GitLab CI\u002FCD"," su istanza self-hosted, accessibile via VPN Tailscale",[11,345,347],{"id":346},"processo-di-sviluppo","Processo di sviluppo",[16,349,350,351,354],{},"Il progetto ha richiesto un piano di sviluppo strutturato su ",[41,352,353],{},"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.",[11,356,146],{"id":145},[16,358,359,360,363],{},"La lezione più grande di MuseumPlay? ",[41,361,362],{},"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.",[16,365,366,367,369],{},"Ho anche imparato l'importanza di ",[41,368,336],{}," 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":162,"searchDepth":163,"depth":163,"links":371},[372,373,379,380,381],{"id":13,"depth":163,"text":14},{"id":218,"depth":163,"text":219,"children":374},[375,376,377,378],{"id":229,"depth":169,"text":230},{"id":236,"depth":169,"text":237},{"id":267,"depth":169,"text":268},{"id":285,"depth":169,"text":286},{"id":300,"depth":163,"text":301},{"id":346,"depth":163,"text":347},{"id":145,"depth":163,"text":146},"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":193,"description":383},"progetti\u002Fmuseumplay",[308,312,318,324,277,281,292,330,336,342],"PWA","MD1jxYWSeZxXBkfqKNetmmuOhsSBQ0JiU2ydQbddqIo",{"id":394,"title":395,"body":396,"date":598,"description":599,"extension":177,"featured":178,"image":600,"meta":601,"navigation":178,"order":169,"path":602,"sector":603,"seo":604,"stem":605,"tech":606,"type":617,"__hash__":618},"progetti\u002Fprogetti\u002Fdatavision.md","DataVision",{"type":8,"value":397,"toc":585},[398,400,407,410,412,415,419,426,430,433,437,444,448,455,459,470,493,497,500,532,535,537,540,566,568,575,582],[11,399,14],{"id":13},[16,401,402,403,406],{},"Un'azienda di distribuzione nel settore sicurezza industriale aveva un problema molto comune nelle PMI italiane: ",[41,404,405],{},"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.",[16,408,409],{},"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.",[11,411,25],{"id":24},[16,413,414],{},"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.",[33,416,418],{"id":417},"dashboard-venduto-con-drill-down","Dashboard Venduto con drill-down",[16,420,421,422,425],{},"La dashboard principale mostra l'andamento delle vendite con filtri per periodo, agente, zona, categoria prodotto. Ma il vero valore è nel ",[41,423,424],{},"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.",[33,427,429],{"id":428},"controllo-fido-con-alert","Controllo fido con alert",[16,431,432],{},"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.",[33,434,436],{"id":435},"sistema-premi-agenti","Sistema premi agenti",[16,438,439,440,443],{},"Uno dei moduli più complessi: il sistema di calcolo premi per la rete agenti. La logica di business richiede il ",[41,441,442],{},"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.",[33,445,447],{"id":446},"valutazione-magazzino","Valutazione magazzino",[16,449,450,451,454],{},"Il modulo warehouse calcola l'",[41,452,453],{},"indice di rotazione"," per ogni articolo, identifica le scorte ferme e suggerisce i riordini. I dati vengono aggiornati quotidianamente tramite pipeline ETL automatizzate.",[33,456,458],{"id":457},"integrazione-ai","Integrazione AI",[16,460,461,462,465,466,469],{},"Ho integrato le API di ",[41,463,464],{},"OpenAI"," e ",[41,467,468],{},"Claude"," per aggiungere un layer di intelligenza all'analisi. Il sistema può:",[65,471,472,479,486],{},[68,473,474,475,478],{},"Generare ",[41,476,477],{},"analisi testuali"," a partire dai dati (es. \"Il fatturato zona Nord è calato del 12% rispetto al trimestre precedente, principalmente a causa del cliente X\")",[68,480,481,482,485],{},"Identificare ",[41,483,484],{},"pattern anomali"," nei dati di vendita",[68,487,488,489,492],{},"Suggerire ",[41,490,491],{},"azioni correttive"," basate sui trend",[11,494,496],{"id":495},"architettura-tecnica","Architettura tecnica",[16,498,499],{},"La piattaforma si compone di diversi layer:",[65,501,502,508,514,520,526],{},[68,503,504,507],{},[41,505,506],{},"Frontend",": Vue.js 3 con Composition API per le dashboard interattive",[68,509,510,513],{},[41,511,512],{},"ETL Layer",": Node-RED e n8n per l'estrazione, trasformazione e caricamento dei dati dall'ERP (SQL Server) al database operativo (MySQL)",[68,515,516,519],{},[41,517,518],{},"BI Engine",": Power BI per i report embedded, con misure DAX avanzate per calcoli complessi (YoY, running totals, ranking)",[68,521,522,525],{},[41,523,524],{},"AI Layer",": API OpenAI\u002FClaude per analisi predittive e generazione insights",[68,527,528,531],{},[41,529,530],{},"Infrastructure",": Docker per il deployment, GitHub Actions per la CI\u002FCD",[16,533,534],{},"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.",[11,536,119],{"id":118},[16,538,539],{},"I numeri che mi rendono più orgoglioso:",[65,541,542,548,554,560],{},[68,543,544,547],{},[41,545,546],{},"-40% tempi di estrazione dati",": quello che prima richiedeva ore di lavoro manuale ora è accessibile in un clic",[68,549,550,553],{},[41,551,552],{},"Analisi bancaria da 3 ore a 20 secondi",": un report che richiedeva mezza giornata di lavoro ora è istantaneo",[68,555,556,559],{},[41,557,558],{},"40+ utenti attivi",": dagli agenti alla direzione, tutta l'azienda usa DataVision quotidianamente",[68,561,562,565],{},[41,563,564],{},"Autonomia operativa",": il management prende decisioni basate sui dati, senza dipendere dall'ufficio IT",[11,567,146],{"id":145},[16,569,570,571,574],{},"DataVision mi ha insegnato che ",[41,572,573],{},"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.",[16,576,577,578,581],{},"Ho anche imparato il valore di ",[41,579,580],{},"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.",[16,583,584],{},"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":162,"searchDepth":163,"depth":163,"links":586},[587,588,595,596,597],{"id":13,"depth":163,"text":14},{"id":24,"depth":163,"text":25,"children":589},[590,591,592,593,594],{"id":417,"depth":169,"text":418},{"id":428,"depth":169,"text":429},{"id":435,"depth":169,"text":436},{"id":446,"depth":169,"text":447},{"id":457,"depth":169,"text":458},{"id":495,"depth":163,"text":496},{"id":118,"depth":163,"text":119},{"id":145,"depth":163,"text":146},"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":395,"description":599},"progetti\u002Fdatavision",[308,607,608,609,610,611,612,613,614,615,616],"Node-RED","n8n","SQL Server","MySQL","Power BI","DAX","OpenAI API","Claude API","Docker","GitHub Actions","BI Dashboard","JprSV2IFbZmzZxKZO98qTrYI5sn6BSCVdMUzBLXRMBQ",1776157867258]