From 9ac361006404d4be2d80e7d4be9ba02c1370ba84 Mon Sep 17 00:00:00 2001 From: SmartRootsSrl Date: Wed, 27 May 2026 17:57:16 +0200 Subject: [PATCH] docs: update CLAUDE.md with chart v2 endpoint, SP schema, SKFont gotcha, ToDecimal gotcha --- CLAUDE.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 620a312..0487f80 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -84,6 +84,25 @@ HTTP (ISIN) → ReportController → ReportOrchestrator | `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 | +| SkiaSharp `SKFont` NON è IDisposable | Non usare `using` su `SKFont` — solo `SKPaint`, `SKPath`, `SKSurface`, `SKImage`, `SKData` sono IDisposable | +| `SqlDataReader.GetDecimal` su colonna `float` SQL | Usare `Convert.ToDecimal(r.GetValue(ord))` — le SP cedlab_ possono restituire `float` (es. `PriceWorst` da subquery su `Prices.Px_close`) | + +## Grafico V2 (`/api/chart/v2/{isin}`) + +**File**: `SkiaChartRendererV2.cs`, `ChartDataServiceV2.cs`, `ChartModelsV2.cs` + +**SP utilizzate** (su `FirstSolutionDB`): +- `cedlab_Chart_UL1 @isin VARCHAR(15)` — metadata sottostanti, già esistente; restituisce tutti i campi V2 (IsWorstOf, PriceWorst, NomeCFT, TriggerAutocallPerc, ecc.). Ordinata `IsWorstOf DESC` → prima riga = worst-of. +- `cedlab_Chart_AllSeriesV2 @isin VARCHAR(15)` — tutte le serie (CTF + UL) in un unico round-trip. Da creare: script in `docs/sql/cedlab_Chart_AllSeriesV2.sql`. + +**Schema DB rilevante** (per le SP chart): +- `dbo.Prices`: `CertificatesID`, `UnderlyingsID`, `Px_date`, `PX_LAST_EOD`, `Px_close`, `Px_closeadj`, `Px_low`, `Px_high`, `Px_open` +- `dbo.Underlyings`: `IDUnderlyings`, `AdjustedPrices`, `deleted`, `sospeso` +- `dbo.CertificatesUnderlyings`: `CertificatesID`, `UnderlyingsID`, `Strike`, `deleted` — lo **Strike per UL** viene da qui, non da `Underlyings` +- `dbo.Certificates`: `IDCertificates`, `ISIN`, `Nominal_amount`, `Direction`, `Domino`, `BasketTypeID` +- `StartDate` nel grafico = `MIN(Prices.Px_date) WHERE CertificatesID = @IDCertificates` (aggregato, non colonna) + +**Colori V2**: CTF = rosso `#CC0000` 2.5px, WorstOf = blu `#1565C0` 2px, altri UL = grigi 1px ## Database @@ -96,7 +115,8 @@ Tutte le stored procedure sono su `FirstSolutionDB`. I dati tornano **già forma - Tutti gli endpoint report accettano `?branding=true` (default `false`) per abilitare il footer "Powered by Smart Roots" - Tutti gli endpoint report accettano `?dividend=true` (default `false`) per aggiungere la pagina Sottostanti+Dividendi - Tutti gli endpoint report accettano `?natixis=true` (default `false`) per mostrare `info.Nome` nel box Tipologia invece di `info.Categoria` -- `GET /api/chart/{isin}[?format=png|pdf&width=&height=]` — grafico standalone +- `GET /api/chart/{isin}[?format=png|pdf&width=&height=]` — grafico standalone v1 +- `GET /api/chart/v2/{isin}[?format=png|pdf&width=&height=]` — grafico standalone v2 (titolo, colori CTF/WorstOf, label linee, legenda in basso) - `GET /health` — health check DB + chart service ## Footer branding @@ -137,3 +157,66 @@ Struttura a 3 sezioni verticali in una singola pagina A4: | **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`. + +# context-mode — MANDATORY routing rules + +You have context-mode MCP tools available. These rules are NOT optional — they protect your context window from flooding. A single unrouted command can dump 56 KB into context and waste the entire session. + +## BLOCKED commands — do NOT attempt these + +### curl / wget — BLOCKED +Any Bash command containing `curl` or `wget` is intercepted and replaced with an error message. Do NOT retry. +Instead use: +- `ctx_fetch_and_index(url, source)` to fetch and index web pages +- `ctx_execute(language: "javascript", code: "const r = await fetch(...)")` to run HTTP calls in sandbox + +### Inline HTTP — BLOCKED +Any Bash command containing `fetch('http`, `requests.get(`, `requests.post(`, `http.get(`, or `http.request(` is intercepted and replaced with an error message. Do NOT retry with Bash. +Instead use: +- `ctx_execute(language, code)` to run HTTP calls in sandbox — only stdout enters context + +### WebFetch — BLOCKED +WebFetch calls are denied entirely. The URL is extracted and you are told to use `ctx_fetch_and_index` instead. +Instead use: +- `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` to query the indexed content + +## REDIRECTED tools — use sandbox equivalents + +### Bash (>20 lines output) +Bash is ONLY for: `git`, `mkdir`, `rm`, `mv`, `cd`, `ls`, `npm install`, `pip install`, and other short-output commands. +For everything else, use: +- `ctx_batch_execute(commands, queries)` — run multiple commands + search in ONE call +- `ctx_execute(language: "shell", code: "...")` — run in sandbox, only stdout enters context + +### Read (for analysis) +If you are reading a file to **Edit** it → Read is correct (Edit needs content in context). +If you are reading to **analyze, explore, or summarize** → use `ctx_execute_file(path, language, code)` instead. Only your printed summary enters context. The raw file content stays in the sandbox. + +### Grep (large results) +Grep results can flood context. Use `ctx_execute(language: "shell", code: "grep ...")` to run searches in sandbox. Only your printed summary enters context. + +## Tool selection hierarchy + +1. **GATHER**: `ctx_batch_execute(commands, queries)` — Primary tool. Runs all commands, auto-indexes output, returns search results. ONE call replaces 30+ individual calls. +2. **FOLLOW-UP**: `ctx_search(queries: ["q1", "q2", ...])` — Query indexed content. Pass ALL questions as array in ONE call. +3. **PROCESSING**: `ctx_execute(language, code)` | `ctx_execute_file(path, language, code)` — Sandbox execution. Only stdout enters context. +4. **WEB**: `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` — Fetch, chunk, index, query. Raw HTML never enters context. +5. **INDEX**: `ctx_index(content, source)` — Store content in FTS5 knowledge base for later search. + +## Subagent routing + +When spawning subagents (Agent/Task tool), the routing block is automatically injected into their prompt. Bash-type subagents are upgraded to general-purpose so they have access to MCP tools. You do NOT need to manually instruct subagents about context-mode. + +## Output constraints + +- Keep responses under 500 words. +- Write artifacts (code, configs, PRDs) to FILES — never return them as inline text. Return only: file path + 1-line description. +- When indexing content, use descriptive source labels so others can `ctx_search(source: "label")` later. + +## ctx commands + +| Command | Action | +|---------|--------| +| `ctx stats` | Call the `ctx_stats` MCP tool and display the full output verbatim | +| `ctx doctor` | Call the `ctx_doctor` MCP tool, run the returned shell command, display as checklist | +| `ctx upgrade` | Call the `ctx_upgrade` MCP tool, run the returned shell command, display as checklist |