Files
clienthub/.planning/phases/04-progetti-multi-project/04-CONTEXT.md
T

9.9 KiB
Raw Blame History

Phase 4: Progetti — Multi-Project per Cliente - Context

Gathered: 2026-05-20 Status: Ready for planning

## Phase Boundary

Ristrutturazione del modello dati per supportare N progetti per cliente. Un cliente può avere più brand/progetti; ogni progetto ha il proprio workspace (fasi, task, pagamenti, preventivo, timer). Il timer si sposta dal livello cliente al livello progetto. La dashboard cliente mostra i suoi progetti con tabs se multipli. Il link cliente diventa personalizzabile tramite slug opzionale.

Sostituisce la Fase 4 AI Onboarding (spostata a Fase 5) perché è prerequisito architetturale per tutto ciò che viene dopo.

Tutti i dati attuali sono di test — nessuna migrazione soft necessaria. Schema ricreato da zero dove serve.

## Implementation Decisions

Modello dati

  • D-01: Nuova tabella projects con campi: id, client_id (FK → clients), name (nome brand/progetto), archived (bool), created_at. Nessun accepted_total diretto — viene calcolato/denormalizzato dai quote_items a livello progetto.
  • D-02: Le seguenti tabelle spostano la FK da client_id a project_id: phases, payments, quote_items, time_entries, documents, notes. La tabella comments rimane su entity_id generico — invariata.
  • D-03: clients perde i campi che diventano di pertinenza del progetto: accepted_total si sposta su projects. Il cliente mantiene: id, name, brand_name (riutilizzato come nome display), token, slug (nuovo), archived, created_at.
  • D-04: Campo slug aggiunto a clients — testo opzionale, univoco, URL-safe (es. mario-rossi). Se assente, il link usa il token random come prima. URL: /c/[slug-o-token].
  • D-05: projects.accepted_total (text, nullable) — denormalizzato come ora su clients, ma al livello progetto. L'admin lo imposta manualmente nel tab Preventivo del progetto.
  • D-06: Il token rimane su clients per l'autenticazione middleware — non è il campo slug. Il middleware controlla prima lo slug (lookup DB), poi il token (come ora). Entrambi portano alla dashboard del cliente.
  • D-07: Lo slug si imposta nella pagina /admin/clients/[id]/edit — campo opzionale con preview del link risultante.
  • D-08: La route /c/[token-or-slug] rimane invariata nel path — il middleware risolve entrambi.

Dashboard cliente (frontend)

  • D-09: Se il cliente ha 1 progetto → la dashboard mostra direttamente quel progetto (nessun selettore).
  • D-10: Se il cliente ha 2+ progetti → tabs in cima con i nomi dei brand (es. "Brand Blu | Brand Verde"). Le tab usano il componente Tabs di shadcn/ui già presente.
  • D-11: La struttura della dashboard cliente cambia: la vista di un singolo progetto mostra le stesse sezioni di oggi (stato fasi/task, pagamenti, approvazioni deliverable, commenti) ma scoped al progetto.

Admin — vista Clienti

  • D-12: La lista /admin/clients mostra ogni cliente con i nomi dei brand sotto il nome (es. "Mario Rossi" + riga sottile "Brand Blu | Brand Verde"). Life Time Value = somma degli accepted_total di tutti i progetti del cliente.
  • D-13: Cliccando un cliente si apre /admin/clients/[id] che mostra la lista progetti di quel cliente (cards o righe), non più il workspace direttamente.

Admin — vista Progetti

  • D-14: Nuova pagina /admin/projects (link nel NavBar) — lista di tutti i progetti con colonne: Nome progetto, Cliente genitore, Valore progetto (accepted_total), Acconto (stato), Saldo (stato), Timer (play/stop), €/h calcolato.
  • D-15: Il timer nella lista Progetti mostra il bottone play/stop per il progetto corrente. Solo un timer attivo alla volta (come ora, ma scoped al progetto).
  • D-16: Cliccando un progetto si apre /admin/projects/[id] — workspace identico all'attuale /admin/clients/[id] ma al livello progetto: tabs Panoramica, Fasi, Documenti, Pagamenti, Note, Preventivo, Timer, Commenti.

Creazione progetto (admin)

  • D-17: Progetto creabile da due punti: (1) dal dettaglio cliente /admin/clients/[id] con un bottone "+ Nuovo Progetto", (2) dalla lista /admin/projects con "+ Nuovo Progetto" che chiede prima il cliente.
  • D-18: Form di creazione progetto: Nome progetto (brand name) + selezione cliente (se creato dalla lista globale). Nessun campo aggiuntivo al momento della creazione — tutto il resto si configura nel workspace del progetto.

Timer e analytics profittabilità

  • D-19: time_entries.client_id diventa time_entries.project_id. Il timer gira per progetto.
  • D-20: Analytics profittabilità nel tab Timer di ogni progetto — card con: ore totali, accepted_total, €/h reale (accepted_total ÷ ore), target_rate × ore (costo ideale), delta (guadagno/perdita vs target).
  • D-21: target_hourly_rate è un valore globale impostato dall'admin — stored in una tabella settings (key-value) o direttamente come env var configurabile. Impostabile da una nuova sezione "Impostazioni" nel NavBar admin.
  • D-22: La Statistiche page mostra la profittabilità aggregata per tutti i progetti + breakdown per cliente.

