Atto II: L'anticamera
La decisione che ti costa settimane invece di un pomeriggio
Un team ha modellato il colore come variante.
Scelta ragionevole. Difendibile. L’admin aveva un aspetto pulito. Tre colori di bottiglia di olio d’oliva—trasparente, verde, satinata—ciascuno come variante dello stesso prodotto, con un unico schema di SKU e un’unica PDP. Il team di merchandising l’aveva approvata alla terza settimana. Gli ingegneri avevano annuito. Tutti erano andati avanti.
Due mesi dopo, l’app di wishlist è andata live. Si agganciava al prodotto, non alla variante. (La maggior parte delle app di wishlist si aggancia al prodotto. Le pagine dei vendor non sempre lo dicono. Le pagine dei vendor dicono “salva i tuoi preferiti”. Non dicono “salva i tuoi preferiti, a meno di una sottigliezza di teoria delle categorie che stai per scoprire alla tua decima settimana”.) Quello che finiva nelle wishlist dei clienti era il prodotto, senza nessun colore associato. L’intero strato di merchandising che era stato costruito sopra il colore-come-variante—il widget dei bestseller, la PDP personalizzata “hai messo questo nella wishlist”, l’email di wishlist abbandonata che usava come immagine principale la bottiglia sbagliata—ha smesso silenziosamente di significare quello che il team pensava significasse.
La soluzione non era uno script di migrazione. La soluzione era una reimportazione completa del catalogo. Ogni prodotto del catalogo andava ristrutturato, il colore a livello di variante riagganciato come distinzione a livello di prodotto, gli SKU rinumerati, gli URL riconciliati. Lo sviluppo frontend che si era accumulato sopra il vecchio modello era stato, per due mesi, lo sviluppo frontend sbagliato. Fare il rollback dello schema non faceva il rollback di una decisione. Faceva il rollback di una stagione.

