L'editor come fonte di verità: normalizzare a valle, non a monte
Ingest massivo da PDF, IDML, schede tecniche e gestionale produce dati affidabili al 60%. Invece di pulirli alla fonte, ho scelto di normalizzarli a valle con un editor editoriale che diventa la fonte di verità canonica.
Il catalogo di prodotti dell'azienda per cui lavoro nasce da fonti eterogenee: PDF di manuali cartacei, file InDesign (IDML) con testi e disegni, schede tecniche per singolo prodotto, anagrafica del gestionale, export dell'ecommerce. Ogni fonte ha il suo formato, il suo lessico, i suoi errori.
L'approccio ingenuo sarebbe: pulisco alla fonte. In pratica non funziona. Alcune fonti non sono editabili (il PDF del manuale è un file pubblicato, non una base dati). Altre sono di sistemi terzi che non gestisco. La manutenzione alla fonte costa più di quanto valga, e comunque non coprirebbe mai il 100%.
Ho scelto l'approccio opposto: l'ingest è rumoroso, la normalizzazione avviene a valle. Ho costruito un editor editoriale in PHP + SQLite che prende i dati dai vari ingest e diventa la fonte di verità canonica per la generazione degli output — schede tecniche PDF, chatbot AI di supporto tecnico, export verso altri sistemi.
Il modello dati ha un punto non ovvio: la struttura per-sezione. Una pagina di manuale cartaceo contiene spesso più famiglie distinte (es. sulla stessa pagina: gambo a vite, gambo sagomato, cardine su lama, estrattore per manutenzione). Ciascuna ha misure, disegni tecnici, descrizioni applicative diverse. Nel modello iniziale avevo una sola tabella legata alla pagina — ma collassava tutto su un unico livello, e l'editor finiva per mostrare colonne misura inutili per metà dei prodotti.
Il refactor ha aggiunto una tabella sezione_gruppo tra pagina e codice prodotto. Ora ogni sezione ha le sue colonne misura, la sua descrizione, il suo flag di validazione editoriale indipendente. Prima di mettere in produzione ho scritto un audit strutturale — una ventina di query che verificano invariants: zero incoerenze di foreign key, zero colonne con scope ambiguo (globali + per-sezione nello stesso gruppo), zero prodotti senza sezione, nessun duplicato.
L'audit è passato pulito su tutto il DB (circa 3900 SKU, 164 pagine di manuale, quasi 500 sezioni). Il che significa due cose: (1) il refactor non ha introdotto regressioni, (2) il modello regge per tutti i casi reali, non solo per quelli che avevo in mente quando l'ho disegnato.
Il pattern che sto consolidando: gli ingest non devono essere puliti, devono essere completi. La pulizia è un lavoro editoriale umano che avviene dopo, su un modello dati disegnato per supportarlo. La fonte di verità non è mai l'ingest — è il risultato del lavoro editoriale sull'ingest.