Files
jobtrackingapp/JobTrackerApi/Services/CvAiClassifier.cs
T

66 lines
2.1 KiB
C#

using System.Net.Http;
using System.Text;
using System.Text.Json;
namespace JobTrackerApi.Services;
public sealed record CvBlockClassificationResult(
string? Section,
double? Confidence,
string? Reason,
string? Title,
string? Company,
string? Location,
string? Start,
string? End,
List<string>? Bullets);
public interface ICvAiClassifier
{
Task<CvBlockClassificationResult?> ClassifyBlockAsync(string block, CancellationToken cancellationToken = default);
}
public sealed class CvAiClassifier : ICvAiClassifier
{
private readonly IHttpClientFactory _httpClientFactory;
public CvAiClassifier(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<CvBlockClassificationResult?> ClassifyBlockAsync(string block, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(block)) return null;
try
{
var client = _httpClientFactory.CreateClient("ai-service");
var payload = JsonSerializer.Serialize(new { block });
using var content = new StringContent(payload, Encoding.UTF8, "application/json");
using var response = await client.PostAsync("/cv/classify-block", content, cancellationToken);
if (!response.IsSuccessStatusCode) return null;
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken);
var parsed = await JsonSerializer.DeserializeAsync<CvBlockClassificationResult>(stream, new JsonSerializerOptions(JsonSerializerDefaults.Web)
{
PropertyNameCaseInsensitive = true
}, cancellationToken);
return parsed;
}
catch
{
return null;
}
}
}
public sealed class NoOpCvAiClassifier : ICvAiClassifier
{
public static NoOpCvAiClassifier Instance { get; } = new();
private NoOpCvAiClassifier() { }
public Task<CvBlockClassificationResult?> ClassifyBlockAsync(string block, CancellationToken cancellationToken = default)
=> Task.FromResult<CvBlockClassificationResult?>(null);
}