< Summary

Information
Class: GistBackend.Services.RecapService
Assembly: GistBackend
File(s): /home/runner/work/the-gist-of-it-sec/the-gist-of-it-sec/backend/GistBackend/Services/RecapService.cs
Line coverage
97%
Covered lines: 42
Uncovered lines: 1
Coverable lines: 43
Total lines: 88
Line coverage: 97.6%
Branch coverage
77%
Covered branches: 17
Total branches: 22
Branch coverage: 77.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
.cctor()100%11100%
ExecuteAsync()50%2283.33%
CreateDailyRecapIfNecessaryAsync()100%22100%
CreateWeeklyRecapIfNecessaryAsync()100%22100%
DailyRecapIsNecessaryAsync()100%22100%
WeeklyRecapIsNecessaryAsync()100%22100%
CreateDailyRecapAsync()66.66%66100%
CreateWeeklyRecapAsync()66.66%66100%

File(s)

/home/runner/work/the-gist-of-it-sec/the-gist-of-it-sec/backend/GistBackend/Services/RecapService.cs

#LineLine coverage
 1using GistBackend.Handlers;
 2using GistBackend.Handlers.AIHandler;
 3using GistBackend.Handlers.MariaDbHandler;
 4using GistBackend.Utils;
 5using Microsoft.Extensions.Hosting;
 6using Microsoft.Extensions.Logging;
 7using Prometheus;
 8using static GistBackend.Utils.LogEvents;
 9
 10namespace GistBackend.Services;
 11
 712public class RecapService(
 713    IMariaDbHandler mariaDbHandler,
 714    IAIHandler aiHandler,
 715    IDateTimeHandler dateTimeHandler,
 716    ILogger<RecapService>? logger = null) : BackgroundService
 17{
 118    private static readonly Gauge DailyRecapGauge =
 119        Metrics.CreateGauge("daily_recap_seconds", "Time spent to create daily recap");
 120    private static readonly Gauge WeeklyRecapGauge =
 121        Metrics.CreateGauge("weekly_recap_seconds", "Time spent to create weekly recap");
 22    private const int UtcHourToCreateRecapAt = 5;
 23
 24    protected override async Task ExecuteAsync(CancellationToken ct)
 25    {
 726        while (!ct.IsCancellationRequested)
 27        {
 728            var startTime = dateTimeHandler.GetUtcNow();
 729            await CreateDailyRecapIfNecessaryAsync(startTime, ct);
 730            await CreateWeeklyRecapIfNecessaryAsync(startTime, ct);
 731            await ServiceUtils.DelayUntilNextExecutionAsync(startTime, 5, logger, ct, dateTimeHandler);
 32        }
 033    }
 34
 35    private async Task CreateDailyRecapIfNecessaryAsync(DateTime startTime, CancellationToken ct)
 36    {
 737        if (await DailyRecapIsNecessaryAsync(startTime, ct))
 38        {
 439            using (new SelfReportingStopwatch(elapsed => DailyRecapGauge.Set(elapsed)))
 40            {
 241                await CreateDailyRecapAsync(ct);
 242            }
 43        }
 744    }
 45
 46    private async Task CreateWeeklyRecapIfNecessaryAsync(DateTime startTime, CancellationToken ct)
 47    {
 748        if (await WeeklyRecapIsNecessaryAsync(startTime, ct))
 49        {
 450            using (new SelfReportingStopwatch(elapsed => WeeklyRecapGauge.Set(elapsed)))
 51            {
 252                await CreateWeeklyRecapAsync(ct);
 253            }
 54        }
 755    }
 56
 57    private async Task<bool> DailyRecapIsNecessaryAsync(DateTimeOffset now, CancellationToken ct) =>
 758        now.Hour >= UtcHourToCreateRecapAt && !await mariaDbHandler.DailyRecapExistsAsync(ct);
 59
 60    private async Task<bool> WeeklyRecapIsNecessaryAsync(DateTimeOffset now, CancellationToken ct) =>
 761        now.Hour >= UtcHourToCreateRecapAt && !await mariaDbHandler.WeeklyRecapExistsAsync(ct);
 62
 63    private async Task CreateDailyRecapAsync(CancellationToken ct)
 64    {
 265        var gists = await mariaDbHandler.GetConstructedGistsOfLastDayAsync(ct);
 266        if (gists.Count == 0)
 67        {
 168            logger?.LogInformation(NoGistsForDailyRecap, "No gists to create daily recap");
 169            return;
 70        }
 171        var recapAIResponse = await aiHandler.GenerateDailyRecapAsync(gists, ct);
 172        await mariaDbHandler.InsertDailyRecapAsync(recapAIResponse, ct);
 173        logger?.LogInformation(DailyRecapCreated, "Daily recap created");
 274    }
 75
 76    private async Task CreateWeeklyRecapAsync(CancellationToken ct)
 77    {
 278        var gists = await mariaDbHandler.GetConstructedGistsOfLastWeekAsync(ct);
 279        if (gists.Count == 0)
 80        {
 181            logger?.LogInformation(NoGistsForWeeklyRecap, "No gists to create weekly recap");
 182            return;
 83        }
 184        var recap = await aiHandler.GenerateWeeklyRecapAsync(gists, ct);
 185        await mariaDbHandler.InsertWeeklyRecapAsync(recap, ct);
 186        logger?.LogInformation(WeeklyRecapCreated, "Weekly recap created");
 287    }
 88}