diff --git a/CLAUDE.md b/CLAUDE.md
index 10e7eca..c5bb4c3 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1,2077 +1 @@
-# CLAUDE.md
-
-This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
-
----
-
-## ISTRUZIONI OBBLIGATORIE PER CLAUDE
-
-### Auto-Aggiornamento CLAUDE.md
-
-**OBBLIGATORIO:** Claude DEVE aggiornare questo file CLAUDE.md ogni volta che:
-
-1. **Viene completato un task significativo** (fix, nuova feature, refactoring importante)
-2. **Viene risolto un problema tecnico** che potrebbe ripresentarsi in futuro
-3. **Si scopre un pattern/workaround** importante da ricordare
-4. **Termina una sessione di lavoro** - aggiornare "Quick Start - Session Recovery"
-
-**Cosa aggiornare:**
-
-- **Sezione "Quick Start - Session Recovery":**
- - Aggiornare "Ultima sessione" con data corrente
- - Spostare lavoro completato da "ultima sessione" a "sessioni precedenti"
- - Aggiungere nuovi task completati alla lista
- - Aggiornare "Prossimi task prioritari" (spuntare completati, aggiungere nuovi)
-
-- **Sezione "Problemi Risolti (da ricordare)":**
- - Aggiungere OGNI problema tecnico risolto con:
- - Descrizione del problema
- - Causa root
- - Soluzione implementata
- - File coinvolti
-
-- **Checklist:**
- - Aggiornare checkbox `[x]` per task completati
- - Aggiungere nuovi task se scoperti durante il lavoro
-
-**Formato per nuovi problemi risolti:**
-
-```markdown
-XX. **Nome Problema (FIX/IMPLEMENTATO DATA):** - **Problema:** Descrizione breve - **Causa:** Perché succedeva - **Soluzione:** Come è stato risolto - **File:** File modificati
-```
-
-**NON dimenticare:** Questo file è la memoria persistente tra sessioni. Se non viene aggiornato, il lavoro fatto andrà perso e dovrà essere riscoperto.
-
----
-
-## Quick Start - Session Recovery
-
-**Ultima sessione:** 29 Novembre 2025 (pomeriggio)
-
-**Stato progetto:** Migrazione Oracle APEX → .NET + React TypeScript in corso
-
-**Lavoro completato nell'ultima sessione:**
-
-- **FIX: Campo Codice Readonly e Codice Alternativo** - COMPLETATO
- - **Obiettivo:** Il campo "Codice" deve essere sempre auto-generato (non modificabile), aggiungere campo "Codice Alternativo" opzionale
- - **Backend modificato:**
- - `WarehouseArticle.cs` - Aggiunto `AlternativeCode`
- - `WarehouseLocation.cs` - Aggiunto `AlternativeCode`
- - `WarehouseArticleCategory.cs` - Aggiunto `AlternativeCode`
- - `Cliente.cs` - Aggiunto `Codice` e `CodiceAlternativo`
- - `Articolo.cs` - Aggiunto `CodiceAlternativo`
- - `AutoCodeService.cs` - Aggiornato per gestire unicità `Cliente.Codice`
- - `ClientiController.cs` - Auto-generazione codice alla creazione
- - `ArticoliController.cs` - Auto-generazione codice alla creazione
- - `WarehouseArticlesController.cs` - Fix DTOs per rimuovere `Code` obbligatorio:
- - `CreateArticleDto` - Rimosso `Code`, aggiunto `AlternativeCode`
- - `UpdateArticleDto` - Rimosso `Code`, aggiunto `AlternativeCode`
- - `ArticleDto` - Aggiunto `AlternativeCode`
- - `MapFromDto` - Rimossa assegnazione Code (generato da service)
- - `UpdateFromDto` - Rimossa modifica Code (immutabile)
- - Migration `AddAlternativeCodeFields` creata e applicata
- - **Frontend modificato:**
- - `frontend/src/modules/warehouse/types/index.ts` - Aggiunto `alternativeCode` ai DTOs
- - `frontend/src/types/index.ts` - Aggiunto `codice` e `codiceAlternativo` a Cliente/Articolo
- - `ArticleFormPage.tsx` - Campo Codice readonly con "(Generato al salvataggio)"
- - `WarehouseLocationsPage.tsx` - Campo Codice readonly
- - `ArticoliPage.tsx` - Campo Codice readonly
- - `ClientiPage.tsx` - Campo Codice readonly
- - **Comportamento UI:**
- - In creazione: campo Codice mostra "(Generato al salvataggio)" in corsivo
- - In modifica: campo Codice mostra il valore reale, sempre disabled
- - Campo "Codice Alternativo" sempre modificabile (opzionale)
-
-**Lavoro completato nelle sessioni precedenti (30 Novembre 2025):**
-
-- **NUOVA FEATURE: Sistema Codici Automatici Configurabili** - COMPLETATO
- - **Obiettivo:** Sistema admin per configurare la generazione automatica di codici (articoli, magazzini, movimenti, ecc.)
- - **Backend implementato:**
- - `AutoCode.cs` - Entity con pattern configurabile, prefisso, sequenza, reset periodico
- - `AutoCodeService.cs` - Logica business (generazione, preview, reset, validazione pattern)
- - `AutoCodesController.cs` - API REST complete
- - Migration EF Core `AddAutoCodeSystem`
- - Seed automatico configurazioni default per tutte le entità
- - **Frontend implementato:**
- - `autoCode.ts` - Types TypeScript
- - `autoCodeService.ts` - API calls
- - `AutoCodesAdminPage.tsx` - Pagina admin con tabella configurazioni, dialog modifica, guida pattern
- - **Pattern supportati:**
- - `{PREFIX}` - Prefisso configurabile
- - `{SEQ:n}` - Sequenza numerica con n cifre
- - `{YYYY}`, `{YY}` - Anno
- - `{MM}`, `{DD}` - Mese, Giorno
- - **Funzionalità:**
- - Configurazione per entità (warehouse_article, stock_movement, cliente, evento, ecc.)
- - Reset sequenza annuale o mensile automatico
- - Preview prossimo codice senza incremento
- - Reset manuale sequenza
- - Abilitazione/disabilitazione per entità
- - Raggruppamento per modulo nell'UI
- - **API Endpoints:**
- - `GET /api/autocodes` - Lista configurazioni
- - `GET /api/autocodes/{entityCode}` - Dettaglio
- - `GET /api/autocodes/{entityCode}/preview` - Anteprima prossimo codice
- - `POST /api/autocodes/{entityCode}/generate` - Genera nuovo codice
- - `PUT /api/autocodes/{id}` - Aggiorna configurazione
- - `POST /api/autocodes/{entityCode}/reset-sequence` - Reset sequenza
- - `GET /api/autocodes/placeholders` - Lista placeholder disponibili
- - **File principali:**
- - `src/Apollinare.Domain/Entities/AutoCode.cs`
- - `src/Apollinare.API/Services/AutoCodeService.cs`
- - `src/Apollinare.API/Controllers/AutoCodesController.cs`
- - `frontend/src/pages/AutoCodesAdminPage.tsx`
-
-**Lavoro completato nelle sessioni precedenti (29 Novembre 2025 notte):**
-
-- **NUOVA FEATURE: Modulo Magazzino (warehouse)** - COMPLETATO
- - **Backend implementato:**
- - Entities complete in `/src/Apollinare.Domain/Entities/Warehouse/`:
- - `WarehouseLocation.cs` - Magazzini fisici/logici con Type enum (Physical, Virtual, Transit)
- - `WarehouseArticleCategory.cs` - Categorie gerarchiche con Color, Icon, Level, FullPath
- - `WarehouseArticle.cs` - Articoli con batch/serial management flags, valorizzazione
- - `ArticleBatch.cs` - Tracciabilità lotti con scadenza
- - `ArticleSerial.cs` - Tracciabilità numeri seriali
- - `StockLevel.cs` - Giacenze per articolo/magazzino/batch
- - `StockMovement.cs` - Movimenti (Inbound/Outbound/Transfer/Adjustment)
- - `StockMovementLine.cs` - Righe movimento
- - `MovementReason.cs` - Causali movimento
- - `ArticleBarcode.cs` - Multi-barcode support
- - `StockValuation.cs` + `StockValuationLayer.cs` - Valorizzazione periodo e layer FIFO/LIFO
- - `InventoryCount.cs` + `InventoryCountLine.cs` - Inventari fisici
- - Service completo `WarehouseService.cs` con:
- - CRUD articoli, categorie, magazzini
- - Gestione movimenti (carico/scarico/trasferimento/rettifica)
- - Conferma movimenti con aggiornamento giacenze
- - Calcolo valorizzazione (WeightedAverage, FIFO, LIFO, StandardCost)
- - Gestione partite e seriali
- - Controllers REST in `/src/Apollinare.API/Modules/Warehouse/Controllers/`:
- - `WarehouseLocationsController.cs`
- - `WarehouseArticlesController.cs`
- - `WarehouseArticleCategoriesController.cs`
- - `StockMovementsController.cs`
- - `StockLevelsController.cs`
- - Seed dati default (magazzino principale + transito, categorie base, causali)
-
-- **CONFIGURAZIONE: EF Core Code First Migrations** - COMPLETATO
- - **Problema:** Le tabelle venivano create manualmente invece che con migrations EF Core
- - **Soluzione implementata:**
- - Sostituito `db.Database.EnsureCreated()` con `db.Database.MigrateAsync()` in `Program.cs`
- - Creata migration `InitialCreate` con tutte le tabelle (sistema + moduli + warehouse)
- - Le migrations vengono applicate **automaticamente all'avvio** dell'applicazione
- - Logging delle migrations pendenti prima dell'applicazione
- - **Comandi per future migrations:**
-
- ```bash
- # Creare nuova migration
- dotnet ef migrations add NomeMigration \
- --project src/Apollinare.Infrastructure \
- --startup-project src/Apollinare.API
-
- # L'applicazione è AUTOMATICA all'avvio - non serve "dotnet ef database update"
- ```
-
- - **File modificati:** `Program.cs`, `src/Apollinare.Infrastructure/Migrations/`
-
-**Lavoro completato nelle sessioni precedenti (29 Novembre 2025 sera):**
-
-- **NUOVA FEATURE: Sistema Moduli Applicativi** - COMPLETATO (continuazione)
- - **Obiettivo:** Sistema di modularizzazione per gestire licenze, abbonamenti e funzionalità dinamiche
- - **Backend implementato:**
- - `AppModule.cs` - Entity per definizione moduli (code, name, description, icon, basePrice, dependencies, etc.)
- - `ModuleSubscription.cs` - Entity per stato abbonamento (isEnabled, subscriptionType, startDate, endDate, autoRenew)
- - `ModuleService.cs` - Logica business (enable/disable, check dipendenze, gestione scadenze, cache)
- - `ModulesController.cs` - API REST complete con DTOs
- - Tabelle SQLite create manualmente (AppModules, ModuleSubscriptions)
- - Seed automatico 5 moduli: warehouse, purchases, sales, production, quality
- - **Frontend implementato:**
- - `module.ts` - Types TypeScript (ModuleDto, SubscriptionDto, enums, helpers)
- - `moduleService.ts` - API calls
- - `ModuleContext.tsx` - React Context con hooks (useModules, useModuleEnabled, useActiveModules)
- - `ModuleGuard.tsx` - Componente per proteggere route
- - `ModulesAdminPage.tsx` - Pagina amministrazione moduli con cards, toggle, dettagli subscription
- - `ModulePurchasePage.tsx` - Pagina acquisto/attivazione modulo con selezione piano
- - **Integrazione:**
- - `App.tsx` - ModuleProvider wrappa l'app, route /modules e /modules/purchase/:code
- - `Layout.tsx` - Voce menu "Moduli" aggiunta
- - **API Endpoints:**
- - `GET /api/modules` - Lista tutti i moduli
- - `GET /api/modules/active` - Solo moduli attivi
- - `GET /api/modules/{code}` - Dettaglio modulo
- - `GET /api/modules/{code}/enabled` - Verifica stato
- - `PUT /api/modules/{code}/enable` - Attiva modulo
- - `PUT /api/modules/{code}/disable` - Disattiva modulo
- - `GET /api/modules/subscriptions` - Lista subscription
- - `PUT /api/modules/{code}/subscription` - Aggiorna subscription
- - `POST /api/modules/{code}/subscription/renew` - Rinnova
- - `GET /api/modules/expiring` - Moduli in scadenza
- - **Funzionalità:**
- - Gestione dipendenze tra moduli (es. purchases richiede warehouse)
- - Blocco disattivazione se altri moduli dipendono
- - Abbonamenti mensili/annuali con date scadenza
- - Auto-rinnovo opzionale
- - Cache con invalidazione automatica
- - Alert moduli in scadenza
-
-**Lavoro completato nelle sessioni precedenti (29 Novembre 2025 mattina):**
-
-- **NUOVA FEATURE: Sistema Pannelli Drag-and-Drop con Sidebar Ridimensionabili** - COMPLETATO
- - **Obiettivo:** I pannelli del report designer devono poter essere trascinati tra sidebar sinistra e destra, con ridimensionamento orizzontale a livello sidebar
- - **Architettura implementata:**
- - `SidebarDropZone.tsx` - Contenitore sidebar con:
- - Drop zone per drag-and-drop pannelli (HTML5 Drag and Drop API)
- - Handle di resize orizzontale sul bordo interno
- - Indicatore visivo durante il drag
- - Props: `position`, `width`, `onWidthChange`, `onPanelDrop`, `panelIds`
- - `ResizablePanel.tsx` - Pannello individuale con:
- - Header trascinabile (`draggable="true"`)
- - Resize verticale (flex) tra pannelli nella stessa sidebar
- - Stato collassato con icona e titolo verticale
- - `width: 100%` - si adatta alla larghezza della sidebar
- - `usePanelLayout.ts` - Hook per gestione stato:
- - `sidebarWidths: { left: number, right: number }` per larghezza sidebar
- - `panels[]` con `flex` per distribuzione verticale
- - `movePanelToPosition()` redistribuisce flex quando un pannello viene droppato
- - Persistenza in localStorage (versione 3)
- - **Comportamento:**
- - Trascinando l'header di un pannello si può spostarlo tra sidebar
- - Quando un pannello viene droppato, tutti i pannelli nella sidebar di destinazione ottengono `flex: 1` (distribuzione equa)
- - Il resize orizzontale agisce sulla sidebar intera, non sui singoli pannelli
- - I pannelli adottano automaticamente la larghezza della sidebar
- - **Layout Full-Width:**
- - `Layout.tsx` modificato per Report Editor: `p: 0`, `overflow: hidden`, `width: 100vw - drawerWidth`
- - `ReportEditorPage.tsx`: `flex: 1`, `minHeight: 0` per espansione corretta
- - Canvas container: `width: 100%` per occupare tutto lo spazio disponibile
-
-- **FIX: Layout Report Designer Non Full-Width** - COMPLETATO
- - **Problema:** Il report designer non occupava tutta la larghezza del browser
- - **Causa:** Il Layout usava `width: 100%` invece di `100vw` e il padding non veniva rimosso per il report editor
- - **Soluzione:**
- - `Layout.tsx`: Usato `width: 100vw` e `calc(100vw - drawerWidth)` invece di `100%`
- - `Layout.tsx`: Padding condizionale `p: 0` per route `/report-editor`
- - `Layout.tsx`: `overflow: hidden` e `height: 100vh` per contenitore main
- - `ReportEditorPage.tsx`: Rimossi margini negativi, usato `flex: 1` e `minHeight: 0`
- - `EditorCanvas.tsx`: Modifiche utente per larghezza canvas
- - **File modificati:** `Layout.tsx`, `ReportEditorPage.tsx`, `EditorCanvas.tsx`
-
-- **NUOVA FEATURE: Panning e Zoom stile Draw.io nel Report Designer** - COMPLETATO (sessione precedente)
- - **Problema:** Le scorciatoie da tastiera (Ctrl+X, Ctrl+C, etc.) venivano intercettate dal browser invece che dalla pagina
- - **Soluzione:** Riscritto completamente l'handler delle scorciatoie con:
- - Controllo se il focus è su campi input/textarea/contenteditable
- - Nuovo metodo `isTextEditing()` esposto da EditorCanvasRef per verificare editing testo nel canvas
- - `e.preventDefault()` per bloccare comportamento browser
- - **Scorciatoie implementate:**
- - `Ctrl+Z` - Annulla
- - `Ctrl+Y` - Ripeti
- - `Ctrl+S` - Salva
- - `Ctrl+X` - Taglia
- - `Ctrl+C` - Copia
- - `Ctrl+V` - Incolla
- - `Ctrl+D` - Duplica
- - `Ctrl+A` - Seleziona tutto
- - `Ctrl+L` - Blocca/Sblocca elemento
- - `Ctrl+G` - Raggruppa
- - `Ctrl+Shift+G` - Separa
- - `Ctrl+]` - Porta avanti
- - `Ctrl+Shift+]` - Porta in primo piano
- - `Ctrl+[` - Porta indietro
- - `Ctrl+Shift+[` - Porta in fondo
- - `Delete/Backspace` - Elimina elemento
- - `Escape` - Deseleziona
- - **File modificati:**
- - `EditorCanvas.tsx` - Aggiunto `isTextEditing()` a `EditorCanvasRef`
- - `ReportEditorPage.tsx` - Importato `EditorCanvasRef`, aggiunto `canvasRef`, riscritto `useEffect` delle scorciatoie
-
-- **FIX: Rimossa Toolbar Contestuale che causava Layout Shift** - COMPLETATO
- - **Problema:** Quando si selezionava un oggetto nel canvas, appariva una toolbar aggiuntiva sotto quella principale che causava uno scroll della pagina
- - **Soluzione:** Rimossa completamente la toolbar contestuale - le proprietà degli oggetti vengono gestite solo dal `PropertiesPanel` sulla destra
- - **Rimosso da EditorToolbar.tsx:**
- - Sezione "Contextual Toolbar Row" (desktop)
- - Sezione "Contextual toolbar for text/shape" (tablet)
- - Funzioni: `handleTextFormat()`, `handleTextAlign()`, `renderContextualToolbar()`
- - Componente `ColorPickerButton`
- - Costante `COLOR_PRESETS`
- - Props: `selectedElement`, `onUpdateSelectedElement`
- - Import non più usati: `TextField`, `ToggleButton`, `ToggleButtonGroup`, icone formattazione
- - **File modificati:**
- - `EditorToolbar.tsx` - Rimossa toolbar contestuale e codice correlato
- - `ReportEditorPage.tsx` - Rimossi props `selectedElement` e `onUpdateSelectedElement` dalla chiamata a EditorToolbar
-
-- **NUOVA FEATURE: Selezione Multipla nel Report Editor** - COMPLETATO
- - Implementato sistema di selezione multipla personalizzato (senza usare ActiveSelection di Fabric.js che causava riposizionamento oggetti)
- - **Selezione con rettangolo di trascinamento**: trascinando sul canvas vuoto appare rettangolo blu tratteggiato, al rilascio seleziona tutti gli oggetti che intersecano
- - **Shift+click**: aggiunge/rimuove oggetti dalla selezione
- - **Spostamento multiplo**: quando più oggetti sono selezionati, trascinandone uno si spostano tutti insieme
- - **Feedback visivo**: oggetti selezionati mostrano bordo blu (#1976d2) e ombra
- - **Gestione corretta degli eventi**: i ref (`selectedElementIdsRef`, `onSelectElementRef`, etc.) evitano stale closures negli event handler
- - **File modificati:**
- - `EditorCanvas.tsx` - Nuovi handler `handleMouseDown`, `handleMouseUp`, logica selezione multipla, refs per valori correnti
- - `ReportEditorPage.tsx` - Cambiato `selectedElementId: string | null` → `selectedElementIds: string[]`, aggiornati tutti i riferimenti
-
-**Lavoro completato nelle sessioni precedenti (28 Novembre 2025 notte):**
-
-- **NUOVA FEATURE: Sincronizzazione Real-Time Efficiente** - COMPLETATO
- - **Prima:** Al salvataggio veniva inviata solo una notifica `DataSaved`, l'altra sessione ricaricava il template dal server (lento)
- - **Dopo:** Al salvataggio viene inviato l'intero template via SignalR (`BroadcastTemplateSync`), l'altra sessione lo applica direttamente (istantaneo)
- - **Compressione automatica** per template > 10KB usando gzip via browser's CompressionStream API
- - **Version tracking** per gestione conflitti (ignora template con versione più vecchia)
- - Nuovo metodo Hub: `BroadcastTemplateSync(roomKey, templateJson, version, compressed)`
- - Nuovo evento: `TemplateSync` con decompressione automatica lato client
- - **FIX: Limite messaggio SignalR** - Aumentato `MaximumReceiveMessageSize` a 1MB in `Program.cs` (default era 32KB)
- - **File modificati:**
- - `CollaborationHub.cs` - Aggiunto `BroadcastTemplateSync` e `TemplateSyncMessage` con campo `Compressed`
- - `collaboration.ts` - Aggiunto `broadcastTemplateSync()`, utilities compressione/decompressione (`compressString`, `decompressString`), handler `TemplateSync`
- - `CollaborationContext.tsx` - Esposto `broadcastTemplateSync` e `onTemplateSync`
- - `ReportEditorPage.tsx` - Sostituito `sendDataSaved()` con `broadcastTemplateSync()`, aggiunto handler per applicare template ricevuti
- - `Program.cs` - Configurato SignalR con `MaximumReceiveMessageSize = 1MB`
-
-- **FIX: Auto-Save Event-Based con Debounce** - COMPLETATO
- - Riscritto auto-save per triggerare ad ogni modifica (non a intervalli)
- - Debounce di 500ms per evitare salvataggi multipli durante editing rapido
- - Usa `useRef` per `saveMutation`, `template`, `templateInfo` per evitare re-creazione del timeout
- - Dipendenze effect: solo `autoSaveEnabled`, `isNew`, `hasUnsavedChanges`, `templateHistory.undoCount`
- - Il check `isPending` avviene al momento dell'esecuzione del timeout, non come dipendenza
-
-**Lavoro completato nelle sessioni precedenti (28 Novembre 2025 pomeriggio - sera):**
-
-- **NUOVA FEATURE: Sistema Collaborazione Real-Time Globale** - COMPLETATO
- - Migrato da sistema report-specific a sistema globale per tutta l'app
- - `CollaborationHub.cs` - Hub SignalR generico per qualsiasi entità/pagina
- - `collaboration.ts` - Service singleton per gestione connessione
- - `CollaborationContext.tsx` - React Context con hooks (`useCollaboration`, `useCollaborationRoom`)
- - `CollaborationIndicator.tsx` - Indicatore globale nella UI
- - Room-based collaboration con formato `{entityType}:{entityId}`
- - **FIX: Incompatibilità versione SignalR** - Rimosso package `Microsoft.AspNetCore.SignalR.Common` v10.0.0 incompatibile con .NET 9, downgrade client `@microsoft/signalr` a v8.0.7
- - **FIX: Auto-save non funzionante** - Usati `useRef` per evitare re-run dell'effect causato da `saveMutation` nelle dependencies
-
-**Lavoro completato nelle sessioni precedenti (28 Novembre 2025 tarda notte):**
-
-- **NUOVA FEATURE: Toolbar Report Designer Migliorata Drasticamente** - COMPLETATO
- - Design moderno stile Canva/Figma con gradient buttons e animazioni fluide
- - **Sezioni etichettate** su desktop (INSERISCI, MODIFICA, CRONOLOGIA, VISTA, ZOOM, PAGINA)
- - **Toolbar contestuale** dinamica che appare quando un elemento è selezionato:
- - Per testo: formattazione (grassetto, corsivo, sottolineato), allineamento, color picker
- - Per forme/linee: color picker riempimento/bordo, spessore bordo
- - Per immagini: indicatore mantieni proporzioni
- - Mostra tipo elemento, nome e dimensioni in tempo reale
- - **Color Picker integrato** con palette di 20 colori predefiniti
- - **Indicatore stato salvataggio** visivo: Salvato (verde), Non salvato (arancione), Salvataggio... (spinner)
- - **Badge** sul pulsante Snap che mostra quante opzioni sono attive
- - **Zoom esteso** fino al 300% con pulsante "Adatta alla finestra"
- - Pannello scorciatoie tastiera ampliato
- - Aggiunto `textDecoration` a `AprtStyle` per supportare sottolineato
-
-- **FIX: Indicatore "Non Salvato" errato** - RISOLTO
- - Prima usava `canUndo` che indicava solo presenza di history
- - Ora usa `undoCount` confrontato con `lastSavedUndoCount` per tracking accurato
-
-- **NUOVA FEATURE: Auto-Save con Toggle** - COMPLETATO
- - Salvataggio automatico dopo 1 secondo di inattività (debounce)
- - **Abilitato di default**
- - Toggle nella toolbar (icona AutoMode) per attivare/disattivare
- - Quando auto-save è attivo, il pulsante "Salva" manuale è nascosto
- - Quando auto-save è disattivo, il pulsante "Salva" appare
- - Non si attiva per template nuovi (richiede primo salvataggio manuale)
- - Non si attiva durante salvataggio in corso
-
-**Lavoro completato nelle sessioni precedenti (28 Novembre 2025 notte):**
-
-- **NUOVA FEATURE: Responsive Design Completo** - COMPLETATO
- - Tutta l'applicazione è ora responsive per mobile, tablet e desktop
- - Breakpoints: mobile (<600px), tablet (600-900px), desktop (>900px)
- - **Layout.tsx**: Sidebar collassata con icone su tablet, drawer mobile
- - **ReportTemplatesPage**: Header stackato su mobile, FAB per nuovo template, dialog fullScreen
- - **ReportEditorPage**: BottomNavigation + SwipeableDrawer (70vh) per pannelli su mobile, auto-zoom
- - **EditorToolbar**: 3 varianti (mobile compatta con riga collassabile, tablet media, desktop completa)
- - **Pannelli laterali** (DataBindingPanel, PropertiesPanel, PageNavigator): larghezza piena su mobile
- - **DatasetSelector**: Header collassabile su mobile
- - **PreviewDialog**: fullScreen su mobile con navigazione step-by-step (dataset → entity)
- - **ImageUploadDialog**: fullScreen su mobile, area drag-drop ottimizzata, bottoni stacked
-
-**Lavoro completato nelle sessioni precedenti (28 Novembre 2025 sera):**
-
-- **FIX: Variabili Globali Report ({{$pageNumber}}, {{$totalPages}}, ecc.)** - RISOLTO
- - Le variabili speciali ora vengono correttamente risolte nel PDF finale
- - Aggiunta classe `PageContext` per passare numero pagina e totale pagine durante il rendering
- - Propagato `PageContext` attraverso tutta la catena di rendering (bitmap, text, binding resolution)
- - `ResolveBindingPath()` ora restituisce valori reali invece di placeholder
-
-**Lavoro completato nelle sessioni precedenti (28 Novembre 2025):**
-
-- **NUOVA FEATURE: Gestione Multi-Pagina nel Report Designer** - Completata
- - Nuovo tipo `AprtPage` per definire pagine con impostazioni individuali (size, orientation, margins, backgroundColor)
- - Ogni elemento ha `pageId` per assegnazione a pagina specifica
- - Nuovo componente `PageNavigator.tsx` - sidebar con lista pagine, context menu, rinomina, duplica, elimina, riordina
- - Navigazione rapida pagine in `EditorToolbar.tsx` (pulsanti prev/next, indicatore "X / Y")
- - `PropertiesPanel.tsx` aggiornato per mostrare/modificare impostazioni pagina corrente
- - Backend `ReportGeneratorService.cs` genera PDF multi-pagina correttamente
- - Migrazione automatica template legacy (elementi senza pageId assegnati a prima pagina)
-
-- **FIX CRITICO: Rotazione oggetti nel PDF** - Gli oggetti ruotati nel canvas ora vengono posizionati correttamente nel PDF generato
- - Implementata la formula Fabric.js per calcolare il centro di rotazione
- - Coordinate corrette per `originX='left'`, `originY='top'`
-
-**Lavoro completato nelle sessioni precedenti:**
-
-- Sistema Report PDF con editor visuale (98% completato)
-- Fabric.js v6 canvas editor funzionante
-- Multi-dataset support con preview
-- **FIX: Data binding PDF ora funzionante** - I campi dati vengono risolti correttamente
-- **FIX: Formattazione campi** - Date, valute, numeri formattati correttamente nel PDF
-- Sistema Virtual Dataset implementato (CRUD completo)
-- SignalR real-time updates funzionante
-- **Context Menu ricco** - Tasto destro con opzioni complete stile Canva (copia, taglia, incolla, layer, allineamento, trasformazioni)
-- **FIX: Posizionamento assoluto PDF FUNZIONANTE** - SVG con viewBox in mm, coordinate corrette
-- **FIX: Immagini nel PDF** - Data URI, API URL e risorse embedded ora renderizzate correttamente
-- **FIX: Font size nel PDF** - Conversione corretta da px screen a mm per SVG
-
-**Per riprendere il lavoro sui Report:**
-
-1. Vai alla sezione "Report PDF System - Implementation Details" più sotto
-2. Consulta la "Checklist Completamento Report System" per vedere cosa manca
-3. I file principali sono:
- - Backend: `/src/Apollinare.API/Controllers/ReportsController.cs`
- - Frontend: `/frontend/src/pages/ReportEditorPage.tsx`
- - Canvas: `/frontend/src/components/reportEditor/EditorCanvas.tsx`
- - **Context Menu:** `/frontend/src/components/reportEditor/ContextMenu.tsx`
- - **PDF Generator:** `/src/Apollinare.API/Services/Reports/ReportGeneratorService.cs`
- - **Page Navigator:** `/frontend/src/components/reportEditor/PageNavigator.tsx`
-
-**Prossimi task prioritari:**
-
-**MODULI BUSINESS (PRIORITÀ ALTA):**
-
-1. [x] **Implementare modulo Magazzino (warehouse)** - COMPLETATO (backend)
- - Backend: Entities, Service, Controllers, API completi
- - Manca: Frontend (pagine React per gestione articoli, movimenti, giacenze)
-2. [ ] **Frontend modulo Magazzino** - Pagine React per warehouse
-3. [ ] **Implementare modulo Acquisti (purchases)** - Dipende da Magazzino
-4. [ ] **Implementare modulo Vendite (sales)** - Dipende da Magazzino
-5. [ ] **Implementare modulo Produzione (production)** - Dipende da Magazzino
-6. [ ] **Implementare modulo Qualità (quality)** - Indipendente
-
-**Report System (completamento):**
-
-- [ ] Aggiungere rendering tabelle dinamiche per collection
-- [ ] Gestire sezioni header/footer ripetute su ogni pagina
-- [ ] UI per relazioni tra dataset multipli
-
-**NOTA:** Vedere sezione "Prossimi Passi: Implementazione Moduli Business" per dettagli architetturali e principi di personalizzazione.
-
-**Comandi utili (usa il Makefile!):**
-
-```bash
-# IMPORTANTE: Usa sempre il Makefile per compilare e avviare l'applicazione
-
-make help # Mostra tutti i comandi disponibili
-make install # Installa tutte le dipendenze (NuGet + npm)
-make dev # Avvia backend e frontend in parallelo (dev mode)
-make build # Compila tutto per produzione
-
-make backend-run # Avvia solo backend (porta 5000)
-make frontend-run # Avvia solo frontend (porta 5173)
-make backend-watch # Backend con hot reload (dotnet watch)
-
-make clean # Pulisce artefatti di build
-make lint # Esegue ESLint sul frontend
-make check # Verifica prerequisiti installati (dotnet, node, npm)
-```
-
-**IMPORTANTE:** Dopo modifiche al codice, i servizi backend e frontend vanno **sempre riavviati** per vedere le modifiche:
-
-- Backend: fermare con `Ctrl+C` e rilanciare `make backend-run`
-- Frontend: in dev mode (`make frontend-run`) il hot-reload è automatico per la maggior parte delle modifiche, ma per modifiche strutturali (nuovi file, cambi a tipi, etc.) potrebbe essere necessario riavviare
-
----
-
-## Project Overview
-
-This repository contains documentation for migrating the **Apollinare Catering & Banqueting Management Software** from Oracle APEX to .NET + React TypeScript.
-
-**Original Application:**
-
-- Oracle APEX 21.1.0 (Application ID: 112)
-- 56 pages, 302 items, 98 processes
-- Database: Oracle 18 XE (schema: APOLLINARECATERINGPROD)
-- Language: Italian
-
-**Target Stack:**
-
-- Backend: .NET (C#)
-- Frontend: React TypeScript (not Vue - note the user request mentions Vue but the actual target is React TypeScript)
-- Database: Oracle 18 XE (read-only access for analysis)
-
-## Database Connection (Read-Only)
-
-**Connection Details:**
-
-- Database: Oracle 18 XE
-- Username: `apollinarecateringprod`
-- Password: `bmwmRaSBRT53Z2J8CCvYK45EPDyAJ4`
-- Database: `xepdb1`
-- Hostname: `apollinare`
-- Port: `1521`
-
-**Important:** This connection is READ-ONLY. Use it only to analyze schema, extract business logic from procedures/packages/functions, and understand data relationships.
-
-## Application Architecture
-
-### Core Business Domain: Event Catering Management
-
-The application manages the complete lifecycle of catering events from quote to execution, including:
-
-- Event creation and management
-- Client and location management
-- Inventory (articles) with image storage
-- Quote generation with complex calculations
-- Resource (staff) scheduling
-- Kitchen and setup reports
-- Multi-level authorization system
-
-### Main Business Entities
-
-**Events (EVENTI)** - Central entity
-
-- Event details (date, location, client, event type)
-- Guest counts by type (adults, children, seated, buffet)
-- Status workflow: 0 (Scheda) → 10 (Preventivo/Quote) → 20 (Confermato/Confirmed)
-- Quote expiration tracking
-- Distance calculations for location
-
-**Event Details (1:N relationships):**
-
-- `EVENTI_DET_OSPITI` - Guest type breakdown
-- `EVENTI_DET_PREL` - Pick lists (articles needed for the event)
-- `EVENTI_DET_RIS` - Resource assignments (staff)
-- `EVENTI_DET_DEGUST` - Tasting event details
-- `EVENTI_ACCONTI` - Deposits/advances
-- `EVENTI_ALLEG` - Attachments
-- `EVENTI_ALTRICOSTI` - Other costs
-
-**Master Data:**
-
-- `ARTICOLI` - Articles/items with images (BLOB), quantities, coefficients
-- `TB_CODICI_CATEG` - Categories with calculation coefficients (COEFF_A/B/S)
-- `TB_TIPI_MAT` - Material types
-- `TB_TIPI_EVENTO` - Event types with meal classifications
-- `TB_TIPI_OSPITI` - Guest types
-- `CLIENTI` - Clients
-- `LOCATION` - Event locations
-- `RISORSE` - Resources (staff) with type classification
-
-### Critical Business Logic in Database
-
-**Key Stored Procedures:**
-
-- `EVENTI_AGGIORNA_QTA_LISTA(p_event_id)` - Updates pick list quantities based on guest counts and coefficients
-- `EVENTI_AGGIORNA_TOT_OSPITI(p_event_id)` - Recalculates total guest count
-- `EVENTI_RICALCOLA_ACCONTI(p_event_id)` - Recalculates deposit amounts
-- `EVENTI_COPIA` - Event duplication functionality
-- `EVENTI_PREPARE` - Event preparation process
-
-**Key Functions:**
-
-- `F_GET_QTA_IMPEGNATA(cod_articolo, data)` - Returns committed quantity for an article on a specific date (inventory reservation)
-- `F_EVENTO_SCADUTO(data_scad, stato, ...)` - Checks if event quote has expired
-- `F_MAX_NUMERO_EVENTI_RAGGIUNTO(data)` - Enforces daily event limit
-- `F_USER_IN_ROLE(app_user, role)` - Role-based authorization
-- `STRING_TO_TABLE_ENUM(string, position, delimiter)` - Utility for string parsing
-
-**Important Views:**
-
-- `V_IMPEGNI_ARTICOLI` - Calculates article commitments across events (inventory availability)
-- `V_IMPEGNI_ARTICOLI_LOC` - Article commitments by location
-- `VW_CALENDARIO_EVENTI` - Calendar view of events
-
-### Quantity Calculation Algorithm
-
-The application uses a sophisticated coefficient-based system:
-
-1. **Coefficients** are defined at category level (`TB_CODICI_CATEG.COEFF_A/B/S`)
-2. **Standard quantities** are stored per article (`ARTICOLI.QTA_STD_A/S/B`)
-3. **Guest counts** by type determine multipliers (`EVENTI_DET_OSPITI`)
-4. **Final quantities** calculated as: `Guest_Count × Coefficient × Standard_Qty`
-
-Types: A (Adulti/Adults), S (Seduti/Seated), B (Buffet)
-
-### Authorization Model
-
-**5 Authorization Levels:**
-
-1. **Admin_auth_schema** - Full admin access
- - Users: admin, monia, andrea, maria, sabrina, nicole, cucina, developer, elia.ballarani
-
-2. **User Read/Write** - Controlled by `USERS_READONLY` table
- - `FLGWRITE` flag determines write access
-
-3. **Consuntivi** - Access to financial summaries
- - Users from `GET_CONSUNTIVI_USERS` view
-
-4. **Gestori** (Managers) - Manager-level permissions
- - Users from `GET_GESTORI_USERS` view
-
-5. **Solo Admins** - Highest level
- - Only: admin, monia
-
-**Session Management:**
-
-- `SET_USER_READONLY` process runs before header on every page
-- Sets `APP_READ_ONLY` application item based on user permissions
-
-### Page Structure (56 Pages)
-
-**Master Data Pages:**
-
-- Pages 2-3: Articles (list + form)
-- Pages 4-5: Categories
-- Pages 6-7: Types
-- Pages 17-18: Clients
-- Pages 15, 20: Locations
-- Page 31: Resources (staff)
-
-**Event Management:**
-
-- Page 1: Dashboard
-- Page 8: Event creation wizard
-- Page 9: Event list
-- Page 12: Calendar view
-- Pages 13-14: Event types
-- **Page 22: Main event form** (most complex - multiple interactive grids)
-- Page 27, 32: Tastings
-- Page 35: Event cards/confirmed cards
-- Page 48: Event templates
-
-**Reports:**
-
-- Page 16: Grid view
-- Page 25: Kitchen summary
-- Page 28: Cakes and extra costs
-- Page 30: Setup summary
-- Page 38: Resources summary
-- Page 39: Article commitments
-
-**Admin:**
-
-- Page 45: Data management
-- Page 46: Max events configuration
-- Page 47: Permissions
-- Page 49: Scheduled jobs
-- Page 50: Sent emails
-- Page 51: Pending emails
-
-### External Integrations
-
-**JasperReports:**
-
-- Quote reports (preventivi)
-- Event cards (schede evento)
-- Kitchen summaries
-- Custom iframeObj.js wrapper for embedding reports
-
-**Email System:**
-
-- Mail queue (pages 50-51)
-- Background job processing (page 49)
-- Template-based notifications
-
-**Custom JavaScript:**
-
-- `ajaxUtils.js` - AJAX utilities for dynamic updates
- - `notifica(pText, pType)` - Dynamic notifications
- - `setSessionState(elemList, pCallback)` - Session state management
- - `ajaxExec(...)` - Generic AJAX execution
- - `execProcessAsync(...)` - Async process execution
- - `execQueryAsync(...)` - Async query execution
-
-### Migration Considerations
-
-**Complex Features Requiring Special Attention:**
-
-1. **Page 22 (Nuovo Evento)** - Most complex page
- - Multiple editable interactive grids on single page
- - Master-detail relationships with real-time calculations
- - Guest type grid → triggers quantity recalculations in pick list grids
- - Resource assignment grid
- - Requires careful state management in React
-
-2. **BLOB Storage for Images**
- - Article images stored as BLOBs in Oracle
- - Migration strategy needed (Azure Blob Storage, AWS S3, or filesystem)
- - MIMETYPE tracking for proper rendering
-
-3. **PL/SQL Business Logic**
- - Decision needed: Port to C# or keep as Oracle functions?
- - Quantity calculations are complex - ensure parity
- - Inventory commitment logic (V_IMPEGNI_ARTICOLI) is critical
-
-4. **State Management**
- - Heavy use of APEX session state
- - Consider Redux Toolkit or Zustand for React
- - Real-time grid updates and calculations
-
-5. **Reporting**
- - JasperReports replacement needed
- - Options: SSRS, Crystal Reports, DevExpress, or PDF libraries (iTextSharp, QuestPDF)
-
-6. **Email Queue System**
- - Asynchronous processing required
- - Consider: Hangfire, Azure Functions, or background services
-
-7. **Calendar Component**
- - Page 12 uses APEX calendar
- - React options: FullCalendar, React Big Calendar, @event-calendar/core
-
-8. **Multi-Grid Interactions**
- - Interactive grids with master-detail relationships
- - Consider: AG Grid, DevExtreme DataGrid, or Material-UI DataGrid
-
-## Business Rules to Preserve
-
-1. **Event Status Workflow:** Must follow 0 → 10 → 20 progression
-2. **Quote Expiration:** Automatic status change when `DATA_SCAD_PREVENTIVO` passed
-3. **Max Events Per Day:** Enforced limit (configurable)
-4. **Article Commitment Tracking:** Prevent overbooking of inventory
-5. **Coefficient-Based Calculations:** Ensure quantity formulas match exactly
-6. **Deposit Calculations:** Auto-recalculation on cost changes
-7. **Role-Based Access:** 5-level authorization system
-8. **Read-Only Mode:** User-specific write restrictions
-
-## Data Extraction Queries
-
-When analyzing the database, useful queries:
-
-```sql
--- Get all tables in schema
-SELECT table_name FROM user_tables ORDER BY table_name;
-
--- Get table structure
-SELECT column_name, data_type, nullable, data_default
-FROM user_tab_columns
-WHERE table_name = 'EVENTI'
-ORDER BY column_id;
-
--- Get all procedures and functions
-SELECT object_name, object_type
-FROM user_objects
-WHERE object_type IN ('PROCEDURE', 'FUNCTION', 'PACKAGE')
-ORDER BY object_type, object_name;
-
--- Get procedure source
-SELECT text FROM user_source
-WHERE name = 'EVENTI_AGGIORNA_QTA_LISTA'
-ORDER BY line;
-
--- Get view definitions
-SELECT view_name, text FROM user_views
-WHERE view_name LIKE 'V_%' OR view_name LIKE 'VW_%';
-
--- Get foreign key relationships
-SELECT a.constraint_name, a.table_name, a.column_name,
- c_pk.table_name r_table_name, c_pk.constraint_name r_constraint_name
-FROM user_cons_columns a
-JOIN user_constraints c ON a.constraint_name = c.constraint_name
-JOIN user_constraints c_pk ON c.r_constraint_name = c_pk.constraint_name
-WHERE c.constraint_type = 'R'
-ORDER BY a.table_name, a.constraint_name;
-```
-
-## File References
-
-- `apollinare-db-connection.md` - Database connection details (credentials)
-- `f112.sql` - Complete APEX export (53,282 lines)
- - Application structure
- - Page definitions
- - Processes and validations
- - LOVs and static data
- - JavaScript libraries
-
-## Development Approach
-
-When working on migration tasks:
-
-1. **Always query the database** to understand current data structure and relationships
-2. **Extract PL/SQL source code** for procedures/functions before implementing equivalent C# logic
-3. **Document business rules** discovered in stored procedures
-4. **Preserve Italian field names** in database but consider English in application layer
-5. **Test quantity calculations** thoroughly - they are core to the business
-6. **Map APEX page flows** to React routes and components
-7. **Identify reusable components** (grids, forms, lookups)
-8. **Plan data migration** for BLOBs and complex relationships
-
-## Key Terminology (Italian → English)
-
-- **Scheda** → Card/Draft (Event status 0)
-- **Preventivo** → Quote (Event status 10)
-- **Confermato** → Confirmed (Event status 20)
-- **Lista Prelievo** → Pick List (articles for event)
-- **Articoli** → Articles/Items
-- **Ospiti** → Guests
-- **Risorse** → Resources (staff)
-- **Degustazioni** → Tastings
-- **Allestimenti** → Setups
-- **Acconti** → Deposits/Advances
-- **Impegni** → Commitments (inventory reservations)
-
-## Notes
-
-- The application is mature and in production use
-- Italian language throughout (UI, database, code comments)
-- Complex business logic embedded in database layer
-- Heavy use of APEX-specific features (Interactive Grids, Dynamic Actions)
-- Real-time calculations and validations are critical to user experience
-
----
-
-## Report PDF System - Implementation Details
-
-### Overview
-
-Sistema completo di generazione report PDF con editor visuale drag-and-drop (stile Canva) e metalinguaggio APRT (Apollinare Report Template) per template portabili.
-
-### Stack Tecnologico
-
-**Backend:**
-
-- QuestPDF (Community License) - Generazione PDF programmatica
-- .NET 9 Web API con Entity Framework Core
-- SQLite per storage template, font e immagini
-
-**Frontend:**
-
-- React 19 + TypeScript + Vite
-- Fabric.js v6 - Canvas editor per design visuale
-- Material-UI per componenti UI
-
-### Stato Corrente dell'Implementazione
-
-#### Backend (COMPLETATO)
-
-**Entities** (`/src/Apollinare.Domain/Entities/`):
-
-- `ReportTemplate.cs` - Template con JSON, thumbnail, metadata
-- `ReportFont.cs` - Font custom uploadabili (TTF/OTF)
-- `ReportImage.cs` - Immagini riutilizzabili nei report
-
-**Services** (`/src/Apollinare.API/Services/Reports/`):
-
-- `ReportGeneratorService.cs` - Parsing APRT e generazione PDF con QuestPDF
-- `AprtModels.cs` - Modelli C# per il metalinguaggio APRT
-
-**Controllers** (`/src/Apollinare.API/Controllers/`):
-
-- `ReportTemplatesController.cs` - CRUD template, clone, import/export
-- `ReportResourcesController.cs` - Gestione font e immagini
-- `ReportsController.cs` - Generazione PDF, schema dati, dataset management
-
-**API Endpoints disponibili:**
-
-```
-# Templates
-GET /api/report-templates
-GET /api/report-templates/{id}
-POST /api/report-templates
-PUT /api/report-templates/{id}
-DELETE /api/report-templates/{id}
-POST /api/report-templates/{id}/clone
-GET /api/report-templates/{id}/export
-POST /api/report-templates/import
-GET /api/report-templates/categories
-
-# Resources
-GET /api/report-resources/fonts
-POST /api/report-resources/fonts
-DELETE /api/report-resources/fonts/{id}
-GET /api/report-resources/fonts/families
-GET /api/report-resources/images
-POST /api/report-resources/images
-DELETE /api/report-resources/images/{id}
-
-# Report Generation
-POST /api/reports/generate
-GET /api/reports/evento/{eventoId}
-POST /api/reports/preview
-GET /api/reports/datasets
-GET /api/reports/schema/{datasetId}
-GET /api/reports/datasets/{datasetId}/entities
-```
-
-#### Frontend (COMPLETATO ~90%)
-
-**Pagine** (`/frontend/src/pages/`):
-
-- `ReportTemplatesPage.tsx` - Lista template con cards, filtri, import/export
-- `ReportEditorPage.tsx` - Editor principale con undo/redo, shortcuts
-
-**Componenti Editor** (`/frontend/src/components/reportEditor/`):
-
-- `EditorCanvas.tsx` - Canvas Fabric.js per design visuale
-- `EditorToolbar.tsx` - Toolbar con strumenti, zoom, grid, azioni
-- `PropertiesPanel.tsx` - Pannello proprietà elemento/pagina
-- `DataBindingPanel.tsx` - Browser campi dati con supporto multi-dataset
-- `DatasetSelector.tsx` - Selezione dataset per template
-- `PreviewDialog.tsx` - Dialog selezione entità per anteprima
-
-**Types** (`/frontend/src/types/report.ts`):
-
-- Definizioni complete APRT (AprtTemplate, AprtElement, AprtStyle, etc.)
-- DTOs per API (ReportTemplateDto, DataSchemaDto, DatasetTypeDto, etc.)
-- Utility functions (mmToPx, pxToMm, getPageDimensions)
-
-**Services** (`/frontend/src/services/reportService.ts`):
-
-- reportTemplateService - CRUD template
-- reportFontService - Gestione font
-- reportImageService - Gestione immagini
-- reportGeneratorService - Generazione PDF e schema
-
-### Metalinguaggio APRT (Apollinare Report Template)
-
-Formato JSON esportabile/importabile per portabilità template:
-
-```json
-{
- "version": "1.0",
- "meta": {
- "name": "Template Evento",
- "pageSize": "A4",
- "orientation": "portrait",
- "margins": { "top": 20, "right": 15, "bottom": 20, "left": 15 }
- },
- "resources": {
- "fonts": [],
- "images": []
- },
- "dataSources": {
- "evento": { "type": "object", "schema": "evento" }
- },
- "sections": [],
- "elements": [
- {
- "id": "uuid",
- "type": "text",
- "position": { "x": 20, "y": 20, "width": 100, "height": 20 },
- "style": {
- "fontFamily": "Helvetica",
- "fontSize": 14,
- "color": "#000000"
- },
- "content": { "type": "binding", "expression": "{{evento.codice}}" },
- "section": "body"
- }
- ]
-}
-```
-
-**Tipi elemento supportati:** text, image, shape, table, line, barcode
-
-**Data binding:** `{{campo}}`, `{{dataset.campo}}`, `{{collection.campo}}`
-
-**Variabili speciali:** `{{$pageNumber}}`, `{{$totalPages}}`, `{{$date}}`, `{{$datetime}}`
-
-### Dataset Disponibili
-
-| Dataset ID | Nome | Descrizione |
-| ---------- | -------- | ------------------------------------------------------------------ |
-| evento | Evento | Dati evento con cliente, location, dettagli ospiti, costi, risorse |
-| cliente | Cliente | Anagrafica clienti completa |
-| location | Location | Sedi e location eventi |
-| articolo | Articolo | Catalogo articoli e materiali |
-| risorsa | Risorsa | Staff e personale |
-
-### Funzionalità Implementate
-
-- [x] Editor visuale drag-and-drop con Fabric.js
-- [x] Supporto elementi: testo, forme, linee, tabelle, immagini (placeholder)
-- [x] Gestione zoom (25% - 300%)
-- [x] Griglia e snap to grid
-- [x] Undo/Redo (max 100 stati)
-- [x] Shortcuts tastiera (Ctrl+Z, Ctrl+Y, Ctrl+S, Delete)
-- [x] Pannello proprietà con posizione, stile, contenuto
-- [x] Data binding con browser campi disponibili
-- [x] Selezione multipla dataset per template
-- [x] Preview con selezione entità reali
-- [x] Salvataggio/caricamento template
-- [x] Import/export template come file .aprt
-- [x] Clone template
-- [x] Generazione PDF default per eventi
-- [x] Formattazione campi (valuta, data, numero, percentuale)
-- [x] **Responsive design completo** (mobile, tablet, desktop)
-- [x] **Toolbar professionale** stile Canva/Figma con sezioni etichettate
-- [x] **Toolbar contestuale** per formattazione rapida (testo, forme, immagini)
-- [x] **Color picker integrato** con palette preset
-- [x] **Auto-save** con toggle (abilitato di default, 1s debounce)
-- [x] **Indicatore stato salvataggio** accurato (Salvato/Non salvato/Salvataggio...)
-
-### Cosa Manca per Completare
-
-#### Alta Priorità
-
-- [ ] **Caricamento immagini reali** - Attualmente placeholder, implementare upload e rendering
-- [ ] **Tabelle dinamiche** - Rendering collection dati (es. lista ospiti, articoli)
-- [ ] **Sezioni header/footer** - Ripetizione su ogni pagina
-- [ ] **Font custom** - Upload e utilizzo font TTF/OTF nei PDF
-
-#### Media Priorità
-
-- [ ] **Relazioni tra dataset** - UI per collegare campi tra dataset diversi
-- [ ] **Barcode/QRCode** - Supporto codici a barre
-- [ ] **Formule calcolate** - Espressioni matematiche nei campi
-- [ ] **Stili condizionali** - Formattazione basata su valore dati
-- [ ] **Raggruppamento elementi** - Group/ungroup nel canvas
-
-#### Bassa Priorità
-
-- [ ] **Template predefiniti** - Library di template pronti all'uso
-- [ ] **Anteprima live** - Preview in tempo reale durante editing
-- [x] ~~**Multi-pagina** - Editor pagine multiple~~ - COMPLETATO
-- [ ] **Righelli e guide** - Ausili allineamento avanzati
-- [ ] **Esportazione altri formati** - Excel, Word oltre PDF
-
----
-
-## Checklist Completamento Report System
-
-### Backend
-
-- [x] Entity ReportTemplate
-- [x] Entity ReportFont
-- [x] Entity ReportImage
-- [x] ReportTemplatesController (CRUD + clone + import/export)
-- [x] ReportResourcesController (fonts + images)
-- [x] ReportsController (generate + preview + schema + datasets)
-- [x] ReportGeneratorService con QuestPDF
-- [x] Schema dati per tutti i dataset (evento, cliente, location, articolo, risorsa)
-- [x] Generazione PDF default evento
-- [x] Generazione PDF multi-pagina
-- [ ] Rendering tabelle dinamiche da collection
-- [ ] Supporto font custom nel PDF
-- [ ] Rendering immagini da storage
-
-### Frontend
-
-- [x] ReportTemplatesPage (lista + filtri + azioni)
-- [x] ReportEditorPage (editor principale)
-- [x] EditorCanvas con Fabric.js v6
-- [x] EditorToolbar completa
-- [x] PropertiesPanel (posizione + stile + contenuto)
-- [x] DataBindingPanel multi-dataset
-- [x] DatasetSelector
-- [x] PreviewDialog con selezione entità
-- [x] Types APRT completi
-- [x] Services API completi
-- [x] Undo/Redo
-- [x] Keyboard shortcuts
-- [x] PageNavigator (gestione multi-pagina)
-- [x] Navigazione pagine in toolbar
-- [x] **Responsive design** (mobile/tablet/desktop)
-- [ ] Upload e gestione immagini nell'editor
-- [ ] Editor tabelle avanzato (colonne, binding dati)
-- [ ] UI relazioni tra dataset
-- [ ] Gestione sezioni header/footer
-
-### Testing
-
-- [x] Build frontend senza errori
-- [x] Build backend senza errori
-- [ ] Test funzionale editor canvas
-- [x] Test generazione PDF con dati reali (binding e formattazione funzionanti)
-- [ ] Test import/export template
-- [ ] Test con font e immagini custom
-
-### Documentazione
-
-- [x] Documentazione APRT metalanguage
-- [x] Lista API endpoints
-- [x] Checklist implementazione
-- [ ] Guida utente editor
-- [ ] Esempi template comuni
-
----
-
-## Note Tecniche per Future Sessioni
-
-### Struttura File Report System
-
-```
-src/
-├── Apollinare.Domain/Entities/
-│ ├── ReportTemplate.cs # Entity template con TemplateJson
-│ ├── ReportFont.cs # Font custom uploadati
-│ └── ReportImage.cs # Immagini riutilizzabili
-│
-├── Apollinare.API/
-│ ├── Controllers/
-│ │ ├── ReportTemplatesController.cs # CRUD template
-│ │ ├── ReportResourcesController.cs # Font e immagini
-│ │ └── ReportsController.cs # Generazione PDF + schema
-│ │
-│ └── Services/Reports/
-│ ├── ReportGeneratorService.cs # QuestPDF generator
-│ └── AprtModels.cs # Modelli C# per APRT JSON
-
-frontend/src/
-├── pages/
-│ ├── ReportTemplatesPage.tsx # Lista template
-│ └── ReportEditorPage.tsx # Editor principale
-│
-├── components/reportEditor/
-│ ├── EditorCanvas.tsx # Fabric.js canvas
-│ ├── EditorToolbar.tsx # Toolbar strumenti
-│ ├── PropertiesPanel.tsx # Proprietà elemento
-│ ├── DataBindingPanel.tsx # Browser campi dati
-│ ├── DatasetSelector.tsx # Selezione dataset
-│ ├── PreviewDialog.tsx # Dialog anteprima
-│ └── ContextMenu.tsx # Menu tasto destro (NEW)
-│
-├── types/
-│ └── report.ts # Types APRT + DTOs
-│
-└── services/
- └── reportService.ts # API calls
-```
-
-### Problemi Risolti (da ricordare)
-
-1. **Fabric.js v6 breaking changes:**
- - `sendToBack()` → `canvas.sendObjectToBack(obj)`
- - Event handlers hanno signature diversa
- - Proprietà `data` non è nel tipo base, serve cast a `FabricObjectWithData`
-
-2. **TypeScript strict mode:**
- - Usare `as any` per event handlers Fabric.js
- - Interface `FabricObjectWithData` per oggetti con metadata custom
-
-3. **QuestPDF TimeSpan:**
- - `evento.OraInizio` è `TimeSpan?` non `string`
- - Formattare con `{evento.OraInizio:hh\\:mm}`
-
-4. **Data Binding PDF (FIX 27/11/2025):**
- - **Problema:** I binding `{{dataEvento}}` non venivano risolti - PDF mostrava campi vuoti
- - **Causa:** Il frontend creava binding senza prefisso dataset quando c'era un solo dataset
- - **Soluzione Frontend** (`DataBindingPanel.tsx`): Sempre includere il prefisso dataset
- ```typescript
- // Prima: {{dataEvento}} - non funzionava
- // Dopo: {{evento.dataEvento}} - corretto
- const createBinding = (datasetId: string, fieldName: string) => {
- return `{{${datasetId}.${fieldName}}}`;
- };
- ```
- - **Soluzione Backend** (`ReportGeneratorService.cs`): Aggiunto fallback per compatibilità con template esistenti
- ```csharp
- // Se binding senza prefisso, cerca in tutti i dataset
- if (current == null && parts.Length == 1)
- {
- foreach (var kvp in dataContext)
- {
- var foundValue = GetPropertyValue(kvp.Value, path);
- if (foundValue != null) { current = foundValue; break; }
- }
- }
- ```
- - **Formattazione:** Aggiunto `ResolveBindingWithFormat()` per applicare format (date, currency, etc.)
-
-5. **SignalR Connection (FIX 27/11/2025):**
- - Aggiunto `app.UseWebSockets()` in Program.cs prima di `app.UseRouting()`
- - Configurato signalr.ts con `withAutomaticReconnect()`
-
-6. **MUI Fragment in Menu (FIX 27/11/2025):**
- - Menu component non accetta Fragment come child
- - Sostituire `<>...>` con array `[, ]`
-
-7. **HTML p/div nesting (FIX 27/11/2025):**
- - Error: `
cannot be a descendant of
`
- - Fix: ``
-
-8. **Context Menu Browser Default (FIX 27/11/2025 notte):**
- - **Problema:** Il menu contestuale del browser appariva invece di quello custom
- - **Soluzione:** Usare `onContextMenu` su Box container React invece di eventi Fabric.js
- - **File:** `EditorCanvas.tsx` - Aggiunto handler sul Box wrapper
-
-9. **Fabric.js v6 Layer Ordering (FIX 27/11/2025 notte):**
- - **Problema:** `canvas.moveTo()` non esiste in Fabric.js v6
- - **Soluzione:** Usare `canvas.remove(obj)` + `canvas.insertAt(targetIndex, obj)`
- - **File:** `EditorCanvas.tsx` - Aggiunto z-index sync in useEffect
-
-10. **QuestPDF Posizionamento Assoluto (RISOLTO 27/11/2025):**
- - **Problema:** QuestPDF non ha API `.Position()` per posizionamento assoluto
- - **Soluzione:** Usare SVG con `viewBox` in mm per avere coordinate 1:1 con il designer
- - **File:** `ReportGeneratorService.cs` - Metodi `GenerateSvgContent()`, `RenderElementToSvg()`
- - **Chiave della soluzione:**
- ```csharp
- // SVG viewBox in mm - 1 unità SVG = 1mm
- svgBuilder.AppendLine($"