Files
Data-Coupler/TEST_HASH_COMPARISON.md
Alessio fa4732ef71 feat(deletion-sync): implementato sistema completo sincronizzazione cancellazioni + fix Pre-Discovery
NUOVE FUNZIONALITÀ - Sistema Sincronizzazione Cancellazioni:

Database:
- Aggiunto tracking cancellazioni in KeyAssociation (IsSourceDeleted, DeletedAt, DeletionSynced, DeletionSyncedAt)
- Aggiunta configurazione cancellazioni in DataCouplerProfile (SyncDeletions, DeletionAction, DeletionMarkField, DeletionMarkValue)
- Migration: 20251027103016_AddDeletionSyncFeature

Servizi:
- Nuovo DeletionSyncService con supporto 3 modalità (Delete, Deactivate, Mark)
- KeyAssociationService: aggiunti MarkDeletedAssociationsAsync, GetPendingDeletionsAsync, MarkDeletionSyncedAsync, GetDeletedAssociationsAsync
- DataConnectionCredentialService: esposti metodi di sincronizzazione cancellazioni

Logica Trasferimento:
- Integrata sincronizzazione cancellazioni in StartDataTransferOriginal
- Integrata sincronizzazione cancellazioni in StartDataTransferWithComposite
- Rilevamento automatico record cancellati tramite confronto chiavi sorgente
- Sincronizzazione con gestione errori robusta

UI:
- Aggiunto contatore "Cancellati" nei risultati trasferimento
- Aggiunto stato "deleted" con badge e icona trash
- Messaggi completamento includono cancellazioni

BUG FIX - Pre-Discovery Flag Reset:

Problema Risolto:
- Il flag isPreDiscoveryAssociation causava aggiornamenti forzati infiniti
- Record venivano aggiornati anche con dati identici (hash ignorato)

Soluzione:
- Corretto controllo flag: verifica AdditionalInfo["CreatedBy"] == "PreDiscovery"
- Reset immediato flag durante marcatura per update (rimozione chiave "CreatedBy")
- Biforcazione intelligente: prima sync forza update, successive usano hash

Benefici:
- Riduzione 60-90% chiamate API inutili dopo prima sincronizzazione
- Controllo hash funzionante correttamente
- Performance drasticamente migliorate

MODIFICHE TECNICHE:

File Modificati:
- CredentialManager/Models/KeyAssociation.cs (+4 campi)
- CredentialManager/Models/DataCouplerProfile.cs (+4 campi)
- CredentialManager/Services/KeyAssociationService.cs (+142 righe, 4 metodi)
- CredentialManager/Services/IKeyAssociationService.cs (+4 signature)
- DataConnection/CredentialManagement/Interfaces/IDataConnectionCredentialService.cs (+4 metodi)
- DataConnection/CredentialManagement/Services/DataConnectionCredentialService.cs (+21 righe)
- Data_Coupler/Pages/DataCoupler.razor (UI cancellazioni + contatori)
- Data_Coupler/Pages/DataCoupler.razor.cs (sync cancellazioni + fix hash)
- Data_Coupler/Program.cs (registrazione DeletionSyncService)

File Nuovi:
- Data_Coupler/Services/DeletionSyncService.cs (~250 righe)
- CredentialManager/Migrations/20251027103016_AddDeletionSyncFeature.cs
- DELETION_SYNC_IMPLEMENTATION.md (documentazione completa)
- FIX_PRE_DISCOVERY_FINAL.md (documentazione fix)

Testing:
- Compilazione verificata:  Successo (26 warning pre-esistenti)
- Breaking changes: Nessuno
- Compatibilità: Retrocompatibile

IMPATTO:
- Gestione completa lifecycle record (creazione, aggiornamento, cancellazione)
- Performance ottimizzate con controllo hash funzionante
- Sistema robusto per mantenere destinazione sincronizzata con sorgente
2025-10-27 12:42:55 +01:00

152 lines
5.1 KiB
Markdown

