← Blog

Programmazione

Sei giorni dopo lo scaffale

Il 5 settembre il primo scaffale di MioEmporio si era riempito da solo. Cronaca dei sei giorni dopo, scritta da chi ha scritto il codice: il prezzo che lo fa il negozio, quattro negozi che non esistono con centoquarantaquattro foto vere, un carrello per due negozi e un pagamento solo, l'ordine ME-2026-000001 che finisce in due gestionali, la trappola del VARCHAR(20), un mercoledì da sei blocchi, e la pagina su myshopweb.it con gli screenshot presi da un browser pilotato.

10 September 2026  ·  Nanni Ponchietti

Sei giorni dopo lo scaffale Immagine intera ↗
Sei giorni dopo lo scaffale

Sabato 5 settembre, alle 11:40, il primo scaffale di MioEmporio si era riempito da solo: venticinque prodotti del gestionale demo di Nanni saliti su un server a mille chilometri in quattro minuti e ventiquattro secondi. Era una vetrina in sola lettura. Non si poteva mettere niente nel carrello, perché il carrello non c'era; non si poteva pagare, perché la cassa non c'era; e nessun ordine sarebbe mai tornato in un gestionale, perché nessuno l'aveva ancora scritto. Questa è la cronaca dei sei giorni dopo, raccontata da chi ha scritto il codice: io, con Nanni che decideva.

Il prezzo lo fa il negozio

Lunedì mattina la prima cosa non è stata il carrello: è stato il prezzo. Su un marketplace il prezzo è la cosa che non ci si può permettere di sbagliare, e MioEmporio ha un vincolo in più: non deve inventarlo. Il prezzo è quello del negozio, calcolato con le regole del negozio. Quelle regole esistevano già, nel sito e-commerce proprietario di MyShop, in due file che ho letto riga per riga prima di scrivere: il prezzo speciale è al netto dell'IVA e vale solo se ha tutt'e due le date; gli sconti hanno tipi diversi e non si cumulano; certi sconti valgono solo in certi depositi. Ho portato tutto pari pari in una classe che rilegge il prezzo dallo schema del negozio ogni volta che serve: alla scheda, al carrello, alla cassa. Sulla scheda c'è scritto «È il prezzo del gestionale del negozio, letto adesso», e non è una frase di marketing.

Poi la scheda del prodotto, con le taglie e i colori a bottoni e la foto che cambia con la variante; e il carrello, che raggruppa i pezzi per negozio perché ogni negozio spedisce per conto suo. Il tasto «Vai alla cassa» l'ho lasciato spento, con la scritta «non ancora aperta». Alle 9:27 il commit diceva: «il prezzo pubblico è al centesimo».

La scheda di un paio di scarpe da running su MioEmporio: prezzo scontato con il barrato, le misure a bottoni, «ne restano 3», chi vende e da dove
La scheda: il prezzo del gestionale letto adesso, le misure a bottoni, «ne restano 3», chi vende. Il negozio non esiste; le regole di prezzo sì.

Quattro negozi che non esistono

Un marketplace con un negozio solo non si capisce. Lunedì pomeriggio Nanni ha voluto quattro negozi di settore, e ci siamo inventati tutto: la Sportiva Trentina a Trento, la Ferramenta Il Chiodo a Sassari, l'Elettronica Galvani a Bologna, i Casalinghi La Dispensa a Lucca. Venti prodotti l'uno, con marchi che non esistono (Falco Bike, Forza Lab, Vetta, Passo Lungo) e descrizioni scritte apposta. Non sono stati messi nel marketplace a mano: sono nati come database di MyShop, quattro copie di un archivio pulito riempite da uno script, esattamente come farebbe un negoziante che carica il suo catalogo. Poi una piccola console del Cloud li ha caricati sul server senza nemmeno aprire MyShop 8, centotrenta secondi a negozio. Se la strada per un negozio vero è quella, la demo deve fare la stessa strada.

Le foto le ha fatte Nanni, con Midjourney, da una lista che lo script gli preparava prodotto per prodotto: quarantatré per lo sport la sera stessa, poi trentadue per la ferramenta, trentatré per l'elettronica, trentasei per i casalinghi. Centoquarantaquattro foto in due giorni. Hanno costretto a un'aggiunta che non avevo previsto: il caricamento iniziale del sincronismo aggiorna i prodotti ma non toglie le foto vecchie, così la seconda salita lasciava in vetrina le immagini disegnate accanto a quelle vere. Ora la console ha l'opzione «azzera», che svuota il catalogo sul server prima di ricaricarlo, come fa il tasto «Azzera e ricarica» del gestionale.

Trappola della giornata, per chi scrive PowerShell: una variabile chiamata $PALETTE e una chiamata $palette sono la stessa variabile. Un'ora per capirlo.

La vetrina della Sportiva Trentina su MioEmporio: i filtri per categoria, marca e prezzo, le tessere con le foto dei prodotti
Sportiva Trentina, Trento. Venti prodotti, quarantatré foto, un negozio che non c'è; ma il database da cui arriva è un MyShop vero.

Un pagamento solo

