FiberSystems installa fibra ottica in sub-appalto per i grandi committenti nazionali — Sirti, Sielte, Site, OpenFiber, FiberCoop. Quando ci hanno chiamati, gli interventi giornalieri arrivavano via Excel in formati diversi a seconda del committente, le foto di collaudo finivano sparse in chat WhatsApp, le ONT si perdevano tra un cantiere e l'altro, i report di fine mese si compilavano a mano la domenica sera. Il problema non era la voglia di lavorare. Era che il sistema operativo dell'azienda erano un foglio di calcolo e la memoria del responsabile.
Connexon è la piattaforma che è uscita da quel cantiere. È ancora in produzione, oggi è venduta come prodotto white-label ad altre aziende del settore. In questo articolo raccontiamo le decisioni di architettura che hanno tenuto, quelle che abbiamo dovuto rifare, e i numeri concreti che possiamo condividere.
Il problema, scritto bene
Prima di scrivere una riga di codice abbiamo passato due settimane in ufficio con FiberSystems. Mappata la giornata tipo, ne è uscita una lista di attriti specifici — quelli che fanno la differenza tra un software che si usa e uno che resta in installazione.
- Lo stesso intervento veniva ribattuto in Excel due o tre volte da uffici diversi (programmazione, magazzino, amministrazione).
- Il magazziniere segnava su un quaderno chi aveva preso quale ONT. Quando un tecnico cambiava commessa, le ONT diventavano fantasmi.
- I report al committente erano fogli Excel pivotati a mano: 6-8 ore di lavoro per chiudere il mese di Sirti, altrettante per Sielte.
- I tecnici sul campo avevano due telefonate aperte: ufficio per i dettagli, cliente per il PIN. La giornata si frammentava.
- Le foto di collaudo si caricavano la sera su Google Drive. A volte. A volte la richiesta del committente arrivava settimane dopo, e la foto giusta non si trovava più.
Decisione 1: una sola codebase, due app
Avremmo potuto fare un'app web per l'ufficio e un'app nativa Android+iOS per i tecnici. Non l'abbiamo fatto. Abbiamo scelto Angular 21 per entrambi i progetti, con la stessa libreria di servizi e modelli condivisi, due bundle distinti per due esperienze diverse: l'admin densa di tabelle e filtri (desktop/tablet), l'app installatori ottimizzata per pollice e schermo da 5 pollici.
L'app installatori è una PWA. Si installa dal browser senza passare da Play Store o App Store. È una scelta che paga ogni settimana: zero review, aggiornamenti immediati, niente certificati di firma da rinnovare. Quando esce un fix, il tecnico lo ha al prossimo refresh.
Decisione 2: Supabase come backbone, RPC come contratto
Backend: Supabase. Postgres puro sotto, autenticazione, storage per le foto, Row Level Security come perimetro multi-committente. È stata una decisione contestata internamente — la tentazione di scrivere un'API Node tradizionale è sempre forte. Abbiamo tenuto duro per un motivo: la logica critica vive nel database.
Oggi Connexon ha più di 70 funzioni RPC Postgres. Ogni operazione complessa — filtraggio interventi con 25+ parametri, movimenti di magazzino con conferma, export Excel, calcolo statistiche delivery/assurance/DAC — è una funzione SQL/PLPGSQL chiamata via RPC. Il client (sia admin che PWA) non sa nulla della complessità: chiama `get_interventi_new(...)` e riceve la pagina di risultati.
I vantaggi che misuriamo a 18 mesi di produzione:
- Una sola fonte di verità per la business logic. Sia l'app admin che la PWA tecnici chiamano la stessa RPC. Niente comportamenti divergenti.
- Performance. Il filtro su 25+ criteri sta sotto i 200ms anche su tabelle da centinaia di migliaia di righe, perché l'ottimizzatore Postgres lavora con indici e query plan, non con ORM e N+1.
- Migrazioni versionate. Ogni RPC è un file SQL versionato in `supabase/migrations/`. Rollback in un comando, audit della history come per qualsiasi altro codice.
Decisione 3: magazzino a 3 livelli, due tipologie di articolo
Il magazzino è la parte che abbiamo rifatto due volte. La prima versione era piatta: un articolo, una giacenza centrale, un movimento di scarico verso il tecnico. Non funzionava. Le ONT non si scaricano alla cieca: vanno tracciate per matricola dal momento in cui entrano in azienda fino a quando finiscono installate a casa del cliente.
La seconda versione — quella in produzione — distingue due tipi di articolo:
- MC (Materiale a Conteggio). Cavi, connettori, fascette, morsetti. Si gestiscono per quantità. Un movimento sposta «12 metri di cavo» dal magazzino centrale al tecnico Marco.
- MM (Materiale con Matricola). ONT, router, switch, media converter. Ogni pezzo ha un seriale univoco. Un movimento sposta «ONT seriale ABCD123» da Marco al cantiere Sirti-12345.
Il flusso è a 3 livelli — centrale → tecnico → intervento — con conferme ai trasferimenti. Quando il magazziniere invia 5 ONT a un tecnico, parte un movimento «pendente». Il tecnico lo conferma dalla PWA al ricevimento, e solo allora le ONT compaiono nel suo magazzino personale. Questo elimina la classica disputa «io non l'ho ricevuta» — c'è un audit trail con timestamp.
Decisione 4: l'import Excel come feature di prima classe
I committenti mandano interventi in Excel. Non lo cambieremo. Era inutile pretendere un EDI dai loro sistemi: i loro sistemi sono quello che sono e non li riscriveremo noi. La scelta è stata accettare il vincolo e farlo bene.
Connexon ha un import massivo che riconosce automaticamente il committente dal layout del foglio (intestazioni colonne, posizione dei campi chiave), geocodifica gli indirizzi via Google Maps API, fa dedup contro gli interventi già esistenti per evitare doppi caricamenti. Un foglio con 300 interventi viene digerito in pochi secondi e finisce nella coda di assegnazione.
Quando un committente cambia formato — capita ogni 6-12 mesi — aggiorniamo il template di parsing, non l'intera applicazione.
Cosa abbiamo sbagliato (la sezione che gli articoli AI non scrivono)
Tre errori che pagheremmo a non raccontare.
- Prima versione del filtro interventi: client-side. Caricavamo tutti gli interventi in pagina e filtravamo in JavaScript. Funzionava finché il database aveva 2.000 righe. A 50.000 il browser piangeva. Abbiamo rifatto tutto come query Postgres parametrizzata via RPC. Lezione: ogni filtro che potrebbe scalare deve scalare dal giorno uno.
- Foto caricate sincrono. La prima versione della PWA caricava ogni foto durante la chiusura intervento, in sequenza. Su 4G zoppicante il tecnico aspettava 40 secondi per chiudere un intervento. Le foto sono diventate upload in background con coda persistente locale: l'intervento si chiude subito, le foto salgono quando la rete lo permette.
- Niente staging serio per i primi tre mesi. Le RPC andavano direttamente in produzione dopo test locali. Una migration con un join sbagliato ci è costata mezza giornata di disservizio. Oggi abbiamo un progetto Supabase di staging con dati anonimizzati e un workflow di migration in due step.
I numeri che possiamo condividere
- 2 app integrate sullo stesso backend (admin desktop/tablet + PWA installatori).
- 70+ funzioni RPC Postgres come API contract.
- 25+ filtri sulla schermata interventi.
- 3 livelli di magazzino (centrale, tecnico, intervento) con due tipologie di articolo.
- 0 server da gestire: Supabase + Vercel/CDN, hosting EU GDPR-compliant.
- Tempi di chiusura mese ai committenti: da una giornata di lavoro a meno di un'ora.
Cosa stiamo migliorando ora
Connexon non è finito. I prossimi cantieri di sviluppo: una vista mappa nativa per la programmazione giornaliera (i dispatcher vogliono vedere i tecnici come spilli su una città), un modulo di integrazione webhook verso i portali dei committenti per evitare anche il passo Excel quando il committente lo permette, e un assistente LLM che pre-classifica le foto di collaudo per rilevare automaticamente quelle non conformi prima dell'invio al committente.
La lezione che ci portiamo via
Il software gestionale di un'azienda di campo non si progetta in ufficio. Si progetta camminando con il magazziniere, salendo sul furgone con un tecnico, leggendo gli Excel veri che il committente ha mandato il martedì alle 18:42. Connexon funziona perché è scritto sopra il modo in cui FiberSystems lavora davvero. Ed è la stessa ragione per cui può funzionare in altre aziende del settore: il dominio è lo stesso, le abitudini sono simili, il prodotto si configura. Ma il punto di partenza non è mai «quale tecnologia». È sempre «come lavora il magazziniere alle 7:30 del mattino».