Chi guida un'unità di business che vende attraverso un canale terzo — un marketplace internazionale, un distributore, un grossista — conosce questa scena. Ogni mese arriva un file di rendicontazione: ordini, resi, rimborsi, commissioni, fee di pagamento, contributi, dazi, rettifiche. Decine di colonne, qualche migliaio di righe. Da quel file si ricostruisce la marginalità reale del canale: cosa è entrato, cosa è uscito, quanto resta. Da quei numeri si decide la prossima campagna di buying, la prossima spinta su una categoria, la prossima negoziazione con il partner.
Il problema non è il volume. Il problema è che quel file è il riassunto contabile di qualcun altro, scritto secondo regole che servono a quel qualcun altro, e che il tuo conto economico interpreta in modo diverso. Tre asimmetrie ricorrenti, su cui ogni tool generico inciampa.
La prima: lo stesso costo è scritto in due righe distinte. I marketplace emettono, per ogni ordine, una riga di livello "ordine" (spedizioni, contributi, dazi) e una di livello "articolo" (commissioni, fee di pagamento, sconti, rimborsi). Per i costi che possono comparire a entrambi i livelli — la commissione di carta di credito è il caso tipico — lo stesso importo è scritto in tutte e due le righe. Una somma ingenua lo conta due volte. Su un canale che fa centinaia di migliaia di euro di volume al mese, il doppio conteggio distorce la marginalità reale di qualche punto percentuale ogni mese. Nessun BI generico conosce questa specifica trappola, perché è una convenzione del canale, non una caratteristica del CSV.
La seconda: il nome del produttore non è in un campo dedicato. Va estratto per inferenza dal testo della description — uno split sul trattino, di solito — con tutte le eccezioni del caso (nomi multi-parola, trattini interni al modello, description malformate, fornitori che usano schemi proprietari). Se la classificazione brand sbaglia, ogni aggregazione "per marchio" su cui si decide il buying è sbagliata.
La terza: la classificazione dei record (vendita, reso, rimborso parziale, rettifica) e l'incrocio con il proprio listino interno richiedono combinazioni di campi che variano per stagione. Lo stesso prodotto può essere stato venduto in due collezioni con codifiche diverse. Il listino interno e il file del marketplace usano identificativi diversi e nessuno dei due garantisce coerenza retroattiva.
Tutti i tool generici risolvono l'80% della pipeline di lettura. Mostrano grafici, aggregano, filtrano. Quello che non sanno fare è il 20% restante: applicare queste tre famiglie di regole sottili. Per anni il 20% è stato gestito a mano da una persona che riapriva il file in Excel e correggeva i totali con formule note solo a lei, oppure è stato semplicemente ignorato — e qualche decisione importante è stata presa su numeri sbagliati di una percentuale sistematica. Una percentuale che, sull'anno, diventa una voce di bilancio.
Questo articolo è su come quel calcolo è cambiato, e perché chi guida un P&L oggi ha un'opzione che fino a poco tempo fa non aveva. La tesi: per la classe di problemi caratterizzata da regole di dominio sottili e pochissimi utenti finali, il costo di costruirsi internamente lo strumento che codifica quelle regole è crollato — abbastanza da rendere razionale, in molti casi specifici, smettere di adattarsi al tool generico e iniziare a costruire il proprio. Non come capriccio tecnologico: come decisione di allocazione. Il vero asset che si costruisce non è la dashboard. È la libreria delle regole di dominio codificate, scritta come funzioni testate, che diventa un pezzo di IP trasportabile e indipendente dal vendor.
Per reggere, questa tesi ha bisogno che il meccanismo regga. Vale la pena guardare cosa, concretamente, succede sotto.
La necessità, tradotta in tre garanzie operative
Mettiamoci nella posizione di chi gestisce il P&L del canale. Le necessità sono tre, e ognuna si traduce in una proprietà che il sistema deve possedere — non come obiettivo morbido, ma come vincolo enforced.
Fiducia nel numero. Il margine mensile comunicato al board deve essere giusto al centesimo, o almeno non sistematicamente sbagliato. Un errore casuale di qualche euro è folklore. Un errore sistematico che sgonfia o gonfia il margine di qualche punto percentuale ogni mese orienta decisioni di lungo periodo. Tradotto in vincolo: il calcolo delle voci di costo che possono comparire a doppio livello (commissione di carta di credito, commissione effettiva, costo dei promo code, differenze prezzo, contributi resi, dazi cross-border) deve essere scritto una sola volta, in una funzione pura, e deve esistere un test automatico che dichiara in linguaggio esplicito: se la stessa fee compare su livello ordine con valore X e su livello articolo con lo stesso valore X, il totale è X e non 2X. Quel test deve essere nell'elenco dei test non-negoziabili, eseguiti in CI prima di ogni rilascio. È una riga di codice. Vale, su molti business, decine di migliaia di euro di margine visto correttamente ogni anno.
Ripetibilità. Un report fatto a mano da una persona brava non è un
sistema, è un servizio. Se la persona se ne va, il report si rompe; se
si ammala, il board aspetta; se questo mese applica una formula
"migliorata" la serie storica diventa inconfrontabile. Tradotto in
vincolo: il processo deve essere idempotente per costruzione. Lo stesso
file ri-importato due, tre, cinque volte deve produrre zero righe
nuove. La realizzazione non richiede una staging table né un sistema
di diff: richiede un vincolo UNIQUE composito sulla tabella ordini —
nel caso tipico UNIQUE(order_id, sku, transaction_type, entry_type, transaction_date, posting_date, version) — combinato con un
INSERT OR IGNORE e l'intero file gestito come singola transazione
SQL. Su eccezione non gestita, ROLLBACK e il file resta nella drop
directory in attesa di retry. Su successo, commit e spostamento del
file in archivio con timestamp prefisso. La proprietà che ne esce —
"posso sempre rifare il processo, senza paura" — è il tipo di garanzia
che chi non l'ha mai avuta non capisce di volere. Chi l'ha persa una
volta sola, dopo un pomeriggio passato a ripulire un database
duplicato, la pretende per sempre.
Controllo del dato. I file di rendicontazione contengono PII
(nomi clienti, indirizzi, codici tracciamento, partite IVA), prezzi
confidenziali del proprio listino, margini per prodotto. Tradotto in
vincolo: i campi PII non vengono mai copiati negli artefatti che la
dashboard consuma. Restano confinati al database locale. La distinzione
non è una policy scritta in un PDF di compliance: è una funzione, in
fase di export, che elenca esplicitamente i campi da escludere
(Ship-to Name, Ship-to Address, Ship-to Phone, Ship-to ZIP,
Tax Registration Number, Tracking Code, AirWayBill No, Invoice No) e li filtra alla sorgente. PII minimization by default: ciò che
non serve, non esce. La differenza fra una policy e una funzione è la
stessa che passa fra una buona intenzione e una garanzia.
Queste tre necessità — fiducia, ripetibilità, controllo — non sono ovvie da soddisfare insieme. Le opzioni che il mercato ha offerto per anni le soddisfano in modo parziale, ognuna a modo suo.
Le tre opzioni di ieri, e cosa ognuna rinunciava
Comprare un BI cloud. Soddisfa la ripetibilità (il processo è il processo della piattaforma) e dà ottimi grafici out-of-the-box. Rinuncia sul punto uno: il vendor non conosce la regola sul doppio livello del tuo canale specifico, e per insegnargliela serve una configurazione custom — semantic layer, calculated fields, derived measures — che costa settimane di consulenza e che resta un asset del vendor, non tuo. Rinuncia anche sul punto tre: il dato deve uscire dall'azienda per essere utile, lo storico si deposita nella piattaforma di qualcun altro, e ogni cambio di fornitore tre anni dopo richiede una migrazione controllata da chi possiede il database di destinazione. Per chi paga una licenza ogni mese, il calcolo è "rinuncio al 20% di precisione per ottenere il 100% di una bella vista". Per molti business è razionale. Per molti altri, è quello che si fa in attesa di una soluzione vera.
Commissionare un software interno a una software house. In teoria soddisfa tutto. In pratica introduce due costi che spesso non vengono preventivati. Il primo è il costo della traduzione: chi conosce le regole del dominio non scrive il codice, chi scrive il codice non conosce le regole, e quello che esce dopo tre cicli di "non è esattamente questo, riprova" è un compromesso fra le due incomprensioni. Il secondo è la dipendenza permanente: il giorno in cui una modifica alla regola di calcolo della commissione effettiva servirebbe in mezza giornata, passa attraverso una richiesta di preventivo, uno sprint, una fattura. La proprietà fondamentale del software che si vuole è "modificabile dal dominio", e questa opzione in genere non la garantisce.
Excel. Sopravvive non perché sia buono, ma perché è sotto
controllo. Soddisfa il punto tre (il file vive sul disco) e ignora di
proposito gli altri due. Excel non offre un vincolo UNIQUE enforced:
copiare in basso una formula sbagliata di una cella può falsare un
trimestre senza che nessuno se ne accorga. Non offre un test che
diventi rosso quando qualcuno modifica una formula in modo scorretto.
Non offre la separazione fra fonte di verità (il dato grezzo
strutturato) e visualizzazione (la pivot che si guarda). Non offre
idempotenza: ri-aprire un file due volte è banale, ri-applicare una
trasformazione due volte sapendo che non duplica nulla è costoso, ed
Excel non aiuta. Soprattutto, non offre la pratica di scrivere la
regola in linguaggio esplicito prima di applicarla: la regola sul
doppio livello, in Excel, è una SUMIFS annidata che chi la legge tra
un anno non riesce a interpretare; in un sistema ingegnerizzato è una
clausola SQL CASE WHEN entry_type='Line' THEN ... ELSE 0 chiamata da
una funzione compute_monthly_kpis con un test associato che si chiama,
in linguaggio umano, test_cc_fee_no_double_count.
Per anni queste tre opzioni hanno coperto lo spazio. Chi gestiva P&L con regole proprie sapeva di vivere in un compromesso. Era così naturalizzato che non veniva più discusso.
La quarta opzione: perché regge tecnicamente, e quanto pesa
L'opzione che oggi esiste, e che fino a poco tempo fa non era
praticabile, è la quarta: il responsabile dell'unità di business si fa
costruire — con l'assistenza di un'AI matura — uno strumento suo, che
codifica le regole del proprio dominio in modo esplicito e testabile.
Single-user o team ristretto. Stack volutamente minimale: Python con
pandas per parsare il CSV, SQLite della stdlib come database (zero
dipendenze esterne, file su disco), HTML statico con Chart.js servito
da disco per la dashboard. Niente
Docker, niente container orchestration, niente CDN runtime, niente
abbonamento mensile a nessuno.
Questo stack regge tecnicamente per un motivo preciso: i volumi reali
del problema. Qualche migliaio di righe al mese di ordini, qualche
decina di migliaia di righe di listino. Su orizzonte cinque anni si
parla di poche centinaia di migliaia di righe ordini totali, che in
formato denormalizzato — un singolo data/orders.json con tutto
dentro — pesa qualche decina di megabyte. Il browser lo carica una
volta all'apertura della pagina e filtra in JavaScript in memoria. Il
re-render completo dei filtri su cinquantamila righe sta sotto il
mezzo secondo; le aggregazioni su scala anno stanno sotto i cento
millisecondi. È un'architettura che a un milione di righe sarebbe
sbagliata e che a centomila è imbattibile per costo totale, latenza
percepita, e debuggability — il dato si apre in qualsiasi editor di
testo e si legge.
Il trucco di compressione che lo rende leggero merita un secondo. Il
JSON di export non è un array di oggetti {order_id: "X", sku: "Y", ...} ripetuti per ogni riga. È un oggetto con due chiavi: schema
(l'elenco dei nomi delle colonne, una volta sola) e rows (un array
di array di valori). Riduzione di dimensione attorno al quaranta per
cento rispetto al formato object-per-row, e la dashboard legge lo
schema una sola volta all'avvio, costruisce un indice nome-colonna → posizione-array, e da lì in poi indicizza ogni riga con
row[IDX.brand_norm]. È una scelta da poche righe di codice che
sposta l'asintoto del problema di un fattore due — la differenza fra
caricamento istantaneo e caricamento percepibile.
Il sistema gira in batch one-shot, senza scheduler e senza daemon. Drop di un CSV in una directory di ingresso, esecuzione di uno script, spostamento del file processato in archivio con timestamp, apertura della dashboard nel browser. Bundle portatile scompattabile su una macchina Windows aziendale in una decina di minuti, servito dietro VPN. Niente Docker, niente cloud, niente abbonamento mensile a nessuno.
Le soluzioni concrete, viste come risposte a necessità
Vale la pena guardare, paragrafo per paragrafo, come ogni necessità del business si traduce in un vincolo tecnico — e cosa ne consegue per chi decide.
Non sommare due volte un costo che il file ripete a due livelli. La
regola sfumata: i costi item-level (commissione effettiva, fee carta
di credito, costo promo code, differenze prezzo, contributo resi
gratuiti, dazi cross-border) si sommano solo da entry_type='Line';
i costi order-level (sussidi spedizione, ordine spedizione,
contributi del partner sulle spedizioni, tassa servizi digitali origine
e destinazione) si sommano solo da entry_type='Header'; le voci
speciali (special payment, adjustment, no-stock voucher) seguono la
riga Line se esiste, altrimenti la Header. Implementato come CASE WHEN entry_type='Line' direttamente in SQL, non come filtro Python
post-fetch — così il vincolo vive nel motore di calcolo e non in un
livello di applicazione che potrebbe non essere chiamato. Test
associato: test_cc_fee_no_double_count, dichiarato esplicitamente
nella regression suite obbligatoria. E quindi: il margine comunicato
al board non sgonfia mai per double-count, e una modifica futura del
sistema che dovesse rompere questa proprietà fallisce in CI prima di
arrivare in produzione. La differenza fra il sistema con questo
vincolo e quello senza si misura in punti percentuali di marginalità
sbagliata ogni mese.
Ricostruire il brand quando il file non lo fornisce in chiaro. La
catena di fallback è esplicita e ordinata: (1) split di
description.split(" - ") con normalizzazione, (2) lookup su listino
per (brand_norm, sku_norm, stagione) con il brand ricavato dalla
chiave matchata, (3) override manuale curato in
brand_overrides.csv su designer_id, (4) fallback finale
brand='UNKNOWN' con WARN nel log. Ogni riga porta scritto, in un
campo brand_source, quale livello della catena l'ha risolta:
description, listino_lookup, override, unknown. Conseguenza:
la domanda di qualità del dato che chi gestisce il P&L dovrebbe porsi ogni
trimestre — quale percentuale dei miei ordini sta passando dal
fallback più debole? — diventa una query SQL di una riga. Senza la
traccia, la domanda non è nemmeno formulabile. Con la traccia, il
controllo costa trenta secondi e abilita una conversazione concreta con
il fornitore quando la percentuale di description cala sotto soglia.
Incrociare gli ordini con il listino interno per misurare il margine
vero. Match a due passaggi. Step 1 (preferito): identificativo
prodotto del fornitore (product_id) contro item_id del listino della
stessa stagione, esatto, ignora il rumore di brand e SKU normalizzato.
Step 2 (fallback): tuple (brand_norm, modello_variante_norm, stagione) con quattro tolleranze crescenti — strict (match esatto),
season_fb (stagione adiacente, es. AW25 trovato in SS25 se manca
AW25), relaxed (ignora stagione), relaxed_fb (combina i due), più
regole speciali per fornitori con SKU non standard. Ogni riga porta
scritto come è stata matchata in prezzo_match_source. Risultato: il
giorno in cui un margine sembra strano, la domanda "è un errore di
calcolo o un fallback troppo generoso?" ha una risposta in trenta
secondi via filtro sulla provenance, non in un pomeriggio di indagine.
E quando si aggiorna il listino della stagione in corso, un caching
incrementale via mtime ricarica solo il file modificato (non l'intero
listino di settantamila righe), e una funzione di backfill rivaluta
automaticamente gli ordini esistenti col nuovo prezzo. La proprietà
operativa che ne esce: l'aggiornamento del listino è un'azione di un
minuto, non una migrazione.
Gestire gli errori senza far cadere tutto. Tassonomia esplicita a
tre livelli, con effetti diversi su file e su DB. FATAL (header CSV
mismatch, file vuoto, encoding non utf-8-sig, eccezione non
recuperabile durante pd.read_csv): rollback dell'intera transazione,
file resta in fatture/ per il retry, log strutturato in
errori_import_YYYYMMDD.log. ROW_REJECT (decimale non parsabile,
date invalide, campi obbligatori NULL): la singola riga viene scartata
e tracciata in errori_righe.csv, il file procede. WARN (transaction
type sconosciuto, brand non risolvibile, stagione fuori archivio
prezzi): la riga viene importata con flag esplicito e tracciata nel
log di tipo (warn_*.csv), il file procede. E quindi: chi opera la
pipeline ha sempre un summary deterministico dopo ogni import (X righe
inserite, Y skip, Z warn), e gli errori vanno in tre code distinte
gestibili separatamente. Niente file in stato sospeso, niente database
in stato incoerente, niente "non so cosa è successo".
Gestire le correzioni del fornitore senza perdere lo storico. I
marketplace correggono periodicamente ordini emessi mesi prima, e li
re-inviano con lo stesso order_id e un campo version incrementato.
Il vincolo UNIQUE include version, e la funzione upsert_row fa
DELETE della versione precedente prima di INSERT della nuova solo
se la nuova è effettivamente maggiore. Re-import della v1 dopo che la
v2 è già stata ingerita è un no-op. Ne consegue: la serie storica resta
coerente nel tempo anche di fronte a correzioni asincrone del
fornitore, e chi guarda un margine retroattivo lo vede sempre come la
versione più recente, non come il primo invio. Questa è una proprietà
che si nota solo quando non c'è: di solito si manifesta come un
duplicato che gonfia i ricavi tre mesi dopo, e che nessuno sa più
spiegare. Un test integration nella regression suite
(test_versioning.py) garantisce che la sostituzione v1→v2 funzioni
identicamente a ogni rilascio.
Voci di costo aggregate che non arrivano dal file del fornitore. Ci
sono costi periodici (Performance Program, Main Incentive, Packaging
Incentive) che il file del canale non contiene e che vivono in un foglio
Excel separato curato a mano. Il sistema li carica in una tabella
monthly_extras con chiave (year, month, cost_type). Source-of-truth
è il file: assente in DB → INSERT, diverso → UPDATE (l'xlsx vince),
identico → no-op. Righe in DB non più presenti nel file restano, per non
perdere correzioni storiche. Convenzione segno: positivo = costo a
carico, negativo = credito. E quindi: le voci di costo "non
strutturate" che ogni azienda ha — quelle che in molti BI generici
finiscono in un campo libero o, peggio, fuori dal calcolo — entrano nel
waterfall del P&L in modo controllato, e una correzione del foglio
Excel si propaga al margine al prossimo import senza intervento
tecnico.
Visualizzazione e PDF. La dashboard è multi-pagina in Vanilla
JavaScript, senza framework né bundler. Ogni pagina espone lo stesso
contratto di controllo, e una pagina di export concatena tutte le
sezioni in un unico layout A4 sopra a un foglio di stile di stampa.
L'utente preme Ctrl+P, sceglie "Salva come PDF", e ottiene un report
mensile pronto per il board con header e page counter. Engine di
generazione: il browser stesso. Dipendenze server-side aggiuntive:
zero. E quindi: il PDF mensile non passa per nessuna pipeline server,
non richiede Playwright o Puppeteer, non ha alcun costo di
infrastruttura in più. Single-user tool servito da architettura
coerente con la propria scala.
Cosa ne consegue, per chi decide
Il movimento ricorrente in tutti i paragrafi sopra è lo stesso. Ogni necessità del business viene tradotta in un vincolo piccolo, locale, esplicito: un test di una riga, un constraint SQL composito, una funzione di filtro PII, una catena di fallback con provenance tracciata. Ogni vincolo si scrive una volta e protegge per sempre — non perché qualcuno si ricordi di rispettarlo, ma perché il sistema lo enforce. È esattamente la differenza tra una pratica e un sistema: la pratica dipende dalla disciplina di chi l'applica oggi, il sistema dipende dal vincolo scritto ieri.
Da questo movimento discendono quattro conseguenze che il C-Level fa bene a guardare in faccia.
La libreria delle regole codificate diventa un asset capitalizzabile. Il valore che si accumula nel tempo non è la dashboard, è l'elenco delle regole — la regola sul doppio livello, la catena di estrazione del brand, le tolleranze di match prezzo, le voci di costo a entrambi i livelli, il filtro PII alla sorgente, il versioning UPSERT. Ogni regola scritta è un pezzo del modello operativo dell'azienda in forma macchina-leggibile. A tre anni di distanza vale più del tool che la contiene, ed è facilmente trasportabile in qualsiasi tecnologia successiva — perché vive come funzioni pure con test associati, non come configurazione proprietaria di un vendor. Per un CFO o un COO è un asset trasferibile, non un costo operativo.
Il lock-in del fornitore scompare per questa classe di tool. Lo storico — tre, cinque anni di marginalità per brand, stagione, gender, geografia — vive in un file SQLite locale che si copia, si versiona, si archivia. Non si negozia con nessuno per riprenderselo. È una voce concreta di rischio operativo che esce dal registro. Chi ha già provato a estrarre lo storico da un BI cloud al momento del cambio fornitore sa quanto pesa quella voce.
Cambia chi può avviare un progetto interno. Fino a ieri, per ottenere uno strumento dedicato al proprio P&L bisognava aprire una RFP, ottenere budget, scegliere un fornitore, attendere quattro o sei mesi. Era un percorso lungo abbastanza da scoraggiare la maggior parte dei progetti che, in astratto, sarebbero stati utili — e che restavano non fatti. Oggi il responsabile dell'unità di business può prototipare lo strumento in 40-120 ore distribuite su due-tre mesi, scoprire se la cosa regge sui dati veri, e solo se serve portarla a un team di sviluppo per industrializzarla. Per chi guida un'organizzazione, è una buona notizia: la maggior parte degli strumenti interni che oggi non vengono mai costruiti — e di cui si vive la mancanza in silenzio — diventano economici da provare.
Asimmetria di scommessa. Una settimana di prototipo con eventuale abbandono costa poco. Anni di abbonamento a un SaaS che non risponde alle proprie regole costano molto — in licenza, in tempo perso a far quadrare numeri, in decisioni sbagliate prese su dati "abbastanza giusti". Quando il rapporto fra cosa si rischia e cosa si può guadagnare è così sbilanciato, il default razionale cambia.
Cosa NON cambia, e quali obiezioni reggono
Onestà intellettuale: questa opzione non sostituisce tutto. Per i sistemi che servono molti utenti contemporaneamente, che integrano molti fornitori esterni, che hanno requisiti di sicurezza enterprise, che devono scalare a milioni di record, il software professionale fatto da team professionali resta indispensabile. Il punto non è "chiunque costruisce qualunque cosa". È che esiste oggi un sotto-insieme di problemi — quelli da uno o pochi utenti, con regole specifiche al business — che è uscito dal perimetro della consulenza necessaria ed è entrato nel perimetro della produzione domestica ragionevole.
E va detto chiaro: l'AI da sola non basta. Senza disciplina ingegneristica
del committente — la pratica di scrivere la regola prima del codice,
testarla in isolamento, lockare le decisioni architetturali con il loro
perché, mantenere un registro del debito tecnico aperto — quello che esce
è un'accozzaglia di feature plausibili che si rompe al primo
cambiamento. Nel sistema descritto sopra la disciplina è esplicita: una
directory .planning/ con sedici requisiti tracciati con identificatori
stabili, trentacinque decisioni architetturali locked con rationale,
una regression suite di cinque test obbligatori (versioning UPSERT,
double-count CC fee, transaction type sconosciuto, idempotenza re-import,
FATAL header mismatch), un debt tracker con voci aperte e chiuse, un
reference architetturale di seicento righe che documenta schema SQLite,
pipeline import, regola Header/Line, fallback chain, match prezzi, KPI
engine, frontend, deploy. La disciplina non viene gratis dal modello.
Viene dal committente che la pretende.
Tre obiezioni meritano risposta seria.
Chi mantiene questo strumento se la persona che l'ha costruito non c'è più? Risposta onesta: il rischio non è zero, è gestibile a una condizione — che la documentazione faccia parte del consegnato fin dall'inizio. Reference architetturale, registro decisioni con rationale, debt tracker. Con questa base, uno sviluppatore terzo riprende il sistema in giorni, non in settimane. Senza, il rischio è alto. La differenza fra "ha senso" e "non ha senso" sta qui.
Excel con macro fa la stessa cosa. No, per i motivi visti sopra:
nessun vincolo UNIQUE enforced, nessun test che diventa rosso a una
formula sbagliata, nessuna separazione fra fonte di verità e
visualizzazione, nessuna pratica di scrivere la regola in linguaggio
esplicito prima di applicarla. La differenza non è cosmetica.
L'AI sbaglia, il codice ha bug. Vero. La mitigazione è la stessa che
si applicherebbe a qualunque scrittore di codice fallibile: TDD sulle
funzioni pure (cento per cento branch coverage realistico, perché sono
funzioni pure), regression suite non-negoziabile in CI, E2E manuale
contro un set di totali di riferimento calcolati a mano (per esempio
tests/e2e/test_full.py che confronta i KPI calcolati su quattromila
righe reali contro un manual_totals.json al centesimo). Non è una
garanzia di assenza di errori. È un arsenale di controllo standard
applicato al collaboratore che si ha. Funziona se si applica davvero,
fallisce se si scrive codice senza test e si spera.
Cosa cambia, da domani, per chi decide
Per chi guida un'unità di business con dati propri, sensibili, e regole di dominio che il SaaS generico non vede: il default della scelta "compriamo o costruiamo?" merita di essere riconsiderato per la categoria specifica di tool interni a basso numero di utenti. Non per tutto, non sempre. Ma una settimana di esperimento ha un costo abbastanza basso da pagarla per sapere su quale lato del calcolo si sta. Concretamente: prendere il file di rendicontazione del proprio canale più importante, identificare le tre regole sottili che oggi vengono applicate a mano (o ignorate), e tentare di codificarle in funzioni testate. Se in due settimane c'è una pipeline che gira con un test verde, il calcolo è fatto. Se non c'è, si è imparato qualcosa sul problema specifico, e il costo è stato comunque inferiore a un trimestre di abbonamento al BI sbagliato.
Per i fornitori SaaS verticali e generici: il margine si erode dove il cliente ha simultaneamente un'AI a disposizione e un domain expert disposto alla disciplina. Non si erode tutto, e non ovunque. Si erode esattamente nei casi in cui la differenza fra "abbastanza vicino" e "esatto" vale soldi visibili nel bilancio. La risposta sensata non è negare il fenomeno; è chiedersi quale parte del prodotto continua a valere — connettori certificati, conformità, supporto enterprise, scala, integrazioni complesse — e investire lì. Il prodotto del fornitore che resta competitivo è quello la cui proposizione di valore non è "ti mostro i tuoi numeri" (questo l'utente ora può farselo da solo) ma "ti garantisco l'integrazione, la conformità, lo SLA, e la gestione di scala che da solo non vorresti gestire".
E l'asset competitivo da costruire negli anni non è la dashboard. È la libreria delle regole codificate. Ogni regola che si scrive in codice è un pezzo di IP che si accumula: la regola sul doppio livello del file di rendicontazione, la catena di estrazione del brand, le tolleranze di match prezzo, le esclusioni PII alla sorgente. Quattro righe di codice e un test, ciascuna. Sommate diventano il modello operativo dell'azienda scritto in modo che una macchina lo possa applicare ogni mese senza dimenticare nulla. Tra cinque anni quella libreria varrà più del tool che la contiene. La dashboard è il modo in cui si guarda. La regola è ciò che si sa di proprio.
Il punto centrale, riassunto in una frase: il valore non è nel grafico, è nel vincolo che impedisce per sempre al grafico di mentire. Chi ha questa intuizione e la mette in pratica, oggi, costruisce un asset che qualche anno fa sarebbe stato impensabile costruire senza un team di sviluppo dedicato. È un cambiamento piccolo, locale, poco appariscente. È esattamente il tipo di cambiamento che, sommato nel tempo, sposta gli equilibri di interi mercati.