Executive Summary
Architettura completa per marketplace bevande artigianali con modello puro intermediario. Stack scelto: Rails 8 + Hotwire + PostgreSQL + Solid Queue/Cache/Cable + Stripe Connect. Priorità: SEO-first, time-to-market veloce, costi infrastruttura minimi.
1. Principi Architetturali
1.1 Core Principles
- SEO-first: Ogni pagina produttore/prodotto è renderizzata server-side, indicizzabile da Google dal giorno 1
- Asset-light: Zero gestione magazzino/logistica, tutto a carico produttore
- Scalabilità graduale: MVP semplice che evolve con i ricavi, non over-engineering
- Developer velocity: Un solo dev (founder) deve poter mantenere e evolvere la piattaforma
- Costi fissi minimi: Nessuna infrastruttura enterprise, scale-up solo quando necessario
- Accessibilità WCAG 2.1 AA: Conformance su tutte le pagine pubbliche — skip link, landmark semantici, aria-label, contrasto colori, focus management
1.2 Non-Requirements (MVP) — stato aggiornato
- ❌ App mobile nativa (web-first, responsive) — confermato
- ❌ Micro-services (monolite Rails fino a 100k utenti) — confermato
- ❌ Real-time notifications via WebSocket attive in UI (Solid Cable presente nel DB, non esposto in frontend ancora)
- ✅ ML/AI recommendations — IMPLEMENTATO (PR #153: personalised product recommendations con ranking e caching)
- ✅ i18n multi-locale — IMPLEMENTATO (routing
/:localecon constraint it/en, LocaleDomain middleware per ccTLD, hreflang full SEO overhaul — PR #150)
2. Stack Tecnologico
2.1 Backend
Framework: Ruby on Rails 8
- Maturo, stabile, veloce per marketplace
- Hotwire (Turbo + Stimulus) per interattività senza SPA
- Action Cable per real-time opzionale (post-MVP)
Database: PostgreSQL 18
- Relazioni complesse produttore-prodotto-ordine-commissione
- Estensioni:
earthdistance(geo-filtering km 0) - Ricerca full-text: Meilisearch (search engine esterno, typo-tolerant, faceting, filtri avanzati)
- Backup automatizzato su Cloudflare R2
Background Jobs / Cache / Real-time: Rails 8 Solid Stack
- Solid Queue — job asincroni (email, indicizzazione Meilisearch, geocoding) su PostgreSQL, zero Redis
- Solid Cache — fragment caching durable su database (256MB namespace)
- Solid Cable — WebSocket per aggiornamenti real-time (notifiche ordini)
- Mission Control Jobs per UI gestione code
Storage: ActiveStorage + Cloudflare R2
- Sviluppo: storage locale su disco
- Produzione: Cloudflare R2 (S3-compatible, free tier 10GB + 10M reads/mese)
- Image processing: libvips (ruby-vips) + mini_magick fallback
- PDF fatture/ricevute
2.2 Frontend
- View Layer: ERB templates + Hotwire (server-rendered HTML per SEO nativo)
- CSS: Tailwind CSS 4 (utility-first, via tailwindcss-rails)
- JavaScript: Importmap + Stimulus controllers (zero bundler, bundle minimo)
- Maps: Leaflet.js + OpenStreetMap (zero API costs)
- Checkout: Stripe.js (PCI compliance out-of-the-box)
2.3 Dashboard Produttori
Framework: Rails + Hotwire (Turbo + Stimulus) — stesso stack del frontend pubblico
Rationale stack unificato: Hotwire fornisce reattività sufficiente per dashboard analytics con aggiornamenti real-time (Turbo Streams) e interazioni complesse (Stimulus controllers). Evita complessità double-stack, riduce bundle size, facilita manutenzione.
3. Architettura Dati
3.1 Schema Database (Core Entities)
Users
- id (UUID), email (unique, index)
- password_digest (bcrypt)
- role (enum: consumer, producer, admin)
- OAuth identities (Google, Facebook, LinkedIn)
- avatar (ActiveStorage attachment)
- timestamps
Producers
- id (UUID), user_id (FK)
- business_name, slug (unique via friendly_id, SEO-friendly URLs)
- ProducerProfile (modello separato per dati editoriali)
- ProducerAddress (indirizzo + geocoding asincrono via Nominatim)
- latitude, longitude (per km 0)
- commission_rate (decimal, default 12% — scala a 8% oltre soglia volume)
- plan (enum: free, pro, partner)
Products
- id (UUID), producer_id (FK, index)
- name, slug (scoped to producer, via friendly_id)
- description (Markdown via Redcarpet)
- category, style, region, product_attributes
- ABV (alcohol_percentage), volume_ml
- price_cents
- stock_quantity, published (boolean)
- images (ActiveStorage, has_many_attached)
- tags (Gutentag — genere, stile, attributi)
- ProductListing (modello separato per arricchimento editoriale SEO)
- Indicizzato su Meilisearch (name, description, producer_name, category)
Orders
- id, user_id (FK consumer)
- producer_id (FK, for filtering)
- order_number (unique: #BRW-20260215-0042)
- status (enum: pending, paid, shipped, delivered, cancelled)
- subtotal_cents, commission_cents, total_cents
- stripe_payment_intent_id, stripe_transfer_id
- shipping_tracking_url, shipped_at, delivered_at
3.2 Relazioni Chiave
- User
has_oneProducer - Producer
has_manyProducts - Order
belongs_toUser (consumer) - Order
belongs_toProducer - Order
has_manyOrderItems - Review polymorphic su
ProductoProducer(un tipo per ogni reviewable) - ProducerAnalyticsSnapshot — snapshot giornalieri per storico trend (piano Pro)
3.3 Indici Critici per Performance
idx_products_producer_publishedON products(producer_id, published)idx_orders_user_statusON orders(user_id, status)idx_producers_locationUSING GIST per query geospazialiidx_producers_slugUNIQUEidx_products_slug_producerUNIQUE
4. Pagine Principali (MVP)
4.1 Pubbliche (SEO-critical)
Gli URL nel browser non hanno il prefisso lingua: il middleware LocaleDomain lo inietta silenziosamente su Rails dall'hostname (torbido.it → Rails gestisce come /it/…) senza alcun redirect. Il visitatore vede sempre URL puliti.
- Home (
/): Hero con value proposition, Featured producers, "Scopri per regione" - Produttori Index (
/produttori/): Lista con navigazione per regione, tipo, km 0 (ogni stile/tipo è una pagina dedicata), paginazione - Produttore Single (
/produttori/:slug/): Storia, processo produttivo, territorio + lista prodotti + recensioni + Schema.org LocalBusiness markup - Prodotti Index (
/birre/,/distillati/,/cocktail-pronti/): Lista cross-produttori con navigazione per categoria, stile, pillar (km0/bio/artigianale/stagionale), regione, prezzo - Prodotto Single (
/produttori/:producer_slug/products/:product_slug/): Foto, descrizione, ingredients + pricing + recensioni + Schema.org Product markup - Recensioni pubbliche (
/reviews-page/): Pagina pubblica con tutte le recensioni della piattaforma - Pillar pages (
/km0/,/bio/,/artigianale/…): Pagine editoriali cross-categoria per SEO long-tail - FAQ (
/faq/): FAQ i18n con FAQPage JSON-LD, HTTP caching - Carrello (
/cart): Session-based, raggruppato per produttore - Checkout (
/checkout): Login/signup required, Stripe Payment Intent
4.2 Autenticate (Produttori)
- Dashboard / Analytics (
/producer/profile/analytics): Snapshot giornalieri ordini/payout/visite, grafici storici, breakdown prodotto, plans comparison. Sezioni avanzate gated su piano Pro. - Prodotti (
/producer/products): CRUD prodotti, upload foto, gestione inventario, preview pubblica - Ordini (
/producer/orders): Lista ordini da evadere, azioni spedizione, tracking URL - Recensioni (
/producer/reviews): Lista recensioni ricevute (prodotto + produttore), risposta pubblica per ogni recensione - Share page (
/producer/share): QR code e link condivisione per canali fisici/social - Profilo (
/producer/profile): Modifica storia, processo produttivo, foto, rigenerazione AI bio, piani abbonamento (Free/Pro/Partner)
5. Flussi Principali
5.1 Onboarding Produttore
- Produttore richiesta accesso (form pubblico
/richiedi-accesso) - Admin review (verifica licenze, P.IVA)
- Admin approva → email invite con link setup
- Produttore completa profilo (storia, foto, prodotti iniziali)
- Admin final review → pubblica profilo
- Stripe Connect onboarding (Standard o Express account)
5.2 Acquisto Consumer
- Consumer naviga
/produttorio/prodotti - Aggiunge prodotti al carrello (session-based)
- Checkout → login/signup
- Inserisce indirizzo spedizione
- Conferma ordine → Stripe Payment Intent
- Pagamento riuscito: email conferma + notifica produttore
- Stripe Connect Transfer a produttore (subtotal - commission, hold 7 giorni)
- Produttore spedisce → segna "shipped" con tracking URL
- Consumer riceve email con tracking
5.4 Post-consegna: Recensioni
- Ordine transita a
delivered(produttore marca consegnato) - Job
Reviews::SendRequestJobsi attiva 3 giorni dopo: email al consumer con link firmato (token, no login richiesto) - Consumer recensisce uno o più prodotti dell'ordine + può recensire il produttore (se ha ordinato ≥2 prodotti distinti dallo stesso)
- Produttore riceve notifica email per ogni recensione
- Produttore può rispondere pubblicamente dalla dashboard (
/producer/reviews) - Recensioni e risposte visibili sulle pagine pubbliche prodotto/produttore e nella pagina consumer (
/account/reviews)
- Application fee model: Torbido trattiene commissione al momento del pagamento
- Split payment: Consumer paga 100% a Torbido → transfer (100% - commission) a produttore
- Payout produttore: automatico via Stripe (settimanale o mensile)
- Costi Stripe: 1.5% + €0.25 transazione (EU cards) → assorbito nella commissione 8%
6. Integrazioni Esterne
| Servizio | Provider | Use Case | Costo |
|---|---|---|---|
| Stripe Connect | Stripe | Pagamenti + trasferimenti produttori | 1.5% + €0.25/tx |
| Ricerca | Meilisearch | Full-text search prodotti (typo-tolerant, faceting) | Self-hosted (Fly Machine dedicata) |
| AI Contenuti | Anthropic (Claude API) | Generazione testi, traduzioni, arricchimento prodotti | Pay-per-use |
| Geocoding | Nominatim (OpenStreetMap) | Geolocalizzazione produttori per filtro km 0 | Gratuito |
| Storage | Cloudflare R2 | Immagini prodotti/produttori (ActiveStorage) | Free tier 10GB; poi ~€0.015/GB/mese |
| Analytics | Google Analytics 4 | Tracking conversioni, e-commerce events | Gratuito |
| Maps | Leaflet + OpenStreetMap | Filtro km 0, visualizzazione produttori | Gratuito |
| SEO | meta-tags + json-ld + sitemap_generator | Dynamic meta tags, Schema.org (LocalBusiness, Product), XML sitemap | Gratuito |
7. Infrastruttura e Deployment
7.1 Hosting e Deploy (MVP)
Fly.io (scelta MVP)
- Fly Machines per app Rails (~$5-15/mo shared CPU)
- Fly Postgres (managed, 1GB free tier)
- Meilisearch su Fly Machine dedicata
- Cloudflare R2 per storage file (S3-compatible, free tier generoso)
- Zero Redis — Rails 8 Solid Stack su PostgreSQL
✅ Deploy con fly deploy, SSL automatico, edge networking globale. Scaling orizzontale semplice con Fly Machines. CDN e R2 via Cloudflare.
7.2 CI/CD
- GitHub Actions (2k minuti/mese gratuiti)
- Pipeline:
test → lint → deploy staging → manual approval → deploy production - Test suite: RSpec (model/integration tests), no full E2E MVP
7.3 Monitoring (MVP)
- Sentry: Error tracking (€26/mese tier base)
- Uptime Robot: Gratuito, ping ogni 5 minuti
- Health check: endpoint
/upintegrato Rails 8
8. Sicurezza e Compliance
8.1 Autenticazione
- Devise gem (Rails standard)
- Password: bcrypt hashing
- Session: signed cookies (Rails encrypted)
- OAuth: OmniAuth (Google, Facebook, LinkedIn) — già implementato
8.2 Verifica Età (Compliance Alcol)
- MVP: Checkbox obbligatorio checkout "Dichiaro di avere almeno 18 anni"
- Post-MVP: Integration con servizio verifica ID (Onfido, Veriff)
8.3 GDPR
- Privacy policy e Cookie policy (template legalizzato)
- Consenso cookie (banner con opt-in analytics)
- Data export/deletion su richiesta utente
8.4 Payment Security
PCI Compliance: gestito da Stripe (zero PCI scope per Torbido, usiamo Stripe.js). No credit card data stored on Torbido servers.
9. Performance e Scalabilità
9.1 Target Performance (MVP)
9.2 Ottimizzazioni MVP
- Fragment caching produttori/prodotti (Solid Cache, TTL 1h, invalidazione automatica on update)
- HTTP headers:
Cache-Control: no-cacheper pagine dinamiche (browser richiede sempre ultima versione) - Database connection pooling (PostgreSQL native)
- Image optimization: libvips resize on upload, WebP format, lazy loading
- CDN: CloudFlare free tier (caching solo assets statici CSS/JS/immagini, HTML sempre fresco)
10. Timeline Sviluppo — Stato Attuale
MVP completato e in sviluppo attivo. La timeline a 3 mesi pianificata a marzo 2026 è stata rispettata. L'app è ora al PR #153 con 185+ commit. Le feature elencate sotto riflettono ciò che è stato costruito.
✅ Core Foundation — Completato
- Rails 8 + PostgreSQL + Solid Queue/Cache/Cable (4 database separati: primary, cache, queue, cable)
- Auth: Devise + OmniAuth (Google, Facebook, LinkedIn) con finish-signup flow per OmniAuth
- Multi-locale routing
/:locale(it/en) con LocaleDomain middleware per ccTLD (torbido.it, torbido.de, …) - Modelli core: User, Producer, Product, Order, OrderItem, Cart, CartItem, Checkout
- Layout Tailwind CSS + Importmap + Hotwire (Turbo + Stimulus)
✅ Storefront & Marketplace — Completato
- Pagine pubbliche SEO: home, produttori index/show, prodotti index/show, style pages, category pages
- Routing IA v1.0:
/{category}/{style}/{pillar}/con constraint localizzati per it/en - Carrello + Checkout + Stripe Payment Intent
- Produttori browse per tipo, regione, stile con constraint locale-aware
- Full-text search via Meilisearch (typo-tolerant, faceting)
- Geocoding produttori (Nominatim) + filtro km 0 Haversine
✅ Producer Dashboard & Post-MVP — Completato
- Producer onboarding multi-step con AI bio generation (Claude API)
- Producer memberships (multi-user per produttore) + invitation system
- Analytics dashboard redesign + plans comparison page (PR #151)
- ProducerAnalyticsSnapshot (giornaliero: ordini, payout, visite prodotti/profilo)
- Sistema recensioni consumer → produttore + producer review invitations
- Product offers (sconti a tempo — PR #140)
- Public user profile pages (PR #149)
- Share buttons su producer e product profiles (PR #147)
- Personalised product recommendations con ranking e caching (PR #153)
- SEO overhaul: editorial content, hreflang completo, noindex strategico (PR #150)
- User saved products, followed producers, favorite styles
11. Costi Ricorrenti (MVP - Anno 1)
| Servizio | Costo Mensile | Note |
|---|---|---|
| Fly.io (hosting) | ~€30 | App + Postgres + Meilisearch Machines |
| Sentry (monitoring) | $26 | Error tracking |
| Dominio (.it) | $2 | Registrazione annuale / 12 |
| Stripe (payment) | Variabile | 1.5% + €0.25 per transazione (assorbito) |
| Totale fisso | ~€55-60/mese | R2 free tier; email da aggiungere quando necessario |
Note: Costi scalano con traffico, ma restano asset-light. Nessun costo logistica/magazzino.
12. Rischi Tecnici e Mitigazione
Rischio 1: Complessità Stripe Connect
Probabilità: Media | Impatto: Alto
Mitigazione:
- Usare Stripe Standard Connect (onboarding hosted, zero custom UI)
- Testing su Stripe test mode con account dummy
- Consultazione documentazione ufficiale + Rails gem
stripe-ruby - Fallback: se troppo complesso, MVP con pagamenti diretti PayPal produttore
Rischio 2: Performance Database (1.000+ prodotti)
Probabilità: Bassa (MVP) | Impatto: Medio
Mitigazione:
- Indici ottimizzati su query critiche
- Fragment caching aggressivo (invalidazione smart on update)
- Monitoring query N+1 (Bullet gem)
- Upgrade Fly Machine se necessario (scaling verticale/orizzontale semplice)
Rischio 3: CTO Single Point of Failure
Probabilità: Media | Impatto: Alto
Mitigazione:
- Documentazione inline codice
- README completo con setup instructions
- Deploy automatizzato (zero deploy manuale)
- Utente non tecnico può gestire contenuti via dashboard admin
- Post-Anno 1: onboarding dev junior per supporto manutenzione
13. Metriche Tecniche di Successo MVP
| Metrica | Target MVP | Strumento Monitoraggio |
|---|---|---|
| Deploy time | < 10 minuti | Fly.io deploy |
| Page load time (avg) | < 1.5s | Google Lighthouse |
| Uptime | > 99.5% | Uptime Robot |
| Error rate | < 1% | Sentry |
| Test coverage | > 80% (models/controllers) | SimpleCov |
| Database query time (p95) | < 100ms | Sentry + Fly Metrics |
| Bugs critical (Mese 1) | < 10 | GitHub Issues |
Conclusioni
MVP completato. Stack confermato in produzione.
Stack (Rails 8 + Hotwire + PostgreSQL + Solid Stack + Fly.io + Cloudflare R2 + Stripe Connect) ha retto allo sviluppo intensivo (153 PR, 185+ commit, Jan–Jun 2026):
- ✅ Maturo e battle-tested — zero rewrite necessario
- ✅ SEO-first nativo — routing locale-aware, hreflang, Schema.org
- ✅ MVP sviluppato nei tempi (3 mesi) — poi evoluto significativamente
- ✅ Costi infrastruttura ~€55-60/mese confermati
- ✅ Scalabile — architettura regge feature non pianificate (AI recs, multi-locale)
Stato attuale (Giugno 2026): Piattaforma funzionante, in fase di onboarding produttori pilota Lombardia (Fase 1). Prossimi step: prime transazioni reali, validazione GMV, attivazione Stripe Connect produttori.
Riferimenti Tecnici
Documentazione ufficiale e fonti per ogni tecnologia adottata nello stack MVP.
Framework e Linguaggi
- Ruby on Rails 8 — rubyonrails.org | Rails Guides
Motivazione scelta: server-rendering nativo (SEO-first), convention over configuration, ecosistema maturo per marketplace (Stripe, Devise, ActionMailer). Rails 8 Solid Stack elimina dipendenza da Redis. - Hotwire (Turbo + Stimulus) — hotwired.dev
Motivazione: SPA-like UX senza JavaScript framework separato; reduce complexity; stessa base Rails.
Database, Search e Storage
- PostgreSQL 18 — postgresql.org/docs
Motivazione: earthdistance per geolocalizzazione km 0, ACID transactions per pagamenti, UUID primary keys. Database separati per cache (Solid Cache), queue (Solid Queue) e cable (Solid Cable). - Meilisearch — meilisearch.com/docs
Usato per: ricerca full-text prodotti (typo-tolerant, faceting, filtri per stato pubblicazione). Gli stili caricano pagine dedicate. Integrazione via gemmeilisearch-rails. - Rails 8 Solid Stack — Solid Queue, Solid Cache, Solid Cable
Motivazione: background jobs, caching e WebSocket senza Redis. Database-backed, zero infrastruttura aggiuntiva. - ActiveStorage + Cloudflare R2 — storage locale in sviluppo, Cloudflare R2 (S3-compatible) in produzione.
Image processing via libvips (ruby-vips) con mini_magick fallback. R2: free tier 10GB storage + 10M reads/mese, zero egress fees.
Pagamenti
- Stripe Connect — stripe.com/connect | Pricing EU
Usato per: split payment (consumer → Torbido → produttore), KYC produttori via Stripe Express, payout automatici. Costo: 1,5% + €0,25/tx (EU cards). - Stripe.js / Stripe Elements — stripe.com/docs/stripe-js
Motivazione: PCI DSS compliance out-of-the-box; zero card data stored su server Torbido.
Hosting e Infrastruttura
- Fly.io — fly.io/pricing
Fly Machines per app Rails e Meilisearch. Fly Postgres managed. Deploy confly deploy, SSL automatico, edge networking. ~€30/mese base stack. - Cloudflare R2 + CDN — cloudflare.com/r2 | CDN plans
R2: object storage S3-compatible, free tier 10GB + 10M reads/mese, zero egress fees. CDN: caching asset statici, DDoS protection, SSL. HTML sempre servito fresco. - Docker — Multi-stage build (ruby:4.0.1-slim), container per app + worker Solid Queue + Meilisearch + PostgreSQL.
Monitoring e Qualità
- Sentry — sentry.io/pricing — Error tracking, performance monitoring. Team tier ~€26/mese.
- ActionMailer + letter_opener (dev) — Email transazionali via Rails ActionMailer. In sviluppo: letter_opener per preview in browser. Produzione: servizio SMTP da configurare (es. Postmark, SendGrid).
- SimpleCov — github.com/simplecov-ruby/simplecov — Code coverage Ruby. Target: >80% su models/controllers.
- RuboCop — rubocop.org — Linter e formatter Ruby standard.
Autenticazione e Sicurezza
- Devise gem — github.com/heartcombo/devise — Authentication standard Rails: registrazione, login, password reset, email verification.
- OmniAuth — OAuth login: Google, Facebook, LinkedIn. CSRF protection via omniauth-rails_csrf_protection.
AI e Contenuti
- Anthropic (Claude API) — docs.anthropic.com — Generazione contenuti produttore, traduzioni editoriali, arricchimento schede prodotto. Gem
anthropic. - Redcarpet — github.com/vmg/redcarpet — Parser Markdown per storytelling produttore e descrizioni prodotti.
SEO e Performance
- Google Search Console — search.google.com/search-console — Monitoraggio indicizzazione, Core Web Vitals, backlink organici.
- Schema.org — LocalBusiness / Product Markup — schema.org/LocalBusiness — Structured data per rich snippet in SERP (produttore locale, prodotti con prezzo e disponibilità).