# 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ì*