5.8 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project
SmartReports / CertReports.Syncfusion — ASP.NET Core 8 REST API che genera PDF di certificati finanziari strutturati, sostituendo il vecchio progetto WebForms DevExpress. Usa Syncfusion PDF (Community License) e SkiaSharp per i grafici.
Progetto unico nella solution: CertReports.Syncfusion/.
Build & Run
# Restore + build
dotnet restore
dotnet build
# Run locale → https://localhost:{porta}/api/report/by-isin/{ISIN}
dotnet run --project CertReports.Syncfusion
# Docker
docker-compose up --build
# → http://localhost:5080/api/report/by-isin/{ISIN}
Non esistono test automatici al momento.
Architettura
Il flusso di generazione è orchestrato da ReportOrchestrator:
HTTP (ISIN) → ReportController → ReportOrchestrator
├── CertificateDataService (4 SP → anagrafica, sottostanti, eventi, scenario)
├── AnagraficaSectionRenderer → PdfDocument (Sezione 1)
├── EventiSectionRenderer → PdfDocument (Sezione 2)
├── ScenarioSectionRenderer → PdfDocument (Sezione 3, opzionale)
├── ChartDataService (3 SP → dati grafico)
├── SkiaChartRenderer → PNG in memoria
├── ChartSectionRenderer → PdfDocument (Sezione 4)
└── PdfMergerService → byte[] → Response
Aggiungere una nuova sezione PDF: implementare IPdfSectionRenderer, impostare SectionName e Order, registrare in Program.cs come AddScoped<IPdfSectionRenderer, NuovaSezione>(). L'orchestratore la include automaticamente ordinandola per Order.
Tema: tutto in PdfTheme.cs — colori, font, layout, brush/pen. Modificare lì per aggiornare tutti i renderer.
Palette colori principale (stile "Ibrido elegante"):
AccentBlue#1565C0— titoli, header tabelle, valori chiaveNegativeRed#CC0000— valori negativi (performance, rendimento)PositiveGreen#2E7D32— valori positivi (performance)- Brush corrispondenti:
AccentBlueBrush,NegativeRedBrush,PositiveGreenBrush,TableHeaderBrush(alias diAccentBlueBrush)
Configurazione chiave
appsettings.json: connection string (CertDb), Syncfusion license key, CryptoSettings passphrase, cache TTLappsettings.Development.json: non deve contenereConnectionStrings, altrimenti sovrascriveappsettings.json- Connection string: usare
Data Source+Initial Catalog+Encrypt=False;perMicrosoft.Data.SqlClientv5 - Se la connessione fallisce via Named Pipes, aggiungere prefisso
tcp:all'indirizzo IP
Gotcha Syncfusion v33 & SkiaSharp
| Problema | Soluzione |
|---|---|
Color(r,g,b) rimosso |
Color.FromArgb(255, r, g, b) |
Syncfusion.Drawing.Net.Core non esiste |
Inglobato in Syncfusion.Pdf.Net.Core, rimuovere dal .csproj |
PdfStandardFont non è IDisposable |
Non usare using sulla dichiarazione |
grid.Headers non iterabile con foreach |
for (int r = 0; r < grid.Headers.Count; r++) |
PdfTextWebLink non trovato |
Aggiungere using Syncfusion.Pdf.Interactive; |
RectangleF non supporta named arguments |
new RectangleF(x, y, w, h) — no startY: o simili |
grid.Draw() restituisce void |
Stimare altezza con (rows + 1) * RowHeight |
PdfMergerService: stream chiuso prima del Save() |
Tenere tutti gli stream aperti fino al salvataggio finale, poi cleanup in finally |
SkiaSharp DrawText obsoleto |
SKFont + canvas.DrawText(text, x, y, SKTextAlign, font, paint) |
Namespace conflict CertReports.Syncfusion.Pdf |
Aggiungere using Syncfusion.Pdf; esplicito nel file |
Database
Tutte le stored procedure sono su FirstSolutionDB. I dati tornano già formattati come stringhe dalle SP (es. FORMAT(value,'P2','it-IT')): i modelli C# usano string per questi campi. Solo NominalValue, PrezzoEmissione, CpnPagati, CpnDaPagare, CpnInMemoria sono decimal? perché servono come valori numerici nel rendering.
API Endpoints
GET /api/report?p={isin_cifrato}/?alias={id}//by-isin/{isin}— PDF inlineGET /api/report/download?p={...}/?alias={...}— PDF come allegato- Tutti gli endpoint report accettano
?branding=true(defaultfalse) per abilitare il footer "Powered by Smart Roots" GET /api/chart/{isin}[?format=png|pdf&width=&height=]— grafico standaloneGET /health— health check DB + chart service
Footer branding
Il parametro ?branding=true aggiunge al footer di ogni pagina del report:
- Sinistra:
"Powered by "+ hyperlink PDF cliccabile"Smart Roots"→https://www.smart-roots.net - Destra: numero pagina
Con branding=false (default): solo numero pagina centrato.
La cache usa chiavi separate: {isin}:branded vs {isin}. Il flag è propagato come CertificateReportData.ShowBranding e passato a PdfTheme.DrawFooter(g, pageWidth, pageHeight, pageNumber, showBranding). L'hyperlink usa PdfTextWebLink (richiede using Syncfusion.Pdf.Interactive;).
Sezione 1 — AnagraficaSectionRenderer
Struttura a 3 sezioni verticali in una singola pagina A4:
| Sezione | Contenuto |
|---|---|
| Titolo | "Scheda Prodotto {ISIN}" blu + Bid/Ask a destra + linea separatrice blu |
| A — Caratteristiche Prodotto | Tabella emittente a sinistra (ISIN, Mercato, Valuta, Date, Autocall) + tabella cedole a destra (CpnPagati/DaPagare/InMemoria, RendimentoAttuale) |
| B — Analisi | 8 KV a sinistra + 9 KV a destra. Leva/FattoreAirbag/TriggerOneStar mostrati come "—" anche se vuoti |
| C — Sottostanti | PdfGrid 9 colonne: Nome, Strike, Last, % Perf., Barr.K, Buffer K, Trig.CPN, Buf.CPN, Trig.AC (Dist.AC rimossa) |
Se la tabella Sottostanti non entra (y > PageH-80pt), si crea una nuova pagina. Il footer viene disegnato su ogni pagina con PdfTheme.DrawFooter.