Il team non era stato sbadato. La scelta che aveva fatto—colore come variante—era la scelta che un merchandiser attento avrebbe fatto sulla maggior parte delle piattaforme. Era la scelta che l’admin della piattaforma li incoraggiava attivamente a fare. Il problema era che uno strumento a valle, l’app di wishlist, si agganciava al livello sbagliato della gerarchia del catalogo, e non esisteva su Shopify nessun meccanismo con cui scoprire questo fatto prima che l’app di wishlist andasse live e un cliente la usasse.
Su una piattaforma custom, una cattiva decisione sullo schema ti costa un pomeriggio. Su Shopify, ti costa settimane.
Un replatform Shopify è un progetto che premia l’iterazione quasi ovunque. Sbaglierai il formato di export al primo tentativo e lo affinerai. Sbaglierai la logica di delta sync e la affinerai. Scoprirai delle regole di validazione a metà strada e le aggiungerai al volo. Cambierai il tuo strumento di import una volta, forse due. Definirai lo scope delle feature a ondate. Quasi tutto questo va bene. Quasi tutto questo è il progetto che funziona come previsto.
C’è esattamente una fase che non funziona così.
Il data modeling—nello specifico, le tre decisioni che stiamo per percorrere—va bloccato prima che venga scritta una riga di codice, perché il costo di cambiarle dopo che il codice è stato scritto non è uno sprint, è una stagione. I team che trattano lo schema come l’ennesimo ciclo di iterazione finiscono per pagare l’assunzione. L’assunzione è che il data model di Shopify si comporti come il data model della piattaforma che stanno lasciando. Non è così. Il problema è strutturale, e vale la pena rallentare.
Shopify non espone un database grezzo. Non puoi fare il drop di una tabella, sistemare lo schema e reimportare. Non puoi troncare una definizione di metafield e rilanciare il seed. Metafield e metaobject si accumulano; farne il rollback significa aggiornare ogni record che li referenzia, un record alla volta, contro un’API. Le definizioni delle collection, una volta che i prodotti vi sono organizzati contro, sono dolorose da ristrutturare—non impossibili, ma dolorose nel modo specifico per cui un senior engineer ci spende una settimana e alla fine nessuno è contento.
Lo store Plus in cui stai sviluppando è, in nove progetti su dieci, lo stesso store Plus che è stato attivato quando è stato firmato il contratto. Non puoi azzerarlo. Non puoi resettarlo. Non c’è nessun flag --force. Puoi chiedere aiuto al supporto Shopify, e ti aiuteranno, e la conversazione non è piacevole. (Chiedici come lo sappiamo.)
Una cattiva decisione di modeling non resta locale. Si propaga. Sistema il modello delle varianti all’ottava settimana e avrai rotto anche la logica delle collection e le mappature dei metafield e la pipeline di import. Sistema lo schema dei metafield alla decima settimana e i frontend dev si ritrovano a fissare una query che restituisce null per metà dei campi da cui dipende il design. Sistema la logica delle collection alla dodicesima settimana e il team di merchandising sta ricostruendo a mano tre mesi di curation. Lo schema è portante in un modo in cui il resto del progetto non lo è. Trattalo di conseguenza.
La prima delle tre decisioni è il modello prodotto-contro-variante.
Il volume non è più il vincolo che era una volta. Shopify ora supporta 2.048 varianti per prodotto, che suona come un numero progettato da un comitato ma che è, per quasi qualunque catalogo, più che sufficiente. Il vincolo che conta non è quante varianti puoi avere. Il vincolo che conta è cosa si ancora al prodotto e cosa si ancora alla variante.
Tre tipi di opzione per prodotto. Quello è il tetto strutturale, e non si è mosso. Colore, taglia, e una cosa in più. Se la tua piattaforma attuale modella colore, taglia, tessuto e finitura, stai per avere una conversazione con il team di merchandising che non gradirà. Scegline tre.
Le regole di sconto si agganciano a livello di prodotto. Le esclusioni fiscali, idem. La maggior parte delle app di terze parti, idem—l’app di wishlist, l’app di bundling, lo strato di personalizzazione, il motore di loyalty. Salvano il prodotto, non la variante selezionata. Se hai modellato i colori come varianti e un cliente mette un prodotto nella wishlist, quello che hai catturato è un cliente a cui piace il prodotto. Non sai quale colore. Hai un’intenzione ambigua e nessun modo per agirci sopra. L’email personalizzata parte con l’immagine principale della variante di default. La variante di default è quella che il team di merchandising ha scelto perché si ordinava in ordine alfabetico. Hai, per sbaglio, fatto marketing di olio d’oliva trasparente a un cliente che aveva esplicitamente scelto il verde.
I temi limitano la visualizzazione delle varianti a 250. Oltre quella soglia, stai scrivendo logica custom dello storefront per renderizzare il picker—il che va bene, tranne che è un workstream che nessuno aveva messo nello scope, perché il volume non dovrebbe essere il vincolo.
La decisione non è tecnica. È editoriale. Quale asse di differenziazione dovrebbe la piattaforma trattare come lo stesso prodotto, e quale dovrebbe trattare come separato? Il merchandising ha una visione. Il design ha una visione. L’engineering ha il foglio dei vincoli. Abbiamo visto questa conversazione andare male quando uno di questi tre manca dalla stanza, e l’abbiamo vista andare molto male quando la conversazione avviene per email. Mettili nella stanza. Non saltarla.
La seconda è lo schema dei metafield e dei metaobject.
Metafield e metaobject sono la forma di ogni attributo custom del tuo store. Paese d’origine su un prodotto. Note di abbinamento su un vino. Composizione del gift set su un bundle. Tier di loyalty su un cliente. Tutto ciò che Shopify non modella nativamente è modellato qui. Ogni record che importerai sarà strutturato contro questo schema. Lo schema, quindi, deve esistere in Shopify prima che parta il primo import.
Non è così che i team lo costruiscono.
Il modo in cui i team lo costruiscono è incrementale. Un ingegnere aggiunge un metafield perché un componente ne ha bisogno. Un designer chiede un blocco strutturato Note di abbinamento, e compare un metaobject a supportarlo. Arriva una nuova feature, e compaiono altri tre campi. Al terzo mese, lo schema è un mosaico. Lo schema non è mai stato progettato—si è sedimentato. Lo schema si sedimenta perché non c’è stata nessuna settimana in cui qualcuno sia stato incaricato di progettarlo. Aggiungere un metafield è un’azione da cinque minuti nell’admin; progettare uno schema è un workshop. L’impostazione di default è l’azione da cinque minuti.
Poi arriva la logica di filtro. Lo storefront deve filtrare i prodotti per una combinazione di attributi—colore e fascia di prezzo e paese d’origine e “attualmente in promozione”—e lo schema non è stato progettato pensando al comportamento dei filtri. I vincoli, si scopre, vanno nella direzione opposta. Quello che il motore di filtri di Shopify supporta dovrebbe dare forma a come modelli i dati. Non il contrario. Il team di prodotto non lo sapeva alla terza settimana. Il team di engineering l’ha imparato alla decima settimana, quando il filtro non ne voleva sapere.
(C’è uno strumento. Si chiama shopify_toolkit. L’abbiamo scritto noi. Mappa e valida lo schema prima che qualcosa si muova. Usalo. Oppure no, ma usa qualcosa—non lanciare il primo import contro uno schema che non hai verificato formalmente. Abbiamo visto la versione di questa storia in cui qualcuno improvvisa e gli costa un trimestre. Erano bravi ingegneri. Non erano, in quel trimestre, fortunati.)
La terza è la logica delle collection.
È quella che frega più team, perché le smart collection di Shopify sembrano la risposta e non lo sono.
La struttura è piatta. Non c’è gerarchia padre-figlio sulle collection di Shopify. Se la tua piattaforma in uscita organizzava il catalogo ad albero—Dispensa > Oli > Oli d’oliva > Monorigine > Toscano—quell’albero non migra. Non te lo porti dietro. Stai costruendo un equivalente dall’altra parte, con gli strumenti che la nuova piattaforma offre davvero. L’equivalente avrà un aspetto diverso. Il team di merchandising dovrà farci pace. La conversazione in cui ci fa pace dovrebbe avvenire alla seconda settimana, non alla decima, perché se avviene alla decima, gli URL sono già sbagliati.
Le smart collection sembrano la risposta. La promessa è elegante: definisci una regola, e la collection si popola da sola. Il colore è verde E il prezzo supera i quindici dollari E il tag contiene “holiday”. In pratica, la logica delle condizioni è gravemente limitata. Niente AND/OR annidati. Niente NOT per la maggior parte delle condizioni. L’algebra booleana che usi per organizzare il tuo catalogo reale probabilmente non può essere replicata nel motore di regole delle smart collection. Provaci. Scoprilo al primo giorno invece che al cinquantesimo.
Due strade funzionano davvero.
La prima sono metafield costruiti su misura più una app custom per mantenerli. Progetti i metafield specificamente per soddisfare le regole che le smart collection riescono a gestire, e scrivi una app che tiene quei metafield sincronizzati man mano che i prodotti cambiano. Il trucco è che Shopify Flow non ha un trigger di aggiornamento prodotto—non puoi far partire la sincronizzazione da un’automazione no-code—quindi la app è vero lavoro di engineering. Ne vale la pena per il catalogo giusto. Non per ogni catalogo.
La seconda è lasciare che il PIM possieda interamente la logica. Il PIM tiene le regole. Il PIM esegue le regole. Il PIM spinge gli ID prodotto su Shopify come collection manuali, in ordine, secondo una pianificazione. Shopify diventa lo strato di rendering, non lo strato di logica. Questa è l’architettura più pulita per qualunque catalogo di complessità significativa, ed è quella che raccomandiamo il più delle volte.
Shopify diventa lo strato di rendering, non lo strato di logica. Tieni a mente questa frase. Tornerà, in questo libro, in diversi costumi differenti.
Greycott & Co. ha fatto questo esercizio alla seconda settimana. La stanza conteneva tre persone: Owen Caldwell, head of e-commerce; Priya Shah, director of operations; e Daniel Okafor, il lead engineer che la settimana prima aveva passato il tempo a costruire un foglio di calcolo che nessuno aveva chiesto ma che si è rivelato la cosa che ha ancorato la conversazione. (L’intero retroscena dei fogli di calcolo di Daniel è una forma ricorrente in questo libro. Lui continua a costruirli. La stanza continua a non chiederli. La stanza continua ad averne bisogno.)
Greycott ha nove tipi di prodotto. Olio d’oliva. Aceto. Mix di spezie. Gift set. Sali. Mieli. Salse. Bundle da dispensa. E una categoria ambigua che il team chiama di volta in volta “specialty” o “monthly” o “il programma a scatola”, a seconda di chi parla.
Tre di questi tipi di prodotto hanno il colore come variante—colore della bottiglia sugli oli, colore del barattolo sui mieli, colore del packaging sui sali. Due di essi assolutamente no—i mix di spezie e gli aceti hanno un colore solo ciascuno, e il team non ha mai pensato a loro come dotati di un asse colore. Uno di essi dipende da se chiedi a Priya o a Owen.
Quello in discussione sono i gift set.
Owen, che gestisce l’e-commerce, pensa a un gift set come a un singolo prodotto con varianti di packaging. Il “Holiday Pantry Trio” esiste in tre colori di confezione regalo—rosso, verde, kraft—e dovrebbero stare tutti su una PDP, con il cliente che sceglie il colore al checkout. Sta pensando a come appare al cliente, alla consolidazione delle recensioni, alla matematica del click-through su un posizionamento di rilievo. Una PDP, tre varianti. Questa è la visione e-commerce.
Priya, che gestisce le operations, pensa a quegli stessi tre colori di confezione regalo come a tre prodotti diversi. SKU diversi, pool di inventario diversi, packing slip diversi, soglie di riordino diverse, fotografia diversa nel catalogo wholesale. Il team wholesale li tratta come separati. Il 3PL li preleva come separati. La riconciliazione QuickBooks, per favore, li tratta come separati. Tre prodotti, nessuna variante. Questa è la visione operations.
Nessuna delle due visioni è sbagliata. Entrambe le visioni sono coerenti all’interno del proprio quadro. La scelta tra loro ha conseguenze che si propagano in direzioni opposte: scegli il modello di Owen e il workflow di prelievo wholesale ha bisogno di logica custom; scegli il modello di Priya e il merchandising dello storefront perde la PDP consolidata e guadagna tre pagine prodotto quasi identiche che il team SEO passerà il trimestre successivo a cercare di deduplicare.

