Ruolo & ambito
Progettata e costruita da zero, e da allora sviluppata di continuo: una piattaforma PIM multi-tenant con isolamento dei tenant (super admin, admin del tenant, utente), un flusso bozza/pubblicazione perché ogni modifica venga rivista prima di andare live, e logging di audit completo con snapshot prima/dopo.
- Sincronizzazione Shopify-first, affiancata dall'integrazione con l'ERP NetSuite e dall'export verso Amazon e altri marketplace tramite ChannelEngine.
- Arricchimento AI di titoli, descrizioni, testi SEO e traduzioni — con uno step di revisione prima che i contenuti generati vengano pubblicati.
- Un assistente RAG integrato che permette al team di prodotto di cercare e lavorare nel catalogo via chat: ricerca vettoriale sui dati di prodotto, con chiamate a tool per le azioni che l'utente deve prima approvare.
- Un'estensione Chrome separata con cui il team può mandare i prodotti dalle pagine dei marketplace direttamente nella coda di arricchimento.
- Un modulo di conformità al GPSR europeo, un modulo SEO con validazione del volume delle keyword e attività in background (sync vettoriale, arricchimento, scheduler) tramite una coda con retry.
Impatto
- Oltre 3.400 prodotti attivi sul mercato principale, con flussi di export verso centinaia di listing aggiuntivi su marketplace come Amazon.
- Una pipeline di traduzione AI che sovrascriveva in silenzio gli URL di categoria è stata annullata e sostituita con una versione che crea redirect e registra tutto in un audit trail.
- Un bug di sincronizzazione per cui ogni collegamento a NetSuite sovrascriveva i contenuti AI e le modifiche fatte su Shopify è stato risolto strutturalmente, invece di essere riparato a mano ogni volta.
- Oltre 350 commit in otto mesi di sviluppo continuo — non una consegna una tantum ma un sistema che cresce con l'assortimento.
Architettura
Un monorepo Turborepo con backend NestJS e frontend Next.js 14 (App Router), un pacchetto database Prisma condiviso e tipi comuni. PostgreSQL con l'estensione pgvector conserva sia i dati di prodotto sia gli embedding, così ricerca vettoriale e query normali girano sullo stesso database. Il lavoro in background (sync vettoriale, arricchimento AI, sync marketplace) passa da code su Redis con retry automatici e backoff esponenziale, disaccoppiate dall'interfaccia perché una sincronizzazione lenta di un marketplace non blocchi il resto della piattaforma.
Scelta del modello
L'assistente RAG integrato è volutamente multi-provider: attività diverse passano da modelli diversi (da un modello economico per la chat di routine a varianti più pesanti di Claude e GPT per i lavori di arricchimento più complessi), con i prezzi dei token tracciati per modello, così il costo per conversazione è visibile e non una scatola nera. I contenuti generati (titoli, descrizioni, traduzioni) passano sempre prima da uno step di revisione — il modello propone, una persona approva: lo stesso motivo per cui, in altri progetti, anche la logica di prezzo non passa mai direttamente da un modello linguistico.
Costi & latenza
- Il costo in token per conversazione è tracciato per modello, così i modelli più costosi vengono usati in modo consapevole e visibile, non per default.
- Le attività in background (sync vettoriale, arricchimento) girano in asincrono con massimo 3 retry e backoff esponenziale, così un disservizio temporaneo di un marketplace non porta subito a perdita di dati.
- Ricerca vettoriale e query di prodotto normali girano sulla stessa istanza PostgreSQL (pgvector), il che rende superflui un database vettoriale separato e il relativo strato di sincronizzazione.
Lezioni apprese
La pipeline di traduzione AI sovrascriveva gli URL di categoria senza avvisare non appena una traduzione veniva rigenerata — all'apparenza un bene per la SEO, ma rompeva i link esterni esistenti. Risolto ripristinando gli URL storici, aggiungendo redirect e costruendo un audit trail che d'ora in poi rende visibili queste modifiche prima che vadano live. Un secondo bug: ogni sincronizzazione con NetSuite sovrascriveva i contenuti generati dall'AI e le modifiche fatte su Shopify non appena un prodotto veniva collegato a NetSuite — non un incidente ma uno schema strutturale, risolto rivedendo la direzione della sincronizzazione invece di riparare a mano ogni volta. E un terzo, più piccolo ma indicativo: la pipeline traduceva male le abbreviazioni dei materiali come «RVS» (acciaio inox), risolto con una regola di glossario esplicita invece di confidare che il modello indovinasse la conoscenza di dominio.