fa4732ef71
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
152 lines
5.1 KiB
Markdown
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.
|