# CLAUDE.md — Comparativo Preventivi

> Aggiornato: 03/03/2026 — v4 (refactoring web PHP + Bootstrap)

---

## Scopo del progetto

Studio di architettura **Calvi Ceschia Viganò / Architetti Associati** — strumento per confrontare preventivi di più imprese edili su un capitolato Excel. Produce un file `.xlsx` con prezzi affiancati, media, anomalie evidenziate, riepilogo per sezione.

**Versione corrente:** app web PHP + Bootstrap 5 + JS vanilla (completata).
**Versione precedente:** app Python desktop (tkinter + openpyxl), archiviata in `_archivio_python/`.

---

## Struttura cartelle

```
comparativo_cme/
├── _archivio_python/          ← vecchia app Python (archiviata, non usare)
├── FILES/                     ← capitolati e preventivi di test
│   ├── test1/                 ← struttura multi-riga
│   └── test2/                 ← struttura riga singola
├── docs/plans/                ← design e piani implementazione
│   ├── 2026-03-03-refactoring-web-design.md
│   └── 2026-03-03-refactoring-web-plan.md
└── (app web PHP — in costruzione)
```

### Struttura target app web

```
comparativo/                    ← root app (sottocartella del sito)
├── index.php                   ← login page
├── .htaccess                   ← protezione cartelle, rewrite
├── config/
│   ├── app.php                 ← costanti (soglia, colori Excel, ecc.)
│   └── database.php            ← connessione SQLite (singleton PDO)
├── core/
│   ├── auth.php                ← login, sessioni, verifica ruoli
│   ├── lettore.php             ← leggiCapitolato(), leggiPreventivo()
│   ├── generatore.php          ← genera(), foglioComparativo(), foglioRiepilogo()
│   └── logger.php              ← scrittura log in SQLite
├── api/                        ← endpoint AJAX
│   ├── login.php, logout.php
│   ├── comparativi.php         ← CRUD comparativi
│   ├── upload.php              ← upload file Excel
│   ├── genera.php              ← avvia generazione
│   ├── download.php            ← scarica Excel generato
│   ├── utenti.php              ← gestione utenti (admin/developer)
│   └── log.php                 ← lettura log (developer)
├── pages/                      ← pagine HTML servite da PHP
│   ├── dashboard.php           ← elenco comparativi + ricerca
│   ├── comparativo.php         ← dettaglio: upload, preview, download
│   ├── utenti.php              ← gestione utenti
│   └── log.php                 ← visualizzazione log
├── assets/css|js|img/          ← stili, script, logo DUEBYTES
├── storage/
│   ├── db/comparativo.sqlite   ← database unico
│   ├── uploads/{id}/           ← file Excel caricati (originali)
│   └── output/{id}/            ← file Excel generati
└── vendor/                     ← PhpSpreadsheet (Composer, FTP)
```

---

## Stack tecnologico

| Componente | Scelta |
|---|---|
| Backend | PHP |
| Frontend | Bootstrap 5 (CDN) + JS vanilla |
| Database | SQLite (PDO, nativo PHP) |
| Libreria Excel | PhpSpreadsheet (Composer locale, vendor/ via FTP) |
| Hosting | Tophost (Apache shared), sottocartella sito esistente |

---

## Database SQLite — tabelle

- `utenti` — id, username, password (bcrypt), ruolo, attivo, creato_da, timestamps
- `comparativi` — id, nome, soglia, utente_id, timestamps, stato (bozza/generato)
- `file_comparativo` — id, comparativo_id, tipo (capitolato/preventivo), nome_impresa, percorso, voci stats
- `log` — id, timestamp, livello, utente_id, azione, dettagli, ip

---

## Autenticazione e ruoli

- Sessioni PHP native + bcrypt
- Gerarchia: **developer** > **admin** > **utente**
- Developer creato automaticamente al primo deploy
- Protezione: ogni pagina include `core/auth.php` che verifica sessione + ruolo

---

## Logica core — regola universale

**Col D numerico = riga dati** (quantità presente → prezzo atteso nelle colonne successive).
Tutto il resto (testo, titoli, numeri voce, righe vuote) viene copiato fedelmente nell'output.

### Mapping Python → PHP

| Python | PHP |
|---|---|
| `leggi_capitolato()` | `Lettore::leggiCapitolato()` |
| `estrai_firma_intestazione()` | `Lettore::estraiFirma()` |
| `trova_riga_intestazione()` | `Lettore::trovaRigaIntestazione()` |
| `leggi_preventivo()` | `Lettore::leggiPreventivo()` |
| `genera_comparativo()` | `Generatore::genera()` |
| `_genera_foglio_comparativo()` | `Generatore::foglioComparativo()` |
| `_genera_foglio_riepilogo()` | `Generatore::foglioRiepilogo()` |

---

## Logica anomalie

```
SOGLIA_ANOMALIA_PERC = 20 (modificabile per comparativo, default)

delta_pct = (prezzo - media) / media * 100
se delta_pct > +soglia  → fill FFCCCC (rosso chiaro)
se delta_pct < -soglia  → fill CCFFCC (verde chiaro)
se prezzo mancante      → usa media, fill FFF2CC (giallo)
```

---

## Palette colori

```
Header/navbar: #1F4E79 (blu scuro) — "Calvi Ceschia Viganò / Architetti Associati"
Accent/bottoni: #4F8EF7 (azzurro)
Sfondo body: #F5F6FA
Card/pannelli: #FFFFFF
Testo: #1A1A2E
Bordi: #E5E7EB
```

---

## Credits

Footer globale + pagina login:
- Logo DUEBYTES: `https://www.duebytes.it/assets/img/duebytes.png`
- Testo: "Sviluppato da DUEBYTES di Paolo Alberti"
- Link: `https://www.duebytes.it/`

---

## Sicurezza

- `.htaccess` blocca accesso diretto a `storage/`, `config/`, `core/`
- Upload: validazione estensione (.xlsx/.xls), limite 10MB, nome sanitizzato
- SQL: prepared statements (PDO) ovunque
- XSS: `htmlspecialchars()` su ogni output
- CSRF: token in sessione su ogni POST
- Sessioni: timeout 2h, rigenerazione ID dopo login

---

## Piano implementazione

12 task nel file `docs/plans/2026-03-03-refactoring-web-plan.md`:
1. Scaffolding (cartelle, Composer, config, .htaccess)
2. Autenticazione (auth.php, login, logout)
3. Layout (navbar, dashboard)
4. API comparativi CRUD
5. Upload file Excel
6. Core Lettore PHP (traduzione da Python)
7. Core Generatore PHP (traduzione da Python)
8. API genera/download
9. Pagina dettaglio comparativo
10. Gestione utenti
11. Pagina log
12. Cleanup e test E2E

---

## Flusso di lavoro in studio

1. Login all'app web
2. Creare un nuovo comparativo (nome, soglia)
3. Caricare il capitolato (.xlsx)
4. Caricare i preventivi delle imprese
5. Generare il comparativo → preview HTML + download Excel
6. L'Excel generato resta archiviato sul server per download futuro
