# Project Research Summary

**Project:** ClientHub — welcomeclient.iamcavalli.net
**Domain:** Freelancer client portal (secret-link access, solo consultant)
**Researched:** 2026-05-09
**Confidence:** HIGH

---

## Executive Summary

ClientHub è un portale web a due ruoli per un consulente di personal branding. I clienti accedono via UUID segreto casuale — nessun account, nessun login, zero attrito. L'admin gestisce tutto: crea clienti, fasi, task, deliverable, pagamenti e preventivi. Il consensus della ricerca è chiaro: costruisci prima la dashboard cliente, poi l'admin CRUD, poi catalogo servizi e preventivi, poi il flusso Claude AI (v2).

Stack confermato: **Next.js 15 + Neon (Postgres) + Drizzle ORM + Auth.js + nanoid + Tailwind v4 + shadcn/ui**. Ogni scelta è ottimizzata per un developer solo su Vercel: nessun backend da mantenere, nessun costo di connection pooling, nessuna infrastruttura di upload file, nessuna libreria di auth per i clienti. Il meccanismo "secret link" è un Next.js Middleware edge check — veloce, zero client JS, 404 se il token non esiste.

I rischi dominanti sono architetturali, non tecnici. Se il token è la primary key diventa non-rotazionabile. Se la client API restituisce `quote_items` (anche nascosti nell'UI), un cliente con DevTools vede i prezzi dei singoli servizi. Se il progetto parte dal flusso Claude prima che un cliente possa aprire la sua dashboard, il portale non esce. Tutti e tre prevenibili con le decisioni corrette sul data model dal giorno uno.

---

## Key Findings

### Stack Raccomandato

| Tecnologia | Ruolo | Perché |
|------------|-------|--------|
| Next.js 15 (App Router) | Framework full-stack | Server Actions sostituiscono un'API REST separata; nativo Vercel |
| Neon (serverless Postgres) | Database principale | Free tier (0.5 GB, 100 CU-h/mese) sufficiente per 5–20 clienti; scala a zero |
| Drizzle ORM + neon-http | Accesso DB + migrazioni | Nessun costo di connection pooling; schema-as-code; inferenza TypeScript end-to-end |
| Auth.js v4 (Credentials) | Sessione admin | Account singolo, cookie JWT firmato, nessuna tabella utenti in DB |
| nanoid | Generazione token | 21 char, ~126 bit di entropia, URL-safe, crittograficamente sicuro |
| Tailwind v4 + shadcn/ui | UI | Componenti copiati nel codebase, accessibilità Radix UI, zero runtime dep |
| Zod + React Hook Form | Validazione e form | Schema unico; RHF solo per form admin complessi |

File upload deliberatamente esclusi dalla v1. I link ai documenti sono campi testo che puntano a Google Drive.

### Features v1

**Table stakes (obbligatori):**
- Panoramica progetto (nome, brand, brief, fase corrente)
- Visibilità fasi e task con stato (todo / in corso / fatto)
- Approvazione deliverable con timestamp immutabile
- Commenti inline su task e deliverable (lista piatta, no threading)
- Link a documenti esterni (solo URL, no file hosting)
- Stato pagamenti: acconto 50% + saldo 50% (da saldare / inviata / saldato)
- Totale preventivo accettato visibile al cliente (cifra unica, mai dettaglio)
- Layout mobile-ready
- Link segreto persistente e non-scadente

**Differenziatori (low-effort, includibili in v1):**
- Log decisioni / storico (nota append-only)
- Indicatore di avanzamento fase (derivato da % task completati)
- Timestamp "ultimo aggiornamento" sulla dashboard
- Vista admin: tutti i clienti con badge stato pagamenti
- Reset link segreto (single UPDATE, solo admin)

**Anti-features (mai costruire):** login cliente, PDF fatture in-app, multi-admin, struttura progetto modificabile dal cliente, prezzi singoli visibili al cliente, kanban board.

### Architettura

Singola applicazione Next.js su Vercel, un database Neon Postgres. Nessun backend separato.

**Due path di accesso isolati:**
- `/c/[token]/*` → Middleware valida il token contro Neon, 404 se mancante
- `/admin/*` → Auth.js session check, singolo account admin

**Decisioni chiave del data model:**
- `clients.token` è un campo separato e rotazionabile — **non** la primary key
- `clients.accepted_total` denormalizzato: la client API non tocca mai `quote_items`
- `deliverables.approved_at` come audit trail immutabile dal giorno uno
- `payments` sempre due righe per cliente (acconto + saldo), create alla finalizzazione del preventivo
- `ClientView` e `AdminView` sono tipi distinti lato server — privacy enforce a livello di query, non di UI

### Pitfall Critici

1. **Token = primary key (non rotazionabile)** — Usa UUID stabile come PK e campo `token` separato e aggiornabile. Deve essere nella schema della Fase 1; non si può correggere dopo che i link sono stati distribuiti.
2. **Client API espone `quote_items` (nascosti solo nell'UI)** — Definisci `ClientView` come tipo server-side che non interroga mai `quote_items`. Un cliente tecnico con DevTools non deve mai vedere i prezzi singoli.
3. **Over-engineering prima che un cliente usi il portale** — Criterio di successo duro per la Fase 1: un link cliente reale è condivisibile e funziona. Non iniziare il flusso Claude prima che l'admin possa creare un cliente e il cliente possa aprire la sua dashboard.
4. **Nessun record di approvazione immutabile** — Salva `approved_at` (timestamp, non solo boolean) dallo schema iniziale.
5. **Area admin senza vera autenticazione** — Il check Middleware su `ADMIN_PASSWORD` env var deve essere in place prima che la Fase 2 vada in produzione.

---

## Implicazioni per la Roadmap

### Struttura suggerita: 4 fasi

**Fase 1 — Foundation: DB schema, token API, dashboard cliente**
Consegna: un link cliente reale condivisibile che mostra il progetto su mobile e desktop.
Copre: panoramica, fasi/task, pagamenti, documenti, link segreto, DNS.

**Fase 2 — Admin CRUD + auth + commenti + approvazioni**
Consegna: admin crea/modifica clienti, fasi, task, deliverable, pagamenti. Cliente commenta e approva. Admin può rigenerare il link.
Copre: auth Middleware, CRUD completo, flow approvazione con timestamp, commenti lista piatta.

**Fase 3 — Catalogo servizi + preventivi**
Consegna: admin costruisce catalogo riutilizzabile e compone preventivi da esso. `accepted_total` scritto sulla riga cliente.
Nessuna dipendenza client-facing oltre `accepted_total` (già in schema dalla Fase 1).

**Fase 4 (v2) — Flusso Claude AI per onboarding**
Dipende da CRUD stabile + catalogo completo. Claude legge il brief e suggerisce fasi + preventivo.
*Richiede ricerca dedicata durante la pianificazione.*

### Flag di ricerca
- Fasi 1–3: pattern standard, nessuna ricerca aggiuntiva necessaria
- Fase 4: richiede ricerca su Claude API structured output, streaming vs batch, prompt engineering per generazione fasi

---

## Confidence Assessment

| Area | Confidence | Note |
|------|------------|------|
| Stack | HIGH | Tutte le tecnologie stabili e in produzione |
| Features | HIGH | Feature set opinionated e ben delimitato |
| Architettura | HIGH | Data model completo, pattern two-path auth provato |
| Pitfall | HIGH | Tutti mappabili a decisioni concrete della Fase 1 |

**Domande aperte (da risolvere durante la pianificazione delle fasi):**
- Access log per i link (utile per rilevare accessi non autorizzati)?
- Approvazioni reversibili (admin-only revoke)?
- Log decisioni visibile al cliente dalla v1 o solo admin?
- DNS: configurare e verificare la propagazione nella Fase 1

---

*Ricerca completata: 2026-05-09 | Pronto per la roadmap: sì*