Historique des modifications
Le système Tracked Changes historise les ajouts, suppressions et modifications d'entités EF Core dans une application Lagoon.
Cette fonctionnalité consomme des ressources et peut ralentir les requêtes. Activez l'historisation uniquement lorsqu'une demande client le justifie.
Informations enregistrées
L'historique contient notamment :
- le nom de la table ;
- l'identifiant de l'utilisateur ayant déclenché l'action ;
- le nom de l'utilisateur ;
- la date et l'heure de l'action ;
- le type d'action : ajout, suppression ou modification ;
- le détail de l'action ;
- l'identifiant de l'objet modifié ;
- les valeurs avant modification au format JSON ;
- les valeurs après modification au format JSON.
La page fournie par Lagoon liste ces modifications dans une grille exportable. L'export contient aussi les colonnes JSON Before et After.
Configurer le DbContext
Modifiez le DbContext applicatif pour hériter d'un contexte avec suivi des modifications.
| Classe de base | Usage |
|---|---|
LgApplicationTrackedChangeDbContext<TUser> | Applications avec identifiant utilisateur string. |
LgApplicationTrackedChangeDbContextGuid<TUser> | Applications avec identifiant utilisateur Guid. |
Le constructeur doit transmettre IHttpContextAccessor à la classe de base.
public class ApplicationDbContext : LgApplicationTrackedChangeDbContextGuid<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions options, IHttpContextAccessor httpContextAccessor = null)
: base(options, httpContextAccessor)
{
}
}
Les applications Pierre Fabre héritent automatiquement du contexte TrackedChangeDbContext. Dans ce cas, poursuivez directement avec la création de la migration.
Créer la table d'historisation
Créez une migration pour ajouter la table LgTrackedChanges.
dotnet ef migrations add AddTrackedChanges
La table est ajoutée automatiquement par les contextes LgApplicationTrackedChangeDbContext<TUser> et LgApplicationTrackedChangeDbContextGuid<TUser> dans OnModelCreating.
Activer le suivi sur une entité
EnableTrackedChangeAttribute
Placez [EnableTrackedChange] sur l'entité à historiser. L'option AllProperties indique que toutes les propriétés doivent être suivies par défaut.
[EnableTrackedChange(AllProperties = true)]
public class Customer
{
public Guid Id { get; set; }
public string Name { get; set; }
[TrackedChange(Ignored = true)]
public string InternalComment { get; set; }
}
TrackedChangeAttribute
Placez [TrackedChange] sur une propriété lorsque l'entité n'utilise pas AllProperties = true. L'option Ignored permet d'exclure un champ lorsque AllProperties est actif.
[EnableTrackedChange]
public class Order
{
public Guid Id { get; set; }
[TrackedChange]
public string Status { get; set; }
}
L'entité doit obligatoirement porter [EnableTrackedChange] pour que ses champs soient historisés.
Ajouter un détail d'action
Les contextes tracked changes exposent une surcharge de SaveChangesAsync qui accepte actionDetails.
public async Task SaveSupplierAsync(ApplicationDbContext db, CancellationToken cancellationToken)
{
// Ajoute un contexte métier à l'action visible dans l'historique.
await db.SaveChangesAsync("Supplier", cancellationToken);
}
Ce détail est utile lorsqu'une même table porte plusieurs concepts métier, par exemple fabricants et fournisseurs dans une table BusinessPartner.
Désactiver temporairement le suivi
Les contextes implémentant ILgApplicationTrackedChangeDbContext exposent TrackedChangeDisabled.
public async Task ImportAsync(ApplicationDbContext db, CancellationToken cancellationToken)
{
// Désactive l'historisation pendant un import technique.
db.TrackedChangeDisabled = true;
await db.SaveChangesAsync(cancellationToken);
db.TrackedChangeDisabled = false;
}
Policy de consultation
Lagoon fournit la policy Policies.TrackedChangeReader, dont la valeur est trackedchange.read. Associez-la au rôle autorisé à consulter l'historique, par exemple un rôle administrateur.
private static RequireRolePolicies<Roles, P> GetRequireRolePolicies()
{
return new()
{
// Donne accès à l'historique des modifications aux administrateurs.
{ Roles.Admin, P.TrackedChangeReader }
};
}
Ajouter la page au menu
La page préfaite est exposée par Lagoon.UI.GridView.Pages.LgPageTrackedChanges.Link().
<AuthorizeView Policy="@Policies.TrackedChangeReader">
<Authorized>
<LgMenuItem Text="#TrackedChanges" IconName="@IconNames.All.ClockHistory" Link="@Lagoon.UI.GridView.Pages.LgPageTrackedChanges.Link()" />
</Authorized>
</AuthorizeView>
Traduire les noms de tables et de champs
Pour traduire les noms affichés par l'interface d'historisation, ajoutez des clés au Dico.xml.
<string key="tc.TableName" fr="Nom de ma table" en="My table name" />
<string key="tc.TableName.FieldName" fr="Nom de mon champ" en="My field name" />
Personnaliser les informations enregistrées
Le contexte tracked changes expose plusieurs méthodes virtuelles à surcharger.
protected override string GetTrackedChangeTableName(string entityName, string tableName)
{
// Personnalise le nom de table stocké dans l'historique.
return entityName;
}
protected override string GetTrackedChangeFieldName(string entityName, string propertyName, string tableName, string fieldName)
{
// Personnalise le nom de champ stocké dans l'historique.
return propertyName;
}
protected override string[] GetTrackedChangePrimaryKeys(string entityName, IEntityType metadata)
{
// Utilise une clé spécifique pour une entité particulière.
return entityName == nameof(Foo)
? new string[] { nameof(Foo.FooPK) }
: base.GetTrackedChangePrimaryKeys(entityName, metadata);
}
protected override void OnNewTrackedChange(TrackedChangeGuid trackedChange)
{
base.OnNewTrackedChange(trackedChange);
// Ajoute ici des informations complémentaires au nouvel historique.
}