Giuseppe.Rega
← Torna ai progetti

A Casa di Dante — e-commerce full-stack in cinque lingue

Astro e .NET 10, cinque lingue, pagamenti, GDPR e SEO tecnica costruiti a mano.

  • Astro 7
  • React
  • Tailwind CSS
  • .NET 10
  • EF Core
  • PostgreSQL
  • PayPal
  • SignalR
  • Docker

Il problema

Un produttore di alimentari artigianali toscani voleva vendere direttamente in Europa. Le piattaforme pronte all'uso costavano una percentuale su ogni ordine e non gestivano in modo corretto né le informazioni obbligatorie sugli alimenti né i cinque mercati linguistici.

Risultato

Un negozio in cinque lingue, con spedizioni calcolate lato server, pagamenti PayPal verificati via webhook, storico prezzi conforme alla direttiva Omnibus e feed prodotti per Google Shopping.

Perché non una piattaforma pronta

Le soluzioni chiave in mano reggono finché i requisiti sono standard. Qui non lo erano: informazioni obbligatorie sugli alimenti, cinque lingue con URL indicizzabili separatamente, storico dei prezzi richiesto dalla direttiva Omnibus, e una percentuale su ogni ordine che, su margini alimentari, pesa. Costruirlo è costato tempo una volta sola.

Le parti che si sono rivelate difficili

La spedizione ha una sola fonte di verità. Costi e soglia di spedizione gratuita vivono nel backend e vengono serviti da un endpoint dedicato. Tutto ciò che calcola un prezzo lo chiede lì. La tentazione di scrivere «49 €» nel frontend è forte e produce, prima o poi, un carrello che promette una cifra e un ordine che ne addebita un’altra.

Il prezzo si calcola sul server, sempre. Il totale dell’ordine — spedizione compresa — viene determinato e salvato lato server al momento della creazione. Quello che arriva dal browser è una richiesta, non un importo.

Lo storico dei prezzi non è un dettaglio legale. La direttiva Omnibus impone di mostrare il prezzo più basso praticato nei trenta giorni precedenti a uno sconto. Serve una tabella storica vera: è un requisito di dominio, non una nota a piè di pagina.

La ricerca sul database sbagliata produce zero risultati validi. La ricerca prodotti usa un confronto insensibile alle maiuscole, tokenizzato per parola. Con un semplice Contains, su PostgreSQL, «chianti» restituiva zero risultati e «Chianti» nove — un bug che non fa rumore e falsa anche le statistiche di ricerca.

Conformità, per davvero

Sei documenti legali tradotti in cinque lingue, consensi registrati e revocabili, area GDPR in cui l’utente esporta o cancella i propri dati, e informazioni alimentari obbligatorie per ogni prodotto. Le analitiche di ricerca sono anonime per progetto: solo il termine normalizzato, il numero di risultati e la lingua. Quel confine è ciò che tiene l’intera funzionalità fuori dall’ambito dei dati personali.

SEO tecnica

Sitemap generata dal server e non dal plugin standard, che vedeva solo le pagine statiche e pubblicava per errore l’area amministrativa omettendo i prodotti. Dati strutturati, hreflang per cinque lingue, font ospitati in proprio, immagini ridimensionate lato server con cache, e nessun ProductListResponse messo in cache: prezzo, disponibilità e prezzo di riferimento Omnibus cambiano sotto la cache, e servirli stantii significa mostrare un prezzo sbagliato.

Realtime e pagamenti

Chat cliente-venditore su SignalR. Pagamenti PayPal con Orders API v2: l’ordine si crea e si cattura lato server, e il webhook firmato è la fonte di verità sullo stato «pagato» — non il ritorno del browser, che un utente può chiudere a metà.