[Feature] Salesforce: batch describe metadati, discovery parallela e fix scheduler External ID
Build and Push Docker Images / Build Linux Container (push) Successful in 6m56s
Build and Push Docker Images / Build Windows Container (push) Has been cancelled
Build and Push Docker Images / Create Multi-Platform Manifest (push) Has been cancelled

- Salesforce Composite Batch API per describe SObject: le describe sono ora
  raggruppate in chunk da 25 e inviate come singole POST a /composite/batch,
  riducendo le chiamate API da N a ceil(N/25); per 200 SObject: da 201 a 9 chiamate.

- Discovery entita' REST in parallelo: DiscoverEntitySummariesAsync e
  DiscoverEntitiesAsync avviate simultaneamente; la lista entita' diventa
  interattiva subito dopo le summaries, i dettagli completano in background
  con StateHasChanged() per aggiornare l'UI istantaneamente.

- Fix scheduler - preservazione ExternalIdRelationshipsJson e DefaultValuesJson:
  in DataCoupler.razor.cs entrambi i blocchi di update profilo esistente
  (riattivazione profilo inattivo e sovrascrittura profilo attivo) omettevano
  questi campi nella copia, causandone l'azzeramento silenzioso ad ogni
  re-salvataggio. Ora entrambi i percorsi propagano correttamente i campi JSON.

- Fix scheduler - esclusione campi sorgente External ID dal mapping normale:
  in ScheduledProfileExecutionService.TransformRecordForRest i campi sorgente
  usati nelle External ID Relationships venivano inclusi anche nel loop di
  field mapping standard, generando dati duplicati nell'entita' destinazione.
  Ora il comportamento e' allineato alla UI manuale (TransformRecordToRestEntity).

- Aggiornata documentazione: README.md, AGENTS.md, copilot-instructions.md
This commit was merged in pull request #11.
This commit is contained in:
Alessio Dal Santo
2026-02-20 14:59:13 +01:00
parent b1f83aa7ab
commit 335d587c89
9 changed files with 518 additions and 108 deletions
@@ -140,23 +140,29 @@ public partial class DataCoupler : ComponentBase
Logger.LogInformation("Autenticazione completata con successo per il servizio REST {ServiceType}", credential.ServiceType);
// Discovery delle entità disponibili usando il metodo batch ottimizzato
Logger.LogInformation("Iniziando discovery batch delle entità REST...");
restEntities = await currentRestDiscovery.DiscoverEntitySummariesAsync();
isRestConnected = true;
// Avvia entrambe le discovery in parallelo:
// - DiscoverEntitySummariesAsync è veloce (1 API call) → sblocca la UI subito
// - DiscoverEntitiesAsync è pesante (batch describe) → completa in background
Logger.LogInformation("Avvio discovery parallela: entity summaries + entity details (batch)...");
Logger.LogInformation("Discovery batch completato: trovate {EntityCount} entità REST", restEntities.Count);
// Carica anche i dettagli completi delle entità per External ID Relationships
var summariesTask = currentRestDiscovery.DiscoverEntitySummariesAsync();
var entitiesTask = currentRestDiscovery.DiscoverEntitiesAsync();
// Attendi le summaries (veloci) e rendi la UI interattiva immediatamente
restEntities = await summariesTask;
isRestConnected = true;
StateHasChanged();
Logger.LogInformation("Entity summaries completate: {EntityCount} entità. UI interattiva.", restEntities.Count);
// Attendi i dettagli completi (già in esecuzione in parallelo)
try
{
Logger.LogInformation("Caricamento dettagli entità per External ID Relationships...");
availableRelationshipObjects = await currentRestDiscovery.DiscoverEntitiesAsync();
Logger.LogInformation("Caricati {Count} oggetti disponibili per External ID Relationships", availableRelationshipObjects.Count);
availableRelationshipObjects = await entitiesTask;
Logger.LogInformation("Entity details (batch) completati: {Count} oggetti disponibili per External ID Relationships.", availableRelationshipObjects.Count);
}
catch (Exception ex)
{
Logger.LogWarning(ex, "Impossibile caricare i dettagli delle entità per External ID Relationships");
Logger.LogWarning(ex, "Impossibile completare il caricamento dei dettagli entità per External ID Relationships");
availableRelationshipObjects = new List<RestEntityInfo>();
}
}