---
phase: 18-cleanup-consolidamento
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - src/components/admin/AdminSidebar.tsx
  - src/app/admin/forecast/page.tsx
  - src/app/admin/quotes/new/page.tsx
  - src/components/admin/leads/SendQuoteModal.tsx
  - src/app/admin/projects/project-actions.ts
autonomous: true
requirements:
  - CLEAN-01
  - CLEAN-02

must_haves:
  truths:
    - "La rotta /admin/forecast non è più raggiungibile (404 o redirect)"
    - "La voce 'Forecast' non appare più nella sidebar admin"
    - "La rotta /admin/quotes/new non è più raggiungibile"
    - "SendQuoteModal non ha più il bottone che naviga a /admin/quotes/new"
    - "project-actions.ts non chiama più revalidatePath('/admin/forecast')"
  artifacts:
    - path: "src/components/admin/AdminSidebar.tsx"
      provides: "Sidebar senza voce Forecast"
      contains: "NON deve contenere href: \"/admin/forecast\""
    - path: "src/app/admin/forecast/page.tsx"
      provides: "File eliminato (rotta rimossa)"
    - path: "src/app/admin/quotes/new/page.tsx"
      provides: "File eliminato (rotta rimossa)"
    - path: "src/components/admin/leads/SendQuoteModal.tsx"
      provides: "Modal senza bottone navigazione a quotes/new"
    - path: "src/app/admin/projects/project-actions.ts"
      provides: "Server actions senza revalidatePath forecast"
  key_links:
    - from: "AdminSidebar.tsx NAV_ITEMS"
      to: "/admin/forecast"
      via: "href nel NAV_ITEMS array"
      pattern: "forecast"
    - from: "SendQuoteModal.tsx"
      to: "/admin/quotes/new"
      via: "window.location.href"
      pattern: "quotes/new"
---

<objective>
Rimuovere le rotte /admin/forecast e /admin/quotes/new e tutti i loro entry point.

Purpose: CLEAN-01 e CLEAN-02 — eliminare feature obsolete prima del Sales Loop. Il forecast è sostituito dal loop AI; il quote builder manuale è sostituito dall'agente AI in Phase 21.
Output: Due rotte rimosse, sidebar pulita, SendQuoteModal senza entry point obsoleto, project-actions.ts senza revalidatePath forecast.
</objective>

<execution_context>
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
</context>

<tasks>

<task type="auto">
  <name>Task 1: Rimuovi rotta Forecast — file, sidebar, revalidatePath (CLEAN-01)</name>

  <read_first>
    - src/components/admin/AdminSidebar.tsx — array NAV_ITEMS, riga con href: "/admin/forecast"
    - src/app/admin/forecast/page.tsx — conferma contenuto prima di eliminare
    - src/app/admin/projects/project-actions.ts — righe 138, 145, 161 con revalidatePath("/admin/forecast")
  </read_first>

  <files>
    src/components/admin/AdminSidebar.tsx,
    src/app/admin/projects/project-actions.ts
  </files>

  <action>
    1. In AdminSidebar.tsx: rimuovi la riga dell'oggetto Forecast dall'array NAV_ITEMS:
       `{ href: "/admin/forecast", label: "Forecast", icon: TrendingUp },`
       Rimuovi anche l'import `TrendingUp` da lucide-react se non è usato altrove nel file.

    2. In project-actions.ts: rimuovi le tre chiamate `revalidatePath("/admin/forecast")` alle righe ~138, ~145, ~161.
       Ogni funzione che la contiene (addProjectOffer, removeProjectOffer, updateProjectOfferTotal)
       mantiene le proprie altre revalidatePath (es. `/admin/projects/${projectId}`) — togli SOLO le righe forecast.

    3. Elimina il file della rotta forecast:
       - src/app/admin/forecast/page.tsx
       Elimina anche la directory se è rimasta vuota:
       - src/app/admin/forecast/ (directory)

    NON toccare: tabelle DB, lib/forecast-queries.ts (deadweight tollerabile, non blocca nulla),
    nessun'altra pagina o componente.
  </action>

  <verify>
    <automated>
      grep -r "admin/forecast" /Users/simonecavalli/Vault/IAMCAVALLI/src --include="*.tsx" --include="*.ts" | grep -v "node_modules" | grep -v ".next" | wc -l
    </automated>
    Risultato atteso: 0 righe (nessun riferimento a /admin/forecast rimasto nel codice sorgente).

    Verifica aggiuntiva sidebar:
    grep "TrendingUp\|forecast" /Users/simonecavalli/Vault/IAMCAVALLI/src/components/admin/AdminSidebar.tsx
    Risultato atteso: nessun output (zero match).
  </verify>

  <acceptance_criteria>
    - grep -r "admin/forecast" src/ produce 0 risultati (esclusi node_modules e .next)
    - Il file src/app/admin/forecast/page.tsx non esiste più
    - AdminSidebar.tsx non contiene la stringa "forecast" né "TrendingUp" (se rimosso)
    - project-actions.ts non contiene revalidatePath("/admin/forecast")
  </acceptance_criteria>

  <done>
    La voce Forecast è assente dalla sidebar, la rotta /admin/forecast è 404, nessun server action
    chiama revalidatePath su quella rotta.
  </done>
</task>

