Lagotto BI — Architettura e funzionamento tecnicoLagotto BI — Architettura e funzionamento tecnico

Lagotto BI — Architettura e funzionamento tecnico

Lagotto BI legge da un gestionale su MSSQL, sincronizza i dati su un database MariaDB interno ogni 5–15 minuti, e li espone tramite dashboard drag&drop configurabili senza scrivere codice. Il tempo che separa “non ho ancora collegato il gestionale” da “ho una dashboard con dati reali” si misura in passaggi di wizard, non in settimane di sviluppo custom.


Stack tecnico

ComponenteTecnologia
BackendFastAPI (Python 3.11+), SQLAlchemy 2.x async, MariaDB
Connettore sorgentepymssql — solo lettura, mai scrittura sul gestionale
SyncAPScheduler — incrementale 5–15 min, full sync notturno zero-downtime
FrontendVue 3 + Vite + TypeScript, Pinia
GraficiApache ECharts (tree-shaken, solo i moduli usati)
Tabelle / PivotTabulator 6 / pivottable.js
IsolamentoSchema MariaDB dedicato per tenant — nessun dato condiviso tra clienti

Tempi reali di configurazione

Ogni passaggio ha un test o un’anteprima integrata. Non si salva mai alla cieca.

PassaggioCosa succedeTempo tipico
1. Connessione al gestionaleWizard 5 step: host, porta, credenziali, schema registry, test di connessione live prima di salvare3–5 minuti
2. Mappatura schemaMapper Builder: wizard visivo campo→campo, trasformazioni predefinite, test con anteprima di 50 righe reali prima di salvare10–20 minuti per tabella la prima volta — istantaneo su schema già certificato
2b. Import tabella interaWizard 3 step: tabella MSSQL → staging MariaDB, senza mappatura campo per campo2–3 minuti
3. Prima sincronizzazioneAutomatica — incrementale ogni 5–15 minuti, configurabile per datasourceDati disponibili entro 15 minuti
4. Prima dashboardGriglia drag&drop, ogni widget con anteprima live durante la configurazione1–2 minuti per widget
5. Filtri e drill-throughWizard filtri con propagazione automatica cross-vista2–3 minuti per filtro

Da gestionale non ancora collegato a dashboard con dati reali: l’ordine di grandezza è la mezz’ora, non il ciclo tipico analisi-preventivo-sviluppo-collaudo di un progetto BI custom.


Motore di aggregazione

La differenza che si vede meno ma pesa di più: l’aggregazione avviene sul database, non nel browser. Un grafico con Top 10 + “Altro” su una vista da centinaia di migliaia di righe non scarica quelle righe nel browser per poi tagliarle in JavaScript — il backend esegue GROUP BY + SUM con l’ordinamento già applicato, e restituisce solo le righe che verranno disegnate.

GET /api/data/v_fatturato_mensile
?_top_n_x=mese&_top_n_y=totale&_top_n=10&_raggruppamento=regione_cliente
-- generato dal backend, parametrizzato — mai interpolazione di stringa
SELECT mese, regione_cliente, SUM(totale) AS totale
FROM v_fatturato_mensile
WHERE anno = :anno
GROUP BY mese, regione_cliente
ORDER BY SUM(totale) DESC

Il widget Pivot (PRO) segue la logica opposta quando serve: dati grezzi senza LIMIT, aggregati client-side da pivottable.js. Verificato su 100.576 righe reali con € 21.142.336 sommati in tempo reale mentre l’utente trascina i campi.

Una cache in memoria (TTL 60 secondi, per utente) evita che un cambio di tab o un doppio clic sul filtro rigeneri la stessa query due volte.


Catalogo widget

Sette tipi di widget, tutti configurabili da pannello — nessuno richiede JSON scritto a mano.

WidgetTierCosa faCosa lo distingue
KPIFREEValore singolo con confronto periodo precedente e formattazione automaticaDelta periodo su periodo calcolato automaticamente
Bar / LineFREEGrafici a barre e linee, singola o multi-serieMulti-serie retrocompatibile
Bar — variantiFREEBarre impilate, orizzontali, valori sopra/accantoConfigurabili a checkbox
Pie / DonutFREEValore assoluto, percentuale o entrambi; Top-N con voce “Altro”Aggregazione server-side
TableFREETabulator con paginazione, ordinamento, colonne aggregateFormattazione automatica per colonna
ComboPROSerie miste barre + linea, doppio asse YOgni serie sceglie asse, tipo e colore indipendentemente
PivotPROPivot interattiva su dati grezzi, righe × colonne trascinabiliNessun limite righe lato backend; export Excel con un click

Esempio: grafico combinato

{
"tipo": "combo",
"titolo": "Fatturato vs margine",
"vista": "v_marginalita_mensile",
"asse_x": "mese",
"serie": [
{ "campo": "fatturato", "etichetta": "Fatturato", "tipo": "bar", "asse_y": "sx", "colore": "#4a90d9" },
{ "campo": "margine_pct", "etichetta": "Margine %", "tipo": "line", "asse_y": "dx", "colore": "#e85d4a" }
]
}

