Add OAth flow for Gmail and update tables and UI

This commit is contained in:
cesnimda
2026-03-21 14:02:19 +01:00
parent 51a539068f
commit ed68e44eaf
17 changed files with 1180 additions and 53 deletions
@@ -0,0 +1,89 @@
using System.Text.Json;
using JobTrackerApi.Data;
using JobTrackerApi.Services.JobImport;
using Microsoft.EntityFrameworkCore;
namespace JobTrackerApi.Services;
public sealed class JobEnrichmentHostedService : BackgroundService
{
private readonly IServiceProvider _services;
private readonly ILogger<JobEnrichmentHostedService> _logger;
public JobEnrichmentHostedService(IServiceProvider services, ILogger<JobEnrichmentHostedService> logger)
{
_services = services;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
while (!stoppingToken.IsCancellationRequested)
{
try
{
using var scope = _services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<JobTrackerContext>();
var summarizer = scope.ServiceProvider.GetRequiredService<ISummarizerService>();
var jobs = await db.JobApplications
.Where(j => !j.IsDeleted)
.Where(j => string.IsNullOrWhiteSpace(j.ShortSummary) || string.IsNullOrWhiteSpace(j.Tags))
.OrderByDescending(j => j.DateApplied)
.Take(20)
.ToListAsync(stoppingToken);
var changed = 0;
foreach (var job in jobs)
{
var sourceText = string.IsNullOrWhiteSpace(job.Description) ? job.Notes : job.Description;
if (string.IsNullOrWhiteSpace(job.Tags) && !string.IsNullOrWhiteSpace(sourceText))
{
var tags = SkillTagger.Detect(sourceText)
.Distinct(StringComparer.OrdinalIgnoreCase)
.OrderBy(x => x, StringComparer.OrdinalIgnoreCase)
.ToList();
if (tags.Count > 0)
{
job.Tags = JsonSerializer.Serialize(tags);
changed++;
}
}
if (string.IsNullOrWhiteSpace(job.ShortSummary) && !string.IsNullOrWhiteSpace(sourceText))
{
try
{
var shortSummary = await summarizer.SummarizeAsync(sourceText, 80, 20);
if (!string.IsNullOrWhiteSpace(shortSummary))
{
job.ShortSummary = shortSummary;
changed++;
}
}
catch
{
// Best effort; leave for a later pass.
}
}
}
if (changed > 0)
{
await db.SaveChangesAsync(stoppingToken);
_logger.LogInformation("Backfilled tags/summaries for {Count} job fields.", changed);
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Job enrichment background pass failed.");
}
await Task.Delay(TimeSpan.FromMinutes(10), stoppingToken);
}
}
}