Non ti diremo in che direzione è andata la conversazione, perché la risposta specifica è meno interessante del fatto che sia avvenuta alla seconda settimana. La stanza aveva Owen, Priya e Daniel. Daniel non ha detto quasi nulla per la prima ora e poi, verso la fine, ha detto qualcosa di utile su quale dei due modelli avrebbe fatto comportare bene l’app di wishlist. La decisione è stata presa. Daniel ha aggiornato il suo foglio di calcolo. L’import dei dati è stato strutturato contro la decisione. I frontend dev, tre settimane dopo, stavano sviluppando contro un modello su cui la stanza si era accordata.
Il requisito che erediti non è il requisito che hai. Il requisito che erediti è il modo in cui la vecchia piattaforma per caso modellava i gift set, che non è affatto un requisito; è un residuo. Il catalogo Magento di Greycott modellava i gift set come varianti, perché nel 2018 un contractor aveva deciso che era più facile così. Il contractor del 2018 non era nella stanza alla seconda settimana. Non avrebbe dovuto esserlo. La stanza della seconda settimana era una stanza di persone che dovevano convivere con la conseguenza. La stanza ha potuto ridecidere.
Il data modeling premia la disciplina waterfall esattamente in questa forma. La stanza esiste. La stanza produce una decisione. La decisione viene messa per iscritto. Lo sviluppo che segue è strutturato contro di essa. Nessuna iterazione. Nessuno sprint di discovery. Nessun “vediamo come va a finire”. Se la stanza non riesce a produrre una decisione, il progetto non passa alla fase successiva. (Se la stanza riesce a produrre una decisione ma Owen e Priya non ci sono, la stanza ha prodotto la decisione sbagliata. L’abbiamo fatto male abbastanza volte da esserne sicuri su questo punto.)
Quasi tutto ciò che resta in un replatform è amichevole con l’iterazione. Il tuo primo export dal sistema sorgente sarà sbagliato. Le colonne non si allineeranno con lo schema di Shopify. La codifica sarà sballata in un modo che non scopri finché una descrizione prodotto non viene renderizzata con una virgoletta tipografica trasformata in tre caratteri. Affinerai l’export. Lo affinerai di nuovo. Lo affinerai, vicino al lancio, per l’ultima volta. Va bene così. È a questo che serve l’iterazione dell’export.
La tua logica di delta sync—come i record creati sulla vecchia piattaforma durante la finestra di migrazione confluiscono in Shopify—si sviluppa man mano che capisci i dati. Le regole di validazione si sviluppano. La logica di trasformazione si sviluppa. Lo stesso strumento di import è una decisione che puoi rivedere. Matrixify è, per la maggior parte degli import una tantum in cui controlli il formato di export e non hai bisogno del supporto multilingua, la scelta giusta: una UI utilizzabile, nessuna infrastruttura aggiuntiva, abbastanza buono. Per sincronizzazioni ricorrenti, trasformazioni complesse, o store con diversi market, la Bulk Operations API ti dà un controllo sul sequencing che Matrixify non ha—sai esattamente quando ogni operazione si completa prima di accodare la successiva, e puoi costruire logica condizionale nella pipeline. Matrixify vuole anche permessi ampi sullo store, il che è un no secco per alcuni client enterprise attenti alla sicurezza. Abbiamo cambiato strumento a progetto in corso. È andata bene.
Il ritmo che funziona: lanci il primo import all’inizio del progetto per far emergere le sorprese. Iteri su export e import man mano che il progetto si sviluppa. Lanci una reimportazione pulita prima del lancio. Quel loop gestisce parecchio—finché il data model che gli sta sotto è stabile.
Il data model è la cosa che il loop non può sistemare.
Prima che parta il primo import—prima che un qualunque frontend dev dipenda da uno schema, prima che venga configurato un qualunque widget di merchandising, prima che lo steering committee chieda una demo—ogni team dovrebbe essere in grado di rispondere a quattro domande.
Il modello prodotto-contro-variante è concordato, per iscritto, e verificato contro le feature native della piattaforma—sconti, tasse, wishlist, tetti di rendering dei temi?
I metafield e i metaobject sono definiti in Shopify, non solo documentati in un foglio di calcolo che qualcuno continua a ripromettersi di sistemare?
La strategia delle collection è decisa—smart collection, app custom guidata dai metafield, o collection manuali guidate dal PIM—con un riconoscimento esplicito di quale logica Shopify possiederà e quale no?
Lo strumento di import è deciso—Matrixify per il caso una tantum, Bulk Operations API per qualunque cosa più duratura?
I team che riescono a rispondere a tutte e quattro prima della prima riga di codice hanno fatto il lavoro difficile. I team che rimandano una di queste risposte la ritroveranno—nel momento peggiore possibile. Il momento peggiore possibile è la decima settimana, quando l’app di wishlist va live, e la PDP di punta del team di merchandising mostra il colore sbagliato. (Il momento peggiore possibile è la dodicesima settimana, quando il motore degli sconti scatta al livello sbagliato. Il momento peggiore possibile è la sedicesima settimana, quando il comportamento del filtro non corrisponde allo schema. Il momento peggiore possibile è il momento in cui scopri la cosa, che è sempre troppo tardi per sistemarla a buon mercato.)
La conversazione la fai presto o la fai tardi. Stessa conversazione. Costo diverso. La conversazione precoce ti costa una settimana di workshop e un avvio leggermente ritardato. La conversazione tardiva ti costa una stagione.

Non waterfall ovunque. Waterfall qui. Il data modeling è la parte di una migrazione Shopify che si guadagna la sua disciplina di pianificazione punendo il progetto che non ha pianificato.
Qui giace l’app di wishlist.
Ha catturato ogni prodotto. Solo nessuno dei colori.