Files

147 lines
9.9 KiB
Markdown
Raw Permalink 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.
# Phase 4: Progetti — Multi-Project per Cliente - Context
**Gathered:** 2026-05-20
**Status:** Ready for planning
<domain>
## 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.
</domain>
<decisions>
## 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.
### Link e accesso cliente
- **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.
</decisions>
<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.ts``getClientFullDetail` è 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>
<specifics>
## 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.
</specifics>
<deferred>
## 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.
</deferred>
---
*Phase: 4 — Progetti Multi-Project*
*Context gathered: 2026-05-20*