using Microsoft.AspNetCore.Mvc; using ScrapperAPI.Dtos; using ScrapperAPI.Interfaces; namespace ScrapperAPI.Controllers; [ApiController] [Route("extraction-runs")] public sealed class ExtractionRunsController : ControllerBase { private readonly IExtractionCoordinator _coord; private readonly IExtractionRunRepository _runs; private readonly IExtractedDataRepository _extracted; public ExtractionRunsController( IExtractionCoordinator coord, IExtractionRunRepository runs, IExtractedDataRepository extracted) { _coord = coord; _runs = runs; _extracted = extracted; } /// /// Inicia uma extração em background (cria um run). /// [HttpPost] public async Task Start([FromBody] StartExtractionRequest req, CancellationToken ct) { var runId = await _coord.StartRunAsync(req, ct); return Accepted(new { runId }); } [HttpGet("{runId:long}")] public async Task GetRun(long runId, CancellationToken ct) { var row = await _runs.GetByIdAsync(runId, ct); if (row is null) return NotFound(); var runtime = _coord.GetRuntimeStatus(runId); return Ok(new { run = row, runtime }); } /// /// Lista os dados extraídos de uma sessão por modelo. /// GET /extraction-runs/session/1/model/10 /// [HttpGet("session/{sessionId:int}/model/{modelId:long}")] public async Task ListExtracted(int sessionId, long modelId, CancellationToken ct) { var rows = await _extracted.ListBySessionAsync(sessionId, modelId, ct); return Ok(rows); } /// /// Pega o JSON extraído de um item específico. /// GET /extraction-runs/queue/123/model/10 /// [HttpGet("queue/{queueId:int}/model/{modelId:long}")] public async Task GetByQueue(int queueId, long modelId, CancellationToken ct) { var row = await _extracted.GetByQueueIdAsync(queueId, modelId, ct); return row is null ? NotFound() : Ok(row); } }