From b76a6760fb0018d00caead4502165eadf50c3300 Mon Sep 17 00:00:00 2001 From: Alessio Dal Santo Date: Fri, 12 Sep 2025 17:51:50 +0200 Subject: [PATCH] Aggiornata la documentazione per gli agents --- AGENTS.md | 921 ++++++++++++++++++ .../DOCUMENTAZIONE_DETTAGLIATA_PROGETTO.md | 591 ----------- 2 files changed, 921 insertions(+), 591 deletions(-) create mode 100644 AGENTS.md delete mode 100644 Data_Coupler/DOCUMENTAZIONE_DETTAGLIATA_PROGETTO.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..cdf5fb4 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,921 @@ +# Data-Coupler: Sistema di Integrazione Dati Multi-Platform + +## 📋 Project Overview + +**Data-Coupler** è una soluzione enterprise di integrazione dati sviluppata in .NET 9.0 con architettura Blazor Server. Il sistema facilita il trasferimento e la sincronizzazione di dati tra diverse tipologie di sorgenti: database relazionali, REST API, file Excel/CSV. + +### 🎯 Obiettivi del Progetto +- **Unificazione Data Sources**: Connessione trasparente a database eterogenei e API REST +- **Trasferimenti Sicuri**: Gestione crittografata delle credenziali cross-platform +- **Automazione**: Sistema di scheduling per operazioni periodiche +- **Mappatura Intelligente**: Sistema avanzato di mapping campi tra sorgenti diverse +- **Gestione Associazioni**: Tracking delle chiavi per evitare duplicati e gestire relazioni + +### 🏗️ Architettura del Sistema + +#### Struttura Modulare +``` +Data-Coupler/ +├── Data_Coupler/ # 🎯 Applicazione principale Blazor Server +├── DataConnection/ # 🔌 Libreria core per connessioni dati +├── CredentialManager/ # 🔐 Gestione sicura credenziali +├── Components/ # 🧩 Componenti UI riutilizzabili +└── DatabaseUpdater/ # 🔧 Utility per manutenzione database +``` + +#### Stack Tecnologico +- **.NET 9.0**: Framework principale +- **Blazor Server**: Framework UI reattivo +- **Entity Framework Core**: ORM per accesso dati +- **SQLite**: Database embedded per configurazioni +- **Bootstrap 5**: Framework CSS responsive + +#### Database Supportati +- SQL Server, MySQL, PostgreSQL, Oracle, SQLite, IBM DB2, SAP HANA + +#### REST API Supportate +- Generic REST APIs, Salesforce, SAP Business One Service Layer + +## 🔨 Build and Test Commands + +### Prerequisiti +- .NET 9.0 SDK +- Git per clone del repository +- Editor: Visual Studio 2022, VS Code, o Rider + +### Setup Ambiente di Sviluppo +```bash +# Clone del repository +git clone https://github.com/AlessioDalsi/Data-Coupler.git +cd Data-Coupler + +# Restore dei pacchetti NuGet +dotnet restore Data_Coupler.sln +``` + +### Build Commands + +#### Build Development +```bash +# Build completo della soluzione +dotnet build Data_Coupler.sln + +# Build singolo progetto +dotnet build Data_Coupler/Data_Coupler.csproj +dotnet build DataConnection/DataConnection.csproj +dotnet build CredentialManager/CredentialManager.csproj +``` + +#### Build Production +```bash +# Build release +dotnet build Data_Coupler.sln --configuration Release + +# Publish per deployment +dotnet publish Data_Coupler/Data_Coupler.csproj \ + --configuration Release \ + --output ./publish \ + --self-contained true \ + --runtime win-x64 +``` + +#### Build per Diverse Piattaforme +```bash +# Windows x64 +dotnet publish --runtime win-x64 --configuration Release + +# Linux x64 +dotnet publish --runtime linux-x64 --configuration Release + +# macOS x64 +dotnet publish --runtime osx-x64 --configuration Release + +# macOS ARM64 (Apple Silicon) +dotnet publish --runtime osx-arm64 --configuration Release +``` + +### Run Commands + +#### Sviluppo Locale +```bash +# Avvio applicazione principale +dotnet run --project Data_Coupler/Data_Coupler.csproj + +# Avvio con hot reload +dotnet watch run --project Data_Coupler/Data_Coupler.csproj + +# Avvio su porta specifica +dotnet run --project Data_Coupler/Data_Coupler.csproj --urls "http://localhost:8080" +``` + +#### Utility e Manutenzione +```bash +# Aggiornamento database +dotnet run --project DatabaseUpdater/DatabaseUpdater.csproj + +# Creazione migrazione Entity Framework +cd CredentialManager +dotnet ef migrations add [MigrationName] +dotnet ef database update +``` + +### Test Commands + +#### Esecuzione Test Unitari +```bash +# Esecuzione tutti i test +dotnet test Data_Coupler.sln + +# Test con verbosità dettagliata +dotnet test Data_Coupler.sln --verbosity detailed + +# Test con coverage +dotnet test Data_Coupler.sln --collect:"XPlat Code Coverage" + +# Test specifici per progetto +dotnet test DataConnection.Tests/DataConnection.Tests.csproj +dotnet test CredentialManager.Tests/CredentialManager.Tests.csproj +``` + +#### Test di Integrazione +```bash +# Test di integrazione database +dotnet test --filter "Category=Integration" + +# Test connessioni REST +dotnet test --filter "Category=RestIntegration" + +# Test end-to-end +dotnet test --filter "Category=E2E" +``` + +#### Performance Testing +```bash +# Benchmark performance +dotnet run --project PerformanceTests/PerformanceTests.csproj --configuration Release + +# Memory profiling +dotnet run --project Data_Coupler/Data_Coupler.csproj --configuration Release +# Utilizzare strumenti come dotMemory o PerfView +``` + +## 📝 Code Style Guidelines + +### Convenzioni di Naming + +#### C# Naming Conventions +```csharp +// Classes e Interfaces: PascalCase +public class DataConnectionFactory { } +public interface IDatabaseManager { } + +// Methods: PascalCase +public async Task> GetDataAsync() { } + +// Properties: PascalCase +public string ConnectionString { get; set; } + +// Private fields: camelCase con underscore +private readonly ILogger _logger; + +// Local variables e parameters: camelCase +public void ProcessData(string connectionName, int batchSize) { } + +// Constants: PascalCase +public const string DefaultTimeout = "30"; +``` + +#### File e Directory Naming +``` +// Cartelle: PascalCase +Services/ +Models/ +Extensions/ + +// File C#: PascalCase con classe principale +DatabaseConnectionService.cs +CredentialEntity.cs + +// File Razor: PascalCase +DataCoupler.razor +ProfileManagement.razor +``` + +### Organizzazione Codice + +#### Structure dei File +```csharp +using System; // System namespaces +using System.Collections.Generic; +using Microsoft.Extensions; // Microsoft namespaces +using DataConnection.Interfaces; // Project namespaces +using ThirdParty.Library; // Third-party namespaces + +namespace Data_Coupler.Services +{ + /// + /// Descrizione chiara della classe + /// + public class ExampleService : IExampleService + { + #region Private Fields + private readonly ILogger _logger; + #endregion + + #region Constructor + public ExampleService(ILogger logger) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + #endregion + + #region Public Methods + public async Task ProcessAsync(Request request) + { + // Implementation + } + #endregion + + #region Private Methods + private void ValidateRequest(Request request) + { + // Validation logic + } + #endregion + } +} +``` + +#### Async/Await Pattern +```csharp +// ✅ Corretto +public async Task> GetDataAsync(CancellationToken cancellationToken = default) +{ + var data = await _repository.GetDataAsync(cancellationToken); + return data.ToList(); +} + +// ❌ Evitare +public async Task> GetData() +{ + var data = await _repository.GetDataAsync().Result; // Blocking call + return data.ToList(); +} +``` + +#### Error Handling +```csharp +// ✅ Gestione errori strutturata +public async Task> ProcessDataAsync(string input) +{ + try + { + if (string.IsNullOrWhiteSpace(input)) + return Result.Failure("Input cannot be empty"); + + var data = await _service.ProcessAsync(input); + return Result.Success(data); + } + catch (ValidationException ex) + { + _logger.LogWarning(ex, "Validation failed for input: {Input}", input); + return Result.Failure(ex.Message); + } + catch (Exception ex) + { + _logger.LogError(ex, "Unexpected error processing input: {Input}", input); + return Result.Failure("An unexpected error occurred"); + } +} +``` + +### Dependency Injection Guidelines + +#### Service Registration +```csharp +// Program.cs - Registrazione servizi +// Singleton per servizi stateless +builder.Services.AddSingleton(); + +// Scoped per servizi con stato per request +builder.Services.AddScoped(); + +// Transient per servizi leggeri +builder.Services.AddTransient, ModelValidator>(); +``` + +#### Constructor Injection +```csharp +public class ProfileService +{ + private readonly IDbContext _context; + private readonly ILogger _logger; + private readonly IOptions _options; + + public ProfileService( + IDbContext context, + ILogger logger, + IOptions options) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _options = options ?? throw new ArgumentNullException(nameof(options)); + } +} +``` + +### Commenti e Documentazione + +#### XML Documentation +```csharp +/// +/// Trasferisce dati da una sorgente a una destinazione utilizzando il mapping specificato +/// +/// Connessione alla sorgente dati +/// Connessione alla destinazione +/// Configurazione mapping campi +/// Token per cancellazione operazione +/// Risultato del trasferimento con statistiche +/// Lanciata quando un parametro richiesto è null +/// Lanciata quando le connessioni non sono valide +public async Task TransferDataAsync( + IDataConnection sourceConnection, + IDataConnection destinationConnection, + FieldMapping mapping, + CancellationToken cancellationToken = default) +{ + // Implementation +} +``` + +## 🧪 Testing Instructions + +### Struttura Test + +#### Test Project Organization +``` +Tests/ +├── Unit/ # Test unitari +│ ├── Data_Coupler.Tests/ +│ ├── DataConnection.Tests/ +│ └── CredentialManager.Tests/ +├── Integration/ # Test di integrazione +│ ├── Database.Integration.Tests/ +│ └── API.Integration.Tests/ +└── E2E/ # Test end-to-end + └── UI.Tests/ +``` + +### Test Unitari + +#### Setup Test Class +```csharp +[TestClass] +public class CredentialServiceTests +{ + private Mock _mockContext; + private Mock _mockEncryption; + private Mock> _mockLogger; + private CredentialService _service; + + [TestInitialize] + public void Setup() + { + _mockContext = new Mock(); + _mockEncryption = new Mock(); + _mockLogger = new Mock>(); + + _service = new CredentialService( + _mockContext.Object, + _mockEncryption.Object, + _mockLogger.Object); + } + + [TestCleanup] + public void Cleanup() + { + _service?.Dispose(); + } +} +``` + +#### Test Methods Pattern +```csharp +[TestMethod] +public async Task GetCredentialAsync_WithValidName_ReturnsCredential() +{ + // Arrange + var credentialName = "TestCredential"; + var expectedCredential = new CredentialEntity { Name = credentialName }; + + _mockContext.Setup(x => x.Credentials.FirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny())) + .ReturnsAsync(expectedCredential); + + // Act + var result = await _service.GetCredentialAsync(credentialName); + + // Assert + Assert.IsNotNull(result); + Assert.AreEqual(credentialName, result.Name); + _mockContext.Verify(x => x.Credentials.FirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny()), Times.Once); +} + +[TestMethod] +public async Task GetCredentialAsync_WithNullName_ThrowsArgumentNullException() +{ + // Act & Assert + await Assert.ThrowsExceptionAsync( + () => _service.GetCredentialAsync(null)); +} +``` + +### Test di Integrazione + +#### Database Integration Tests +```csharp +[TestClass] +public class DatabaseIntegrationTests +{ + private TestDatabase _testDb; + private IDatabaseManager _databaseManager; + + [TestInitialize] + public async Task Setup() + { + _testDb = await TestDatabase.CreateAsync(); + _databaseManager = new EFCoreDatabaseManager(_testDb.ConnectionString); + } + + [TestCleanup] + public async Task Cleanup() + { + await _testDb.DisposeAsync(); + } + + [TestMethod] + public async Task ExecuteQueryAsync_WithValidQuery_ReturnsData() + { + // Arrange + await _testDb.SeedDataAsync(); + var query = "SELECT * FROM TestTable WHERE Id = 1"; + + // Act + var result = await _databaseManager.ExecuteQueryAsync(query); + + // Assert + Assert.IsNotNull(result); + Assert.IsTrue(result.Any()); + } +} +``` + +#### REST API Integration Tests +```csharp +[TestClass] +public class RestApiIntegrationTests +{ + private TestServer _testServer; + private HttpClient _client; + + [TestInitialize] + public void Setup() + { + var builder = WebApplication.CreateBuilder(); + // Configure test server + _testServer = new TestServer(builder); + _client = _testServer.CreateClient(); + } + + [TestMethod] + public async Task GetData_WithValidCredentials_ReturnsSuccess() + { + // Arrange + var apiClient = new GenericRestServiceClient(_client); + + // Act + var result = await apiClient.GetAsync("/api/data"); + + // Assert + Assert.IsNotNull(result); + Assert.IsTrue(result.Success); + } +} +``` + +### Test End-to-End + +#### Playwright UI Tests +```csharp +[TestClass] +public class UITests +{ + private IPlaywright _playwright; + private IBrowser _browser; + private IPage _page; + + [TestInitialize] + public async Task Setup() + { + _playwright = await Playwright.CreateAsync(); + _browser = await _playwright.Chromium.LaunchAsync(); + _page = await _browser.NewPageAsync(); + } + + [TestMethod] + public async Task DataTransfer_CompleteWorkflow_Success() + { + // Navigate to application + await _page.GotoAsync("http://localhost:7550"); + + // Configure source connection + await _page.ClickAsync("#source-database-tab"); + await _page.FillAsync("#connection-name", "TestConnection"); + + // Configure mapping + await _page.ClickAsync("#next-step"); + + // Execute transfer + await _page.ClickAsync("#execute-transfer"); + + // Verify results + var successMessage = await _page.WaitForSelectorAsync(".success-message"); + Assert.IsNotNull(successMessage); + } +} +``` + +### Test Configuration + +#### appsettings.Test.json +```json +{ + "ConnectionStrings": { + "DefaultConnection": "Data Source=:memory:", + "TestDatabase": "Server=(localdb)\\mssqllocaldb;Database=DataCouplerTest;Trusted_Connection=true;" + }, + "Logging": { + "LogLevel": { + "Default": "Debug", + "Microsoft": "Warning" + } + }, + "TestSettings": { + "UseInMemoryDatabase": true, + "MockExternalServices": true + } +} +``` + +### Test Execution Scripts + +#### PowerShell Test Runner +```powershell +# run-tests.ps1 +param( + [string]$Configuration = "Debug", + [string]$Filter = "", + [switch]$Coverage +) + +Write-Host "Running tests..." -ForegroundColor Green + +if ($Coverage) { + dotnet test Data_Coupler.sln ` + --configuration $Configuration ` + --collect:"XPlat Code Coverage" ` + --results-directory TestResults ` + --filter $Filter + + # Generate coverage report + reportgenerator ` + -reports:"TestResults/*/coverage.cobertura.xml" ` + -targetdir:"TestResults/CoverageReport" ` + -reporttypes:Html +} else { + dotnet test Data_Coupler.sln ` + --configuration $Configuration ` + --filter $Filter +} +``` + +## 🔒 Security Considerations + +### Gestione Credenziali + +#### Crittografia dei Dati Sensibili +```csharp +public class EncryptionService : IEncryptionService +{ + private readonly IDataProtector _protector; + + public EncryptionService(IDataProtectionProvider provider) + { + _protector = provider.CreateProtector("DataCoupler.Credentials.v1"); + } + + public string Encrypt(string plaintext) + { + if (string.IsNullOrEmpty(plaintext)) + return plaintext; + + return _protector.Protect(plaintext); + } + + public string Decrypt(string ciphertext) + { + if (string.IsNullOrEmpty(ciphertext)) + return ciphertext; + + try + { + return _protector.Unprotect(ciphertext); + } + catch (CryptographicException) + { + // Handle decryption failure + throw new SecurityException("Failed to decrypt data"); + } + } +} +``` + +#### Configurazione Data Protection +```csharp +// Program.cs +builder.Services.AddDataProtection() + .PersistKeysToFileSystem(new DirectoryInfo(keyPath)) + .SetApplicationName("DataCoupler") + .SetDefaultKeyLifetime(TimeSpan.FromDays(90)); +``` + +### Validazione Input + +#### SQL Injection Prevention +```csharp +// ✅ Parametrized Queries +public async Task> GetDataAsync(string tableName, int id) +{ + // Validate table name against whitelist + if (!IsValidTableName(tableName)) + throw new ArgumentException("Invalid table name"); + + var query = $"SELECT * FROM [{tableName}] WHERE Id = @id"; + var parameters = new { id }; + + return await _connection.QueryAsync(query, parameters); +} + +// ❌ Mai utilizzare string concatenation +public async Task> GetDataUnsafe(string tableName, int id) +{ + var query = $"SELECT * FROM {tableName} WHERE Id = {id}"; // VULNERABLE + return await _connection.QueryAsync(query); +} +``` + +#### Input Sanitization +```csharp +public class InputValidator +{ + private static readonly Regex AllowedTableName = new(@"^[a-zA-Z][a-zA-Z0-9_]*$"); + private static readonly Regex AllowedFieldName = new(@"^[a-zA-Z][a-zA-Z0-9_]*$"); + + public static bool IsValidTableName(string tableName) + { + return !string.IsNullOrWhiteSpace(tableName) && + tableName.Length <= 128 && + AllowedTableName.IsMatch(tableName); + } + + public static bool IsValidFieldName(string fieldName) + { + return !string.IsNullOrWhiteSpace(fieldName) && + fieldName.Length <= 128 && + AllowedFieldName.IsMatch(fieldName); + } + + public static string SanitizeStringInput(string input, int maxLength = 255) + { + if (string.IsNullOrEmpty(input)) + return string.Empty; + + // Remove potential XSS characters + input = input.Replace("<", "<") + .Replace(">", ">") + .Replace("\"", """) + .Replace("'", "'") + .Replace("/", "/"); + + return input.Length > maxLength ? input.Substring(0, maxLength) : input; + } +} +``` + +### Autenticazione e Autorizzazione + +#### Connection Security +```csharp +public class SecureConnectionFactory : IDataConnectionFactory +{ + public async Task CreateDatabaseManagerAsync(string credentialName) + { + var credential = await _credentialService.GetCredentialAsync(credentialName); + if (credential == null) + throw new UnauthorizedAccessException("Credential not found"); + + // Validate credential permissions + if (!await ValidateCredentialPermissions(credential)) + throw new UnauthorizedAccessException("Insufficient permissions"); + + // Create connection with timeout + var connectionString = BuildSecureConnectionString(credential); + return new DatabaseManager(connectionString); + } + + private string BuildSecureConnectionString(CredentialEntity credential) + { + var builder = new SqlConnectionStringBuilder + { + DataSource = credential.Host, + InitialCatalog = credential.DatabaseName, + UserID = credential.Username, + Password = _encryptionService.Decrypt(credential.EncryptedPassword), + + // Security settings + Encrypt = true, + TrustServerCertificate = false, + ConnectTimeout = 30, + CommandTimeout = 300 + }; + + return builder.ConnectionString; + } +} +``` + +### HTTPS e Comunicazioni Sicure + +#### HTTPS Configuration +```csharp +// Program.cs +if (!app.Environment.IsDevelopment()) +{ + app.UseHsts(); + app.UseHttpsRedirection(); +} + +// Force HTTPS in production +app.Use(async (context, next) => +{ + if (!context.Request.IsHttps && !app.Environment.IsDevelopment()) + { + var httpsUrl = $"https://{context.Request.Host}{context.Request.Path}{context.Request.QueryString}"; + context.Response.Redirect(httpsUrl, permanent: true); + return; + } + await next(); +}); +``` + +#### HTTP Client Security +```csharp +public class SecureHttpClientFactory +{ + public HttpClient CreateSecureClient(RestCredentialSettings settings) + { + var handler = new HttpClientHandler(); + + if (!settings.IgnoreSslErrors) + { + handler.ServerCertificateCustomValidationCallback = + (sender, cert, chain, sslPolicyErrors) => + { + // Validate certificate chain + return sslPolicyErrors == SslPolicyErrors.None; + }; + } + + var client = new HttpClient(handler) + { + Timeout = TimeSpan.FromSeconds(settings.TimeoutSeconds) + }; + + // Add security headers + client.DefaultRequestHeaders.Add("User-Agent", "DataCoupler/1.0"); + client.DefaultRequestHeaders.Add("X-Requested-With", "XMLHttpRequest"); + + return client; + } +} +``` + +### Logging e Audit + +#### Secure Logging +```csharp +public class SecurityAuditLogger +{ + private readonly ILogger _logger; + + public void LogCredentialAccess(string credentialName, string operation, string userId) + { + _logger.LogInformation( + "Credential Access: {Operation} on {CredentialName} by {UserId} at {Timestamp}", + operation, credentialName, userId, DateTime.UtcNow); + } + + public void LogDataTransfer(string sourceType, string destinationType, int recordCount, string userId) + { + _logger.LogInformation( + "Data Transfer: {RecordCount} records from {SourceType} to {DestinationType} by {UserId} at {Timestamp}", + recordCount, sourceType, destinationType, userId, DateTime.UtcNow); + } + + public void LogSecurityEvent(string eventType, string details, string userId) + { + _logger.LogWarning( + "Security Event: {EventType} - {Details} by {UserId} at {Timestamp}", + eventType, details, userId, DateTime.UtcNow); + } +} +``` + +### Error Handling Sicuro + +#### Information Disclosure Prevention +```csharp +public class SecureErrorHandler +{ + private readonly ILogger _logger; + + public ErrorResponse HandleError(Exception ex, bool isDevelopment) + { + // Log full error details + _logger.LogError(ex, "Error occurred: {Message}", ex.Message); + + // Return sanitized error to client + if (isDevelopment) + { + return new ErrorResponse + { + Message = ex.Message, + StackTrace = ex.StackTrace, + Type = ex.GetType().Name + }; + } + + // Production: return generic message + return new ErrorResponse + { + Message = "An error occurred while processing your request", + ErrorId = Guid.NewGuid().ToString() // For correlation + }; + } +} +``` + +### Database Security + +#### Connection Security +```csharp +public class DatabaseSecuritySettings +{ + public static SqlConnectionStringBuilder CreateSecureConnectionString( + string server, string database, string username, string password) + { + return new SqlConnectionStringBuilder + { + DataSource = server, + InitialCatalog = database, + UserID = username, + Password = password, + + // Security settings + Encrypt = true, + TrustServerCertificate = false, + IntegratedSecurity = false, + MultipleActiveResultSets = false, + + // Timeout settings + ConnectTimeout = 30, + CommandTimeout = 300, + + // Connection pooling + Pooling = true, + MinPoolSize = 0, + MaxPoolSize = 100 + }; + } +} +``` + +--- + +**Versione**: 1.0 +**Ultimo Aggiornamento**: Settembre 2025 +**Framework**: .NET 9.0 +**Sviluppatore**: Alessio Dalsanto \ No newline at end of file diff --git a/Data_Coupler/DOCUMENTAZIONE_DETTAGLIATA_PROGETTO.md b/Data_Coupler/DOCUMENTAZIONE_DETTAGLIATA_PROGETTO.md deleted file mode 100644 index e317574..0000000 --- a/Data_Coupler/DOCUMENTAZIONE_DETTAGLIATA_PROGETTO.md +++ /dev/null @@ -1,591 +0,0 @@ -# Data-Coupler: Documentazione Completa del Progetto - -## Indice -1. [Descrizione Generale del Progetto](#descrizione-generale-del-progetto) -2. [Architettura e Struttura del Progetto](#architettura-e-struttura-del-progetto) -3. [Mappatura dei Progetti della Soluzione](#mappatura-dei-progetti-della-soluzione) -4. [Funzionalità Dettagliate](#funzionalità-dettagliate) -5. [Mappa delle Funzioni e Procedure](#mappa-delle-funzioni-e-procedure) -6. [Riferimenti Esterni e Percorsi](#riferimenti-esterni-e-percorsi) -7. [Interconnessioni tra Componenti](#interconnessioni-tra-componenti) -8. [Stato delle Implementazioni](#stato-delle-implementazioni) -9. [Utilizzo e Configurazione](#utilizzo-e-configurazione) - ---- - -## Descrizione Generale del Progetto - -**Data-Coupler** è un sistema avanzato per l'accoppiamento e sincronizzazione di dati tra diverse fonti di dati e destinazioni. Il progetto è sviluppato in .NET 9.0 utilizzando Blazor Server e fornisce un'interfaccia web intuitiva per configurare, gestire ed eseguire operazioni di trasferimento dati. - -### Funzionalità Principali -- **Connessione Multi-Database**: Supporta SQL Server, MySQL, PostgreSQL, Oracle, SQLite, DB2, SAP HANA -- **Integrazione REST API**: Supporta API generiche, Salesforce, SAP Business One Service Layer -- **Elaborazione File**: Gestisce file Excel (.xlsx, .xls) e CSV -- **Sistema di Mapping**: Mappatura intelligente dei campi tra sorgenti e destinazioni -- **Gestione Associazioni**: Sistema di tracking delle chiavi per evitare duplicati -- **Gestione Profili**: Salvataggio e riutilizzo di configurazioni -- **Background Services**: Servizi in background per operazioni periodiche -- **Sicurezza**: Crittografia delle credenziali cross-platform - -### Caratteristiche Tecniche -- **Framework**: .NET 9.0, Blazor Server -- **Database**: SQLite con Entity Framework Core -- **UI**: Bootstrap 5, Font Awesome -- **Architettura**: Modulare con separazione delle responsabilità -- **Cross-Platform**: Windows, Linux, macOS - ---- - -## Architettura e Struttura del Progetto - -Il progetto segue un'architettura modulare con separazione chiara delle responsabilità: - -``` -Data-Coupler/ -├── Data_Coupler/ # Applicazione principale Blazor Server -├── DataConnection/ # Libreria per connessioni dati -├── CredentialManager/ # Gestione sicura delle credenziali -├── Components/ # Componenti UI riutilizzabili -└── Documentation/ # File di documentazione -``` - -### Principi Architetturali -1. **Separation of Concerns**: Ogni progetto ha responsabilità specifiche -2. **Dependency Injection**: Utilizzo estensivo di DI per loose coupling -3. **Factory Pattern**: Per la creazione di connessioni database e REST -4. **Repository Pattern**: Per l'accesso ai dati -5. **Service Layer**: Logica business separata dalla presentazione - ---- - -## Mappatura dei Progetti della Soluzione - -### 1. Data_Coupler (Progetto Principale) -**Tipo**: Applicazione Web Blazor Server -**Tecnologie**: .NET 9.0, Blazor Server, Bootstrap 5 -**Responsabilità**: Interfaccia utente principale e orchestrazione - -#### Strutture Principali: -- **Pages/**: Pagine Blazor per le diverse funzionalità - - `DataCoupler.razor(.cs)`: Pagina principale per il trasferimento dati - - `ProfilesManagement.razor(.cs)`: Gestione dei profili salvati - - `CredentialManagement.razor`: Gestione delle credenziali - - `KeyAssociations.razor`: Gestione delle associazioni chiavi -- **Extensions/DataCoupler/**: Metodi estesi per funzionalità specifiche - - `DatabaseMethod.cs`: Metodi per connessioni database - - `RESTMethod.cs`: Metodi per connessioni REST API -- **Services/**: Servizi dell'applicazione - - `DataConnectionFactory.cs`: Factory per connessioni dati -- **Models/**: Modelli di dati specifici dell'app - - `DataCouplerModels.cs`: Modelli per risultati trasferimenti -- **BackgroundServices/**: Servizi in background - - `BackgroundServices.cs`: Servizi periodici (attualmente placeholder) - -### 2. DataConnection (Libreria Core) -**Tipo**: Class Library -**Responsabilità**: Gestione connessioni database e REST API - -#### Strutture Principali: -- **DB/**: Gestione database - - **Interfaces/**: Interfacce per abstraction layer - - `IDatabaseManager.cs`: Interfaccia principale per database - - `IDatabaseSchemaProvider.cs`: Provider per schema discovery - - `IDatabaseDiscovery.cs`: Discovery di database disponibili - - **EF/**: Implementazioni Entity Framework - - `EFCoreDatabaseManager.cs`: Manager EF Core per database esistenti - - **DatabaseDiscovery/**: Discovery specifiche per DB type -- **REST/**: Gestione REST API - - **Interfaces/**: Interfacce REST - - **Implementations/**: Implementazioni specifiche (Salesforce, Generic) - - **Models/**: Modelli per richieste/risposte REST -- **CredentialManagement/**: Integrazione con CredentialManager - -### 3. CredentialManager (Gestione Credenziali) -**Tipo**: Class Library -**Responsabilità**: Gestione sicura delle credenziali - -#### Strutture Principali: -- **Data/**: Contesto Entity Framework - - `CredentialDbContext.cs`: DbContext per credenziali -- **Models/**: Modelli di dati - - `CredentialModels.cs`: DTOs per credenziali - - `CredentialEntity.cs`: Entità database - - `KeyAssociation.cs`: Modello per associazioni chiavi - - `DataCouplerProfile.cs`: Modello per profili salvati -- **Services/**: Servizi di gestione - - `CredentialService.cs`: Servizio principale per credenziali - - `DataCouplerProfileService.cs`: Gestione profili -- **Utilities/**: Utilità varie - - `EncryptionService.cs`: Crittografia cross-platform -- **Integration/**: Helper per integrazione - - `DataConnectionHelper.cs`: Utilità per DataConnection - -### 4. Components (Componenti UI) -**Tipo**: Razor Class Library -**Responsabilità**: Componenti UI riutilizzabili - -#### Componenti Principali: -- `ProfileManagement.razor(.cs)`: Componente per gestione profili -- `ProfileSelector.razor(.cs)`: Selettore di profili -- `ProfileSaver.razor(.cs)`: Componente per salvare profili - ---- - -## Funzionalità Dettagliate - -### 1. Gestione Sorgenti Dati - -#### Connessioni Database -- **Supporto Multi-DB**: SQL Server, MySQL, PostgreSQL, Oracle, SQLite, DB2, SAP HANA -- **Schema Discovery**: Automatic discovery di tabelle, colonne e metadati -- **Query Custom**: Supporto per query SQL personalizzate -- **Connection String Generation**: Generazione automatica connection string -- **Test Connessioni**: Validazione connessioni prima dell'uso - -#### Elaborazione File -- **Formati Supportati**: Excel (.xlsx, .xls), CSV -- **Multi-Sheet**: Gestione fogli multipli in Excel -- **Preview Data**: Anteprima dati con paginazione -- **Encoding Detection**: Rilevamento automatico encoding - -#### Connessioni REST API -- **API Generiche**: Supporto per REST API standard -- **Salesforce**: Integrazione specifica con autenticazione OAuth -- **SAP B1 Service Layer**: Integrazione con SAP Business One -- **Composite API**: Ottimizzazione per operazioni batch (Salesforce) - -### 2. Sistema di Mapping - -#### Mapping Campi -- **Drag & Drop**: Interfaccia intuitiva per mapping -- **Auto-Detection**: Rilevamento automatico campi simili -- **Validazione**: Controllo compatibilità tipi dati -- **Preview**: Anteprima risultati mapping - -#### Gestione Chiavi -- **Chiavi Sorgente**: Identificazione univoca record sorgente -- **Chiavi Destinazione**: Tracking ID destinazione -- **Associazioni**: Sistema di associazioni per evitare duplicati -- **Hash Verification**: Controllo modifiche tramite hash dati - -### 3. Trasferimento Dati - -#### Modalità di Trasferimento -- **Insert**: Creazione nuovi record -- **Update**: Aggiornamento record esistenti -- **Upsert**: Insert o update automatico -- **Batch Processing**: Elaborazione in lotti per performance - -#### Gestione Errori -- **Logging Dettagliato**: Log completi di ogni operazione -- **Error Handling**: Gestione granulare degli errori -- **Rollback**: Possibilità di rollback operazioni -- **Report Risultati**: Report dettagliati successi/errori - -### 4. Gestione Profili - -#### Salvataggio Configurazioni -- **Profili Completi**: Salvataggio di tutte le configurazioni -- **Metadati**: Nome, descrizione, data creazione/utilizzo -- **Versioning**: Gestione versioni profili -- **Export/Import**: Esportazione profili in JSON - -#### Gestione Profili -- **Lista Profili**: Visualizzazione tutti i profili salvati -- **Filtri**: Ricerca per nome, tipo, utilizzo -- **Statistiche**: Dashboard con statistiche utilizzo -- **Eliminazione**: Soft delete profili - ---- - -## Mappa delle Funzioni e Procedure - -### Data_Coupler.Pages.DataCoupler - -#### Metodi di Gestione Stato -- `OnInitializedAsync()`: Inizializzazione componente -- `LoadCredentials()`: Caricamento credenziali database/REST -- `LoadProfiles()`: Caricamento profili disponibili -- `ResetAllState()`: Reset completo stato applicazione - -#### Metodi Database (DatabaseMethod.cs) -- `ConnectToDatabase()`: Connessione database principale -- `ConnectToDatabaseWithSpecificDatabase(string)`: Connessione a DB specifico -- `ConnectToDatabaseWithSchema(string)`: Connessione con schema specifico -- `LoadTablesFromConnectedDatabase()`: Caricamento tabelle -- `LoadAvailableDatabases()`: Discovery database disponibili -- `SelectTable(string)`: Selezione tabella e caricamento schema -- `ValidateCustomQuery()`: Validazione query personalizzate -- `LoadQueryPreview()`: Anteprima risultati query - -#### Metodi REST (RESTMethod.cs) -- `ConnectToRestService()`: Connessione servizio REST -- `LoadRestMetadata()`: Caricamento metadati REST -- `TestRestConnection()`: Test connessione REST API - -#### Metodi File -- `ProcessFileUpload()`: Elaborazione file caricati -- `LoadFileData()`: Lettura dati da file -- `ParseExcelFile()`: Parsing file Excel -- `ParseCsvFile()`: Parsing file CSV - -#### Metodi Mapping -- `MapField(string, string)`: Mapping singolo campo -- `RemoveMapping(string)`: Rimozione mapping -- `ClearAllMappings()`: Reset tutti i mapping -- `ValidateMapping()`: Validazione configurazione mapping -- `AutoMapFields()`: Auto-mapping campi simili - -#### Metodi Trasferimento -- `StartDataTransfer()`: Avvio trasferimento standard -- `StartDataTransferWithComposite()`: Trasferimento con Composite API -- `ProcessRecord()`: Elaborazione singolo record -- `CreateAssociationAsync()`: Creazione associazione chiave -- `UpdateAssociationHashAsync()`: Aggiornamento hash associazione - -#### Metodi Profili -- `OnProfileLoaded()`: Caricamento profilo salvato -- `ApplyProfileConfiguration()`: Applicazione configurazione profilo -- `SaveCurrentProfile()`: Salvataggio profilo corrente - -### DataConnection.EF.EFCoreDatabaseManager - -#### Metodi Core -- `TestConnectionAsync()`: Test connessione database -- `GetDatabaseSchemaAsync()`: Recupero schema completo -- `GetAvailableDatabasesAsync()`: Lista database disponibili -- `ChangeDatabaseAsync(string)`: Cambio database corrente - -#### Metodi CRUD Generici -- `GetAsync()`: Query generiche con filtri -- `GetByIdAsync(object)`: Recupero per ID -- `CreateAsync(T)`: Creazione entity -- `UpdateAsync(T)`: Aggiornamento entity -- `DeleteAsync(T)`: Eliminazione entity - -#### Metodi SQL Raw -- `ExecuteRawSqlAsync(string, object[])`: Esecuzione SQL raw -- `ExecuteCommandAsync(string, object[])`: Comandi SQL - -### CredentialManager.Services.CredentialService - -#### Gestione Credenziali Database -- `SaveDatabaseCredentialAsync()`: Salvataggio credenziali DB -- `GetDatabaseCredentialAsync()`: Recupero credenziali DB -- `GetAllDatabaseCredentialsAsync()`: Lista tutte credenziali DB -- `TestDatabaseConnectionAsync()`: Test connessione DB - -#### Gestione Credenziali REST -- `SaveRestApiCredentialAsync()`: Salvataggio credenziali REST -- `GetRestApiCredentialAsync()`: Recupero credenziali REST -- `GetAllRestApiCredentialsAsync()`: Lista tutte credenziali REST -- `TestRestConnectionAsync()`: Test connessione REST - -#### Gestione Associazioni Chiavi -- `SaveKeyAssociationAsync()`: Salvataggio associazione -- `FindKeyAssociationByValueAsync()`: Ricerca per valore chiave -- `UpdateKeyAssociationAsync()`: Aggiornamento associazione -- `GetKeyAssociationsAsync()`: Lista associazioni - -### CredentialManager.Services.DataCouplerProfileService - -#### Gestione Profili -- `SaveProfileAsync()`: Salvataggio nuovo profilo -- `UpdateProfileAsync()`: Aggiornamento profilo esistente -- `GetAllProfilesAsync()`: Lista tutti i profili -- `GetProfileByIdAsync()`: Recupero profilo per ID -- `GetProfileByNameAsync()`: Recupero profilo per nome -- `DeleteProfileAsync()`: Eliminazione profilo (soft delete) -- `UpdateLastUsedAsync()`: Aggiornamento ultimo utilizzo - -#### Utilità Profili -- `ProfileExistsAsync()`: Verifica esistenza profilo -- `SerializeFieldMappings()`: Serializzazione mapping -- `DeserializeFieldMappings()`: Deserializzazione mapping -- `ToDto()`: Conversione a DTO -- `FromDto()`: Conversione da DTO - ---- - -## Riferimenti Esterni e Percorsi - -### Database SQLite Principale -**Percorso**: -- **Windows**: `%ProgramData%\Data_Coupler\credentials.db` -- **Linux**: `/var/lib/Data_Coupler/credentials.db` -- **macOS**: `/Library/Application Support/Data_Coupler/credentials.db` - -### Tabelle Database -1. **Credentials**: Memorizzazione credenziali crittografate -2. **KeyAssociations**: Associazioni chiavi sorgente-destinazione -3. **DataCouplerProfiles**: Profili di configurazione salvati - -### File di Configurazione -- `appsettings.json`: Configurazione generale -- `appsettings.Development.json`: Configurazione sviluppo -- `nuget.config`: Configurazione pacchetti NuGet - -### Dipendenze Esterne Principali -- **Microsoft.EntityFrameworkCore**: ORM per database -- **ExcelDataReader**: Lettura file Excel -- **System.Data.SqlClient**: SQL Server -- **MySqlConnector**: MySQL -- **Npgsql**: PostgreSQL -- **Oracle.ManagedDataAccess**: Oracle -- **IBM.Data.Db2**: DB2 - -### Porte di Default -- **Applicazione Web**: `http://localhost:7550` -- **SQL Server**: 1433 -- **MySQL**: 3306 -- **PostgreSQL**: 5432 -- **Oracle**: 1521 - ---- - -## Interconnessioni tra Componenti - -### Flusso di Dipendenze -``` -Data_Coupler (App) -├── CredentialManager (Gestione Credenziali) -├── DataConnection (Connessioni Dati) -├── Components (UI Components) -└── Background Services -``` - -### Interazioni Principali - -#### 1. Caricamento Credenziali -``` -Data_Coupler → CredentialManager.CredentialService → SQLite Database -``` - -#### 2. Connessione Database -``` -Data_Coupler → DataConnectionFactory → DataConnection.EF.EFCoreDatabaseManager → Database Target -``` - -#### 3. Connessione REST -``` -Data_Coupler → DataConnectionFactory → DataConnection.REST.Implementations → REST API -``` - -#### 4. Gestione Profili -``` -Data_Coupler → CredentialManager.DataCouplerProfileService → SQLite Database -``` - -### Pattern di Comunicazione - -#### Dependency Injection -Tutti i servizi sono registrati nel container DI e iniettati dove necessario: -```csharp -// Program.cs -builder.Services.AddDataConnectionCredentialManagement(dbPath); -builder.Services.AddScoped(); -``` - -#### Factory Pattern -Le connessioni sono create tramite factory per garantire configurazione corretta: -```csharp -var dbManager = await ConnectionFactory.CreateDatabaseManagerAsync(credentialName); -var restClient = await ConnectionFactory.CreateRestServiceClientAsync(credentialName); -``` - -#### Service Layer -La logica business è incapsulata in servizi dedicati: -- `CredentialService`: Gestione credenziali -- `DataCouplerProfileService`: Gestione profili -- `DataConnectionFactory`: Creazione connessioni - ---- - -## Stato delle Implementazioni - -### ✅ Funzionalità Completamente Implementate - -#### Gestione Credenziali -- ✅ Salvataggio/recupero credenziali database -- ✅ Salvataggio/recupero credenziali REST API -- ✅ Crittografia cross-platform -- ✅ Test connessioni -- ✅ Validazione credenziali - -#### Connessioni Database -- ✅ Supporto multi-database (SQL Server, MySQL, PostgreSQL, etc.) -- ✅ Schema discovery automatico -- ✅ Query personalizzate -- ✅ Gestione connection string - -#### Connessioni REST -- ✅ API generiche -- ✅ Integrazione Salesforce completa -- ✅ Salesforce Composite API per performance -- ✅ Autenticazione OAuth - -#### Elaborazione File -- ✅ Lettura Excel (.xlsx, .xls) -- ✅ Lettura CSV -- ✅ Preview dati con paginazione -- ✅ Gestione multi-sheet - -#### Sistema Mapping -- ✅ Mapping manuale campi -- ✅ Auto-detection campi simili -- ✅ Validazione mapping -- ✅ Preview risultati - -#### Gestione Associazioni -- ✅ Tracking chiavi sorgente-destinazione -- ✅ Prevenzione duplicati -- ✅ Hash verification per rilevare modifiche -- ✅ Gestione update vs insert intelligente - -#### Gestione Profili -- ✅ Salvataggio configurazioni complete -- ✅ Caricamento profili salvati -- ✅ Lista e gestione profili -- ✅ Statistiche utilizzo -- ✅ Export/import JSON - -### 🔄 Funzionalità Parzialmente Implementate - -#### Background Services -- 🔄 **Struttura base**: Implementata ma placeholder -- 🔄 **Servizi specifici**: Da implementare funzionalità specifiche -- 🔄 **Scheduling**: Da aggiungere scheduling operazioni - -#### Gestione Errori Avanzata -- 🔄 **Logging base**: Implementato -- 🔄 **Error recovery**: Parziale -- 🔄 **Rollback automatico**: Da implementare - -#### Performance Optimization -- 🔄 **Batch processing**: Implementato per Salesforce -- 🔄 **Parallelizzazione**: Parziale -- 🔄 **Caching**: Base implementato - -#### Security Features -- 🔄 **Autenticazione utente**: Da implementare -- 🔄 **Autorizzazione**: Da implementare -- 🔄 **Audit trail**: Parziale - -### ❌ Funzionalità Da Implementare - -#### Integrazione Database Avanzata -- ❌ **Supporto Stored Procedures**: Da implementare -- ❌ **Triggers**: Da implementare -- ❌ **Views materialized**: Da implementare - -#### API Extensions -- ❌ **GraphQL**: Da implementare -- ❌ **SAP B1 Service Layer completo**: Struttura presente ma da completare -- ❌ **Altri ERP**: Da aggiungere - -#### Data Transformation -- ❌ **Trasformazioni custom**: Da implementare -- ❌ **Formule/Calcoli**: Da implementare -- ❌ **Data cleansing**: Da implementare - -#### Monitoring & Analytics -- ❌ **Dashboard performance**: Da implementare -- ❌ **Metriche dettagliate**: Da implementare -- ❌ **Alerting**: Da implementare - -#### Advanced Features -- ❌ **Real-time sync**: Da implementare -- ❌ **Conflict resolution**: Da implementare -- ❌ **Multi-tenant**: Da implementare -- ❌ **REST API del Data Coupler**: Da implementare - ---- - -## Utilizzo e Configurazione - -### Configurazione Iniziale - -1. **Compilazione e Avvio**: - ```bash - dotnet run --project Data_Coupler/Data_Coupler.csproj - ``` - -2. **Accesso Web Interface**: - - URL: `http://localhost:7550` - - L'applicazione inizializza automaticamente il database SQLite - -### Workflow Tipico - -#### 1. Configurazione Credenziali -- Accedere alla sezione "Gestione Credenziali" -- Aggiungere credenziali database e/o REST API -- Testare le connessioni - -#### 2. Configurazione Trasferimento -- Selezionare tipo sorgente (Database/File) -- Configurare connessione sorgente -- Configurare destinazione REST API -- Definire mapping campi -- Configurare gestione chiavi - -#### 3. Esecuzione Trasferimento -- Avviare trasferimento dati -- Monitorare progresso -- Verificare risultati - -#### 4. Gestione Profili (Opzionale) -- Salvare configurazione come profilo -- Riutilizzare profili per operazioni ricorrenti - -### Configurazioni Avanzate - -#### Database Path Personalizzato -Modificare `Program.cs` per percorso custom: -```csharp -string customDbPath = "/path/to/custom/credentials.db"; -builder.Services.AddDataConnectionCredentialManagement($"Data Source={customDbPath}"); -``` - -#### Logging Personalizzato -Configurare logging in `Program.cs`: -```csharp -builder.Logging.AddConsole(); -builder.Logging.SetMinimumLevel(LogLevel.Debug); -``` - -#### Performance Tuning -- **Batch Size**: Configurabile nel codice per operazioni batch -- **Timeout**: Configurabile per connessioni database/REST -- **Memory**: Gestione automatica, configurabile per file grandi - -### Troubleshooting - -#### Problemi Comuni -1. **Database Lock**: Riavviare applicazione -2. **Credenziali non funzionanti**: Verificare test connessione -3. **File non leggibili**: Verificare formato e permissions -4. **API Rate Limiting**: Configurare delays appropriati - -#### Log Files -I log sono disponibili nella console dell'applicazione e possono essere configurati per output su file. - ---- - -## Conclusioni - -Data-Coupler rappresenta una soluzione robusta e flessibile per l'integrazione di dati tra diverse piattaforme. L'architettura modulare consente estensioni future, mentre le funzionalità già implementate coprono la maggior parte dei casi d'uso comuni. - -Il progetto è in uno stato maturo per quanto riguarda le funzionalità core, con spazio per miglioramenti in aree come monitoring, security avanzata e funzionalità enterprise. - -### Prossimi Sviluppi Consigliati -1. Implementazione sistema di autenticazione utenti -2. Dashboard analytics e monitoring -3. API REST per automazione -4. Supporto trasformazioni dati avanzate -5. Integrazione con sistemi di workflow - ---- - -**Versione Documentazione**: 1.0 -**Data**: 11 Settembre 2025 -**Autore**: Sistema di Documentazione Automatica Data-Coupler