feat(discovery): schedule saved-search alerts
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user