17 KiB
Memoria Field + Natixis Parameter — Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Add a "Memoria" KV field in the Analisi section of all reports, and a ?natixis query param that switches the Tipologia source from info.Categoria to info.Nome.
Architecture: The ShowNatixis bool follows the existing ShowBranding/ShowDividend pattern: added to CertificateReportData, propagated from controller → orchestrator → renderers. Cache keys follow the existing suffix-concatenation pattern. The DrawTitle private method in both renderers gains a bool showNatixis parameter (Option A from spec).
Tech Stack: ASP.NET Core 8, Syncfusion PDF, C# 12
Important Pre-Read
Before starting, note these facts about the existing code:
CertificateInfo.Memory(string) already exists inCertificateModels.cs:22— no model/SP changes needed for Feature 1.ExpiredAnagraficaSectionRenderer.DrawAnalisialready contains("Memoria Cedola", info.Memory)at line 211 — it only needs to be renamed to"Memoria".AnagraficaSectionRenderer.DrawAnalisidoes not have the field — it needs to be added after("Leva", ...)at line 327.- No automated tests exist in this project. Each task ends with
dotnet buildas verification.
File Map
| File | Change |
|---|---|
Models/CertificateModels.cs |
Add bool ShowNatixis to CertificateReportData |
Services/Interfaces/IServices.cs |
Add showNatixis param to GenerateReportAsync |
Controllers/ReportController.cs |
Add [FromQuery] natixis to all 3 endpoints + helper |
Services/Implementations/ReportOrchestrator.cs |
Add param, propagate flag, update cache key logic |
Services/Implementations/AnagraficaSectionRenderer.cs |
Add Memoria item in DrawAnalisi; add showNatixis to DrawTitle |
Services/Implementations/ExpiredAnagraficaSectionRenderer.cs |
Rename "Memoria Cedola"→"Memoria"; add showNatixis to DrawTitle |
Task 1: Add ShowNatixis to CertificateReportData
Files:
-
Modify:
CertReports.Syncfusion/Models/CertificateModels.cs(around line 162) -
Step 1: Add the property
In
CertificateModels.cs, find theCertificateReportDataclass:public class CertificateReportData { public CertificateInfo Info { get; set; } = new(); public List<CertificateEvent> Eventi { get; set; } = new(); public ScenarioAnalysis Scenario { get; set; } = new(); public byte[]? ChartImage { get; set; } public bool ShowBranding { get; set; } = false; public bool ShowDividend { get; set; } = false; }Add
ShowNatixisafterShowDividend:public bool ShowDividend { get; set; } = false; public bool ShowNatixis { get; set; } = false; -
Step 2: Build
dotnet build CertReports.SyncfusionExpected: Build succeeded, 0 errors.
-
Step 3: Commit
git add CertReports.Syncfusion/Models/CertificateModels.cs git commit -m "feat: add ShowNatixis flag to CertificateReportData"
Task 2: Update IReportOrchestrator interface
Files:
-
Modify:
CertReports.Syncfusion/Services/Interfaces/IServices.cs(line 49) -
Step 1: Update the signature
Find:
Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false, bool showDividend = false);Replace with:
Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false, bool showDividend = false, bool showNatixis = false); -
Step 2: Build
dotnet build CertReports.SyncfusionExpected: Build fails with CS0535 ("ReportOrchestrator does not implement interface member GenerateReportAsync") — this is intentional and will be resolved in Task 4.
-
Step 3: Commit
git add CertReports.Syncfusion/Services/Interfaces/IServices.cs git commit -m "feat: add showNatixis param to IReportOrchestrator interface"
Task 3: Update ReportController
Files:
-
Modify:
CertReports.Syncfusion/Controllers/ReportController.cs -
Step 1: Update
GenerateReportendpoint (line 43)Find:
public async Task<IActionResult> GenerateReport( [FromQuery(Name = "p")] string? encryptedIsin = null, [FromQuery(Name = "alias")] string? aliasId = null, [FromQuery(Name = "branding")] bool showBranding = false, [FromQuery(Name = "dividend")] bool showDividend = false)Replace with:
public async Task<IActionResult> GenerateReport( [FromQuery(Name = "p")] string? encryptedIsin = null, [FromQuery(Name = "alias")] string? aliasId = null, [FromQuery(Name = "branding")] bool showBranding = false, [FromQuery(Name = "dividend")] bool showDividend = false, [FromQuery(Name = "natixis")] bool showNatixis = false) -
Step 2: Update the call to
GenerateAndReturnPdfinsideGenerateReport(line 74)Find:
return await GenerateAndReturnPdf(isin, showBranding, showDividend);Replace with:
return await GenerateAndReturnPdf(isin, showBranding, showDividend, showNatixis); -
Step 3: Update
GenerateReportByIsinendpoint (line 82)Find:
public async Task<IActionResult> GenerateReportByIsin( string isin, [FromQuery(Name = "branding")] bool showBranding = false, [FromQuery(Name = "dividend")] bool showDividend = false)Replace with:
public async Task<IActionResult> GenerateReportByIsin( string isin, [FromQuery(Name = "branding")] bool showBranding = false, [FromQuery(Name = "dividend")] bool showDividend = false, [FromQuery(Name = "natixis")] bool showNatixis = false) -
Step 4: Update the call to
GenerateAndReturnPdfinsideGenerateReportByIsin(line 92)Find:
return await GenerateAndReturnPdf(isin, showBranding, showDividend);Replace with:
return await GenerateAndReturnPdf(isin, showBranding, showDividend, showNatixis);Note: there are two identical
return await GenerateAndReturnPdf(isin, showBranding, showDividend);lines — make sure you update the one insideGenerateReportByIsin(around line 92). -
Step 5: Update
DownloadReportendpoint (line 99)Find:
public async Task<IActionResult> DownloadReport( [FromQuery(Name = "p")] string? encryptedIsin = null, [FromQuery(Name = "alias")] string? aliasId = null, [FromQuery(Name = "branding")] bool showBranding = false, [FromQuery(Name = "dividend")] bool showDividend = false)Replace with:
public async Task<IActionResult> DownloadReport( [FromQuery(Name = "p")] string? encryptedIsin = null, [FromQuery(Name = "alias")] string? aliasId = null, [FromQuery(Name = "branding")] bool showBranding = false, [FromQuery(Name = "dividend")] bool showDividend = false, [FromQuery(Name = "natixis")] bool showNatixis = false) -
Step 6: Update the
_orchestrator.GenerateReportAsynccall insideDownloadReport(line 117)Find:
var pdfBytes = await _orchestrator.GenerateReportAsync(isin, showBranding, showDividend);Replace with:
var pdfBytes = await _orchestrator.GenerateReportAsync(isin, showBranding, showDividend, showNatixis); -
Step 7: Update
GenerateAndReturnPdfhelper signature (line 129)Find:
private async Task<IActionResult> GenerateAndReturnPdf(string isin, bool showBranding = false, bool showDividend = false)Replace with:
private async Task<IActionResult> GenerateAndReturnPdf(string isin, bool showBranding = false, bool showDividend = false, bool showNatixis = false) -
Step 8: Update the
_orchestrator.GenerateReportAsynccall insideGenerateAndReturnPdf(line 134)Find:
var pdfBytes = await _orchestrator.GenerateReportAsync(isin, showBranding, showDividend);Replace with:
var pdfBytes = await _orchestrator.GenerateReportAsync(isin, showBranding, showDividend, showNatixis); -
Step 9: Build
dotnet build CertReports.SyncfusionExpected: Build succeeded.
-
Step 10: Commit
git add CertReports.Syncfusion/Controllers/ReportController.cs git commit -m "feat: add natixis query param to all ReportController endpoints"
Task 4: Update ReportOrchestrator
Files:
-
Modify:
CertReports.Syncfusion/Services/Implementations/ReportOrchestrator.cs -
Step 1: Update method signature (line 47)
Find:
public async Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false, bool showDividend = false)Replace with:
public async Task<byte[]> GenerateReportAsync(string isin, bool showBranding = false, bool showDividend = false, bool showNatixis = false) -
Step 2: Update cache key logic (lines 50-52)
Find:
var dividendSuffix = showDividend ? ":dividend" : ""; var baseCacheKey = showBranding ? $"{isin}:branded{dividendSuffix}" : $"{isin}{dividendSuffix}"; var expiredCacheKey = showBranding ? $"{isin}:expired:branded{dividendSuffix}" : $"{isin}:expired{dividendSuffix}";Replace with:
var dividendSuffix = showDividend ? ":dividend" : ""; var natixisSuffix = showNatixis ? ":natixis" : ""; var baseCacheKey = showBranding ? $"{isin}:branded{dividendSuffix}{natixisSuffix}" : $"{isin}{dividendSuffix}{natixisSuffix}"; var expiredCacheKey = showBranding ? $"{isin}:expired:branded{dividendSuffix}{natixisSuffix}" : $"{isin}:expired{dividendSuffix}{natixisSuffix}"; -
Step 3: Propagate
ShowNatixisintoCertificateReportData(lines 64-71)Find:
var reportData = new CertificateReportData { Info = await _dataService.GetCertificateInfoAsync(isin), Eventi = await _dataService.GetCertificateEventsAsync(isin), Scenario = await _dataService.GetScenarioAnalysisAsync(isin), ShowBranding = showBranding, ShowDividend = showDividend, };Replace with:
var reportData = new CertificateReportData { Info = await _dataService.GetCertificateInfoAsync(isin), Eventi = await _dataService.GetCertificateEventsAsync(isin), Scenario = await _dataService.GetScenarioAnalysisAsync(isin), ShowBranding = showBranding, ShowDividend = showDividend, ShowNatixis = showNatixis, }; -
Step 4: Build
dotnet build CertReports.SyncfusionExpected: Build succeeded, 0 errors.
-
Step 5: Commit
git add CertReports.Syncfusion/Services/Implementations/ReportOrchestrator.cs git commit -m "feat: propagate showNatixis through orchestrator and cache keys"
Task 5: Update AnagraficaSectionRenderer (active certs)
Two changes: (A) add Memoria to DrawAnalisi, (B) support natixis in DrawTitle.
Files:
- Modify:
CertReports.Syncfusion/Services/Implementations/AnagraficaSectionRenderer.cs
Change A — Add Memoria to DrawAnalisi
-
Step 1: Add Memoria item after Leva (line 327)
Find (this is the closing
};of theleftItemsarray — NOT therightItemsarray that follows a few lines later):("Leva", string.IsNullOrWhiteSpace(info.Leva) ? "—" : info.Leva), };Replace with:
("Leva", string.IsNullOrWhiteSpace(info.Leva) ? "—" : info.Leva), ("Memoria", string.IsNullOrWhiteSpace(info.Memory) ? "—" : info.Memory), };
Change B — Support Natixis in DrawTitle
-
Step 2: Update the
DrawTitlecall site inRender(line 37)Find:
y = DrawTitle(g, info, PageW, y);Replace with:
y = DrawTitle(g, info, PageW, y, data.ShowNatixis); -
Step 3: Update
DrawTitlesignature (line 74)Find:
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y)Replace with:
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y, bool showNatixis) -
Step 4: Update Tipologia resolution in
DrawTitle(line 95)Find:
bool showTip = !string.IsNullOrEmpty(info.Categoria);Replace with:
string tipologia = showNatixis ? info.Nome : info.Categoria; bool showTip = !string.IsNullOrEmpty(tipologia); -
Step 5: Replace
info.Categoriawithtipologiain theDrawInfoBoxcall (line 110)Find:
"TIPOLOGIA", info.Categoria,Replace with:
"TIPOLOGIA", tipologia, -
Step 6: Build
dotnet build CertReports.SyncfusionExpected: Build succeeded, 0 errors.
-
Step 7: Commit
git add CertReports.Syncfusion/Services/Implementations/AnagraficaSectionRenderer.cs git commit -m "feat: add Memoria field to Analisi and natixis support to AnagraficaSectionRenderer"
Task 6: Update ExpiredAnagraficaSectionRenderer (expired certs)
Two changes: (A) rename "Memoria Cedola" → "Memoria" in DrawAnalisi, (B) support natixis in DrawTitle.
Files:
- Modify:
CertReports.Syncfusion/Services/Implementations/ExpiredAnagraficaSectionRenderer.cs
Change A — Rename label in DrawAnalisi
-
Step 1: Rename "Memoria Cedola" to "Memoria" (line 211)
Find:
("Memoria Cedola", info.Memory),Replace with:
("Memoria", info.Memory),
Change B — Support Natixis in DrawTitle
-
Step 2: Update the
DrawTitlecall site inRender(line 36)Find:
y = DrawTitle(g, info, PageW, y);Replace with:
y = DrawTitle(g, info, PageW, y, data.ShowNatixis); -
Step 3: Update
DrawTitlesignature (line 72)Find:
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y)Replace with:
private float DrawTitle(PdfGraphics g, CertificateInfo info, float w, float y, bool showNatixis) -
Step 4: Update Tipologia resolution in
DrawTitle(line 86)Find:
if (!string.IsNullOrEmpty(info.Categoria)) { DrawInfoBox(g, 0, y, w, boxH, "TIPOLOGIA", info.Categoria,Replace with:
string tipologia = showNatixis ? info.Nome : info.Categoria; if (!string.IsNullOrEmpty(tipologia)) { DrawInfoBox(g, 0, y, w, boxH, "TIPOLOGIA", tipologia, -
Step 5: Build
dotnet build CertReports.SyncfusionExpected: Build succeeded, 0 errors.
-
Step 6: Commit
git add CertReports.Syncfusion/Services/Implementations/ExpiredAnagraficaSectionRenderer.cs git commit -m "feat: rename Memoria Cedola and add natixis support to ExpiredAnagraficaSectionRenderer"
Task 7: Manual Verification
-
Step 1: Run the application
dotnet run --project CertReports.Syncfusion -
Step 2: Verify Memoria field (active cert)
Open:
https://localhost:{port}/api/report/by-isin/{ISIN_ATTIVO}Expected: In the Analisi section (left column), "Memoria" appears below "Leva" as the 9th item. If
info.Memoryis empty, shows "—". -
Step 3: Verify Memoria field (expired cert)
Open:
https://localhost:{port}/api/report/by-isin/{ISIN_SCADUTO}Expected: In the Analisi section, the field is labeled "Memoria" (not "Memoria Cedola").
-
Step 4: Verify Natixis=false (default)
Open:
https://localhost:{port}/api/report/by-isin/{ISIN}(no natixis param)Expected: Tipologia box shows
info.Categoria— same as before. -
Step 5: Verify Natixis=true
Open:
https://localhost:{port}/api/report/by-isin/{ISIN}?natixis=trueExpected: Tipologia box shows
info.Nomeinstead ofinfo.Categoria. -
Step 6: Verify cache keys are independent
Open the same ISIN first without natixis, then with
?natixis=true. Both should generate fresh PDFs with the correct Tipologia value (not the cached one).