< Summary - Heimdall API

Information
Class: ArturRios.Heimdall.WebApi.Retention.AuditRetentionService
Assembly: ArturRios.Heimdall.WebApi
File(s): /home/ci/agent/workspace/heimdall-api-docs_main/app/src/Presentation/ArturRios.Heimdall.WebApi/Retention/AuditRetentionService.cs
Line coverage
95%
Covered lines: 23
Uncovered lines: 1
Coverable lines: 24
Total lines: 57
Line coverage: 95.8%
Branch coverage
87%
Covered branches: 7
Total branches: 8
Branch coverage: 87.5%
Method coverage
80%
Covered methods: 4
Fully covered methods: 4
Total methods: 5
Method coverage: 80%
Full method coverage: 80%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_PassName()100%210%
get_StartupDescription()100%11100%
RunAsync()87.5%88100%
Rows(...)100%11100%

File(s)

/home/ci/agent/workspace/heimdall-api-docs_main/app/src/Presentation/ArturRios.Heimdall.WebApi/Retention/AuditRetentionService.cs

#LineLine coverage
 1using ArturRios.Heimdall.Command.Input;
 2using ArturRios.Heimdall.Command.Output;
 3using ArturRios.Heimdall.Shared.Retention;
 4using ArturRios.Mediator.Command;
 5
 6namespace ArturRios.Heimdall.WebApi.Retention;
 7
 8/// <summary>
 9///     Runs <see cref="PseudonymiseAuditActorsCommand" /> on an interval, so the audit trail stops
 10///     naming people, as actors or as targets, once it no longer needs to, and drops the tombstones of
 11///     hard-deleted identities once nothing names them (NFR-21).
 12/// </summary>
 13public class AuditRetentionService(
 14    IServiceScopeFactory scopeFactory,
 15    DataRetentionOptions retention,
 16    ILogger<AuditRetentionService> logger)
 97017    : ScheduledPassService(scopeFactory, retention.PurgeInterval, logger)
 18{
 019    public override string PassName => "audit-retention";
 20
 21    protected override string StartupDescription =>
 96622        $"Audit attribution pseudonymisation scheduled every {retention.PurgeInterval}, clearing " +
 96623        $"attributions and person targets after {retention.AuditActorRetention} and immediately " +
 96624        "for erased identities";
 25
 26    protected override async Task<ScheduledPassResult> RunAsync(IServiceProvider scope)
 27    {
 428        var mediator = scope.GetRequiredService<CommandMediator>();
 29
 430        var result = await mediator
 431            .ExecuteCommandAsync<PseudonymiseAuditActorsCommand, PseudonymiseAuditActorsCommandOutput>(
 432                new PseudonymiseAuditActorsCommand());
 33
 434        if (!result.Success)
 35        {
 136            return ScheduledPassResult.Failure(
 137                "Audit attribution pseudonymisation", result.Errors, result.Data is { } done ? Rows(done) : 0);
 38        }
 39
 340        var pseudonymised = result.Data!;
 341        var rows = Rows(pseudonymised);
 42
 43        // The rows still due are what the run left at its batch cap (#206): a number that does not fall
 44        // from run to run is a backlog that is not draining.
 345        return rows == 0 && pseudonymised.Backlog == 0
 346            ? ScheduledPassResult.Quiet
 347            : new ScheduledPassResult(
 348                $"Cleared the actor attribution from {pseudonymised.EntriesPseudonymised} audit entries " +
 349                $"and the person target from {pseudonymised.TargetsCleared}, and removed " +
 350                $"{pseudonymised.TombstonesRemoved} tombstones of hard-deleted identities; " +
 351                $"{pseudonymised.Backlog} still due after this run",
 352                false, rows);
 453    }
 54
 55    private static long Rows(PseudonymiseAuditActorsCommandOutput pseudonymised) =>
 456        (long)pseudonymised.EntriesPseudonymised + pseudonymised.TargetsCleared + pseudonymised.TombstonesRemoved;
 57}