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);
}
}