Implementato sistema robusto di salvataggio/caricamento profili Data Coupler

- Aggiunto metodo GetCredentialIdByNameAsync in CredentialService per recuperare ID credenziali per nome
- Implementata gestione robusta dei profili duplicati con riattivazione, sovrascrittura e auto-rinomina
- Migliorata logica di caricamento profili con simulazione workflow utente e logging dettagliato
- Fixata gestione errori UNIQUE constraint nel salvataggio profili
- Aggiunto supporto per salvataggio ID credenziali reali invece di placeholder
- Implementato metodo GetProfileByNameIncludingInactiveAsync per gestire profili inattivi
- Aggiunto logging esteso per debug e troubleshooting
- Integrato componente ProfileSaver nella UI principale
- Risolti errori di compilazione e validazione build completa
- Migliorata gestione errori con feedback utente per credenziali/entità mancanti
This commit is contained in:
Alessio Dal Santo
2025-07-03 16:30:57 +02:00
parent d837339f7e
commit 65ed2bb93a
19 changed files with 967 additions and 115 deletions
@@ -31,6 +31,17 @@ public class DataCouplerProfileService : IDataCouplerProfileService
.ToListAsync();
}
/// <summary>
/// Ottiene tutti i profili per nome (inclusi quelli inattivi)
/// </summary>
public async Task<DataCouplerProfile?> GetProfileByNameIncludingInactiveAsync(string name)
{
return await _context.DataCouplerProfiles
.Include(p => p.SourceCredential)
.Include(p => p.DestinationCredential)
.FirstOrDefaultAsync(p => p.Name.ToLower() == name.ToLower());
}
/// <summary>
/// Ottiene un profilo per ID
/// </summary>
@@ -80,8 +91,12 @@ public class DataCouplerProfileService : IDataCouplerProfileService
throw new InvalidOperationException($"Profilo con ID {profile.Id} non trovato");
}
// Aggiorna le proprietà
existingProfile.Name = profile.Name;
// Aggiorna le proprietà (evita di aggiornare il nome se è uguale per evitare unique constraint)
if (!string.Equals(existingProfile.Name, profile.Name, StringComparison.OrdinalIgnoreCase))
{
existingProfile.Name = profile.Name;
}
existingProfile.Description = profile.Description;
existingProfile.SourceType = profile.SourceType;
existingProfile.SourceCredentialId = profile.SourceCredentialId;
@@ -94,6 +109,9 @@ public class DataCouplerProfileService : IDataCouplerProfileService
existingProfile.DestinationTable = profile.DestinationTable;
existingProfile.DestinationEndpoint = profile.DestinationEndpoint;
existingProfile.FieldMappingJson = profile.FieldMappingJson;
existingProfile.SourceKeyField = profile.SourceKeyField;
existingProfile.UseRecordAssociations = profile.UseRecordAssociations;
existingProfile.IsActive = profile.IsActive;
await _context.SaveChangesAsync();
return existingProfile;
@@ -195,15 +213,19 @@ public class DataCouplerProfileService : IDataCouplerProfileService
Description = profile.Description,
SourceType = profile.SourceType,
SourceCredentialId = profile.SourceCredentialId,
SourceCredentialName = profile.SourceCredential?.Name,
SourceSchema = profile.SourceSchema,
SourceTable = profile.SourceTable,
SourceFilePath = profile.SourceFilePath,
DestinationType = profile.DestinationType,
DestinationCredentialId = profile.DestinationCredentialId,
DestinationCredentialName = profile.DestinationCredential?.Name,
DestinationSchema = profile.DestinationSchema,
DestinationTable = profile.DestinationTable,
DestinationEndpoint = profile.DestinationEndpoint,
FieldMappings = DeserializeFieldMappings(profile.FieldMappingJson)
FieldMappings = DeserializeFieldMappings(profile.FieldMappingJson),
SourceKeyField = profile.SourceKeyField,
UseRecordAssociations = profile.UseRecordAssociations
};
}
@@ -228,6 +250,8 @@ public class DataCouplerProfileService : IDataCouplerProfileService
DestinationTable = dto.DestinationTable,
DestinationEndpoint = dto.DestinationEndpoint,
FieldMappingJson = SerializeFieldMappings(dto.FieldMappings),
SourceKeyField = dto.SourceKeyField,
UseRecordAssociations = dto.UseRecordAssociations,
CreatedBy = createdBy
};
}