Files
Data-Coupler/CredentialManager/Services/IKeyAssociationService.cs
T
Alessio 04f0403f12 feat: Implementato sistema di associazioni chiave per prevenire duplicati nel data coupling
BREAKING CHANGE: Rimosso completamente il vecchio sistema RecordAssociation

Modifiche principali:
- Sostituito RecordAssociation con KeyAssociation basato sui valori delle chiavi
- Implementata logica robusta di UPDATE vs INSERT basata su associazioni esistenti
- Aggiunta normalizzazione delle chiavi (.Trim()) per consistenza
- Implementato fallback nella ricerca associazioni per maggiore affidabilità
- Sostituita verifica pre-UPDATE con tentativo diretto più efficiente

Componenti modificati:
- Nuovo modello: KeyAssociation.cs con campi ottimizzati
- Nuovo servizio: KeyAssociationService.cs con metodi completi
- Aggiornato: DataCoupler.razor con logica migliorata di gestione associazioni
- Aggiornato: CredentialDbContext per gestire solo KeyAssociations
- Aggiornati: tutti i servizi di interfaccia per supportare il nuovo sistema
- Creata: pagina KeyAssociations.razor per gestione associazioni
- Aggiornato: NavMenu.razor con link alla gestione associazioni

Miglioramenti tecnici:
- Logica di UPDATE più robusta: tenta direttamente l'aggiornamento invece di verificare prima l'esistenza
- Gestione errori migliorata con cleanup automatico delle associazioni non valide
- Debug logging estensivo per troubleshooting
- Fallback nella ricerca associazioni se parametri specifici falliscono
- Normalizzazione valori chiave per prevenire problemi di whitespace

Risultato:
Il sistema ora previene correttamente i duplicati utilizzando le associazioni per decidere
se fare INSERT (nuovo record) o UPDATE (record esistente) basandosi sui valori delle chiavi.

Database:
- Creata migrazione EF per rimuovere RecordAssociations e aggiungere KeyAssociations
- Eliminati file e codice legacy non più necessari
2025-06-29 20:44:20 +02:00

110 lines
3.7 KiB
C#

using CredentialManager.Models;
namespace CredentialManager.Services;
/// <summary>
/// Interfaccia per il servizio di gestione delle associazioni basate sui valori delle chiavi
/// </summary>
public interface IKeyAssociationService
{
/// <summary>
/// Salva una nuova associazione o aggiorna una esistente
/// </summary>
Task<int> SaveAssociationAsync(KeyAssociation association);
/// <summary>
/// Cerca un'associazione esistente tramite valore chiave
/// </summary>
Task<KeyAssociation?> FindAssociationByKeyValueAsync(string keyValue, string destinationEntity, string restCredentialName);
/// <summary>
/// Cerca un'associazione esistente tramite valore chiave, indipendentemente dalla destinazione
/// </summary>
Task<KeyAssociation?> FindAssociationByKeyValueAsync(string keyValue);
/// <summary>
/// Ottiene tutte le associazioni per un'entità di destinazione specifica
/// </summary>
Task<List<KeyAssociation>> GetAssociationsByDestinationAsync(string destinationEntity, string restCredentialName);
/// <summary>
/// Ottiene tutte le associazioni attive
/// </summary>
Task<List<KeyAssociation>> GetAllActiveAssociationsAsync();
/// <summary>
/// Ottiene tutte le associazioni (attive e non)
/// </summary>
Task<List<KeyAssociation>> GetAllAssociationsAsync();
/// <summary>
/// Aggiorna un'associazione esistente
/// </summary>
Task<bool> UpdateAssociationAsync(KeyAssociation association);
/// <summary>
/// Disattiva un'associazione
/// </summary>
Task<bool> DeactivateAssociationAsync(int id);
/// <summary>
/// Elimina definitivamente un'associazione
/// </summary>
Task<bool> DeleteAssociationAsync(int id);
/// <summary>
/// Pulisce le associazioni più vecchie di un determinato periodo
/// </summary>
Task<int> CleanupOldAssociationsAsync(TimeSpan olderThan);
/// <summary>
/// Elimina tutte le associazioni per una specifica combinazione entità-credenziale
/// </summary>
Task<int> ClearAssociationsAsync(string destinationEntity, string restCredentialName);
/// <summary>
/// Elimina tutte le associazioni nel sistema
/// </summary>
Task<int> ClearAllAssociationsAsync();
/// <summary>
/// Verifica se un ID di destinazione esiste ancora nel sistema target
/// </summary>
Task<bool> ValidateDestinationIdAsync(string destinationId, string destinationEntity, string restCredentialName);
/// <summary>
/// Ottiene tutte le associazioni con ID di destinazione non validi
/// </summary>
Task<List<KeyAssociation>> GetInvalidAssociationsAsync(string destinationEntity, string restCredentialName);
/// <summary>
/// Pulisce le associazioni con ID di destinazione non più validi
/// </summary>
Task<int> CleanupInvalidAssociationsAsync(string destinationEntity, string restCredentialName);
/// <summary>
/// Aggiorna la data di ultima verifica per un'associazione
/// </summary>
Task<bool> UpdateLastVerifiedAsync(int id);
/// <summary>
/// Ottiene statistiche sulle associazioni
/// </summary>
Task<AssociationStatistics> GetStatisticsAsync();
}
/// <summary>
/// Statistiche sulle associazioni
/// </summary>
public class AssociationStatistics
{
public int TotalAssociations { get; set; }
public int ActiveAssociations { get; set; }
public int InactiveAssociations { get; set; }
public int UniqueKeyValues { get; set; }
public int UniqueDestinationEntities { get; set; }
public DateTime? OldestAssociation { get; set; }
public DateTime? NewestAssociation { get; set; }
public Dictionary<string, int> AssociationsByEntity { get; set; } = new();
}