This commit is contained in:
2025-11-29 13:30:28 +01:00
parent 824a761bf6
commit bb2d0729e1
16 changed files with 3102 additions and 37 deletions

528
CLAUDE.md
View File

@@ -46,12 +46,52 @@ XX. **Nome Problema (FIX/IMPLEMENTATO DATA):** - **Problema:** Descrizione breve
## Quick Start - Session Recovery
**Ultima sessione:** 29 Novembre 2025
**Ultima sessione:** 29 Novembre 2025 (sera)
**Stato progetto:** Migrazione Oracle APEX → .NET + React TypeScript in corso
**Lavoro completato nell'ultima sessione:**
- **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:**
@@ -274,15 +314,23 @@ XX. **Nome Problema (FIX/IMPLEMENTATO DATA):** - **Problema:** Descrizione breve
- **PDF Generator:** `/src/Apollinare.API/Services/Reports/ReportGeneratorService.cs`
- **Page Navigator:** `/frontend/src/components/reportEditor/PageNavigator.tsx`
**Prossimi task prioritari (Report System):**
**Prossimi task prioritari:**
1. [x] ~~**CRITICO: Posizionamento assoluto PDF**~~ - COMPLETATO
2. [x] ~~Implementare caricamento immagini reali~~ - COMPLETATO
3. [x] ~~**FIX: Rotazione oggetti nel PDF**~~ - COMPLETATO
4. [x] ~~**Gestione Multi-Pagina**~~ - COMPLETATO
5. [ ] Aggiungere rendering tabelle dinamiche per collection
6. [ ] Gestire sezioni header/footer ripetute su ogni pagina
7. [ ] UI per relazioni tra dataset multipli
**MODULI BUSINESS (PRIORITÀ ALTA):**
1. [ ] **Implementare modulo Magazzino (warehouse)** - Base per tutti gli altri
2. [ ] **Implementare modulo Acquisti (purchases)** - Dipende da Magazzino
3. [ ] **Implementare modulo Vendite (sales)** - Dipende da Magazzino
4. [ ] **Implementare modulo Produzione (production)** - Dipende da Magazzino
5. [ ] **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!):**
@@ -1345,3 +1393,465 @@ Migration già applicata per SQLite.
```
Menu aggiunto in `Layout.tsx` sotto "Report" con icona PrintIcon.
---
## Sistema Moduli - Architettura e Implementazione
### Overview
Sistema di modularizzazione dell'applicazione per gestione licenze, abbonamenti e funzionalità dinamiche. Ogni modulo rappresenta una sezione business completa (es. Magazzino, Acquisti, Vendite) che può essere attivata/disattivata per cliente.
### Requisiti Funzionali
**Moduli previsti:**
- `warehouse` - Magazzino (gestione inventario, movimenti, giacenze)
- `purchases` - Acquisti (ordini fornitori, DDT entrata, fatture passive)
- `sales` - Vendite (ordini clienti, DDT uscita, fatture attive)
- `production` - Produzione (cicli produttivi, distinte base, MRP)
- `quality` - Qualità (controlli, non conformità, certificazioni)
**Funzionalità Core (sempre attive):**
- Report e template PDF
- Gestione utenti e autenticazione (futuro)
- Dashboard e navigazione base
- Impostazioni sistema
### Comportamento UI
1. **Modulo attivo:** Menu visibile, route accessibili, funzionalità complete
2. **Modulo disattivato:**
- Menu nascosto
- Route redirect a pagina `/modules/purchase/{moduleCode}`
- Le funzioni di altri moduli che usavano dati del modulo disattivato continuano a funzionare (dati storici preservati)
### Modello Dati
```
AppModule (tabella moduli disponibili)
├── Id: int (PK)
├── Code: string (unique, es. "warehouse")
├── Name: string (es. "Magazzino")
├── Description: string
├── Icon: string (nome icona MUI)
├── BasePrice: decimal (prezzo base annuale)
├── MonthlyMultiplier: decimal (moltiplicatore per abbonamento mensile, es. 1.2)
├── SortOrder: int (ordine nel menu)
├── IsCore: bool (true = sempre attivo, non disattivabile)
├── Dependencies: string[] (codici moduli prerequisiti)
├── CreatedAt: DateTime
├── UpdatedAt: DateTime
ModuleSubscription (stato abbonamento per istanza)
├── Id: int (PK)
├── ModuleId: int (FK → AppModule)
├── IsEnabled: bool
├── SubscriptionType: enum (None, Monthly, Annual)
├── StartDate: DateTime?
├── EndDate: DateTime?
├── AutoRenew: bool
├── CreatedAt: DateTime
├── UpdatedAt: DateTime
```
### API Endpoints
```
# Moduli (lettura per tutti, scrittura solo admin)
GET /api/modules # Lista tutti i moduli con stato subscription
GET /api/modules/{code} # Dettaglio singolo modulo
GET /api/modules/active # Solo moduli attivi (per menu)
PUT /api/modules/{code}/enable # Attiva modulo
PUT /api/modules/{code}/disable # Disattiva modulo
# Subscriptions (admin only)
GET /api/modules/subscriptions # Lista tutte le subscription
PUT /api/modules/{code}/subscription # Aggiorna subscription (tipo, date)
POST /api/modules/{code}/subscription/renew # Rinnova abbonamento
```
### Frontend Architecture
**Context e State:**
- `ModuleContext.tsx` - React Context con stato moduli globale
- `useModules()` - Hook per accesso a lista moduli
- `useModuleEnabled(code)` - Hook per check singolo modulo
- `useActiveModules()` - Hook per moduli attivi (per menu)
**Componenti:**
- `ModuleGuard.tsx` - HOC/wrapper che verifica accesso a route
- `ModulePurchasePage.tsx` - Pagina acquisto/attivazione modulo
- `ModulesAdminPage.tsx` - Pannello admin gestione moduli
**Integrazione Menu (Layout.tsx):**
```typescript
// Filtra voci menu in base a moduli attivi
const menuItems = allMenuItems.filter(
(item) => !item.moduleCode || activeModuleCodes.includes(item.moduleCode),
);
```
**Routing (App.tsx):**
```typescript
// Route protette da modulo
<Route
path="/warehouse/*"
element={
<ModuleGuard moduleCode="warehouse">
<WarehouseRoutes />
</ModuleGuard>
}
/>
// Pagina acquisto modulo
<Route path="/modules/purchase/:code" element={<ModulePurchasePage />} />
```
### Logica Backend
**ModuleService:**
```csharp
public class ModuleService
{
// Verifica se modulo è attivo (usato da altri servizi)
public async Task<bool> IsModuleEnabledAsync(string code);
// Verifica subscription valida (non scaduta)
public async Task<bool> HasValidSubscriptionAsync(string code);
// Attiva modulo (crea/aggiorna subscription)
public async Task EnableModuleAsync(string code, SubscriptionType type, DateTime? endDate);
// Disattiva modulo (preserva dati)
public async Task DisableModuleAsync(string code);
// Job schedulato: controlla scadenze e disattiva moduli scaduti
public async Task CheckExpiredSubscriptionsAsync();
}
```
### Principi di Design
1. **Riutilizzo codice:** I moduli possono importare servizi/componenti da altri moduli
2. **Dati persistenti:** Disattivare un modulo non elimina i dati, solo nasconde l'accesso
3. **Dipendenze:** Un modulo può richiedere altri moduli (es. Produzione richiede Magazzino)
4. **Core inattaccabile:** Report, utenti, dashboard non sono disattivabili
5. **Check lato backend:** La verifica modulo avviene sempre sul server, mai solo frontend
6. **Cache:** Stato moduli cachato con invalidazione su modifica
### Struttura File
```
src/Apollinare.Domain/Entities/
├── AppModule.cs
└── ModuleSubscription.cs
src/Apollinare.API/
├── Controllers/
│ └── ModulesController.cs
├── Services/
│ └── ModuleService.cs
└── DTOs/
└── ModuleDtos.cs
frontend/src/
├── contexts/
│ └── ModuleContext.tsx
├── components/
│ └── ModuleGuard.tsx
├── pages/
│ ├── ModulesAdminPage.tsx
│ └── ModulePurchasePage.tsx
├── services/
│ └── moduleService.ts
└── types/
└── module.ts
```
### Checklist Implementazione
**Backend:**
- [x] Entity `AppModule`
- [x] Entity `ModuleSubscription`
- [x] `ModuleService` con logica business
- [x] `ModulesController` con tutti gli endpoint
- [x] DbSet e migration EF Core (tabelle create manualmente in SQLite)
- [x] Seed dati iniziali (5 moduli)
- [ ] Job controllo scadenze (opzionale - futuro)
**Frontend:**
- [x] Types `module.ts`
- [x] Service `moduleService.ts`
- [x] Context `ModuleContext.tsx`
- [x] Component `ModuleGuard.tsx`
- [x] Page `ModulesAdminPage.tsx`
- [x] Page `ModulePurchasePage.tsx`
- [x] Integrazione `Layout.tsx` per menu dinamico
- [x] Route protection in `App.tsx`
**Testing:**
- [x] API CRUD moduli
- [x] API subscription
- [x] Redirect su modulo disattivato
- [x] Menu filtrato correttamente
- [ ] Scadenza subscription (da testare con date reali)
---
## Prossimi Passi: Implementazione Moduli Business
**PRIORITÀ ALTA - Da implementare:**
I moduli sono stati definiti a livello infrastrutturale (sistema licenze/abbonamenti). Ora bisogna implementare le funzionalità reali di ogni modulo.
### Ordine di Implementazione Consigliato
1. **Magazzino (warehouse)** - Base per tutti gli altri moduli
2. **Acquisti (purchases)** - Dipende da Magazzino
3. **Vendite (sales)** - Dipende da Magazzino
4. **Produzione (production)** - Dipende da Magazzino
5. **Qualità (quality)** - Indipendente
### Architettura Modulare - Principi di Personalizzazione
**IMPORTANTE:** Ogni modulo deve essere facilmente personalizzabile da codice per adattarsi a esigenze specifiche del cliente.
**Struttura consigliata per ogni modulo:**
```
src/Apollinare.API/
├── Modules/
│ ├── Warehouse/
│ │ ├── Controllers/
│ │ │ └── WarehouseController.cs
│ │ ├── Services/
│ │ │ ├── IWarehouseService.cs # Interfaccia per DI/mock
│ │ │ └── WarehouseService.cs
│ │ ├── DTOs/
│ │ │ └── WarehouseDtos.cs
│ │ └── Configuration/
│ │ └── WarehouseConfig.cs # Configurazione modulo
│ ├── Purchases/
│ │ └── ...
│ └── Sales/
│ └── ...
src/Apollinare.Domain/
├── Entities/
│ ├── Warehouse/
│ │ ├── Article.cs
│ │ ├── StockMovement.cs
│ │ └── Warehouse.cs
│ ├── Purchases/
│ │ ├── PurchaseOrder.cs
│ │ └── Supplier.cs
│ └── Sales/
│ ├── SalesOrder.cs
│ └── Customer.cs
frontend/src/
├── modules/
│ ├── warehouse/
│ │ ├── pages/
│ │ │ ├── ArticlesPage.tsx
│ │ │ ├── StockMovementsPage.tsx
│ │ │ └── InventoryPage.tsx
│ │ ├── components/
│ │ │ └── ArticleForm.tsx
│ │ ├── services/
│ │ │ └── warehouseService.ts
│ │ ├── types/
│ │ │ └── warehouse.ts
│ │ ├── hooks/
│ │ │ └── useWarehouse.ts
│ │ └── routes.tsx # Route del modulo
│ ├── purchases/
│ │ └── ...
│ └── sales/
│ └── ...
```
**Pattern di Personalizzazione:**
1. **Interfacce per Services:** Usare sempre interfacce (`IWarehouseService`) per permettere override tramite DI
2. **Configurazione esterna:** Parametri configurabili in `appsettings.json` o database
3. **Hook points:** Esporre eventi/callback per estensioni custom
4. **Component composition:** Componenti React piccoli e componibili
5. **Feature flags:** Sotto-funzionalità attivabili/disattivabili per modulo
**Esempio configurazione modulo:**
```csharp
// WarehouseConfig.cs
public class WarehouseConfig
{
public bool EnableBarcodeScanning { get; set; } = true;
public bool EnableMultiWarehouse { get; set; } = false;
public bool EnableSerialTracking { get; set; } = false;
public bool EnableBatchTracking { get; set; } = false;
public int LowStockThreshold { get; set; } = 10;
public List<string> CustomFields { get; set; } = new();
}
```
**Esempio hook point per estensioni:**
```csharp
// IWarehouseService.cs
public interface IWarehouseService
{
// Metodi standard
Task<Article> GetArticleAsync(int id);
Task<Article> CreateArticleAsync(ArticleDto dto);
// Hook points per customizzazione
event Func<Article, Task>? OnArticleCreated;
event Func<StockMovement, Task<bool>>? OnBeforeStockMovement;
event Func<StockMovement, Task>? OnAfterStockMovement;
}
```
### Dettaglio Moduli da Implementare
#### 1. Magazzino (warehouse)
**Funzionalità:**
- Anagrafica articoli (CRUD, categorie, immagini)
- Gestione magazzini multipli (opzionale)
- Movimenti di magazzino (carico, scarico, trasferimento)
- Giacenze e disponibilità
- Inventario e rettifiche
- Alert scorte minime
- Codici a barre / QR code (opzionale)
- Tracciabilità lotti/serial (opzionale)
**Entità principali:**
- `Article` - Articolo/prodotto
- `ArticleCategory` - Categorie articoli
- `Warehouse` - Magazzino fisico
- `StockMovement` - Movimento di magazzino
- `StockLevel` - Giacenza per articolo/magazzino
#### 2. Acquisti (purchases)
**Funzionalità:**
- Anagrafica fornitori
- Richieste di acquisto (RDA)
- Ordini a fornitore (OdA)
- DDT entrata (ricezione merce)
- Fatture passive
- Listini fornitore
- Storico prezzi
**Entità principali:**
- `Supplier` - Fornitore
- `PurchaseRequest` - Richiesta d'acquisto
- `PurchaseOrder` - Ordine a fornitore
- `PurchaseOrderLine` - Riga ordine
- `GoodsReceipt` - DDT entrata
- `SupplierInvoice` - Fattura passiva
#### 3. Vendite (sales)
**Funzionalità:**
- Anagrafica clienti
- Preventivi
- Ordini cliente
- DDT uscita
- Fatture attive
- Listini cliente
- Provvigioni agenti (opzionale)
**Entità principali:**
- `Customer` - Cliente
- `Quote` - Preventivo
- `SalesOrder` - Ordine cliente
- `SalesOrderLine` - Riga ordine
- `DeliveryNote` - DDT uscita
- `Invoice` - Fattura attiva
#### 4. Produzione (production)
**Funzionalità:**
- Distinte base (BOM)
- Cicli di lavorazione
- Ordini di produzione
- Avanzamento produzione
- Pianificazione (MRP semplificato)
- Costi di produzione
**Entità principali:**
- `BillOfMaterials` - Distinta base
- `BomComponent` - Componente distinta
- `WorkCenter` - Centro di lavoro
- `ProductionOrder` - Ordine di produzione
- `ProductionStep` - Fase produzione
#### 5. Qualità (quality)
**Funzionalità:**
- Piani di controllo
- Controlli in accettazione
- Controlli in produzione
- Non conformità
- Azioni correttive
- Certificazioni/documenti
**Entità principali:**
- `ControlPlan` - Piano di controllo
- `QualityCheck` - Controllo qualità
- `NonConformity` - Non conformità
- `CorrectiveAction` - Azione correttiva
- `Certificate` - Certificazione
---
### Problemi Risolti Durante Implementazione
31. **EF Core Migration Fallita per Tabella Esistente (FIX 29/11/2025):**
- **Problema:** `dotnet ef database update` falliva con "Table 'Clienti' already exists"
- **Causa:** La migration tentava di ricreare tutte le tabelle invece di aggiungere solo quelle nuove
- **Soluzione:** Create tabelle manualmente via SQLite:
```sql
CREATE TABLE AppModules (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Code TEXT NOT NULL UNIQUE,
Name TEXT NOT NULL,
...
);
CREATE TABLE ModuleSubscriptions (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
ModuleId INTEGER NOT NULL REFERENCES AppModules(Id),
...
);
```
- **File:** Database SQLite, rimossa migration problematica
32. **TypeScript Unused Variables Build Errors (FIX 29/11/2025):**
- **Problema:** Build frontend falliva per variabili importate ma non usate
- **Soluzione:** Rimossi import inutilizzati:
- `ModuleGuard.tsx`: Rimosso `CircularProgress`, `showLoader`
- `ModuleContext.tsx`: Rimosso `useState`, `useEffect`
- `ModulePurchasePage.tsx`: Rimosso `moduleService` import
- `ModulesAdminPage.tsx`: Rimosso `PowerIcon`, `CheckIcon`, `CancelIcon`
- **File:** Vari componenti frontend