using api.Services.Contracts.Rag; using Api.Models.Rag; using Api.Services.Rag; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.RateLimiting; namespace Api.Controllers; [ApiController] [Route("api/rag")] [EnableRateLimiting("rag")] public sealed class RagController : ControllerBase { private readonly ICvRagService _cvRagService; private readonly ILogger _logger; public RagController(ICvRagService cvRagService, ILogger logger) { _cvRagService = cvRagService; _logger = logger; } [HttpPost("cv")] [RequestSizeLimit(8 * 1024 * 1024)] public async Task UploadCv([FromForm(Name = "cv")] IFormFile? cv, [FromForm] bool gdprConsent, CancellationToken ct) { try { if (cv is null) return BadRequest(new { error = "Missing CV PDF." }); var result = await _cvRagService.IngestCvAsync(cv, gdprConsent, ct); return Ok(result); } catch (InvalidOperationException ex) { return BadRequest(new { error = ex.Message }); } catch (Exception ex) { _logger.LogError(ex, "CV ingestion failed"); return StatusCode(500, new { error = "CV ingestion failed." }); } } [HttpPost("match-job")] public async Task MatchJob([FromBody] JobMatchRequest request, CancellationToken ct) { try { var result = await _cvRagService.MatchJobAsync(request, ct); return Ok(result); } catch (InvalidOperationException ex) { return BadRequest(new { error = ex.Message }); } catch (Exception ex) { _logger.LogError(ex, "Job matching failed"); return StatusCode(500, new { error = "Job matching failed." }); } } }