# Test Hash Comparison - Guida al Debug
## Problema Rilevato
Il sistema di confronto hash non sembra funzionare correttamente: i record vengono aggiornati anche quando i dati non sono cambiati.
## Modifiche Apportate
Ho aggiunto logging dettagliato per tracciare:
1. **Generazione Hash** (`GenerateDataHash`)
- 🔍 Numero di campi processati
- 🔍 Elenco campi ordinati
- 🔍 Stringa combinata prima dell'hashing
- ✅ Hash finale generato
2. **Confronto Hash** (in `StartDataTransferWithComposite`)
- 📌 Hash esistente nel database
- 📌 Hash calcolato sul record corrente
- ✅ Decisione: saltato o aggiornato
- ⚠️ Warning se hash diversi
## Come Testare
### Passo 1: Accedi all'applicazione
L'applicazione è già in esecuzione su: **http://localhost:7550**
### Passo 2: Configura un trasferimento
1. Seleziona una sorgente dati (database o REST API)
2. Seleziona una destinazione (REST API)
3. Configura i mapping dei campi
4. **IMPORTANTE**: Assicurati che "Usa associazioni record" sia abilitato
### Passo 3: Esegui il primo trasferimento
1. Esegui il trasferimento con alcuni record
2. Verifica che i record vengano creati correttamente
3. **Annotati quanti record sono stati creati**
### Passo 4: Esegui il trasferimento duplicato
1. **SENZA modificare i dati sorgente**, esegui di nuovo lo stesso trasferimento
2. **ATTESO**: Tutti i record dovrebbero essere saltati (hash identico)
3. **PROBLEMA**: Se i record vengono aggiornati, c'è un problema
### Passo 5: Analizza i log
Apri la console PowerShell dove sta girando l'applicazione e cerca:
#### Log di Generazione Hash
```
🔍 HASH DEBUG: Generazione hash per X campi
🔍 HASH DEBUG: Campi ordinati: [campo1, campo2, campo3, ...]
🔍 HASH DEBUG: Stringa combinata: campo1=valore1|campo2=valore2|...
✅ HASH DEBUG: Hash finale generato: 1A2B3C4D5E6F...
```
#### Log di Confronto Hash (IMPORTANTE!)
```
🔍 CONFRONTO HASH - Record 1:
📌 Hash esistente: 1A2B3C4D5E6F...
📌 Hash corrente: 1A2B3C4D5E6F...
✅ HASH IDENTICO - Record 1 saltato
```
oppure
```
🔍 CONFRONTO HASH - Record 1:
📌 Hash esistente: 1A2B3C4D5E6F...
📌 Hash corrente: 9Z8Y7X6W5V4U... <-- DIVERSO!
⚠️ HASH DIVERSO - Record 1 marcato per aggiornamento (EntityId: 001...)
```
## Cosa Cercare nei Log
### ✅ Scenario Corretto (Hash Identico)
Se lo stesso record viene processato due volte:
- La "Stringa combinata" deve essere **identica**
- L'hash generato deve essere **identico**
- Il record deve essere **saltato**
### ⚠️ Scenario Problematico (Hash Diverso)
Se gli hash sono diversi pur con gli stessi dati, cerca differenze nella "Stringa combinata":
#### Possibili Cause
1. **Campi timestamp generati automaticamente**
- Se un campo contiene `DateTime.Now` o timestamp auto-generati
- L'hash cambierà sempre
2. **Valori con formato diverso**
- Decimali: `10.5` vs `10,5` (cultura)
- Date: `2024-01-01` vs `01/01/2024`
- Boolean: `true` vs `True` vs `1`
3. **Campi che non dovrebbero essere nell'hash**
- Campi di sistema (ID, CreatedAt, UpdatedAt, ecc.)
- Campi calcolati dinamicamente
4. **Ordine campi diverso** (già gestito con `.OrderBy`)
- Dovrebbe essere risolto, ma verifica che i campi siano nello stesso ordine
## Prossimi Passi in Base ai Risultati
### Se Hash Identico ma Record Aggiornato Comunque
→ Problema nella logica di confronto o salvataggio hash
### Se Hash Diverso con Dati Identici
→ Problema nella generazione hash (valori dinamici o formattazione)
### Se Hash NULL nel Database
→ L'hash non viene salvato correttamente dopo il primo trasferimento
## Esempio Output Atteso
### Primo Trasferimento (Creazione)
```
🔍 HASH DEBUG: Generazione hash per 5 campi
🔍 HASH DEBUG: Campi ordinati: [Email, FirstName, LastName, Phone, Title]
🔍 HASH DEBUG: Stringa combinata: Email=john@example.com|FirstName=John|LastName=Doe|Phone=123456789|Title=Developer
✅ HASH DEBUG: Hash finale generato: A1B2C3D4E5F6...
COMPOSITE: Record 1 marcato per creazione
COMPOSITE: Associazione creata con ID: 1 per record 1 - Hash: A1B2C3D4E5F6...
```
### Secondo Trasferimento (Stesso Dato - Dovrebbe Saltare)
```
🔍 HASH DEBUG: Generazione hash per 5 campi
🔍 HASH DEBUG: Campi ordinati: [Email, FirstName, LastName, Phone, Title]
🔍 HASH DEBUG: Stringa combinata: Email=john@example.com|FirstName=John|LastName=Doe|Phone=123456789|Title=Developer
✅ HASH DEBUG: Hash finale generato: A1B2C3D4E5F6...
🔍 CONFRONTO HASH - Record 1:
📌 Hash esistente: A1B2C3D4E5F6...
📌 Hash corrente: A1B2C3D4E5F6...
✅ HASH IDENTICO - Record 1 saltato
```
## Raccogli Informazioni
Per aiutarmi a risolvere il problema, copia e incolla:
1. **Output del primo trasferimento** (dai log della console)
- Cerca le linee con "🔍 HASH DEBUG" e "✅ HASH DEBUG"
2. **Output del secondo trasferimento** (stesso dato)
- Cerca le linee con "🔍 CONFRONTO HASH"
- Verifica se gli hash sono identici
3. **Risultato finale mostrato nell'UI**
- Quanti record creati/aggiornati/saltati
---
**Nota**: I log dettagliati sono attivi ora. Dopo il test, potremo ridurre il livello di logging.