# ADR 2026-06-07 — Stack e architettura

**Stato:** proposto/scelto (revisabile sul punto DB) · **Decisore:** Paolo (delega a Claude per le scelte tecniche)

## Contesto
- Piattaforma pro bono: vetrina pubblica + gestionale per i tornei TTA della Tana dei Goblin.
- Sviluppo: interamente a cura di Claude. Manutenzione a lungo termine: Paolo, da solo.
- **Hosting**: produzione su **Vercel** (flusso abituale di Paolo). Il **NAS di casa è solo per
  sviluppo locale e backup** (NON è il server di produzione; la MariaDB del NAS resta dev/backup).
- Vincolo cardine: **motore eventi generico e configurabile** (vedi `../05-requisiti-prodotto.md`).

## Decisione
Stack unico **SvelteKit** su Vercel:

| Pezzo | Scelta | Alternativa considerata |
|---|---|---|
| Framework | **SvelteKit** + `adapter-vercel` (app unica: vetrina + gestionale + dashboard) | Astro+SvelteKit split (scartato), Next.js |
| Rendering | `prerender`/SSG per pagine info; SSR/ISR per dati live | — |
| DB | **Neon (Postgres)** via Marketplace Vercel | **Turso/libSQL** (valida, revisabile) |
| ORM | **Drizzle** (TS, migrations type-safe) | Prisma |
| Auth | **Better Auth** (self-registration + verifica email, dati self-hosted) | Clerk (gestito), Auth.js |
| Email | **Resend** | SMTP |
| Cron | **Vercel Cron** → endpoint SvelteKit | — |
| UI | **Tailwind + shadcn-svelte** + libreria grafici (ranking) | Skeleton/Melt |
| PWA/Push | **Fase 2** (`@vite-pwa/sveltekit`) | da subito (scartato per ora) |

## Razionale
- **Astro vs SvelteKit → unico SvelteKit**: vetrina e gestionale condividono dati (classifiche,
  albo, eventi, giocatori), tipi e design; uno split duplicherebbe DB/tipi/componenti tra due
  codebase — inaccettabile per un manutentore solo. SvelteKit con `prerender` dà già SEO/perf
  ~equivalenti per questa mole di contenuto. (Astro conviene su siti puri di contenuto o vs framework pesanti.)
- **Neon (Postgres) vs Turso**: il dominio è relazionale+analitico (classifiche, spareggi = % cultura
  vs vincitore, ranking persistente, promo/retro). Postgres offre **window functions** (calcoli più
  puliti) e **JSONB** (ideale per il `format_config` del motore generico). Neon = integrazione
  first-party Vercel, free tier, driver serverless. Turso resta valido se si preferisce semplicità SQLite.
- **Better Auth**: registrazione autonoma + verifica email, gratuito, i dati personali restano nel
  nostro DB (utile per GDPR). Clerk se si vuole un servizio gestito.

## Conseguenze
- Un'unica codebase/deploy; tipi, DB layer, auth e design system condivisi.
- DB di produzione nel cloud (Neon), **non** la MariaDB del NAS (incompatibile con serverless+sito pubblico).
- Admin del gestionale costruito su misura (no Filament): scaffolding CRUD riusabile.

## Punti revisabili
- **DB**: Neon Postgres (proposto) vs Turso (preferenza pregressa di Paolo) — da confermare.
- **Auth gestita** (Clerk) se in futuro si vuole ridurre manutenzione.

## Limiti noti
- **Transazioni con `drizzle-orm/neon-http`**: il driver HTTP di Neon **non supporta `db.transaction()`**.
  Per Fase 1 (solo auth) va bene. La logica di dominio in Fase 3 (generazione gironi, promozioni/retrocessioni,
  assegnazione punteggi = scritture multi-tabella atomiche) dovrà usare il driver `neon-serverless`
  (WebSocket) o una connessione unpooled per le sezioni transazionali.
