# Handoff Living document — update at the end of each session so the next one can resume without re-deriving context. Overwrite stale sections; keep it short and actionable. --- ## 2026-06-11 (sera) — Phase 10 redo COMPLETATO, root cause trovata ### Root cause del crash (diversa dall'ipotesi del handoff precedente) Il DB di produzione (Coolify, container `xwkk0040w0kk0gsgcgog8owk`, db `clienthub`) **non aveva NESSUNA migration applicata dopo la 0000**: mancavano `services` (0001), `leads`/`offer_phases`/`offer_phase_services`/`quotes` (0003), le colonne quotes (0004). Le summary di Phase 7/8 dicevano "migration pending connectivity" e nessuno le ha mai applicate. Conseguenze: catalogo (→`services`), quote builder e `/quote/[token]` (→`quotes`) erano **già rotti in produzione prima di Phase 10**. Il deploy di Phase 10 ha solo aggiunto il crash della dashboard (FollowUpWidget→`leads`). Il rollback a `0bca8a6` ha mascherato il sintomo dashboard ma /quote/[token] dava ancora 500 (verificato con token 21-char valido). NB: l'app NON è su Vercel — Gitea (`git.iamcavalli.net`) → Coolify self-hosted. Il problema non era di piattaforma; nessun motivo di migrare a Replit. ### Cosa è stato fatto (redo staged) 1. **Stage A** — commit `5aa6614`: deps `@radix-ui/react-dialog@^1.1.16` + `date-fns@^4.4.0` + `ui/dialog.tsx`/`ui/form.tsx`. Deployato e verificato. 2. **Stage B** — migrations **0001+0003+0004+0005 applicate in unica transazione atomica** al DB prod via `ssh root@178.104.27.55` → `docker exec psql` (porta 54321 chiusa dal firewall dall'esterno; SSH ok). Verificato: 25 tabelle, `leads` con 12 colonne, righe protette intatte (4 clients / 5 projects / 13 payments / 6 phases). `/quote/[token]` 500→404. Script riusabile: `scripts/push-phase10-migration.ts` (funziona solo dal server o con tunnel). 3. **Stage C** — commit `008a434`: tutto il modulo CRM da `phase10-wip` (schema, lead-service/validators, /admin/leads, modali, FollowUpWidget, sidebar). Build pulita, push fatto, deploy Coolify in corso a fine sessione. ### Da verificare a inizio prossima sessione - [ ] Deploy Stage C live (chunk hash homepage cambiato rispetto a `797e433ab948586e-s.p.08e28id.o-okb.woff2`) - [ ] Da browser autenticato: `/admin` (dashboard con FollowUpWidget), `/admin/leads`, `/admin/catalog`, `/admin/quotes/new` — tutte devono caricare - [ ] Se tutto ok: `git branch -D phase10-wip` (lavoro ormai su main) ### Prossimi passi - `/gsd-plan-phase 11` e `/gsd-plan-phase 12` — i planning folder non sono mai stati committati, vanno rigenerati (Phase 11: auto-provisioning con `winLead(leadId, quoteId)` idempotente keyed `SHA256(leadId+quoteId)`; Phase 12: Resend email + quote expiration) - Eventuale cherry-pick di `5d75752` (sidebar "App shortcuts") se ancora desiderato — dangling, recuperabile da reflog - **Regola da ora in poi**: ogni phase con migration → applicare al DB prod PRIMA del push del codice (le migration qui sono manuali, niente runner automatico) ### Hash utili `5aa6614` (Stage A) · `008a434` (Stage C) · `phase10-wip` = `8e2752a` (originale recuperato) · `5d75752` (sidebar shortcuts, ancora dangling)