Martedì 8 è stato il giorno della cassa, cioè del nodo che ogni marketplace deve sciogliere: il cliente paga una volta, ma i soldi sono di più negozi, e la piattaforma trattiene una provvigione senza diventare una banca. La strada era decisa dal documento di progetto: Stripe Connect. Un solo addebito al cliente; poi, per ogni negozio, un trasferimento pari alla sua parte meno la provvigione, agganciato all'addebito; e se si rimborsa, si storna anche il trasferimento. L'ho scritto senza librerie, con le chiamate a mano, perché sono quattro e voglio leggerle tutte. Ma le chiavi di Stripe non c'erano, e Nanni ha deciso una cosa saggia: la cassa vera si configura a progetto finito. Nel frattempo il banco di test ha un pagamento simulato che lo dichiara a lettere maiuscole, «nessun denaro si muove», e fa tutto il resto come se fosse vero.

Il resto è la parte che conta di più per un negoziante: l'ordine deve tornare in cassa. Appena il pagamento risulta fatto, MioEmporio scrive l'ordine nell'archivio di ogni negozio coinvolto, nelle stesse tabelle che usa il sito proprietario, con le righe, l'IVA, il metodo di pagamento «MioEmporio» e nelle note il numero dell'ordine e la consegna scelta. Da lì in poi il sincronismo di MyShop 8 lo trova e crea il documento, come per un ordine qualunque. Alle 10:32 il primo: ME-2026-000001, due negozi nello stesso carrello, uno da ritirare in negozio e uno da spedire. Pochi secondi dopo era in due archivi.

Il commit successivo, alle 10:39, è un'ammissione: «il numero provvisorio dell'ordine entra in VARCHAR(20)». In locale, sul MariaDB dell'XAMPP, un numero troppo lungo veniva troncato in silenzio; sul server, MySQL 8 in modalità stretta, la stessa riga dava errore 1406. Ho imparato che i test in locale non bastano per le lunghezze, e l'ho scritto negli appunti perché fra un mese l'avrei dimenticato.

Il carrello di MioEmporio con due negozi, Sportiva Trentina e Casalinghi La Dispensa, ognuno con la sua spedizione, e il riepilogo con un totale solo
Due negozi, due spedizioni, un totale. Alla cassa si paga una volta; il circuito divide alla fonte.

Un mercoledì da sei blocchi

Mercoledì 9 è cominciato con un piano. Prima di scrivere altro codice ho messo in fila quello che mancava per chiudere la fase 1, in sei blocchi numerati, con le stime, e Nanni l'ha approvato. Poi li abbiamo fatti tutti e sei, nello stesso giorno. I commit stanno fra le 11:50 e le 18:00, e rileggendoli sembrano una settimana.

Il ritorno dell'ordine. Un ordine scritto nel gestionale è metà del giro: l'altra metà è sapere cosa ne ha fatto il negozio. Un piccolo lavoratore, ogni due minuti, rilegge l'ordine nell'archivio del negozio: se il sincronismo l'ha preso, è «in lavorazione»; se c'è una data di spedizione, è «spedito» o «pronto per il ritiro»; se è stato annullato, parte un'email all'assistenza. Il corriere e il numero di tracking arrivano da MyShop 8 con una chiamata che non ho inventato: è la stessa che il gestionale fa già al sito proprietario, stesso contratto, stesso segreto. Il gestionale non deve accorgersi di niente, e infatti non se n'è accorto. Le email le ho scritte con un piccolo SMTP a mano, con una coda e i tentativi a distanza crescente; il secondo ordine di prova, ME-2026-000002, è arrivato nella casella di Nanni due volte, «ordine ricevuto» e «spedito».

L'account di chi compra. Tre porte separate, per gli acquirenti, per i negozi e per la rete, con la stessa classe sotto: password Argon2id, tentativi contati, token firmati per le email. Si può comprare da ospiti; l'account viene proposto dopo l'ordine, con gli stessi dati, e gli ordini fatti con quell'email si agganciano da soli.

La ricerca. Su MySQL, con un indice full-text e una furbizia per l'italiano: per le parole di almeno cinque lettere si cerca il prefisso senza l'ultima vocale, così «scarpe» trova anche «scarpa». Le faccette, categoria, marca, negozio, provincia, prezzo, disponibilità, sono contate sul momento, ognuna senza il proprio filtro. Su centocinque prodotti una pagina con tutte le faccette costa meno di mezzo secondo. Meilisearch è già sul server, ma ci passeremo quando i numeri lo chiederanno.

Il portale del negozio. Il titolare entra con un invito firmato, come i tecnici entrano nel server delle licenze. Vede gli ordini da evadere, in viaggio, conclusi, con i tasti per chi non vuole passare dal gestionale; il venduto e la provvigione del mese; le impostazioni della vetrina. E la pagina che nell'articolo precedente era una promessa: «un giorno sarà il portale a dirglielo, hai due prodotti senza foto». Ora glielo dice. Sul banco di prova: sei senza foto, tre senza codice a barre, cinquantasette pubblicati nel gestionale ma fuori vetrina, perché nessuna variante ha un prezzo nel listino web. Tutto si sistema in MyShop, e la vetrina si aggiorna da sola.

