feat: add /api/chart/v2/{isin} endpoint and register IChartDataServiceV2

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 15:54:23 +02:00
parent 0caccc72d5
commit 44e2098584
2 changed files with 56 additions and 1 deletions

View File

@@ -20,11 +20,16 @@ namespace CertReports.Syncfusion.Controllers;
public class ChartController : ControllerBase
{
private readonly IChartDataService _chartDataService;
private readonly IChartDataServiceV2 _chartDataServiceV2;
private readonly ILogger<ChartController> _logger;
public ChartController(IChartDataService chartDataService, ILogger<ChartController> logger)
public ChartController(
IChartDataService chartDataService,
IChartDataServiceV2 chartDataServiceV2,
ILogger<ChartController> logger)
{
_chartDataService = chartDataService;
_chartDataServiceV2 = chartDataServiceV2;
_logger = logger;
}
@@ -77,6 +82,55 @@ public class ChartController : ControllerBase
}
}
/// <summary>
/// Endpoint V2: grafico migliorato con titolo, colori distinti, label sulle linee e legenda in basso.
/// Richiede SP cedlab_Chart_UL1 e cedlab_Chart_AllSeriesV2 nel DB.
/// </summary>
[HttpGet("v2/{isin}")]
public async Task<IActionResult> GenerateChartV2(
string isin,
[FromQuery] int width = 1100,
[FromQuery] int height = 700,
[FromQuery] string format = "png")
{
if (string.IsNullOrWhiteSpace(isin))
return BadRequest("ISIN non valido.");
width = Math.Clamp(width, 400, 2000);
height = Math.Clamp(height, 300, 1500);
try
{
var chartData = await _chartDataServiceV2.GetChartDataV2Async(isin);
if (chartData == null || chartData.SeriesPoints.Count == 0)
{
return NotFound(new
{
status = "KO",
message = $"Nessun dato per il grafico V2 di {isin} (meno di 30 prezzi EOD?).",
});
}
byte[] pngBytes = SkiaChartRendererV2.RenderToPng(chartData, width, height);
if (format.Equals("pdf", StringComparison.OrdinalIgnoreCase))
{
byte[] pdfBytes = WrapPngInPdf(pngBytes);
Response.Headers.Append("Content-Disposition", $"inline; filename=chart_v2_{isin}.pdf");
return File(pdfBytes, "application/pdf");
}
Response.Headers.Append("Content-Disposition", $"inline; filename=chart_v2_{isin}.png");
return File(pngBytes, "image/png");
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore generazione chart V2 per ISIN {Isin}", isin);
return StatusCode(500, new { status = "KO", message = "Errore nella generazione del grafico V2." });
}
}
private static byte[] WrapPngInPdf(byte[] pngBytes)
{
var doc = new PdfDocument();

View File

@@ -41,6 +41,7 @@ builder.Services.AddHealthChecks()
// Registra i servizi applicativi
builder.Services.AddScoped<ICertificateDataService, CertificateDataService>();
builder.Services.AddScoped<IChartDataService, ChartDataService>();
builder.Services.AddScoped<IChartDataServiceV2, ChartDataServiceV2>();
builder.Services.AddScoped<IPdfSectionRenderer, AnagraficaSectionRenderer>();
builder.Services.AddScoped<IPdfSectionRenderer, EventiSectionRenderer>();
builder.Services.AddScoped<IPdfSectionRenderer, ScenarioSectionRenderer>();