Marketplace · annunci

Admister — sette marketplace che condividono un motore

Annunci, auto, immobili, un mercato di beni con negozi, chiavi digitali, coupon e un aggregatore di prezzi. Sette servizi vivono sui loro sottodomini, e ognuno di essi è la stessa applicazione: il servizio è scelto dal nome host, e il catalogo, gli account, il denaro, la moderazione e la ricerca sono condivisi. Abbiamo progettato il modello, scritto il motore e spedito tutti e sette.

Categoria
Marketplace · annunci
Costo stimato
da €32.000
Servizi
sette, un codice sorgente
Lingue
EN, UK · quattro valute di visualizzazione
Stack
PHP 8.3, MariaDB, nessun framework
admister.org
Amministrare
Homepage del progetto — admister.org

01Panoramica del progetto

Amministrareè un marketplace multi-settoriale. Sotto lo stesso tetto gestisce annunci, una bacheca per auto e parti, immobili in vendita e in affitto, un mercato di beni con negozi di venditori, beni digitali, un servizio di coupon e un aggregatore di prezzi. Ognuno di essi ha il proprio sottodominio, la propria homepage e la propria idea di cosa sia un articolo.

Dall'esterno sembrano sette prodotti separati. Dall'interno sono un'unica applicazione: il servizio è deciso dal nome host della richiesta, e tutto ciò che sta sotto — account, denaro, moderazione, ricerca, media, notifiche — è condiviso. Il progetto era nostro dall'inizio alla fine: il modello, il motore, l'interfaccia e il lancio di ogni verticale.

02Contesto e problema

Il modo abituale per lanciare diversi marketplace è lanciare diversi siti web. Funziona fino al secondo: ora ci sono due tabelle utenti, due code di moderazione, due integrazioni di pagamento e due posti dove lo stesso bug deve essere corretto due volte — e corretto in modo diverso, perché nel frattempo il codice si è allontanato.

L'estremo opposto è altrettanto brutto. Un sito con una categoria chiamata «Auto» non può chiedere chilometraggio, motore e targa come deve fare una bacheca per auto, e una ricerca immobiliare che non può filtrare per piano e stanze non è una ricerca immobiliare. Il compito era mantenere un unico motore senza pretendere che sette cataloghi molto diversi siano lo stesso catalogo.

03Obiettivi del progetto

  • un'unica base di codice e un unico account per tutti i verticali, con il servizio scelto dal nome host;
  • attributi e filtri per verticale: dozzine di campi per auto e immobili, nessuno di essi trascinato negli altri servizi;
  • denaro di cui il proprietario può fidarsi — un saldo, fatture crypto, accredito idempotente e riconciliazione dei pagamenti bloccati;
  • motivi per cui gli acquirenti tornano: ricerche salvate con push, badge per venditori, aste e acquisti di gruppo;
  • due lingue e quattro valute di visualizzazione senza duplicare contenuti;
  • un'applicazione mobile che comunica con un backend-for-frontend piuttosto che estrarre dati dal sito.

04Cosa abbiamo fatto

Abbiamo integrato il registro dei servizi nella sequenza di avvio. Una richiesta arriva, il nome host viene confrontato con il registro, e da quel momento l'applicazione sa quale verticale è: quali moduli caricare, quale set di attributi utilizzare, quale pagina principale e quale menu visualizzare. Il dominio nudo è il pannello delle inserzioni, quindi l'indirizzo più breve è anche il più generale.

Tutto ciò che non è specifico per il verticale è stato scritto una sola volta: account e sessioni, saldo e pagamenti, acquisizione media, moderazione, ricerche salvate, notifiche, la mappa del sito e l'API. Aggiungere il settimo servizio è stato principalmente scrivere i suoi attributi e la sua pagina principale — non un altro mercato.

05Sette servizi, sette cataloghi

  • Annunci — la bacheca generale: qualsiasi cosa, da una bicicletta a un divano, gratuito per pubblicare.
  • Auto — veicoli, targhe e parti, con un set di attributi dedicato di diverse dozzine di campi e filtri costruiti su di esso.
  • Immobili — vendita e affitto, il proprio set di attributi, mappe e ricerca per distretto.
  • Mercato — beni con negozi di venditori: una vetrina per venditore, stock, ordini.
  • Digitale — chiavi, carte regalo e eSIM: beni che vengono consegnati, non spediti.
  • Affari — coupon e codici promozionali dei negozi partner.
  • Prezzo — un aggregatore di prezzi: lo stesso prodotto tra i negozi, confrontato, con clic in uscita conteggiati.

Condividono l'account, il saldo, la coda di moderazione e l'indice di ricerca — e non condividono nulla nelle loro attribuzioni, che è il punto.

06Denaro: un saldo, fatture crypto, riconciliazione

Le funzionalità a pagamento — promozione, piani negozio, beni digitali — sono pagate da un saldo interno, e il saldo viene ricaricato con crypto tramite Payora, il nostro gateway. Il corpo della fattura è costruito in esattamente una funzione, perché lo stesso corpo viene riprodotto dal cron di riconciliazione sotto la stessa chiave di idempotenza: un singolo campo che differisce tra i due tornerebbe come un conflitto e lascerebbe il pagamento in sospeso.

Due dettagli che ripeteremmo su qualsiasi gateway. La fattura riporta la locale del compratore presa dalla riga del loro account, non dalla richiesta web — il cron non ha richiesta e altrimenti invierebbe a tutti in inglese. E riporta un indirizzo di ritorno che riporta all'account sul dominio nudo, quindi un compratore che ha iniziato nella verticale auto torna loggato, non a una pagina che chiede di accedere di nuovo.

