- Rename src/app/c/[token] → src/app/client/[token] - Update proxy.ts, ClientRow, admin client detail with /client/ path - Add output: "standalone" to next.config.ts for Docker build - Add Dockerfile (multi-stage, node:20-alpine) and .dockerignore - Push schema to Coolify Postgres via SSH tunnel (drizzle-kit push ✓) - Update CLAUDE.md constraint 4 to reflect /client/ route - Add Phase 4 planning artifacts (04-00, 04-RESEARCH, 04-PATTERNS) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
7.2 KiB
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 keyclients.accepted_totaldenormalizzato: la client API non tocca maiquote_itemsdeliverables.approved_atcome audit trail immutabile dal giorno unopaymentssempre due righe per cliente (acconto + saldo), create alla finalizzazione del preventivoClientVieweAdminViewsono tipi distinti lato server — privacy enforce a livello di query, non di UI
Pitfall Critici
- Token = primary key (non rotazionabile) — Usa UUID stabile come PK e campo
tokenseparato e aggiornabile. Deve essere nella schema della Fase 1; non si può correggere dopo che i link sono stati distribuiti. - Client API espone
quote_items(nascosti solo nell'UI) — DefinisciClientViewcome tipo server-side che non interroga maiquote_items. Un cliente tecnico con DevTools non deve mai vedere i prezzi singoli. - 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.
- Nessun record di approvazione immutabile — Salva
approved_at(timestamp, non solo boolean) dallo schema iniziale. - Area admin senza vera autenticazione — Il check Middleware su
ADMIN_PASSWORDenv 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ì