Files
clienthub/.planning/PROJECT.md
T
simone f7eb7eec23 docs(planning): archivia v2.1/v2.2/v2.3 e documenta v2.4
.planning/ documentava in dettaglio cio che era vecchio e per niente cio
che e in produzione: le fasi 11-22 (v2.1 e v2.2, chiuse a giugno) erano
ancora in phases/ mentre v1.0 e v2.0 stavano gia in milestones/, e il
lavoro degli ultimi due mesi - gate OTP e ciclo di vita dei retainer, cioe
quello che gira su hub.iamcavalli.net - non aveva nessuna cartella.

- phases/{11,12,14} -> milestones/v2.1-phases/, phases/{18..22} ->
  milestones/v2.2-phases/. Ora phases/ contiene solo la milestone in
  corso, che e quello che state.cjs conta per il progresso
- v2.1-ROADMAP.md ricostruito: era l'unica milestone senza archivio,
  interrotta dal reset del 19/06 e mai chiusa formalmente
- v2.3-ROADMAP.md + v2.3-REQUIREMENTS.md: v2.3 e stata eseguita fuori dal
  ciclo GSD, non esistono PLAN/SUMMARY per fase. L'archivio E la doc
- REQUIREMENTS.md riscritto per v2.4 con il backlog reale
- phases/13 e phases/26: SUMMARY ricostruiti da commit, migration e
  STATUS.md. 26 e il primo numero libero
- research/: cancellate 4 varianti dello stesso PITFALLS e FEATURES/
  SUMMARY, superati da PROJECT.md. Diverse anti-feature erano ormai
  contraddette dai fatti (il Kanban e stato costruito in Phase 19,
  l'email in v2.3, il time tracking esiste)
- cancellati UI-RULES.md e DESIGN-SYSTEM.md (CLAUDE.md li dichiara
  superseded: impongono l'inverso della regola attuale) e HANDOFF.md,
  fermo al 13/06
- SECURITY-*.md -> security/: audit chiuso, ma i report restano la doc di
  cosa e stato ruotato e perche
- PROJECT.md/MILESTONES.md/ROADMAP.md allineati: milestone corrente v2.4,
  sessione OTP 90gg non 30, migrazioni fino alla 0016

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 22:38:36 +02:00

148 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.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/C → vinto/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.4 Post-vendita
**Goal:** Chiudere il ciclo di vita di ciò che è già venduto — un retainer deve poter finire, e l'admin deve poter vedere il portale con gli occhi del cliente.
**Consegnato (in produzione):**
- Phase 13 — Ciclo di vita dei servizi ricorrenti (RET-01..05), prod 2026-08-01
- Phase 26 — Anteprima admin del portale + toggle password sul login (PREV-01/02, AUTH-09), prod 2026-08-08
**Backlog:** RET-06 (canoni mensili tracciabili), SEND-01/02 (invio preventivo via email), PROP-03 (Stripe Payment Link), PROP-04 (auto-provisioning al "Vinto"), DEBT-01 (debito design). Elenco completo in `REQUIREMENTS.md`.
## Requirements
### Validated
Shipped in v1.0 (Phases 16, 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 710, 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<any>`; `SendQuoteModal`/`assignQuoteToLead` senza rami di codice irraggiungibili — Phase 14 (CRM-08, CRM-09, CRM-10, CRM-11, CRM-12)
Validated in v2.2 Sales Loop (shipped 2026-06-20):
- ✓ 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)
Validated in v2.3 Email & Accesso (shipped 2026-07-29):
- ✓ Gate OTP sul portale cliente: whitelist `client_emails`, codice 6 cifre via Resend, sessione firmata **90 giorni** (non 30: modificata il 2026-07-28), revoca in blocco dall'admin — Phase 23/24/25 (OTP-01..08). Migr. 0015.
- ✗ PUB-03 / SEND-01/02 (invio preventivo via email) **non consegnato**: rinviato al backlog il 2026-07-28. Il preventivo si manda a mano; l'infrastruttura Resend è comunque in prod.
Validated in v2.4 Post-vendita (in produzione):
- ✓ Ciclo di vita dei servizi ricorrenti: `project_offers.status` + `end_date`, forecast che si ferma, comandi Sospendi/Riattiva/Cessa, stato visibile al cliente — Phase 13 (RET-01..05). Migr. 0016.
- ✓ Anteprima admin in sola lettura del portale cliente + toggle password sul login — Phase 26 (PREV-01/02, AUTH-09).
### Active
Nessun requisito in lavorazione. Il prossimo va scelto dal backlog in `REQUIREMENTS.md`.
### 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
- 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) + `/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: migrazioni applicate a prod fino alla **0016**; `proposals` con `content jsonb` snapshot; `client_transcripts` per lead; `client_emails`/`otp_codes` per il gate OTP
- Migrations sono manuali: SQL a mano applicato via **SSH + docker exec** PRIMA di pushare il codice schema-dipendente (procedura in `CLAUDE.md`); `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
- **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**: progressiva e mai riusata — v1.0 16, v2.0 710, v2.1 1117 (13/15/16/17 mai eseguite), v2.2 1822, v2.3 2325, v2.4 13 (ripresa dal congelamento) + 26
## 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é | ✓ 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) |
| 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 | ✓ 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 | ✓ 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 — rinviata di nuovo il 2026-07-28, il mailer però è in prod |
| Il gate OTP sta in cima alla `page`, mai nel layout | Nell'App Router il `page` è renderizzato in parallelo al layout: gattare nel layout lascia i dati nel payload RSC | ✓ Good — verificato: 46.907 → 17.594 byte di HTML |
| Sessione OTP a 90 giorni invece di 30 | Rientro più fluido per il cliente, compensato dalla revoca in blocco lato admin (OTP-08) | ✓ Good — in prod dal 2026-07-29 |
| Storico di vendita ≠ forecast | `getOffersSoldBreakdown` non filtra per stato: escludere le offerte cessate riscriverebbe il fatturato passato | ✓ Good — Phase 13 |
| Anteprima admin del portale in sola lettura | Le API client autenticano sul token nel body, non sulla sessione: un click distratto approverebbe un deliverable, e `approved_at` è immutabile (LOCKED #3) | ✓ Good — protezione a livello UI, deviazione da LOCKED #4 accettata (Phase 26) |
## 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-08-08 — v2.3 archiviata, v2.4 Post-vendita corrente (Phase 13 + 26 in produzione)*