Compare commits

...

3 Commits

Author SHA1 Message Date
simone 55a2da5faf chore: remove REQUIREMENTS.md for v2.2 milestone — fresh for v2.3 2026-06-20 18:31:13 +02:00
simone fb1ef95c96 chore: archive v2.2 Sales Loop milestone
- ROADMAP.md: collassato a milestone summary, v2.2 in <details>
- PROJECT.md: full evolution review — What This Is, Validated v2.2, Active v2.3, Key Decisions aggiornate
- MILESTONES.md: entry v2.2 + entry v2.1 aggiunti
- milestones/v2.2-ROADMAP.md: archivio completo fasi 18-22
- milestones/v2.2-REQUIREMENTS.md: archivio requirements con outcomes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 18:31:08 +02:00
simone cbfd959c36 docs(v2.2): close planning docs — SUMMARY.md 21+22, req Complete
- 21-01-SUMMARY.md: agente AI Opus 4.8, schema Zod, proposals table
- 22-01-SUMMARY.md: deck 20+ slide 100vh, accept/reject, PUB-03 deferred
- REQUIREMENTS.md: PIPE/KB/AI-01/02 + PUB-01/02 → Complete; PUB-03 deferred
- ROADMAP.md: Phase 20/21/22 → [x] con date
- STATE.md: status complete, percent 100, 5/5 fasi

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 18:24:00 +02:00
9 changed files with 445 additions and 461 deletions
+30
View File
@@ -1,5 +1,35 @@
# Milestones
## v2.2 Sales Loop (Phases 1822, shipped 2026-06-20)
**Phases completed:** 5 phases (1822) · 9 plans · 27 commits · 87 files · +7.349/-842 righe
**Key accomplishments:**
- Cleanup & Consolidamento (Phase 18): rimossi Forecast, quote builder manuale e rotta `/admin/analytics` duplicata; tutte le statistiche admin in un'unica Dashboard (CLEAN-01..04)
- Pipeline CRM Kanban (Phase 19): board lead 6 colonne stile Pipedrive con drag-drop persistente via `@dnd-kit`; toggle Lista/Kanban con ricerca integrata; vinto/perso come cambio-colonna manuale (PIPE-01, PIPE-02)
- Knowledge Base Transcript (Phase 20): tabella `client_transcripts` applicata a prod via SSH; data layer Drizzle + server actions; UI incolla/elenca/cancella nel dettaglio lead (KB-01, KB-02)
- Agente AI Preventivo (Phase 21): `generateProposalContent()` con Claude Opus 4.8 (~$0.44/preventivo); Zod schema 20+ sezioni; `AssembledProposal` snapshot JSONB; form admin con pre-fill da LeadDetail (AI-01, AI-02)
- Deck Pubblico (Phase 22): `/preventivo/[slug]` — deck 20+ slide `h-screen` con keyboard nav + dots; accept/reject con `accepted_at` immutabile; PUB-03 email Resend deferred a backlog (PUB-01, PUB-02)
**Known deferred items at close:** 1 — PUB-03 email Resend (vedi backlog v2.3)
Archive: `.planning/milestones/v2.2-ROADMAP.md` · `.planning/milestones/v2.2-REQUIREMENTS.md`
---
## v2.1 Offer Studio + CRM (Phases 1114, parziale — reset 2026-06-19)
**Phases completed:** 3 phases (11, 12, 14) · fasi 13/15/16/17 congelate/abbandonate/ri-scopate in v2.2
**Key accomplishments:**
- Catalog Database-View UX (Phase 11): catalogo `services` come tabella inline-edit con tag multi-select, quick-add e ricerca istantanea; consolidamento legacy (OFFER-07..10, OFFER-13)
- Offer Editor Tier A/B/C (Phase 12): editor offerte con matrice checkbox servizi×tier, totale live, prezzo pubblico manuale, tag 4-dimensioni, promessa di trasformazione; 55 servizi reali caricati (OFFER-11, OFFER-15..18)
- CRM Attio-style (Phase 14): `/admin/leads` ridisegnata con inline edit + tag multi-select; FollowUpWidget in italiano; LeadForm tipizzato; SendQuoteModal senza rami irraggiungibili (CRM-08..12)
---
## v2.0 Business Operations Suite (Phases 710, completato 2026-06-13)
**Phases completed:** 4 phases (710)
+35 -47
View File
@@ -2,26 +2,21 @@
## 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 pubblicalink di pagamento.
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.2 ("Sales Loop") il focus è diventato il loop commerciale completo: lead in pipeline Kanban → transcript datati delle call → agente AI (Claude Opus 4.8) genera preventivo personalizzato leggendo transcript + offerta → deck pubblico 20+ slide navigabile a `/preventivo/[slug]` → cliente accetta tier A/B/Cvinto/perso nel CRM.
## 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)*
## Current State: v2.2 Sales Loop ✅ SHIPPED 2026-06-20
**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`.
Il loop di vendita end-to-end è live in produzione: lead in pipeline Kanban → transcript datati → agente AI (Claude Opus 4.8) genera preventivo personalizzato → deck pubblico 20+ slide a `/preventivo/[slug]` → cliente sceglie tier A/B/C e accetta → vinto/perso nel CRM.
**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.
**Prossima milestone:** `/gsd-new-milestone` — candidati backlog:
- **PUB-03** — Invio link preventivo via email Resend (primo candidato, piccola effort)
- **PROP-03/04** — Stripe Payment Link + auto-provisioning al "Vinto"
- **AUTH-OTP-01** — Accesso cliente via OTP email (design già pronto)
- **Phase 13** — Servizi attivi/ricorrenti post-vendita (congelata, ripescabile)
## Requirements
@@ -54,31 +49,20 @@ Validated in v2.1 (consegnato, in prod):
- ✓ 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<any>`; `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)
Validated in v2.2 Sales Loop (shipped 2026-06-20):
**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)
- Cleanup: Forecast + quote builder manuale rimossi; analytics fuse in Dashboard — Phase 18 (CLEAN-01..04)
- ✓ Pipeline CRM Kanban 6 colonne con drag-drop; toggle Lista/Kanban; vinto/perso come cambio-colonna — Phase 19 (PIPE-01, PIPE-02)
- ✓ Knowledge Base transcript: `client_transcripts` in prod; UI incolla/elenca nel dettaglio lead — Phase 20 (KB-01, KB-02)
- ✓ Agente AI: Claude Opus 4.8, Zod schema 20+ sezioni, snapshot JSONB proposals, form admin — Phase 21 (AI-01, AI-02)
- ✓ Deck pubblico `/preventivo/[slug]`: 20+ slide 100vh, keyboard nav; accept/reject `accepted_at` immutabile — Phase 22 (PUB-01, PUB-02)
**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)
### Active — v2.3 (prossima milestone)
**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).
- [ ] PUB-03 — Invio link preventivo via email Resend (primo candidato)
- [ ] PROP-03 — Stripe Payment Link su offerta pubblica
- [ ] PROP-04 — Auto-provisioning cliente/progetto/fasi al "Vinto"
- [ ] AUTH-OTP-01 — Accesso cliente via OTP email (design pronto)
### Out of Scope
@@ -95,12 +79,13 @@ Validated in v2.1 (consegnato, in prod):
- 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
- Tutto sotto la stessa app: `/admin/*` (sessione Auth.js) + `/client/[token]/*` (token) + `/preventivo/[slug]` (pubblico)
- La sidebar admin include: Dashboard, Leads (con toggle Lista/Kanban), Offerte, Catalogo, Preventivi (con CTA globale "Genera preventivo")
- Stack v2.2: `@anthropic-ai/sdk@0.105.0` (Claude Opus 4.8), `@dnd-kit` (Kanban), `nanoid` (slug proposals)
- DB live: 10 migrazioni applicate a prod (00000010); `proposals` table con `content jsonb` snapshot; `client_transcripts` per lead
- Migrations sono manuali: SSH tunnel → `node` script PRIMA di pushare codice schema-dipendente; `drizzle-kit generate` rotto da Phase 8
- `ANTHROPIC_API_KEY` in Coolify — aggiunta 2026-06-20 via PHP artisan; costo ~$0.44/preventivo (Opus 4.8)
- Il flusso commerciale reale: call con lead → transcript incollato → genera preventivo AI → deck pubblica → cliente sceglie tier → vinto/perso
## Constraints
@@ -119,13 +104,16 @@ Validated in v2.1 (consegnato, in prod):
| 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) |
| Tier offerte indipendenti (A/B/C separati, stesso tag) | Più semplice di un meccanismo di ereditarietà; ogni tier configurato a sé | ✓ Good — usato in deck slide Pricing/StagesRecap/Comparison |
| Prezzi pacchetti per-preventivo, non da catalogo | Permette di alzare i prezzi nel tempo senza toccare il catalogo | ✓ Good — `public_price` per tier, snapshot in `proposals.content` |
| Al "Vinto" le fasi dell'offerta sono COPIATE nel progetto | Il progetto resta modificabile senza toccare il template offerta | — Pending (PROP-04, backlog v2.3) |
| 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 |
| Catalogo/Offerte UX = database view custom (non Notion-clone) | Notion troppo complesso per v1; serve velocità, non sezioni analitiche | ✓ Good — confermato in v2.1 |
| 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 |
| Ordine: Offer Studio (UX dato) prima, Proposal AI (AI) dopo | L'AI è l'ultimo miglio, serve un dato pulito e veloce da gestire prima | ✓ Good — strategia validata: catalogo+offerte puliti → AI in v2.2 |
| Output AI = JSON strutturato Zod → template fisso | Coerenza visiva garantita; zero rischio HTML rotto dall'AI | ✓ Good — 20+ sezioni Zod validate, deck sempre coerente |
| `proposals.content` = JSONB snapshot immutabile | Prezzi e profilo consulente "bloccati" al momento della generazione | ✓ Good — invariante di audit, coerente con `accepted_at` |
| Email Resend (PUB-03) deferred | Scope minimo funziona; link condiviso manualmente per ora | — Pending (v2.3 candidato #1) |
## Evolution
@@ -145,4 +133,4 @@ This document evolves at phase transitions and milestone boundaries.
4. Update Context with current state
---
*Last updated: 2026-06-14Phase 14 (CRM Attio-style & Fix) complete: CRM-08..12 validated*
*Last updated: 2026-06-20v2.2 milestone complete: Sales Loop end-to-end shipped (Phases 1822)*
-186
View File
@@ -1,186 +0,0 @@
# Requirements — ClientHub (v2.1 chiuso → v2.2 Sales Loop)
**Defined:** 2026-06-13 · **Reset:** 2026-06-19
**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.
v2.0 (Phases 710) ha consegnato catalogo unificato, offerte con fasi, preventivo pubblico e CRM pipeline (vedi MILESTONES.md, REQUIREMENTS.md archiviato in `.planning/milestones/v2.0-REQUIREMENTS.md`). v2.1 rifà la UX di catalogo/offerte in stile database-view, ristruttura il workspace progetto, ricostruisce il CRM in stile Attio e chiude il loop commerciale con un builder preventivi AI.
> **RESET 2026-06-19 — milestone v2.2 "Sales Loop".** v2.1 ha consegnato Offer Studio (Phase 11+12) e CRM Attio (Phase 14). Le fasi residue v2.1 — **13 (Servizi Attivi), 15 (Dashboard Revenue), 16/17 (Proposal AI originali)** — sono state **congelate/abbandonate/ri-scopate** dopo che l'utente ha articolato il flusso commerciale reale (vedi piano `.claude/plans/glittery-sprouting-pudding.md`). Il nuovo north-star è il **loop di vendita**: lead in pipeline Kanban → transcript call → agente AI genera preventivo → pagina pubblica `/preventivo/[slug]` → vinto/perso. Requirements attivi: sezione **v2.2** più sotto.
## Offer Studio — Catalogo & Offerte (v1)
| ID | Requirement | Status |
|----|-------------|--------|
| OFFER-07 | L'utente vede ed edita il catalogo `services` come tabella con inline editing (click su cella → edit → invio salva) | Complete |
| OFFER-08 | L'utente assegna tag multi-select a servizi/offerte, creando nuovi tag al volo senza uscire dalla tabella | Complete |
| OFFER-09 | L'utente aggiunge un nuovo servizio/offerta tramite riga vuota in fondo alla tabella (nome + invio) | Complete |
| OFFER-10 | L'utente filtra/cerca servizi e offerte istantaneamente (ricerca client-side, nessun reload) | Complete |
| OFFER-11 | L'admin compone un'offerta a 3 tier (A/B/C) assegnando i servizi del catalogo unificato `services` tramite matrice di checkbox (servizio × tier); il totale servizi di ogni tier si aggiorna live | Complete |
| OFFER-15 | Ogni offerta ha tag su 4 dimensioni (categoria, ticket, tipo, obiettivo) creabili al volo, riusando il sistema tag polimorfico di Phase 11 | Complete |
| OFFER-16 | Per ogni tier l'admin imposta un "prezzo pubblico" manuale, distinto e indipendente dal totale dei servizi | Complete |
| OFFER-17 | Ogni offerta ha una promessa di trasformazione strutturata (Cliente Ideale / Risultato / tempo / Pain / Metodo) | Complete |
| OFFER-18 | La lista offerte è filtrabile per categoria e supporta l'archiviazione (mostra/nascondi archiviate) | Complete |
| OFFER-13 | I dati legacy di `service_catalog` e `offer_services` sono consolidati in `services` senza perdita (migration additiva) | Complete |
## Workspace Progetto — Servizi Attivi (ex Phase 13 — CONGELATO v2.2)
> Congelato dal reset 2026-06-19: tocca il portale post-vendita che l'utente vuole lasciare invariato. Ripescabile in futuro se serve il tracking ricavi ricorrenti. (PROJ-10 "rimuovi Forecast" è confluito in CLEAN-01 v2.2.)
| ID | Requirement | Status |
|----|-------------|--------|
| PROJ-06 | La tab "Preventivo" è rimossa dal workspace progetto (solo UI — `quote_items` resta intatta, `accepted_total` resta editabile via tab Pagamenti) | Congelato (v2.2) |
| PROJ-07 | La tab "Offerte" diventa "Servizi attivi": mostra tutte le offerte assegnate al progetto (`project_offers`) | Congelato (v2.2) |
| PROJ-08 | L'utente marca ogni "servizio attivo" come one-shot o ricorrente mensile | Congelato (v2.2) |
| PROJ-09 | Per i servizi ricorrenti, l'utente registra in quali mesi è stata incassata la fattura (schema nuovo, additivo — UI può essere minimale) | Congelato (v2.2) |
| PROJ-10 | La pagina "Forecast" e la relativa voce di sidebar sono rimosse | → CLEAN-01 (v2.2) |
## CRM Custom Attio-style (v1)
| ID | Requirement | Status |
|----|-------------|--------|
| CRM-08 | La tabella lead (`/admin/leads`) supporta inline editing dei campi principali (status, next_action, ecc.) senza apertura modale | Complete |
| CRM-09 | L'utente assegna tag multi-select ai lead, creando nuovi tag al volo | Complete |
| CRM-10 | Il `FollowUpWidget` è in italiano, coerente col resto dell'app | Complete |
| CRM-11 | Il form lead (`LeadForm`) valida i campi senza workaround di type-relaxation su react-hook-form | Complete |
| CRM-12 | Il flusso `SendQuoteModal` (preventivo esistente vs nuovo) non contiene rami di codice irraggiungibili | Complete |
## Dashboard — Revenue Stats (ex Phase 15 — ABBANDONATO v2.2)
> Abbandonato dal reset 2026-06-19: mockup mai arrivato, valore dubbio nel nuovo flusso. L'esigenza analytics è coperta da CLEAN-03 (fusione `/admin/analytics` nella dashboard, no fase dedicata).
| ID | Requirement | Status |
|----|-------------|--------|
| DASH-11 | La Dashboard admin mostra le statistiche di revenue mensile (ex `/admin/forecast`, calcolate da `project_offers`) | Dropped (v2.2 → CLEAN-03) |
## Proposal AI — versione v2.1 originale (SUPERSEDED da v2.2)
> Ri-scopata dal reset 2026-06-19 nelle fasi v2.2 (PIPE/KB/AI/PUB) con il flusso chiaro + l'aggiunta dei transcript (che mancava). PROP-03 (Stripe Payment Link) e PROP-04 (auto-provisioning al "Vinto") restano backlog: non nel loop minimo, da rivalutare dopo R5.
| ID | Requirement | Status |
|----|-------------|--------|
| PROP-01 | L'admin avvia un builder AI che genera una proposta a partire da cliente + offerta(e) selezionata(e) + note extra fornite manualmente | Superseded → AI-01/AI-02 (v2.2) |
| PROP-02 | La pagina pubblica `/quote/[token]` è ridisegnata (HTML/CSS) per presentare la proposta generata | Superseded → PUB-01 (v2.2) |
| PROP-03 | Ogni offerta/preventivo ha un campo "link di pagamento" (Stripe Payment Link) mostrato come CTA nella pagina pubblica | Backlog (post-R5) |
| PROP-04 | All'accettazione del preventivo, il sistema crea automaticamente cliente + progetto, copia le fasi dall'offerta e configura 1-4 pagamenti (ex-Phase 11 WIN-01..06) | Backlog (post-R5) |
| PROP-05 | Il sistema invia via email (Resend) il link della proposta pubblica al lead (ex-Phase 12) | Superseded → PUB-03 (v2.2) |
## v2.2 — Sales Loop: Lead → AI → Preventivo (ATTIVO)
> Reset 2026-06-19. Il flusso commerciale articolato dall'utente sostituisce le fasi residue v2.1. Fasi eseguite in ordine R1→R5 (numerazione GSD continua: Phase 18→22). Le fasi 11/12/14 restano completate.
### Cleanup & Consolidamento (Phase 18 / R1)
| ID | Requirement | Status |
|----|-------------|--------|
| CLEAN-01 | La pagina Forecast (`/admin/forecast`) e la sua voce di sidebar sono rimosse | Complete |
| CLEAN-02 | Il quote builder manuale (`/admin/quotes/new`) e il suo entry point sono rimossi (superato dall'agente AI) | Complete |
| CLEAN-03 | Le statistiche di `/admin/analytics` sono fuse nella Dashboard `/admin` (vista unica); la rotta duplicata è eliminata | Complete |
| CLEAN-04 | Le fasi v2.1 residue (13/15/16/17) sono archiviate/ri-scopate nel planning | Complete |
### Pipeline CRM Kanban (Phase 19 / R2)
| ID | Requirement | Status |
|----|-------------|--------|
| PIPE-01 | I lead sono visualizzabili in una board Kanban stile Pipedrive con colonne per stage e drag-drop per cambiare stage | Pending |
| PIPE-02 | Spostare un lead nelle colonne "Vinto"/"Perso" è il cambio-stato manuale dell'esito | Pending |
### Knowledge Base Cliente — Transcript (Phase 20 / R3)
| ID | Requirement | Status |
|----|-------------|--------|
| KB-01 | Schema additivo per memorizzare transcript datati e multipli per lead/cliente | Pending |
| KB-02 | L'admin incolla ed elenca i transcript (storico ordinato per data) nel dettaglio lead/cliente | Pending |
### Agente AI — Generazione preventivo (Phase 21 / R4)
| ID | Requirement | Status |
|----|-------------|--------|
| AI-01 | L'admin seleziona cliente + offerta; l'agente AI (Claude) legge i transcript + i dati dell'offerta e genera una bozza di preventivo personalizzata | Pending |
| AI-02 | L'admin rivede ed edita la bozza generata prima di pubblicarla | Pending |
### Pagina pubblica preventivo + email (Phase 22 / R5)
| ID | Requirement | Status |
|----|-------------|--------|
| PUB-01 | La proposta generata è pubblicata come pagina pubblica HTML/CSS a `/preventivo/[slug]` (evolve la meccanica di `/quote/[token]`) | Pending |
| PUB-02 | Il cliente accetta/rifiuta dalla pagina; l'esito si riflette nel CRM (conferma vinto/perso manuale lato admin) | Pending |
| PUB-03 | Il link della proposta viene inviato al lead via email (Resend) | Pending |
## v2 Requirements (Deferred)
### Catalogo Avanzato
- **OFFER-12**: Import CSV/Notion one-shot per popolare servizi/offerte esistenti (solo seed iniziale, non sync continuo) — *rimandato il 2026-06-14 su decisione utente ("per ora saltiamo"); rientra nel filone "import dati da Notion" da valutare in una fase futura*
- **OFFER-14**: Sezioni analitiche stile Notion per le offerte (psicologia, rating, performance)
### Accesso Cliente
- **AUTH-OTP-01**: Accesso dashboard cliente via OTP email (design pronto, vedi memoria `project_clienthub_otp_access`)
### Architettura
- **ARCH-01**: Split di un modulo "compartimento stagno" in deploy separato (solo se il modulo cresce abbastanza da giustificarlo)
## Out of Scope
| Feature | Reason |
|---------|--------|
| Fatturazione e invio fatture | Solo stato pagamenti, gestione contabile fuori |
| App mobile nativa | Solo web responsive |
| Multi-utente con team | Solo admin singolo per ora |
| Prezzi singoli visibili al cliente | Vede solo il totale accettato (vincolo LOCKED) |
| File hosting | Documenti solo come URL esterni (vincolo v1, ancora valido) |
| Database esterno o Excel come fonte dati | Postgres unica fonte di verità — il problema è la UX, non il dato |
| Notion-clone completo (sezioni psicologia/rating/performance) | Troppo complesso per v1, vedi v2 Requirements |
| Deploy separati per modulo (architettura OMC multi-app) | Non finché un modulo non cresce abbastanza da giustificarlo |
## Traceability
Popolata dal roadmapper durante la creazione della roadmap.
| Requirement | Phase | Status |
|-------------|-------|--------|
| OFFER-07 | Phase 11 | Complete |
| OFFER-08 | Phase 11 | Complete |
| OFFER-09 | Phase 11 | Complete |
| OFFER-10 | Phase 11 | Complete |
| OFFER-13 | Phase 11 | Complete |
| OFFER-11 | Phase 12 | Complete |
| OFFER-15 | Phase 12 | Complete |
| OFFER-16 | Phase 12 | Complete |
| OFFER-17 | Phase 12 | Complete |
| OFFER-18 | Phase 12 | Complete |
| OFFER-12 | Deferred (v2) | Rimandato 2026-06-14 |
| PROJ-06 | Phase 13 | Congelato (v2.2) |
| PROJ-07 | Phase 13 | Congelato (v2.2) |
| PROJ-08 | Phase 13 | Congelato (v2.2) |
| PROJ-09 | Phase 13 | Congelato (v2.2) |
| PROJ-10 | Phase 13 | → CLEAN-01 |
| CRM-08 | Phase 14 | Complete |
| CRM-09 | Phase 14 | Complete |
| CRM-10 | Phase 14 | Complete |
| CRM-11 | Phase 14 | Complete |
| CRM-12 | Phase 14 | Complete |
| DASH-11 | Phase 15 | Dropped (→ CLEAN-03) |
| PROP-03 | Phase 16 | Backlog (post-R5) |
| PROP-04 | Phase 16 | Backlog (post-R5) |
| PROP-01 | Phase 17 | Superseded → AI-01/02 |
| PROP-02 | Phase 17 | Superseded → PUB-01 |
| PROP-05 | Phase 17 | Superseded → PUB-03 |
| CLEAN-01 | Phase 18 (R1) | Complete |
| CLEAN-02 | Phase 18 (R1) | Complete |
| CLEAN-03 | Phase 18 (R1) | Complete |
| CLEAN-04 | Phase 18 (R1) | Complete |
| PIPE-01 | Phase 19 (R2) | Pending |
| PIPE-02 | Phase 19 (R2) | Pending |
| KB-01 | Phase 20 (R3) | Pending |
| KB-02 | Phase 20 (R3) | Pending |
| AI-01 | Phase 21 (R4) | Pending |
| AI-02 | Phase 21 (R4) | Pending |
| PUB-01 | Phase 22 (R5) | Pending |
| PUB-02 | Phase 22 (R5) | Pending |
| PUB-03 | Phase 22 (R5) | Pending |
---
*Requirements defined: 2026-06-13*
*Last updated: 2026-06-19 — RESET v2.2 "Sales Loop": Phase 13 congelata, 15 abbandonata, 16/17 ri-scopate; nuovi requirements CLEAN/PIPE/KB/AI/PUB (Phase 18→22)*
+47 -221
View File
@@ -1,238 +1,64 @@
# Roadmap: ClientHub — v2.1 (chiuso) → v2.2 Sales Loop
# Roadmap: ClientHub
## Overview
## Milestones
**v2.0 (Phases 110, Complete)**: ClientHub è una suite operativa completa — catalogo servizi unificato, offerte con fasi, preventivo pubblico (`/quote/[token]`), CRM pipeline lead con activity log. Archiviato in `.planning/milestones/v2.0-ROADMAP.md`.
**v2.1 (Phases 1117) — PARZIALE / CHIUSO dal reset 2026-06-19**: ha consegnato Offer Studio (Phase 11 catalogo database-view + Phase 12 offer editor tier A/B/C) e CRM Attio-style (Phase 14). Le fasi residue **13/15/16/17 sono congelate/abbandonate/ri-scopate** (vedi sotto).
**v2.2 (Phases 1822, Sales Loop) — ATTIVO**: dopo che l'utente ha articolato il flusso commerciale reale (piano `.claude/plans/glittery-sprouting-pudding.md`), il focus diventa il **loop di vendita**: cleanup dei doppioni → pipeline CRM Kanban (Pipedrive-style) → knowledge base transcript per cliente → agente AI che genera il preventivo → pagina pubblica `/preventivo/[slug]` + email. Numerazione GSD continua: v2.2 parte da Phase 18. Le fasi R1R5 mappano su Phase 1822.
-**v1.0 Client Portal & Offer System** — Phases 16 (shipped 2026-06-10) — [archive](milestones/v1.0-ROADMAP.md)
-**v2.0 Business Operations Suite** — Phases 710 (shipped 2026-06-13) — [archive](milestones/v2.0-ROADMAP.md)
-**v2.1 Offer Studio + CRM**Phases 1114 parziale (chiuso 2026-06-19, reset → v2.2)
-**v2.2 Sales Loop** — Phases 1822 (shipped 2026-06-20) — [archive](milestones/v2.2-ROADMAP.md)
- 📋 **v2.3** — prossima milestone (in definizione)
## Phases
- [x] **Phase 11: Catalog Database-View UX & Legacy Consolidation** - Catalogo `services` come tabella con inline edit, tag multi-select, quick-add, ricerca istantanea; consolidamento `service_catalog`/`offer_services``services`
- [x] **Phase 12: Offer Editor — Tier A/B/C, Tag & Prezzo Pubblico** - Editor offerte completo: lista filtrabile + 3 tier (A/B/C) via matrice checkbox sui servizi `services`, totale live per tier, prezzo pubblico manuale, tag multi-dimensione, promessa di trasformazione (completed 2026-06-18)
- [~] **Phase 13: Workspace — Servizi Attivi** - ❌ CONGELATA (reset 2026-06-19): tocca il post-vendita lasciato invariato; ripescabile in futuro
- [x] **Phase 14: CRM Attio-style & Fix** - Redesign `/admin/leads` stile Attio/Pipedrive (inline edit + tag), fix FollowUpWidget IT / LeadForm types / SendQuoteModal rami irraggiungibili (completed 2026-06-14)
- [~] **Phase 15: Dashboard Revenue Stats** - ❌ ABBANDONATA (reset 2026-06-19): mockup mai arrivato; analytics confluisce nella dashboard via CLEAN-03
- [~] **Phase 16: Proposal AI — Data Foundations & Auto-Provisioning** - ❌ RI-SCOPATA in v2.2; Stripe Payment Link + auto-provisioning → backlog post-R5
- [~] **Phase 17: Proposal AI — Builder, Pagina Pubblica & Email** - ❌ RI-SCOPATA in v2.2 (Phase 21/22 con transcript + flusso chiaro)
- [x] **Phase 18: Cleanup & Consolidamento** - Rimuovi Forecast + quote builder manuale; fondi `/admin/analytics` nella dashboard; archivia fasi residue v2.1
- [x] **Phase 19: Pipeline CRM Kanban** - Board lead stile Pipedrive con colonne per stage + drag-drop; vinto/perso come cambio-colonna manuale
- [ ] **Phase 20: Knowledge Base Cliente** - Schema additivo + UI per incollare transcript datati multipli per lead/cliente
- [ ] **Phase 21: Agente AI — generazione preventivo** - Builder: admin sceglie cliente+offerta, l'AI (Claude) legge transcript + offerta e genera bozza preventivo; admin revisiona
- [ ] **Phase 22: Pagina pubblica preventivo + email** - Pagina pubblica HTML/CSS, accept/reject → CRM, invio link via email (Resend)
<details>
<summary>✅ v1.0 + v2.0 + v2.1 (Phases 117) — SHIPPED / CHIUSE</summary>
## Phase Details
Vedi archivi:
- `milestones/v1.0-ROADMAP.md` — Phases 16
- `milestones/v2.0-ROADMAP.md` — Phases 710
- Phases 11, 12, 14 — Offer Studio + CRM Attio (shipped in prod)
- Phases 13, 15, 16, 17 — congelate/abbandonate/ri-scopate in v2.2
> **Reset 2026-06-19**: i dettagli delle fasi 13/15/16/17 sotto sono conservati per storico ma quelle fasi sono **cancellate/congelate** (vedi checklist Phases sopra e Progress sotto). Le fasi attive sono **1822 (R1R5)**, in fondo a questa sezione.
</details>
### Phase 11: Catalog Database-View UX & Legacy Consolidation
**Goal**: L'utente vede ed edita il catalogo servizi come una tabella stile database (Notion-like) — inline editing, tag multi-select, quick-add, ricerca istantanea — su un'unica tabella `services` consolidata senza perdita di dati legacy
**Mode:** migration + ui
**Depends on**: Phase 10 (CRM Pipeline, ultima fase v2.0)
**Requirements**: OFFER-07, OFFER-08, OFFER-09, OFFER-10, OFFER-13
**Success Criteria** (what must be TRUE):
1. L'utente edita inline ogni cella del catalogo `services` (click sulla cella → edit → invio salva) senza apertura di modali
2. L'utente assegna tag multi-select a servizi/offerte, creando nuovi tag al volo senza uscire dalla tabella
3. L'utente aggiunge un nuovo servizio tramite riga vuota in fondo alla tabella (nome + invio)
4. L'utente filtra/cerca servizi e offerte istantaneamente (ricerca client-side, nessun reload)
5. I dati legacy di `service_catalog` e `offer_services` sono consolidati in `services` senza perdita (migration additiva, audit trail `migrated_from`/`migrated_id`)
**Plans**: 4 plans
**Plan list**:
- [x] 11-01-PLAN.md
- [x] 11-02-PLAN.md
- [x] 11-03-PLAN.md
- [x] 11-04-PLAN.md
**UI hint**: yes
**Status**: ✅ Complete (2026-06-13) — migration 0007 (`services.fase`) applicata in prod, commit pushato su `gitea/main`
<details>
<summary>✅ v2.2 Sales Loop (Phases 1822) — SHIPPED 2026-06-20</summary>
### Phase 12: Offer Editor — Tier A/B/C, Tag & Prezzo Pubblico
**Goal**: L'admin crea e modifica offerte complete da una lista filtrabile: editor con 3 tier (A/B/C) composti via matrice di checkbox dai servizi del catalogo unificato `services`, totale servizi live per tier, prezzo pubblico manuale per tier, tag multi-dimensione (categoria/ticket/tipo/obiettivo) e promessa di trasformazione strutturata. I servizi disponibili nella matrice sono filtrati per categoria offerta (entry/signature/retainer), designazione già impostata sul servizio a livello di catalogo.
**Mode:** ui + schema
**Depends on**: Phase 11 (tabella `services` unificata + sistema tag polimorfico)
**Requirements**: OFFER-11, OFFER-15, OFFER-16, OFFER-17, OFFER-18
**Success Criteria** (what must be TRUE):
1. L'admin compone un'offerta a 3 tier (A/B/C) assegnando i servizi del catalogo `services` tramite matrice di checkbox; il totale servizi di ogni tier si aggiorna live
2. Ogni offerta ha tag su 4 dimensioni (categoria, ticket, tipo, obiettivo) creabili al volo, riusando il sistema tag di Phase 11
3. Per ogni tier l'admin imposta un "prezzo pubblico" manuale, distinto e indipendente dal totale dei servizi
4. Ogni offerta ha una promessa di trasformazione strutturata (Cliente Ideale / Risultato / tempo / Pain / Metodo)
5. La lista offerte è filtrabile per categoria e supporta l'archiviazione (mostra/nascondi archiviate)
**Note**: Import CSV/Notion (ex OFFER-12) spostato a fase futura su decisione utente (2026-06-14, "per ora saltiamo") — vedi REQUIREMENTS.md
**Plans**: 5 plans
**Plan list**:
**Wave 1**
- [x] 12-01-PLAN.md — Schema: offer_macros/offer_micros additive columns (category, ticket, is_archived, transformation promise, tier_letter, public_price) + offer_tier_services junction table, migration 0008 + idempotent push script
**Wave 2** *(blocked on Wave 1 completion)*
- [x] 12-02-PLAN.md — BLOCKING checkpoint: apply migration 0008 to production database (SSH+docker exec, manual)
**Wave 3** *(blocked on Wave 2 — prod migration applied before schema-dependent code)*
- [x] 12-03-PLAN.md — Query layer (getOfferEditorData/getOfferListCards/getOfferFieldOptions) + server actions (saveOfferEditor/toggleOfferArchived/tag CRUD/createOfferMacro)
**Wave 4** *(blocked on Wave 3 completion)*
- [x] 12-04-PLAN.md — Offer list page redesign: category filter chips, archive toggle, card grid, "+ Nuova Offerta" CTA
- [x] 12-05-PLAN.md — Offer editor detail page: tags (4 dimensions), services matrix (tier A/B/C checkboxes + live totals), prezzo pubblico, promessa di trasformazione, Salva/Annulla/Archivia
**UI hint**: yes — riferimento mockup utente 2026-06-14 (lista card per categoria + editor con matrice servizi×tier)
**Status**: Planned (2026-06-14) — ready for `/gsd-execute-phase 12`
- [x] Phase 18: Cleanup & Consolidamento (3/3 plans) — completed 2026-06-19
- [x] Phase 19: Pipeline CRM Kanban (1/1 plan) — completed 2026-06-19
- [x] Phase 20: Knowledge Base Cliente (3/3 plans) — completed 2026-06-20
- [x] Phase 21: Agente AI — generazione preventivo (1/1 plan) — completed 2026-06-20
- [x] Phase 22: Pagina pubblica preventivo (1/1 plan, PUB-03 deferred) — completed 2026-06-20
### Phase 13: Workspace — Servizi Attivi
**Goal**: Il workspace progetto sostituisce le tab "Preventivo"/"Offerte"/"Forecast" con un'unica tab "Servizi attivi" che traccia servizi one-shot e ricorrenti con incassi mensili, senza perdere `accepted_total`/`quote_items`
**Mode:** ui + schema
**Depends on**: Phase 5 (`project_offers`), Phase 9 (flusso `accepted_total` via quote)
**Requirements**: PROJ-06, PROJ-07, PROJ-08, PROJ-09, PROJ-10
**Success Criteria** (what must be TRUE):
1. La tab "Preventivo" è rimossa dal workspace progetto (solo UI — `quote_items` resta intatta, `accepted_total` resta editabile via tab Pagamenti)
2. La tab "Offerte" diventa "Servizi attivi" e mostra tutte le offerte assegnate al progetto (`project_offers`)
3. L'utente marca ogni "servizio attivo" come one-shot o ricorrente mensile
4. Per i servizi ricorrenti, l'utente registra in quali mesi è stata incassata la fattura (schema nuovo, additivo)
5. La pagina "Forecast" e la relativa voce di sidebar sono rimosse
**Plans**: TBD
**UI hint**: yes
**Status**: Pending planning
Archivio completo: [milestones/v2.2-ROADMAP.md](milestones/v2.2-ROADMAP.md)
### Phase 14: CRM Attio-style & Fix
**Goal**: La tabella lead (`/admin/leads`) è ridisegnata in stile Attio/Pipedrive — inline editing dei campi principali e tag multi-select — e i bug residui del modulo CRM (FollowUpWidget non in italiano, LeadForm con type-relaxation, SendQuoteModal con rami irraggiungibili) sono risolti
**Mode:** ui
**Depends on**: Phase 10 (CRM Pipeline base)
**Requirements**: CRM-08, CRM-09, CRM-10, CRM-11, CRM-12
**Success Criteria** (what must be TRUE):
1. La tabella lead supporta inline editing dei campi principali (status, next_action, ecc.) senza apertura di modale
2. L'utente assegna tag multi-select ai lead, creando nuovi tag al volo
3. Il `FollowUpWidget` è interamente in italiano, coerente col resto dell'app
4. Il form lead (`LeadForm`) valida i campi senza workaround di type-relaxation su react-hook-form
5. Il flusso `SendQuoteModal` (preventivo esistente vs nuovo) non contiene rami di codice irraggiungibili
**Plans:** 5/5 plans complete
Plans:
**Wave 1**
- [x] 14-01-PLAN.md — Data-layer foundation: getLeadsWithTags/getLeadFieldOptions query helpers + updateLeadField/addLeadTag/removeLeadTag/renameLeadTag server actions (requireAdmin-guarded)
- [x] 14-03-PLAN.md — Bug fixes: FollowUpWidget Italian translation (CRM-10), LeadForm typed useForm (CRM-11), SendQuoteModal dead branch removal (CRM-12)
</details>
**Wave 2** *(blocked on Wave 1 completion)*
- [x] 14-02-PLAN.md — LeadTable raw-table rewrite (inline edit + status dropdown + tag multi-select), LeadsSearch instant filter, page wiring, LeadDetail tags
**UI hint**: yes — riferimento design Pipedrive/Attio (confermato dall'utente 2026-06-13)
**Status**: ✅ Complete (2026-06-14) — 5/5 success criteria verified, code review 0 critical/6 warnings/3 info
### 📋 v2.3 — Prossima Milestone (in definizione)
### Phase 15: Dashboard Revenue Stats
**Goal**: La Dashboard admin mostra le statistiche di revenue mensile (ex `/admin/forecast`), calcolate da `project_offers`
**Mode:** ui
**Depends on**: Phase 13 (modello dati Servizi attivi)
**Requirements**: DASH-11
**Success Criteria** (what must be TRUE):
1. La Dashboard admin mostra un breakdown di revenue mensile calcolato da `project_offers`
**Plans**: TBD
**UI hint**: yes
**Status**: Blocked — attesa mockup dashboard dall'utente (isolata/skippabile, non blocca Phase 16/17)
Candidati backlog (da formalizzare con `/gsd-new-milestone`):
### Phase 16: Proposal AI — Data Foundations & Auto-Provisioning
**Goal**: Ogni offerta/preventivo ha un campo link di pagamento Stripe mostrato come CTA pubblica, e all'accettazione del preventivo il sistema crea automaticamente cliente + progetto, copia le fasi dall'offerta e configura 1-4 pagamenti
**Mode:** schema + automation
**Depends on**: Phase 9 (flusso accettazione preventivo), Phase 13 (Servizi attivi come target del provisioning)
**Requirements**: PROP-03, PROP-04
**Success Criteria** (what must be TRUE):
1. Ogni offerta/preventivo ha un campo "link di pagamento" (Stripe Payment Link) mostrato come CTA nella pagina pubblica
2. All'accettazione del preventivo, il sistema crea automaticamente cliente + progetto, copia le fasi dall'offerta e configura 1-4 pagamenti
**Plans**: TBD
**UI hint**: yes
**Status**: Pending planning
### Phase 17: Proposal AI — Builder, Pagina Pubblica & Email
**Goal**: Un builder AI genera una proposta a partire da cliente + offerta(e) selezionata(e) + note extra; la pagina pubblica `/quote/[token]` è ridisegnata; il link della proposta viene inviato via email (Resend) al lead
**Mode:** ai + ui
**Depends on**: Phase 16
**Requirements**: PROP-01, PROP-02, PROP-05
**Success Criteria** (what must be TRUE):
1. L'admin avvia un builder AI che genera una proposta a partire da cliente + offerta(e) selezionata(e) + note extra fornite manualmente
2. La pagina pubblica `/quote/[token]` è ridisegnata (HTML/CSS) per presentare la proposta generata
3. Il sistema invia via email (Resend) il link della proposta pubblica al lead
**Plans**: TBD
**UI hint**: yes
**Status**: Pending planning
---
## v2.2 — Sales Loop (fasi attive)
### Phase 18: Cleanup & Consolidamento
**Goal**: Sgomberare il campo dai doppioni e dal peso morto prima di costruire il loop di vendita, senza perdere dati.
**Mode:** ui (solo rimozioni/rotte, nessun drop di tabelle)
**Depends on**: nessuna (può partire subito)
**Requirements**: CLEAN-01, CLEAN-02, CLEAN-03, CLEAN-04
**Success Criteria** (what must be TRUE):
1. La pagina Forecast (`/admin/forecast`) e la sua voce di sidebar non esistono più
2. Il quote builder manuale (`/admin/quotes/new`) e il suo entry point non esistono più
3. Le statistiche annuali di `/admin/analytics` sono visibili nella Dashboard `/admin` come vista unica; la rotta `/admin/analytics` è eliminata (nessun doppione)
4. Le fasi v2.1 residue (13/15/16/17) sono marcate cancellate/congelate nel planning
**Plans**: 3 plans
**Plan list**:
- [x] 18-01-PLAN.md — Rimozione Forecast + Quote Builder manuale (CLEAN-01, CLEAN-02)
- [x] 18-02-PLAN.md — Fusione analytics nella Dashboard, eliminazione rotta /admin/analytics (CLEAN-03)
- [x] 18-03-PLAN.md — Verifica CLEAN-04 planning docs + build check + checkpoint visuale
**Status**: ✅ Complete (2026-06-19) — CLEAN-01..04 verificati, build verde
### Phase 19: Pipeline CRM Kanban
**Goal**: I lead si gestiscono in una board Kanban stile Pipedrive con drag-drop tra gli stage; vinto/perso è un cambio-colonna manuale.
**Mode:** ui
**Depends on**: Phase 14 (CRM lead esistente). Riusa `@dnd-kit` (pattern KanbanBoard progetti).
**Requirements**: PIPE-01, PIPE-02
**Success Criteria** (what must be TRUE):
1. I lead sono mostrati in colonne per stage (contacted → qualified → proposal_sent → negotiating → won/lost) con drag-drop che aggiorna `leads.status`
2. La tabella inline-edit esistente resta disponibile come vista alternativa
3. Spostare un lead su "Vinto"/"Perso" è l'azione manuale che ne registra l'esito
**Plans**: 1 plan
**Plan list**:
- [x] 19-01-PLAN.md — LeadsKanbanBoard + LeadsViewToggle + page wiring (PIPE-01, PIPE-02)
**Status**: ✅ Complete (2026-06-19) — board 6 colonne, drag-drop persistente, toggle Lista/Kanban, search integrata
### Phase 20: Knowledge Base Cliente
**Goal**: Memorizzare i transcript datati delle call (multipli per lead/cliente) e mostrarli nel profilo, pronti per essere dati in pasto all'AI.
**Mode:** schema + ui
**Depends on**: Phase 14 (lead) / clienti. Migration a prod via SSH PRIMA del codice dipendente.
**Requirements**: KB-01, KB-02
**Success Criteria** (what must be TRUE):
1. Esiste uno schema additivo `client_transcripts` (lead_id/client_id, testo, data, titolo/tipo, created_at)
2. L'admin incolla un transcript con data dal dettaglio lead/cliente
3. I transcript sono elencati in ordine cronologico nel profilo
**Plans:** 3 plans
Plans:
- [ ] 20-01-PLAN.md — Migration SQL 0009_client_transcripts (BLOCKING checkpoint prod)
- [ ] 20-02-PLAN.md — Schema Drizzle + getTranscripts + addTranscript/deleteTranscript actions
- [ ] 20-03-PLAN.md — TranscriptModal + sezione LeadDetail + wiring page.tsx
**Status**: Planned (2026-06-19) — ready for `/gsd-execute-phase 20`
### Phase 21: Agente AI — generazione preventivo
**Goal**: L'admin seleziona cliente + offerta; l'agente AI (Claude) legge i transcript + i dati dell'offerta e genera una bozza di preventivo personalizzata, che l'admin può rivedere ed editare.
**Mode:** ai + ui
**Depends on**: Phase 20 (transcript) + DB Offerte (Phase 11/12, fatto)
**Requirements**: AI-01, AI-02
**Success Criteria** (what must be TRUE):
1. Dal builder l'admin sceglie cliente + offerta e lancia la generazione
2. L'AI produce una bozza di preventivo che riflette i transcript del cliente e i contenuti dell'offerta
3. L'admin rivede/edita la bozza prima di pubblicarla
**Note**: decisioni di design AI (modello Claude, prompt, storage output) in fase di planning dedicata
**Status**: Pending planning — `/gsd-plan-phase 21`
### Phase 22: Pagina pubblica preventivo + email
**Goal**: Pubblicare la proposta come pagina pubblica a `/preventivo/[slug]`, con accept/reject che si riflette nel CRM, e inviare il link via email.
**Mode:** ui
**Depends on**: Phase 21 (modello dati proposta). Evolve la meccanica di `/quote/[token]`.
**Requirements**: PUB-01, PUB-02, PUB-03
**Success Criteria** (what must be TRUE):
1. La proposta generata è visibile come pagina pubblica HTML/CSS a `/preventivo/[slug]`
2. Il cliente accetta/rifiuta dalla pagina; l'esito è disponibile lato admin per la conferma vinto/perso nel CRM
3. Il link della proposta viene inviato al lead via email (Resend)
**Status**: Pending planning — `/gsd-plan-phase 22`
- [ ] PUB-03 — Invio link preventivo via email Resend
- [ ] PROP-03 — Stripe Payment Link su offerta pubblica
- [ ] PROP-04 — Auto-provisioning cliente/progetto/fasi al "Vinto"
- [ ] AUTH-OTP-01 — Accesso cliente via OTP email (design pronto)
- [ ] Phase 13 — Servizi attivi/ricorrenti post-vendita (congelata, ripescabile)
## Progress
| Phase | Plans | Status | Completed |
|-------|-------|--------|-----------|
| 11. Catalog Database-View UX & Legacy Consolidation | 4/4 | ✅ Done | 2026-06-13 |
| 12. Offer Editor — Tier A/B/C, Tag & Prezzo Pubblico | 5/5 | ✅ Done | 2026-06-18 |
| 13. Workspace — Servizi Attivi | — | ❌ Congelata (v2.2) | — |
| 14. CRM Attio-style & Fix | 3/3 | ✅ Done | 2026-06-14 |
| 15. Dashboard Revenue Stats | — | ❌ Abbandonata (v2.2) | — |
| 16. Proposal AI — Data Foundations & Auto-Provisioning | — | ❌ Ri-scopata (v2.2) | — |
| 17. Proposal AI — Builder, Pagina Pubblica & Email | — | ❌ Ri-scopata (v2.2) | — |
| 18 (R1). Cleanup & Consolidamento | 3/3 | ✅ Done | 2026-06-19 |
| 19 (R2). Pipeline CRM Kanban | 1/1 | ✅ Done | 2026-06-19 |
| 20 (R3). Knowledge Base Cliente (transcript) | 3 plans | Planned (2026-06-19) | — |
| 21 (R4). Agente AI — generazione preventivo | — | Pending planning | — |
| 22 (R5). Pagina pubblica preventivo + email | — | Pending planning | — |
| Phase | Milestone | Plans | Status | Completed |
|-------|-----------|-------|--------|-----------|
| 16. Foundation → UX Overhaul | v1.0 | 24/24 | ✅ Done | 2026-06-10 |
| 710. Unified Catalog → CRM Pipeline | v2.0 | 12/12 | ✅ Done | 2026-06-13 |
| 11. Catalog Database-View UX | v2.1 | 4/4 | ✅ Done | 2026-06-13 |
| 12. Offer Editor Tier A/B/C | v2.1 | 5/5 | ✅ Done | 2026-06-18 |
| 13. Workspace Servizi Attivi | v2.1 | — | ❌ Congelata | — |
| 14. CRM Attio-style & Fix | v2.1 | 3/3 | ✅ Done | 2026-06-14 |
| 15. Dashboard Revenue Stats | v2.1 | — | ❌ Abbandonata | — |
| 1617. Proposal AI originale | v2.1 | — | ❌ Ri-scopata in v2.2 | — |
| 18. Cleanup & Consolidamento | v2.2 | 3/3 | ✅ Done | 2026-06-19 |
| 19. Pipeline CRM Kanban | v2.2 | 1/1 | ✅ Done | 2026-06-19 |
| 20. Knowledge Base Cliente | v2.2 | 3/3 | ✅ Done | 2026-06-20 |
| 21. Agente AI Preventivo | v2.2 | 1/1 | ✅ Done | 2026-06-20 |
| 22. Pagina Pubblica + Deck | v2.2 | 1/1 | ✅ Done | 2026-06-20 |
| 23+. v2.3 TBD | v2.3 | TBD | 📋 Planned | — |
+7 -7
View File
@@ -2,16 +2,16 @@
gsd_state_version: 1.0
milestone: v2.2
milestone_name: — Sales Loop
status: executing
stopped_at: "Phase 21+22 codice completopending: (1) migration 0010 a prod via SSH tunnel; (2) dati reali in profile.ts"
last_updated: "2026-06-20T14:00:00.000Z"
last_activity: 2026-06-20 -- Phase 21+22 eseguite insieme — agente AI Opus 4.8 + deck pubblico 20+ slide + entry point LeadDetail + sidebar globale
status: complete
stopped_at: "v2.2 completatutto in prod. Backlog: PUB-03 email Resend, PROP-03 Stripe, PROP-04 auto-provisioning"
last_updated: "2026-06-20T16:30:00.000Z"
last_activity: 2026-06-20 -- v2.2 chiusa — 5/5 fasi complete, REQUIREMENTS aggiornati, SUMMARY.md scritti per 21+22
progress:
total_phases: 5
completed_phases: 4
completed_phases: 5
total_plans: 7
completed_plans: 6
percent: 80
completed_plans: 7
percent: 100
---
# Project State
+73
View File
@@ -0,0 +1,73 @@
# Requirements Archive — v2.2 Sales Loop
**Archived:** 2026-06-20
**Milestone:** v2.2 Sales Loop (Phases 1822)
**Outcome:** 10/11 requirements Complete · 1 deferred (PUB-03 email Resend)
---
## v2.2 — Sales Loop Requirements
### Cleanup & Consolidamento (Phase 18 / R1)
| ID | Requirement | Outcome |
|----|-------------|---------|
| CLEAN-01 | Pagina Forecast + voce sidebar rimossa | ✅ Complete — Phase 18-01 |
| CLEAN-02 | Quote builder manuale rimosso | ✅ Complete — Phase 18-01 |
| CLEAN-03 | Analytics fusa nella Dashboard, rotta duplicata eliminata | ✅ Complete — Phase 18-02 |
| CLEAN-04 | Fasi v2.1 residue archiviate nel planning | ✅ Complete — Phase 18-03 |
### Pipeline CRM Kanban (Phase 19 / R2)
| ID | Requirement | Outcome |
|----|-------------|---------|
| PIPE-01 | Board Kanban Pipedrive-style con drag-drop tra stage | ✅ Complete — Phase 19-01 |
| PIPE-02 | Vinto/Perso come cambio-colonna manuale | ✅ Complete — Phase 19-01 |
### Knowledge Base Cliente (Phase 20 / R3)
| ID | Requirement | Outcome |
|----|-------------|---------|
| KB-01 | Schema additivo `client_transcripts` con migration a prod | ✅ Complete — Phase 20-01/02 |
| KB-02 | UI incolla/elenca transcript nel dettaglio lead | ✅ Complete — Phase 20-03 |
### Agente AI — Generazione Preventivo (Phase 21 / R4)
| ID | Requirement | Outcome |
|----|-------------|---------|
| AI-01 | Admin seleziona cliente+offerta; AI legge transcript+offerta → bozza | ✅ Complete — Phase 21-01 |
| AI-02 | Admin rivede ed edita la bozza prima di pubblicare | ✅ Complete — Phase 21-01 |
### Pagina Pubblica Preventivo (Phase 22 / R5)
| ID | Requirement | Outcome |
|----|-------------|---------|
| PUB-01 | Pagina pubblica `/preventivo/[slug]` — deck 20+ slide | ✅ Complete — Phase 22-01 |
| PUB-02 | Cliente accetta/rifiuta; esito riflesso nel DB | ✅ Complete — Phase 22-01 |
| PUB-03 | Invio link via email Resend | ❌ Not implemented — deferred to v2.3 backlog |
---
## Backlog Portato Avanti
| ID | Requirement | Stato |
|----|-------------|-------|
| PUB-03 | Email Resend invio link preventivo | Deferred → v2.3 |
| PROP-03 | Stripe Payment Link su offerta | Backlog (post-R5 originale) |
| PROP-04 | Auto-provisioning al "Vinto" | Backlog (post-R5 originale) |
| AUTH-OTP-01 | Accesso cliente via OTP email | Design pronto, deferred |
| OFFER-12 | Import CSV/Notion one-shot | Rimandato 2026-06-14 |
---
## Requirements Non-v2.2 (Storico)
*I requirements di v1.0 e v2.0/v2.1 sono archiviati in:*
- `.planning/milestones/v1.0-REQUIREMENTS.md`
- `.planning/milestones/v2.0-REQUIREMENTS.md`
*I requirements congelati/abbandonati di v2.1 (PROJ-06..10, DASH-11, PROP-01..05) sono documentati in `.planning/milestones/v2.2-ROADMAP.md` sezione "Milestone Summary".*
---
*Archived: 2026-06-20 at v2.2 milestone close*
+144
View File
@@ -0,0 +1,144 @@
# Milestone v2.2: Sales Loop
**Status:** ✅ SHIPPED 2026-06-20
**Phases:** 1822 (R1R5)
**Total Plans:** 9 plans · 27 commits · 87 files · +7.349/-842 righe
**Timeline:** 2026-06-19 → 2026-06-20
## Overview
v2.2 chiude il **loop di vendita end-to-end**: dopo che l'utente ha articolato il flusso commerciale reale (piano `.claude/plans/glittery-sprouting-pudding.md`), le fasi residue v2.1 (13/15/16/17) sono state congelate/abbandonate e sostituite da 5 fasi nuove. Il flusso: lead in pipeline Kanban → transcript datati delle call → agente AI genera preventivo → deck pubblico 20+ slide → accept/reject manuale nel CRM.
## Phases
### Phase 18: Cleanup & Consolidamento (R1)
**Goal**: Sgomberare il campo dai doppioni e dal peso morto prima di costruire il loop di vendita.
**Mode:** ui (solo rimozioni/rotte, nessun drop di tabelle)
**Requirements**: CLEAN-01, CLEAN-02, CLEAN-03, CLEAN-04
**Plans**: 3 plans
Plans:
- [x] 18-01-PLAN.md — Rimozione Forecast + Quote Builder manuale (CLEAN-01, CLEAN-02)
- [x] 18-02-PLAN.md — Fusione analytics nella Dashboard, eliminazione rotta /admin/analytics (CLEAN-03)
- [x] 18-03-PLAN.md — Verifica CLEAN-04 planning docs + build check + checkpoint visuale
**Status**: ✅ Complete (2026-06-19)
**What was built:**
- Rimossa pagina `/admin/forecast` + voce sidebar
- Rimosso quote builder manuale `/admin/quotes/new` + SendQuoteModal rami irraggiungibili
- Statistiche annuali `/admin/analytics` fuse nella Dashboard `/admin` (CLEAN-03); rotta duplicata eliminata
- Fasi v2.1 residue (13/15/16/17) marcate cancellate/congelate nel planning
---
### Phase 19: Pipeline CRM Kanban (R2)
**Goal**: I lead si gestiscono in una board Kanban stile Pipedrive con drag-drop tra gli stage.
**Mode:** ui
**Depends on**: Phase 14 (CRM lead esistente). Riusa `@dnd-kit`.
**Requirements**: PIPE-01, PIPE-02
**Plans**: 1 plan
Plans:
- [x] 19-01-PLAN.md — LeadsKanbanBoard + LeadsViewToggle + page wiring (PIPE-01, PIPE-02)
**Status**: ✅ Complete (2026-06-19)
**What was built:**
- Board Kanban 6 colonne (contacted → qualified → proposal_sent → negotiating → won/lost) con drag-drop persistente
- Toggle Lista/Kanban con ricerca integrata
- Spostare un lead su "Vinto"/"Perso" aggiorna `leads.status` → registra l'esito manuale
---
### Phase 20: Knowledge Base Cliente (R3)
**Goal**: Memorizzare i transcript datati delle call e mostrarli nel profilo lead.
**Mode:** schema + ui
**Depends on**: Phase 14 (lead). Migration a prod via SSH.
**Requirements**: KB-01, KB-02
**Plans**: 3 plans
Plans:
- [x] 20-01-PLAN.md — Migration SQL `0009_client_transcripts` (BLOCKING prod checkpoint)
- [x] 20-02-PLAN.md — Schema Drizzle `clientTranscripts` + `getTranscripts`/`addTranscript`/`deleteTranscript`
- [x] 20-03-PLAN.md — `TranscriptModal` + sezione "Transcript Call" in `LeadDetail` + wiring `page.tsx`
**Status**: ✅ Complete (2026-06-20)
**What was built:**
- Tabella `client_transcripts` (lead_id, client_id, content, call_date, title, created_at) applicata a prod via SSH tunnel
- Data layer completo con Drizzle ORM + server actions
- UI: sezione "Transcript Call" nel dettaglio lead con modal per incollare, lista espandibile/collassabile, elimina
---
### Phase 21: Agente AI — Generazione Preventivo (R4)
**Goal**: Admin seleziona cliente+offerta; AI legge transcript+offerta → genera bozza preventivo.
**Mode:** ai + ui
**Depends on**: Phase 20 (transcript) + Phase 11/12 (offerte)
**Requirements**: AI-01, AI-02
**Plans**: 1 plan (21+22 eseguiti insieme per coerenza architetturale)
Plans:
- [x] 21-01-PLAN.md — Agente AI + form builder admin + migration 0010 proposals
**Status**: ✅ Complete (2026-06-20)
**What was built:**
- `@anthropic-ai/sdk@0.105.0` + `ANTHROPIC_API_KEY` in Coolify
- `src/lib/proposal/schema.ts` — Zod schema `ProposalContent` (20+ sezioni strutturate)
- `src/lib/proposal/agent.ts``generateProposalContent()` → Claude Opus 4.8, JSON validato Zod
- `src/lib/proposal/assemble.ts``assembleProposal()`: fonde AI + offerta DB + profilo consulente
- `src/lib/proposal/profile.ts``CONSULTANT_PROFILE` (bio, fatti, testimonianze, legal, nextSteps)
- `proposals` table in DB: id, slug, lead_id, client_id, offer_macro_id, content jsonb, state, accepted_at
- Admin pages: lista preventivi, form genera (con pre-fill `?lead_id=X`), review bozza, pubblica/elimina
---
### Phase 22: Pagina Pubblica Preventivo + Email (R5)
**Goal**: Pubblicare la proposta come deck pubblico `/preventivo/[slug]` con accept/reject.
**Mode:** ui
**Depends on**: Phase 21 (proposals table + content)
**Requirements**: PUB-01, PUB-02 ✅ · PUB-03 ❌ deferred
**Plans**: 1 plan
Plans:
- [x] 22-01-PLAN.md — ProposalDeck + public page + accept/reject actions
**Status**: ✅ Complete (2026-06-20) · PUB-03 deferred
**What was built:**
- `src/app/preventivo/[slug]/page.tsx` — server component pubblico con gestione stati
- `src/app/preventivo/[slug]/actions.ts``acceptProposal` + `rejectProposal` con `accepted_at` immutabile
- `ProposalDeck.tsx` — deck client component: `h-screen overflow-hidden`, keyboard nav, dots
- 20 componenti slide: Cover, Vision, Index, ChapterDivider ×5, Strategist, Facts, Testimonials, ProblemNode ×N, SynthesisDiagram, SolutionNode ×N, SolutionSynthesis, Scope, Deliverables, Timeline, Pricing, StagesRecap, ComparisonMatrix, NextSteps, Accept, Closing
- **PUB-03 (email Resend) NOT implemented** — link va condiviso manualmente; deferred a v2.3 backlog
---
## Milestone Summary
**Key Decisions:**
- Sales Loop come north-star v2.2: abbandonato workspace post-vendita (Phase 13), revenue stats (Phase 15), Proposal AI v2.1 (16/17) — riscopate come 21+22 con transcript
- AI model: `claude-opus-4-8` per qualità copywriting strategico (~$0.44/preventivo)
- Output AI: JSON strutturato validato Zod → template fisso → coerenza visiva garantita
- `proposals.content` come JSONB snapshot (non riferimento a entità live) → immutabile
- Email Resend (PUB-03) deferred: scope minimo funziona, priorità al loop core
**Known Gaps at Close:**
- PUB-03: invio email Resend non implementato (1 item, vedi backlog v2.3)
- `profile.ts`: testimonianze placeholder, da aggiornare con dati reali
**Technical Debt:**
- Tabelle legacy `service_catalog`/`offer_services`/`offer_micro_services` ancora presenti (deadweight, cleanup futuro)
- `createService`/`serviceSchema` dead code in `catalog/actions.ts`
- `drizzle-kit generate` rotto da Phase 8 (meta snapshots out of sync) — SQL scritto a mano
---
*Per lo stato corrente del progetto, vedi `.planning/ROADMAP.md`*
@@ -0,0 +1,53 @@
---
phase: 21-agente-ai-generazione-preventivo
plan: "01"
status: complete
completed_at: "2026-06-20"
requirements_satisfied:
- AI-01
- AI-02
---
# Plan 21-01 Summary: Agente AI — Generazione Preventivo
## What Was Built
Sistema completo di generazione preventivo AI: l'admin seleziona un lead/cliente e un'offerta, il sistema legge i transcript della call e chiama Claude Opus 4.8 per generare una bozza di preventivo strutturata in JSON. La bozza viene salvata nel DB come `draft`, l'admin la rivede e la pubblica.
## Key Files
### Created
- `src/lib/proposal/schema.ts` — Zod schema `ProposalContent` (vision, problems 3-5, solutions, scope, deliverables, timeline, stagesRecap, comparisonMatrix)
- `src/lib/proposal/agent.ts``generateProposalContent()`: chiama Claude Opus 4.8, valida output Zod, gestisce JSON wrapping in backtick
- `src/lib/proposal/assemble.ts``assembleProposal()`: fonde content AI + offerta DB (snapshot prezzi) + profilo consulente in `AssembledProposal`
- `src/lib/proposal/profile.ts``CONSULTANT_PROFILE`: fonte di verità statica (bio, facts, testimonianze, legal, nextSteps) — editare direttamente per aggiornare
- `src/lib/proposal/queries.ts``listProposals`, `getProposalById`, `getProposalBySlug` con join leads/clients/offer_macros
- `src/app/admin/preventivi/actions.ts``generateProposalDraft`, `publishProposal`, `updateProposalTitle`, `deleteProposal` (server actions)
- `src/app/admin/preventivi/page.tsx` — lista preventivi admin con stato (bozza/pubblicato/accettato/rifiutato)
- `src/app/admin/preventivi/genera/page.tsx` + `GeneraProposalForm.tsx` — form builder con pre-fill `?lead_id=X` da LeadDetail
- `src/app/admin/preventivi/[id]/page.tsx` — review bozza: titolo editabile, pubblica, elimina
- `src/db/migrations/0010_proposals.sql``CREATE TABLE IF NOT EXISTS proposals` (id, slug, lead_id, client_id, offer_macro_id, title, content jsonb, model, state, selected_tier, accepted_at immutabile, client_email, client_notes)
### Modified
- `src/db/schema.ts` — tabella `proposals` + `proposalsRelations` + tipi `Proposal`/`NewProposal`
- `src/components/admin/AdminSidebar.tsx` — voce "Preventivi" + CTA globale lime "Genera preventivo"
- `src/components/admin/leads/LeadDetail.tsx` — pulsante "Genera preventivo" → `/admin/preventivi/genera?lead_id=X`
## Architecture Decisions
| Decisione | Scelta | Motivo |
|-----------|--------|--------|
| Output AI | JSON strutturato → Zod validate | Coerenza visiva garantita, zero rischio HTML rotto |
| Storage | `content jsonb` snapshot completo | Parser automatico postgres-js, type-safe, immutabile |
| Profile | File `profile.ts` hardcoded | No UI necessaria v1, editing diretto semplice |
| Modello | `claude-opus-4-8` | Qualità copywriting strategico superiore |
## Requirements Verified
- AI-01: ✅ Admin seleziona cliente+offerta → AI legge transcript + offerta → genera bozza personalizzata
- AI-02: ✅ Admin rivede ed edita il titolo della bozza, la pubblica o elimina prima dell'invio
## Post-Deploy Steps Completed
- Migration 0010 applicata a prod via SSH tunnel (2026-06-20 14:29)
- `ANTHROPIC_API_KEY` configurata in Coolify (2026-06-20 — fix chiave invalida)
@@ -0,0 +1,56 @@
---
phase: 22-pagina-pubblica-preventivo
plan: "01"
status: complete
completed_at: "2026-06-20"
requirements_satisfied:
- PUB-01
- PUB-02
known_gaps:
- PUB-03 (email Resend — non implementata, deferred to backlog)
---
# Plan 22-01 Summary: Pagina Pubblica Preventivo + Deck
## What Was Built
Pagina pubblica `/preventivo/[slug]` che presenta la proposta generata come deck interattivo di 20+ slide navigabili (frecce, tasti keyboard, dot navigator). Il cliente sceglie il tier A/B/C e accetta/rifiuta dalla pagina; l'esito si riflette nel DB con `accepted_at` immutabile. PUB-03 (invio email Resend) non implementato — il link va condiviso manualmente.
## Key Files
### Created
- `src/app/preventivo/[slug]/page.tsx` — server component pubblico; gestisce stati: draft (blocca accesso), published (mostra + accept), accepted/rejected (mostra con stato)
- `src/app/preventivo/[slug]/actions.ts``acceptProposal` (guard `accepted_at` immutabile + `selected_tier` validato A/B/C), `rejectProposal`
- `src/components/public/proposal/ProposalDeck.tsx` — deck client component: navigazione keyboard (←/→), dot cliccabili, topbar fissa (titolo + counter), bottombar fissa (frecce + dots); `h-screen overflow-hidden` per 100vh per slide
- `src/components/public/proposal/sections/` — 20 componenti slide:
- CoverSection, VisionSection, IndexSection
- ChapterDivider (×5), StrategistSection, FactsSection, TestimonialsSection
- ProblemNodeSection, SynthesisDiagramSection
- SolutionNodeSection, SolutionSynthesisSection
- ScopeSection, DeliverablesSection, TimelineSection
- PricingSection, StagesRecapSection, ComparisonMatrixSection
- NextStepsSection, AcceptSection, ClosingSection
## Architecture Decisions
| Decisione | Scelta | Motivo |
|-----------|--------|--------|
| Layout | `h-screen overflow-hidden` per slide | Nessun scroll di pagina, navigazione slide-by-slide |
| Navigazione | Keyboard + dots + click frecce | Universale, funziona su desktop e touch |
| Accettazione | `accepted_at` immutabile (guard server action) | Pattern coerente con `deliverables.approved_at` |
| Tier selezione | Radio A/B/C prima dell'accettazione | Cliente sceglie l'opzione, l'esito è univoco |
| Email | Non implementata (PUB-03) | Scope minimo, link condiviso manualmente per ora |
## Requirements Verified
- PUB-01: ✅ Proposta visibile come pagina pubblica HTML a `/preventivo/[slug]`, deck 20+ slide
- PUB-02: ✅ Cliente accetta/rifiuta dalla pagina; `state` + `accepted_at` + `selected_tier` aggiornati nel DB; admin vede esito nella lista preventivi
## Known Gap
- **PUB-03 — Email Resend**: il link preventivo non viene inviato automaticamente. Va copiato dall'admin e condiviso manualmente (es. via WhatsApp/email). Da implementare nella prossima milestone come prima feature.
## Fix Post-Deploy
- 2026-06-20: fix `h-screen overflow-hidden` su tutte le slide (erano `min-h-screen`, causavano scroll di pagina)
- 2026-06-20: `ANTHROPIC_API_KEY` mancante in Coolify — aggiunta via PHP artisan + redeploy