07Fiducia: moderazione, badge, controversie

Un marketplace è giudicato dalla sua peggior inserzione, quindi la moderazione non è un aspetto secondario qui. Ogni decisione — approvare, rifiutare, rimuovere — passa attraverso un gestore, e «rifiutare» non è deliberatamente la stessa cosa di «rimuovere»: il primo è una risposta all'autore con una motivazione, il secondo rimuove qualcosa che era già attivo. Due verbi, due lettere diverse, due stati diversi nel record.

I venditori e i negozi portano distintivi che si guadagnano, non si comprano: da quanto tempo esiste l'account, quanti affari sono stati chiusi, se il telefono e l'email sono confermati. L'acquirente vede lo stesso distintivo ovunque il venditore appaia, perché viene calcolato in un unico posto.

09Un'app mobile con il proprio backend

L'applicazione non estrae dati dal sito web. Parla con un backend-for-frontend di sua proprietà: un piccolo insieme di endpoint che rispondono nelle forme di cui hanno bisogno gli schermi, con token emessi separatamente dalle sessioni web. Due percorsi sono aperti senza un token — i dati di riferimento di cui l'app ha bisogno prima che qualcuno acceda, e un endpoint di salute.

Quel punto finale della salute è un indirizzo separato di proposito. Il registro che monitora la flotta usava chiedere il punto finale di riferimento, e quello assembla ogni dizionario e ogni tariffa — un controllo di vitalità non dovrebbe costare più del lavoro. Risponde anche con la versione del contratto, quindi un client costruito per un contratto più vecchio viene notato prima che i suoi utenti se ne accorgano.

10Sette fronti di SEO

Sette servizi su un dominio significano sette sitemap, sette set di dati strutturati e un modo molto semplice per produrre duplicati. Ogni verticale pubblica la propria sitemap dalla cache, le pagine di elenco dichiarano il proprio tipo di dati strutturati e le pagine dei risultati di ricerca non pretendono mai di essere canoniche per un elenco.

Anche il lato contenuti è automatizzato: un flusso editoriale arriva da Astrina, la piattaforma che abbiamo costruito esattamente per questo, e nel momento in cui un articolo arriva, la cache della sitemap per il suo verticale viene eliminata — altrimenti la nuova pagina dovrebbe aspettare il prossimo ricostruzione e nessuno saprebbe perché mancava.

11Un canale outbound

Tutto ciò che l'applicazione invia verso l'esterno — chiamate API, webhook, feed dei partner, immagini che recupera, email — passa attraverso un singolo modulo legato a un proxy egress SOCKS5, con DNS risolto attraverso il proxy. Il modulo è fail-closed: se il proxy non è disponibile, la richiesta viene bloccata piuttosto che inviata silenziosamente dall'indirizzo del server.

Questo non è decorazione. Un marketplace estrae feed dei partner e immagini remote tutto il giorno; ognuna di queste è una richiesta che altrimenti porterebbe l'indirizzo di origine del sito a una terza parte. Le email seguono lo stesso percorso, attraverso YourTrend, quindi le lettere sono firmate e il nome host del server non appare mai in un'intestazione.

12Stack tecnologico

  • PHP 8.3 senza un framework, un sottile wrapper PDO e dichiarazioni preparate ovunque;
  • MariaDB, schema mantenuto come file di migrazione numerati piuttosto che come la memoria di qualcuno;
  • media memorizzati al di fuori della radice web e serviti da un controller, quindi un upload non è mai un percorso eseguibile;
  • un passaggio di build che hash gli asset e non inlines nulla che dovrebbe essere memorizzato nella cache, con un kill switch per quando si comporta male;
  • uscita SOCKS5 per ogni chiamata in uscita, posta tramite YourTrend SMTP;
  • Payora per fatture crypto, Astrina per accesso e contenuti editoriali, Adgora per pubblicità interna.

13Il risultato

Sette servizi attivi su un'unica base di codice, un account e un saldo su tutti loro, con attributi e filtri che differiscono tanto quanto i cataloghi. Un nuovo verticale è un insieme di attributi e una pagina principale — non un nuovo progetto, non una seconda tabella utenti, non una seconda integrazione di pagamento.

Ciò che il proprietario ottiene giorno per giorno è un luogo dove guardare. Moderazione, denaro, venditori e contenuti sono gestiti dal pannello di controllo condiviso dell'intero gruppo, e il marketplace li espone attraverso un'API admin firmata piuttosto che attraverso un secondo sito admin di propria.

14Lezioni apprese

La lezione che porteremmo nel prossimo marketplace: condividi la macchina, non il significato. Conti, denaro, moderazione e ricerca sono lo stesso problema in ogni settore e devono essere scritti una sola volta. Attributi, filtri e la forma di un annuncio sono il prodotto stesso, e costringerli in un'unica tabella universale è come i marketplace diventano inutilizzabili per tutti allo stesso tempo.

La seconda lezione riguarda il denaro. Il luogo in cui viene descritto un pagamento deve essere una funzione singola, perché qualcos'altro lo ripeterà — un cron, un tentativo di nuovo, una riconciliazione — e due descrizioni di un pagamento sono il modo più economico per perdere denaro silenziosamente.

Se stai costruendo un marketplace, un pannello di annunci o una piattaforma multi-settore su un unico motore, questo è il tipo di lavoro che facciamo dalla A alla Z.