# ClientHub — Gestione Clienti & Dashboard ## What This Is Suite operativa per un consulente di personal branding, live su hub.iamcavalli.net (Coolify/Hetzner): un'area admin (`/admin/*`) per gestire clienti, progetti, offerte, preventivi e CRM, e una dashboard cliente via link segreto (`/client/[token]`) dove ogni cliente vede lo stato del suo progetto. Con la v2.0 (Phase 7-10) è diventata suite completa: catalogo servizi unificato, builder offerte con fasi, preventivi pubblici e CRM con pipeline lead. La v2.1 ("Offer Studio + Proposal AI") rifà la UX di catalogo/offerte in stile database-view veloce, ristruttura il workspace progetto, ricostruisce il CRM in stile Attio e chiude il loop con un builder preventivi AI → pagina pubblica → link di pagamento. ## Core Value Il cliente apre il link e vede esattamente a che punto è il suo progetto, cosa deve ancora succedere e cosa ha già approvato — senza dover scrivere email per chiedere aggiornamenti. ## Current Milestone: v2.2 Sales Loop *(reset 2026-06-19)* **Contesto reset:** v2.1 ha consegnato Offer Studio (catalogo + offer editor) e il CRM Attio. Dopo aver articolato il flusso commerciale reale, le fasi residue v2.1 (13/15/16/17) sono congelate/abbandonate/ri-scopate. Piano completo: `.claude/plans/glittery-sprouting-pudding.md`. **Goal:** Chiudere il **loop di vendita** end-to-end: lead in pipeline Kanban (Pipedrive-style) → transcript datati delle call per cliente → agente AI (io scelgo l'offerta, l'AI personalizza) che genera il preventivo → pagina pubblica `/preventivo/[slug]` + invio email → vinto/perso manuale nel CRM. Il portale cliente post-vendita resta invariato. **Target features (Phase 18→22 / R1→R5):** - **R1 Cleanup** — rimuovere Forecast e quote builder manuale; fondere `/admin/analytics` nella Dashboard (no doppioni) - **R2 Pipeline Kanban** — board lead stile Pipedrive con drag-drop tra stage; vinto/perso = cambio-colonna manuale - **R3 Knowledge Base** — schema + UI per transcript datati multipli per lead/cliente - **R4 Agente AI** — builder: admin sceglie cliente+offerta, l'AI (Claude) legge transcript + offerta → bozza preventivo; admin revisiona - **R5 Pagina pubblica** — `/preventivo/[slug]` HTML/CSS, accept/reject → CRM, invio link via email (Resend) **Backlog post-R5** (ex Proposal AI v2.1): Stripe Payment Link su offerta (PROP-03) + auto-provisioning cliente/progetto/fasi/pagamenti al "Vinto" (PROP-04). Phase 13 (Servizi attivi/ricorrenti post-vendita) congelata, ripescabile. ## Requirements ### Validated Shipped in v1.0 (Phases 1–6, in produzione su hub.iamcavalli.net): - ✓ Ogni cliente ha un URL segreto univoco, nessun login (token rotatable + slug opzionale) — Phase 1/4 - ✓ Dashboard cliente: brand, brief, fasi/task con stato, progress, multi-progetto — Phase 1/4 - ✓ Il cliente approva deliverable (approved_at immutabile) e lascia commenti — Phase 2 - ✓ Il cliente vede solo il totale accettato, mai i prezzi dei singoli servizi — Phase 2/3 - ✓ Stato pagamenti acconto/saldo visibile al cliente — Phase 1 - ✓ Link a documenti esterni + storico note/decisioni — Phase 1/2 - ✓ Area admin completa: clienti, progetti, fasi, task, pagamenti, documenti — Phase 2/4 - ✓ Catalogo servizi + quote builder admin (quote_items mai esposti al cliente) — Phase 3 - ✓ Sistema offerte: macro/micro/servizi, assegnazione a progetti, forecast 12 mesi — Phase 5 - ✓ Offerte attive visibili nella dashboard cliente (solo public_name) — Phase 5 - ✓ UX admin: sidebar + dashboard operativa con KPI e activity feed — Phase 6 Shipped in v2.0 (Phases 7–10, in produzione su hub.iamcavalli.net): - ✓ Catalogo servizi unificato (tabella `services`) usato dal quote builder — Phase 7 (legacy `service_catalog`/`offer_services` ancora presenti, consolidamento finale spostato in v2.1) - ✓ Offerte con fasi ordinate (`offer_phases`/`offer_phase_services`) e builder preventivo admin — Phase 8 - ✓ Preventivo pubblico `/quote/[token]`: stati draft→sent→viewed→accepted/rejected, `accepted_at` immutabile, raccolta email/note cliente — Phase 9 - ✓ CRM pipeline lead: stati, activity log, reminder follow-up in dashboard — Phase 10 Validated in v2.1 (consegnato, in prod): - ✓ Catalogo `services` come vista database (inline edit, tag multi-select, quick-add, ricerca istantanea) + consolidamento legacy — Phase 11 (OFFER-07..10, OFFER-13) - ✓ Offer Editor: lista filtrabile/archiviabile + 3 tier A/B/C via matrice checkbox, totale live, prezzo pubblico manuale, tag 4-dimensioni, promessa di trasformazione — Phase 12 (OFFER-11, OFFER-15..18). 55 servizi reali + tag offerta caricati. - ✓ CRM custom Attio-style: `/admin/leads` ridisegnata come tabella inline-edit (status, next_action, ecc.) + tag multi-select con creazione al volo; FollowUpWidget interamente in italiano; `LeadForm` tipizzato senza `useForm`; `SendQuoteModal`/`assignQuoteToLead` senza rami di codice irraggiungibili — Phase 14 (CRM-08, CRM-09, CRM-10, CRM-11, CRM-12) ### Active — v2.2 Sales Loop (reset 2026-06-19) **R1 Cleanup & Consolidamento (Phase 18):** - [ ] Rimuovere pagina Forecast (`/admin/forecast`) + voce sidebar (CLEAN-01) - [ ] Rimuovere quote builder manuale (`/admin/quotes/new`) (CLEAN-02) - [ ] Fondere `/admin/analytics` nella Dashboard `/admin`, eliminare la rotta duplicata (CLEAN-03) **R2 Pipeline CRM Kanban (Phase 19):** - [ ] Board lead stile Pipedrive con colonne per stage + drag-drop (PIPE-01) - [ ] Vinto/perso come cambio-colonna manuale (PIPE-02) **R3 Knowledge Base Cliente (Phase 20):** - [ ] Schema additivo transcript datati multipli per lead/cliente (KB-01) - [ ] UI per incollare/elencare transcript nel profilo (KB-02) **R4 Agente AI — generazione preventivo (Phase 21):** - [ ] Builder: admin sceglie cliente+offerta, l'AI (Claude) legge transcript + offerta → bozza preventivo (AI-01) - [ ] Admin rivede/edita la bozza prima di pubblicare (AI-02) **R5 Pagina pubblica `/preventivo/[slug]` + email (Phase 22):** - [ ] Pagina pubblica HTML/CSS della proposta (PUB-01) - [ ] Accept/reject → riflesso nel CRM (PUB-02) - [ ] Invio link proposta via email Resend (PUB-03) **Backlog (post-R5):** Stripe Payment Link su offerta (PROP-03), auto-provisioning al "Vinto" (PROP-04), Servizi attivi/ricorrenti post-vendita (ex Phase 13). ### Out of Scope - Fatturazione e invio fatture — la gestione contabile resta fuori, solo stato pagamenti - App mobile nativa — solo web responsive - Multi-utente con team — solo tu come admin per ora - Prezzi singoli visibili al cliente — vede solo il totale accettato - Email OTP per accesso cliente — design pronto ma deferito a batch successivo su richiesta utente - File hosting — documenti solo come URL esterni (v1 constraint, ancora valido) - Sezioni analitiche stile Notion (psicologia, rating, performance) — fuori v2.1, eventuale milestone futura - Deploy separati per modulo (architettura OMC multi-app) — non finché un modulo non cresce abbastanza da giustificarlo ## Context - Produzione: hub.iamcavalli.net su Coolify (Hetzner), Postgres self-hosted, deploy via webhook Gitea (NON Vercel) - Stack: Next.js 16 App Router, Drizzle ORM, Auth.js v4 (admin), token middleware (clienti), Tailwind v4, shadcn/ui, `@dnd-kit` già in deps - Tutto sotto la stessa app: `/admin/*` (sessione Auth.js) + `/client/[token]/*` (token) + pagine pubbliche preventivo `/quote/[token]` - La sidebar admin (Phase 6) è l'hub di navigazione per le nuove sezioni (CRM, Preventivi, Offerte) - `project_offers` (Phase 5) già copre l'attribuzione di offerte a progetti con `start_date`+`accepted_total`+`duration_months` — base per "Servizi attivi", da rifinire non ricostruire - `PaymentsTab` ha già un editor `accepted_total` (stessa server action di QuoteTab) — rimozione tab "Preventivo" è zero-perdita, verificato 2026-06-13 - Migrations sono manuali: applicare a prod via SSH+docker exec PRIMA di pushare codice che usa il nuovo schema (vedi REGOLA in HANDOFF.md storico) - Il flusso commerciale reale: call con lead → preventivo 3 tier (es. Signature A/B/C) in giornata → accettazione → onboarding automatico nell'hub ## Constraints - **Data Safety (LOCKED)**: migration solo additive su `clients`, `projects`, `payments`, `phases` — qualsiasi consolidamento di catalogo va pianificato senza drop/truncate - **Architettura (LOCKED)**: `clients.token` separato e rotatable; `quote_items` mai esposti via client API; `deliverables.approved_at` immutabile; no file hosting - **Compartimenti stagni**: un'unica app Next.js, moduli isolati (route group + service layer propri) su Postgres condiviso; migrations solo additive; niente deploy separati per ora (modello OMC adattato) - **NO database esterno / Excel come fonte dati**: Postgres resta l'unica fonte di verità — il problema è la UX, non il dato - **Numerazione fasi**: v2.0 ha chiuso a Phase 10; v2.1 parte da Phase 11 ## Key Decisions | Decision | Rationale | Outcome | | --- | --- | --- | | Link segreto senza login per i clienti | Massima semplicità — nessun account da creare, zero friction | ✓ Good | | Dashboard prima del flusso Claude | Clienti attivi ora, la visibilità al cliente è il valore immediato | ✓ Good | | Preventivo: cliente vede solo il totale | Il dettaglio dei prezzi è informazione commerciale riservata | ✓ Good | | Suite unica sotto /admin/* invece di 3 app separate | Stesso DB, stesso deploy, auth unica — overhead di 3 app ingiustificato per singolo admin | ✓ Confermato — formalizzato come "compartimenti stagni" (2026-06-12) | | Catalogo servizi unificato (una tabella `services`) | Due cataloghi paralleli (service_catalog + offer_services) duplicano manutenzione prezzi | ✓ Good — tabella `services` live da Phase 7, consolidamento legacy in v2.1 | | Tier offerte indipendenti (A/B/C separati, stesso tag) | Più semplice di un meccanismo di ereditarietà; ogni tier configurato a sé | — Pending | | Prezzi pacchetti per-preventivo, non da catalogo | Permette di alzare i prezzi nel tempo senza toccare il catalogo | — Pending | | Al "Vinto" le fasi dell'offerta sono COPIATE nel progetto | Il progetto resta modificabile senza toccare il template offerta | — Pending (ex-Phase 11, ora in Proposal AI) | | NO DB esterno/Excel, Postgres unica fonte | Lezione 2026-06-11: due fonti disallineate hanno causato il crash Phase 10 | ✓ Good | | Catalogo/Offerte UX = database view custom (non Notion-clone) | Notion troppo complesso per v1; serve velocità, non sezioni analitiche | — Pending | | Tab "Preventivo" rimossa, "Offerte" → "Servizi attivi" | Preventivo Builder è l'unico flusso; `accepted_total` già coperto da Payments | ✓ Confermato — zero perdita funzionale verificata (2026-06-13) | | Ordine: Offer Studio (UX dato) prima, Proposal AI (AI) dopo | L'AI è l'ultimo miglio, serve un dato pulito e veloce da gestire prima | — Pending | ## Evolution This document evolves at phase transitions and milestone boundaries. **After each phase transition** (via `/gsd-transition`): 1. Requirements invalidated? → Move to Out of Scope with reason 2. Requirements validated? → Move to Validated with phase reference 3. New requirements emerged? → Add to Active 4. Decisions to log? → Add to Key Decisions 5. "What This Is" still accurate? → Update if drifted **After each milestone** (via `/gsd-complete-milestone`): 1. Full review of all sections 2. Core Value check — still the right priority? 3. Audit Out of Scope — reasons still valid? 4. Update Context with current state --- *Last updated: 2026-06-14 — Phase 14 (CRM Attio-style & Fix) complete: CRM-08..12 validated*