using System.Net.Http; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; namespace JobTrackerApi.Services; public sealed record CvNormalizationResult( double? Confidence, string? Reason, [property: JsonPropertyName("normalized_text")] string? NormalizedText); public interface ICvAiNormalizer { Task NormalizeAsync(string text, CancellationToken cancellationToken = default); } public sealed class CvAiNormalizer : ICvAiNormalizer { private readonly IHttpClientFactory _httpClientFactory; public CvAiNormalizer(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } public async Task NormalizeAsync(string text, CancellationToken cancellationToken = default) { if (string.IsNullOrWhiteSpace(text)) return null; try { var client = _httpClientFactory.CreateClient("ai-service"); var payload = JsonSerializer.Serialize(new { text }); using var content = new StringContent(payload, Encoding.UTF8, "application/json"); using var response = await client.PostAsync("/cv/normalize", content, cancellationToken); if (!response.IsSuccessStatusCode) return null; await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken); return await JsonSerializer.DeserializeAsync(stream, new JsonSerializerOptions(JsonSerializerDefaults.Web) { PropertyNameCaseInsensitive = true }, cancellationToken); } catch { return null; } } } public sealed class NoOpCvAiNormalizer : ICvAiNormalizer { public static NoOpCvAiNormalizer Instance { get; } = new(); private NoOpCvAiNormalizer() { } public Task NormalizeAsync(string text, CancellationToken cancellationToken = default) => Task.FromResult(null); }