# 09 — API: database e schema utenti Leggi `CLAUDE.md`. ## Obiettivo Drizzle ORM su `iti_app` con le tabelle di identità. ## Cosa fare - Drizzle ORM + drizzle-kit, migrazioni versionate in `apps/api/src/db/migrations`. - Plugin Fastify `db` che espone l'istanza Drizzle. - Tabelle: - `users`: id uuid, email unique (case-insensitive, salvata lowercase), password_hash, role (enum `customer|company|installer|admin`), first_name, last_name, company_name null, vat_number null, medusa_customer_id null unique, email_verified_at null, created_at, updated_at, disabled_at null. - `refresh_tokens`: id, user_id FK, token_hash, family_id, expires_at, revoked_at null, created_at, user_agent, ip. - `password_reset_tokens`: id, user_id FK, token_hash, expires_at, used_at null. - `email_verification_tokens`: stessa struttura. - Script `db:migrate`, `db:generate`, `db:seed` (seed: un utente admin da env `SEED_ADMIN_EMAIL/PASSWORD`). ## Criteri di accettazione - `npm run db:migrate -w apps/api` crea le tabelle su un DB vuoto. - Il seed crea l'admin ed è idempotente. - I token sono salvati solo come hash, mai in chiaro. - `CLAUDE.md` aggiornato.