Questo blocco JSON — generato dal Widget Builder, mai scritto a mano — è tutto ciò che serve per un grafico che in molti strumenti BI richiede una vista SQL dedicata più configurazione manuale del secondo asse.

Azioni e drill-through

Ogni widget può reagire a un click. Lo stack di drill-through è ricorsivo — un clic dentro un modal aperto da un clic precedente apre un terzo livello, con breadcrumb per tornare indietro. Configurabile da pannello, non da codice.

AzioneComportamento
open_table / open_bar / open_pie / open_line / open_pivotApre un modal fullscreen con il widget scelto, filtrato sul valore cliccato
open_clienteNaviga a una dashboard specifica, pre-filtrata sul cliente selezionato
filter_dashboardApplica un filtro globale a tutta la dashboard corrente

Mapper Builder e Query Manager

Ogni gestionale ha un file JSON che mappa le proprie tabelle allo schema standard di Lagotto:

{
"gestionale": "custom_erp",
"tabelle": {
"FATT_TESTATE": {
"vista_target": "v_fatturato_mensile",
"colonne": {
"DATA_DOC": { "target": "data_fattura", "tipo": "date" },
"COD_CLI": { "target": "cod_cliente", "tipo": "string" },
"TOT_DOC": { "target": "fatturato", "tipo": "decimal",
"display": { "tipo": "currency", "simbolo": "€", "decimali": 0 } }
}
}
}
}

Sei trasformazioni predefinite coprono i casi che normalmente finiscono in uno script scritto a mano:

  • simple — copia diretta
  • map — lookup a dizionario
  • lookup — tabella esterna (es. provincia→regione)
  • coalesce — primo valore non nullo tra più campi
  • concat — concatenazione
  • aritmetico — somma/sottrazione tra campi

Il campo display propaga automaticamente la formattazione fino al widget finale senza configurarla una seconda volta.

Query Manager (View Builder, PRO): editor SQL con pannello delle tabelle di staging disponibili. Una vista creata qui è disponibile nel Widget Builder immediatamente — nessun riavvio del backend, nessun deploy.

-- margine per categoria, calcolato in una vista custom
CREATE OR REPLACE VIEW v_margine_categoria AS
SELECT categoria,
SUM(ricavo) AS ricavo_totale,
SUM(costo) AS costo_totale,
ROUND((SUM(ricavo) - SUM(costo)) / NULLIF(SUM(ricavo),0) * 100, 1) AS ricarico_pct
FROM raw_fatturato
GROUP BY categoria

Sicurezza e isolamento multi-tenant

  • Whitelist vista obbligatoria: l’endpoint dati accetta solo viste nella whitelist esplicita — nessuna query arbitraria dal frontend
  • Query sempre parametrizzate: mai interpolazione di stringa, anche per nomi colonna con spazi o caratteri accentati
  • Filtro agente forzato lato server: un utente con ruolo agente vede solo i propri dati — il filtro è applicato nel backend, non aggirabile dal frontend
  • Schema per tenant: ogni cliente ha un proprio schema MariaDB (lagotto_{slug}) — zero dati condivisi, zero query cross-tenant possibili per costruzione
  • Profilazione granulare per utente: un admin può restringere dashboard, tab, widget e filtri permanenti per singolo utente — filtrato server-side

Piani e licenza

PianoDashboardWidget BuilderPivot / ComboDatasourceUtentiPrezzo
Starter10 standard11Sempre gratuito
ProfessionalIllimitate35Dinamico — vedi listino
AIIllimitateIllimitati>100Su richiesta

Il limite utenti è verificato server-side a ogni creazione. Il piano viene ri-verificato live contro il License Server ogni 30 minuti — revoche e upgrade si propagano senza riavviare nulla. I prezzi mostrati all’utente sono letti in tempo reale dal License Server, non un numero fisso nel codice.


Velocità — numeri, non aggettivi

MetricaValore
Sync incrementale5–15 minuti, configurabile per datasource
Downtime full sync notturnoZero — tabella-ombra + RENAME TABLE atomico
Cache dati per widget60 secondi per utente, invalidata sul cambio filtro
Righe aggregate in pivot100.576 righe reali verificate
Valore sommato in tempo reale€ 21.142.336
Latenza propagazione cambio piano30 minuti massimo

Roadmap dichiarata

Non ancora in produzione:

  • Query Manager esteso: materializzare il risultato di una query in una tabella di staging, non solo in una vista calcolata a ogni lettura — per join pesanti su milioni di righe
  • Libreria di mapper certificati: esportare/importare uno schema di mappatura collaudato tra installazioni diverse dello stesso gestionale
  • Import/export dashboard complete: layout, widget e filtri come file esportabile, riutilizzabile come punto di partenza per un nuovo cliente

Documento tecnico — Lagotto BI. Le funzionalità in roadmap non sono ancora disponibili in produzione.


Fonti

Autore: Giantommaso Fogli
Data Pubblicazione: 2026-07-09

Diritti e attribuzioni

Immagini, loghi e fotografie sono di proprietà dei legittimi titolari. Utilizzati per finalità di commento.


← Back to journal