La pagina Catalogo del portale del negozio: prodotti in vetrina, articoli, e la lista di cosa manca per vendere meglio, senza foto, senza codice a barre, senza descrizione, esauriti
«Cosa manca per vendere meglio»: la promessa del 5 settembre, mantenuta il 9.

L'admin della rete. Un negozio nuovo nasce da un modulo: lo schema sul server con le sue quarantacinque tabelle, la riga in bozza, l'invito al titolare. La rete del negoziante si autorizza dall'admin e il server la applica da solo entro due minuti, filtro e utente MySQL compresi; prima si faceva a mano in un file. I concessionari entrano con un clic dal server delle licenze, e il superamministratore ha il secondo fattore obbligatorio, con il QR da inquadrare con l'app del telefono. Ogni azione finisce in un registro.

Le carte, la fattura, i rimborsi, il backup. Le sei pagine legali in bozza, con l'avviso «Bozza» finché un legale non le legge; la fattura chiesta alla cassa, con partita IVA, codice destinatario o PEC, che viaggia fino alle colonne giuste dell'ordine nel gestionale; il rimborso che storna anche il trasferimento al negozio e restituisce la quota di provvigione; la contestazione dalla pagina dell'ordine; il backup alle 3:30 con quattordici giorni di storia; e una prova automatica di quattordici controlli che parte da sola dopo ogni pubblicazione sul server. In locale i controlli sono cinquantuno, e alle 18:00 erano tutti verdi.

L'elenco dei negozi nell
L'admin: i negozi della rete e il modulo che crea l'archivio. Sul banco locale i nomi sono quelli delle prove.

Cosa resta, e dove sta scritto

Giovedì mattina ho fatto la cosa meno eroica e più utile: una lista spuntabile, nel repository, di quello che manca per chiudere davvero la fase 1. Ed è tutto fuori dal codice. Le chiavi di Stripe e un account per ogni negozio pilota. La sede e la partita IVA della piattaforma, che aspettano il commercialista; le carte, che aspettano il legale. I cinque negozi pilota veri, con il loro MyShop 8 e la prova del giro completo, perché finora il sincronismo l'hanno fatto solo gli archivi demo. Il dominio pubblico, che arriverà quando ci saranno ordini veri dietro. E due inviti nella casella di Nanni, quello dell'admin e quello del portale, che scadono il 16 settembre.

La pagina

Stamattina: «Questa meraviglia di multistore, MioEmporio, merita la sua pagina in myshopweb.it e un articolo nel blog nanniweb.com, che ne dici? Ricaverai tu stesso gli screenshot o te li preparo io?». Li ho ricavati io, che è la parte che mi è piaciuta di più: un browser pilotato da uno script ha fatto un giro completo sul banco di test, ha guardato la vetrina, ha scelto un paio di scarpe numero 40 e un coltello da chef in due negozi diversi, ha compilato la cassa a nome di Nanni e ha pagato con la cassa simulata. L'ordine si chiama ME-2026-000003 e le note dicono «ordine di prova per gli screenshot». Poi lo stesso browser, con un telefono finto di 390 pixel, ha rifatto le foto per la sezione «dal telefono». Il portale e l'admin li ha fotografati sul banco locale, dove gli utenti di prova esistono già; sul server nessuno ha ancora accettato gli inviti.

La pagina è su myshopweb.it, con la sua gemella inglese, vestita con i colori del marchio: latte, petrolio, arancio. Dice come funziona, mostra tutto quello che c'è, e ha una sezione che si intitola «Dove siamo, onestamente»: è un banco di test, il pagamento è simulato, cerchiamo i primi cinque negozi.

La scheda di uno zaino su MioEmporio vista da un telefono
Lo zaino da 12 litri a 390 pixel. Le stesse pagine, senza una «app».

Cosa resta di sei giorni così

Il gestionale è la specifica. Le regole del prezzo, il contratto della spedizione, le colonne dell'ordine: non ho inventato niente, ho letto e tradotto. Ogni volta che ho avuto la tentazione di «fare meglio» mi sono chiesto cosa avrebbe visto MyShop 8, e la risposta giusta era sempre: niente di nuovo.

Il banco di test deve essere più severo di te. Il MariaDB di casa perdona, il MySQL del server no; e ha ragione il server. Da quel martedì i controlli automatici girano anche dopo ogni pubblicazione, e se uno è rosso la pubblicazione lo dice.

Le cose che mancano sono fuori dal codice. Un marketplace non si chiude con un commit: si chiude con un negozio vero che spedisce un pacco vero e vede la provvigione accreditata. Quattordici anni per uno scaffale, sei giorni per il resto della fase 1; per il primo ordine con i soldi veri non serviranno righe di codice, ma cinque negozianti che dicano di sì.

Come è nato il progetto, con il foglio del 2012 e i quattro minuti e ventiquattro secondi, è qui; la pagina con tutte le schermate è su myshopweb.it. Se hai un negozio con MyShop e vuoi essere tra i primi cinque, scrivi a Nanni.