feat(audit): schema del documento di restituzione (migration 0017)

Sette tabelle additive per la milestone v2.5 "Audit": audits, audit_findings,
audit_optimizations, checklist_items, audit_checklist_results, audit_runs e
audit_visits. Nessun DROP, nessun TRUNCATE, nessuna colonna rimossa.

Tre scelte che vale la pena spiegare:

- Colonne scalari su audits, non un jsonb unico. A differenza di proposals non
  c'e' snapshot da congelare: il copy fisso sta in moduli TS versionati e
  l'editor mappa 1:1 sui campi. Tutti i campi di contenuto sono NULLABLE — e'
  cio' che rende possibile "si salva sempre, anche a meta'".
- checklist_items.profili e' jsonb: 71 voci su 264 valgono per entrambi i
  profili, una colonna singola costringerebbe a duplicarle.
- audit_checklist_results.esito ammette 'non_verificabile'. E' l'esito piu'
  frequente misurato sullo spike (107 su 204) e serve a sapere quanto il motore
  NON riesce a vedere: buttarlo via renderebbe impossibile misurare se le
  rilevazioni Lighthouse stanno recuperando terreno.

Migration gia' applicata in produzione il 2026-08-18, dati esistenti intatti.
CLAUDE.md annota la deroga al vincolo LOCKED #5, limitata agli asset di audit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-18 17:48:11 +02:00
parent ee47f35e97
commit 31237da11c
3 changed files with 600 additions and 2 deletions
+2 -1
View File
@@ -31,7 +31,8 @@ Next.js 16 App Router · Neon Postgres · Drizzle ORM · Auth.js v4 · Tailwind
3. `deliverables.approved_at` immutable once set
4. Auth: `/client/[token]/*` → middleware token check + gate OTP | `/admin/*` → Auth.js session.
**Unica deroga (Phase 26, 2026-08-08):** `getClientGate()` legge anche `getServerSession` per l'anteprima admin in sola lettura, e solo se `?preview=1` è presente. Non estendere questa lettura ad altre route client.
5. No file hosting v1 — documenti come URL esterni
5. No file hosting per i documenti — restano URL esterni.
**Unica deroga (Phase 27, 2026-08-18):** le immagini dell'audit (screenshot delle rilevazioni e redesign prima/dopo) sono caricate su volume persistente Coolify via Server Action e servite da `/api/uploads/[...path]`, con whitelist MIME e limite di dimensione. Non estendere l'upload ad altre entità senza modificare questo vincolo.
## Conventions
- **Mutations are Server Actions**, colocated as `actions.ts` (or `*-actions.ts`) inside the route folder. There is no REST API for admin: `src/app/api/` holds only NextAuth, the two internal validation routes, and two client endpoints.