Files
jobtrackingapp/JobTrackerApi/Services/SavedJobSearchRunner.cs
T
2026-08-31 22:23:34 +02:00

45 lines
1.7 KiB
C#

using JobTrackerApi.Data;
using JobTrackerApi.Models;
namespace JobTrackerApi.Services;
public sealed record SavedJobSearchRunResult(
IReadOnlyList<SavedJobSearchJobResult> Jobs,
int NewCount,
bool WasInitialRun);
public sealed record SavedJobSearchJobResult(DiscoveredJob Job, bool IsNew, bool IsDismissed);
public sealed class SavedJobSearchRunner(
JobTrackerContext db,
IJobDiscoverySearchService discovery,
TimeProvider timeProvider)
{
public async Task<SavedJobSearchRunResult> RunAsync(SavedJobSearch search, CancellationToken cancellationToken)
{
var jobs = await discovery.SearchAsync(search.Query, search.Location, cancellationToken);
var now = timeProvider.GetUtcNow();
var wasInitialRun = search.LastRunAtUtc is null;
var existing = search.Results.ToDictionary(item => item.ExternalJobId, StringComparer.OrdinalIgnoreCase);
var results = new List<SavedJobSearchJobResult>(jobs.Count);
var newCount = 0;
foreach (var job in jobs)
{
var isNew = !existing.TryGetValue(job.Id, out var state);
if (state is null)
{
state = new SavedJobSearchResult { ExternalJobId = job.Id, FirstSeenAtUtc = now, LastSeenAtUtc = now };
search.Results.Add(state);
db.SavedJobSearchResults.Add(state);
newCount++;
}
else state.LastSeenAtUtc = now;
results.Add(new SavedJobSearchJobResult(job, isNew, state.IsDismissed));
}
search.LastRunAtUtc = now;
search.UpdatedAtUtc = now;
return new SavedJobSearchRunResult(results, newCount, wasInitialRun);
}
}