<task type="auto">
  <name>Task 2: Rimuovi rotta Quote Builder manuale e il suo entry point (CLEAN-02)</name>

  <read_first>
    - src/app/admin/quotes/new/page.tsx — conferma contenuto prima di eliminare
    - src/components/admin/leads/SendQuoteModal.tsx — riga ~120 con window.location.href = /admin/quotes/new
    - src/components/admin/quotes/QuoteBuilderForm.tsx — identifica che è usato solo da quotes/new
    - src/components/admin/quotes/OfferSelector.tsx — identifica che è usato solo da QuoteBuilderForm
    - src/components/admin/quotes/PriceOverrideInput.tsx — stesso
    - src/components/admin/quotes/QuotePreview.tsx — stesso
  </read_first>

  <files>
    src/app/admin/quotes/new/page.tsx,
    src/components/admin/leads/SendQuoteModal.tsx,
    src/components/admin/quotes/QuoteBuilderForm.tsx,
    src/components/admin/quotes/OfferSelector.tsx,
    src/components/admin/quotes/PriceOverrideInput.tsx,
    src/components/admin/quotes/QuotePreview.tsx
  </files>

  <action>
    1. In SendQuoteModal.tsx: trova il blocco che naviga a /admin/quotes/new:
       `window.location.href = /admin/quotes/new?lead_id=${leadId};`
       Rimuovi il pulsante / branch che lo contiene. Se il modal ha una logica "crea nuovo preventivo"
       che porta a quella rotta, rimuovi quella branch. Mantieni tutto il resto del modal intatto
       (il flusso "preventivo esistente" non va toccato).
       Prima di modificare, leggi il file per capire la struttura esatta del branch da eliminare.

    2. Elimina i file della rotta e i componenti esclusivi:
       - src/app/admin/quotes/new/page.tsx
       - src/components/admin/quotes/QuoteBuilderForm.tsx
       - src/components/admin/quotes/OfferSelector.tsx
       - src/components/admin/quotes/PriceOverrideInput.tsx
       - src/components/admin/quotes/QuotePreview.tsx
       Elimina le directory rimaste vuote:
       - src/app/admin/quotes/new/ (directory)
       - src/components/admin/quotes/ (directory, solo se completamente vuota dopo la rimozione)

    NON toccare: src/app/admin/quotes/ se esistono altre sotto-rotte (verifica prima),
    lib/admin-queries.ts (getAllOfferMacrosWithMicros — usata altrove), DB.

    ATTENZIONE — verifica preventiva: prima di eliminare src/components/admin/quotes/,
    esegui: grep -r "quotes/" src/components --include="*.tsx" --include="*.ts"
    per confermare che i quattro componenti sopra non sono importati da altri file al di fuori di quotes/new.
    Se ci sono altri consumer, NON eliminare il componente e segnala in SUMMARY.
  </action>

  <verify>
    <automated>
      grep -r "quotes/new" /Users/simonecavalli/Vault/IAMCAVALLI/src --include="*.tsx" --include="*.ts" | grep -v "node_modules" | grep -v ".next" | wc -l
    </automated>
    Risultato atteso: 0 righe.

    Verifica esistenza file:
    test -f /Users/simonecavalli/Vault/IAMCAVALLI/src/app/admin/quotes/new/page.tsx && echo "ESISTE_ANCORA" || echo "OK_RIMOSSO"
    Risultato atteso: OK_RIMOSSO

    Verifica SendQuoteModal:
    grep "quotes/new" /Users/simonecavalli/Vault/IAMCAVALLI/src/components/admin/leads/SendQuoteModal.tsx
    Risultato atteso: nessun output.
  </verify>

  <acceptance_criteria>
    - grep -r "quotes/new" src/ produce 0 risultati
    - src/app/admin/quotes/new/page.tsx non esiste più
    - src/components/admin/quotes/QuoteBuilderForm.tsx non esiste più
    - SendQuoteModal.tsx non contiene la stringa "quotes/new"
  </acceptance_criteria>

  <done>
    La rotta /admin/quotes/new è 404, il pulsante di navigazione nel SendQuoteModal è rimosso,
    i componenti esclusivi del quote builder sono eliminati.
  </done>
</task>

</tasks>

<threat_model>
## Trust Boundaries

| Boundary | Description |
|----------|-------------|
| admin UI → file system | Operazioni di eliminazione file irreversibili |

## STRIDE Threat Register

| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-18-01 | Tampering | project-actions.ts | accept | Rimozione di sole righe revalidatePath inerte — nessun path di dati toccato; le funzioni restano funzionali |
| T-18-02 | Denial of Service | SendQuoteModal.tsx | mitigate | Leggere il file prima di modificare per evitare di rompere il flusso "preventivo esistente" che resta necessario |
</threat_model>

<verification>
Al termine del piano:
1. `npm run build` deve completare senza errori TypeScript (nessun import rotto)
2. `grep -r "admin/forecast" src/` → 0 risultati
3. `grep -r "quotes/new" src/` → 0 risultati
4. La sidebar admin non mostra la voce "Forecast"
</verification>

<success_criteria>
- CLEAN-01: /admin/forecast → 404, sidebar senza voce Forecast, project-actions.ts senza revalidatePath forecast
- CLEAN-02: /admin/quotes/new → 404, SendQuoteModal senza navigazione a quotes/new, componenti quotes/ rimossi
- Build TypeScript pulita (nessun import broken)
</success_criteria>

<output>
After completion, create `.planning/phases/18-cleanup-consolidamento/18-01-SUMMARY.md`
</output>
