Name Message Date
📁 Properties Add web dashboard for viewing monitor status and detections. 5 hours ago
📁 Protos Initialize project 1 month ago
📁 wwwroot Add configurable settings and per-monitoring SMS recipients. 4 hours ago
📄 .containerfile Containerize 10 days ago
📄 .dockerignore Containerize 10 days ago
📄 .editorconfig Initialize project 1 month ago
📄 .gitignore Remove database file from repository 10 days ago
📄 AppSettings.cs Add configurable settings and per-monitoring SMS recipients. 4 hours ago
📄 appsettings.Development.json Fix Claudes mess 11 days ago
📄 appsettings.json Fix Claudes mess 11 days ago
📄 BfiMonitor.csproj Add web dashboard for viewing monitor status and detections. 5 hours ago
📄 BfiMonitor.slnx Initialize project 1 month ago
📄 CheckMonitoringJob.cs Add configurable settings and per-monitoring SMS recipients. 4 hours ago
📄 dotnet-tools.json Initialize project 1 month ago
📄 global.json Fix Claudes mess 11 days ago
📄 IntervalScheduler.cs Add configurable settings and per-monitoring SMS recipients. 4 hours ago
📄 MonitoringCheckScheduler.cs Add multi-monitoring management with scan triggers and editing. 5 hours ago
📄 MonitorOptions.cs Add configurable settings and per-monitoring SMS recipients. 4 hours ago
📄 OpenTelemetryExtensions.cs Add web dashboard for viewing monitor status and detections. 5 hours ago
📄 packages.lock.json Add web dashboard for viewing monitor status and detections. 5 hours ago
📄 PlaywrightBrowserService.cs Use Playwright settings from Lukas 10 days ago
📄 Program.cs Add configurable settings and per-monitoring SMS recipients. 4 hours ago
📄 ScheduleMonitoringChecksJob.cs Add multi-monitoring management with scan triggers and editing. 5 hours ago
📄 ScreeningRepository.cs Add configurable settings and per-monitoring SMS recipients. 4 hours ago
📄 SendSmsJob.cs Add tracing 10 days ago
📄 Tracing.cs Add configurable settings and per-monitoring SMS recipients. 4 hours ago
📄 MonitoringCheckScheduler.cs
using Quartz;

internal static class MonitoringCheckJobs
{
    public const string JobGroup = "monitoring-checks";
    public const string TriggerGroup = "monitoring-check-triggers";

    public static JobKey JobKeyFor(int monitorId) => new($"check-{monitorId}", JobGroup);
}

internal sealed class MonitoringCheckScheduler(ISchedulerFactory schedulerFactory, ScreeningRepository repository)
{
    public Task TriggerAsync(int monitorId, CancellationToken cancellationToken = default) =>
        ScheduleCheckAsync(monitorId, force: true, cancellationToken);

    public async Task<int> TriggerAllAsync(CancellationToken cancellationToken = default)
    {
        var monitors = await repository.GetNonArchivedMonitoringsAsync(cancellationToken);
        foreach (var monitor in monitors)
        {
            await ScheduleCheckAsync(monitor.Id, force: true, cancellationToken);
        }

        return monitors.Count;
    }

    public async Task ScheduleRunningChecksAsync(CancellationToken cancellationToken = default)
    {
        var monitors = await repository.GetActiveMonitoringsAsync(cancellationToken);
        foreach (var monitor in monitors)
        {
            await ScheduleCheckAsync(monitor.Id, force: false, cancellationToken);
        }
    }

    private async Task ScheduleCheckAsync(int monitorId, bool force, CancellationToken cancellationToken)
    {
        var scheduler = await schedulerFactory.GetScheduler(cancellationToken);
        var jobKey = MonitoringCheckJobs.JobKeyFor(monitorId);

        if (!await scheduler.CheckExists(jobKey, cancellationToken))
        {
            await scheduler.AddJob(
                JobBuilder
                    .Create<CheckMonitoringJob>()
                    .WithIdentity(jobKey)
                    .UsingJobData("monitorId", monitorId)
                    .StoreDurably()
                    .RequestRecovery()
                    .Build(),
                replace: true,
                cancellationToken
            );
        }

        var trigger = TriggerBuilder
            .Create()
            .ForJob(jobKey)
            .WithIdentity(new TriggerKey($"{monitorId}-{Guid.NewGuid():N}", MonitoringCheckJobs.TriggerGroup))
            .UsingJobData("force", force)
            .StartNow()
            .Build();

        await scheduler.ScheduleJob(trigger, cancellationToken);
    }
}