45 lines
1.7 KiB
C#
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);
|
|
}
|
|
}
|