Claude's Discretion

  • Struttura esatta della tabella settings (key-value o colonne specifiche) — scegliere l'approccio più semplice (probabile: tabella settings con key text PK, value text).
  • Ordine delle tabs nel dettaglio progetto — seguire l'ordine attuale del dettaglio cliente.
  • Stile delle cards progetto nel dettaglio cliente — seguire i pattern UI esistenti.

<canonical_refs>

Canonical References

Downstream agents MUST read these before planning or implementing.

Schema attuale (punto di partenza)

  • src/db/schema.ts — schema completo con tutte le tabelle e relazioni. Le FK da migrare: phases.client_id → project_id, payments.client_id → project_id, quote_items.client_id → project_id, time_entries.client_id → project_id, documents.client_id → project_id, notes.client_id → project_id.

Architettura constraints (LOCKED)

  • CLAUDE.md §Architecture Constraints — specialmente: token rotatable (mai PK), quote_items mai esposti via client API, deliverables.approved_at immutable. Questi vincoli si applicano anche al livello progetto.

Patterns UI esistenti da replicare

  • src/components/admin/tabs/ — pattern tab workspace esistente (QuoteTab, ecc.) da replicare per il dettaglio progetto.
  • src/components/admin/TimerCell.tsx — timer da adattare da client_id a project_id.
  • src/components/admin/ClientRow.tsx — pattern riga lista da replicare per ProjectRow.
  • src/app/admin/clients/[id]/page.tsx — layout tabs workspace da replicare per /admin/projects/[id].

Dashboard cliente

  • src/lib/client-view.ts — la query che alimenta la dashboard cliente. Va riscritta per supportare progetto singolo e multi-progetto.
  • src/app/c/[token]/page.tsx — dashboard cliente da ristrutturare per mostrare tabs progetto.

Phase 3 artifacts (prerequisito)

  • .planning/phases/03-service-catalog-quote-builder/03-CONTEXT.md — decisioni sul preventivo e catalogo (quote_items → project_id in questa fase).
  • .planning/phases/03-service-catalog-quote-builder/03-03-SUMMARY.md — implementazione QuoteTab.

</canonical_refs>

<code_context>

Existing Code Insights

Reusable Assets

  • src/components/ui/tabs.tsx — Tabs shadcn già presente, usato in dettaglio cliente. Riutilizzare per il selettore progetto nella dashboard cliente e per il workspace progetto admin.
  • src/components/admin/TimerCell.tsx — implementazione timer completa, da adattare con project_id invece di client_id.
  • src/components/admin/tabs/QuoteTab.tsx — quote builder completo, da ri-wiring con project_id.
  • src/lib/admin-queries.tsgetClientFullDetail è il template per getProjectFullDetail.
  • src/app/admin/clients/[id]/page.tsx — layout workspace admin con tabs, da clonare per /admin/projects/[id].

Established Patterns

  • Server Actions con requireAdmin() per tutte le operazioni admin-only.
  • Query pattern: un'unica funzione getXFullDetail che recupera tutto in parallelo per ridurre round-trip.
  • drizzle-kit push per applicare le modifiche schema al DB Neon live.
  • Token middleware in src/proxy.ts — da estendere per slug lookup.

Integration Points

  • Il middleware src/proxy.ts deve risolvere /c/[slug-o-token] → lookup slug prima, poi token.
  • src/lib/client-view.ts va riscritta completamente per il modello multi-progetto.
  • src/components/admin/NavBar.tsx — aggiungere link "Progetti" e "Impostazioni".
  • getAllClientsWithPayments in admin-queries.ts va riscritta per includere i progetti annidati.

</code_context>

## Specific Ideas
  • Screenshot di riferimento (utente): Lista Clienti mostra "Mario Rossi" in bold con "Brand Blu | Brand Verde" come testo secondario sotto, Life Time Value come somma, link /c/slug.
  • Screenshot di riferimento (utente): Lista Progetti mostra "Brand Blu" in bold con "Mario Rossi" come testo secondario, colonne Valore, Acconto, Saldo, Timer (play icon), €/h calcolato.
  • Analytics formula (utente): accepted_total ÷ ore_lavorate = €/h reale. target_rate × ore = costo ideale. Delta = accepted - costo_ideale. Mostra se si guadagna, perde, o break-even.
  • Target rate: valore globale (es. 50€/h) che l'admin imposta una volta. Non per progetto.
  • Link cliente: preferibilmente con nome cliente (es. /c/mario-rossi). Customizzabile dall'admin. Fallback al token se non impostato.
## Deferred Ideas
  • Fatturazione per progetto — calcolo automatico fatture basato su pagamenti. Fuori scope (out of scope globale del progetto).
  • Export PDF preventivo per progetto — utile ma separato. Fase futura.
  • AI Onboarding (ex Fase 4) — spostato a Fase 5. Richiede questa ristrutturazione come prerequisito.
  • Notifiche email al cliente — quando le fasi cambiano stato. Fase futura.

Phase: 4 — Progetti Multi-Project Context gathered: 2026-05-20