From e2e9111860a9396afa694858a5dbc0004ecec744 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 14:45:51 +0200 Subject: [PATCH] Inizio update agents e modifiche x pagina ART con async vari e num records --- AGENTS.md | 110 ++++++------------------------- AGENTS.pdf | Bin 0 -> 33556 bytes MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Articoli.razor | 6 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- Refactor_Plan.md | 49 ++++++++++++++ refactor_spec.md | 63 ------------------ 9 files changed, 76 insertions(+), 160 deletions(-) create mode 100644 AGENTS.pdf create mode 100644 Refactor_Plan.md delete mode 100644 refactor_spec.md diff --git a/AGENTS.md b/AGENTS.md index 9c089229..16215e2e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,94 +1,22 @@ -# CI to Local Workflow Guide +# MAPO-CORE Agent Instructions -This document describes how the GitLab CI pipeline in this repository translates to local commands that can be run on your machine. It also contains helper scripts and environment variables used by the CI. +## Core Context +- **Primary Goal**: Optimization and refactoring of the `MP-SPEC.sln` solution, focusing on migrating legacy Redis/DB caching to `FusionCache` (Memory + Redis + DB) in `MP.SPEC\Data\MpDataService.cs`. +- **Language**: C# (primary), PowerShell (scripts). +- **Documentation/Comments**: MUST be in **Italiano**. +- **Code Style**: Maintain existing region organization (`#region Public Methods`, etc.). -## Environment Variables -All variables listed below are interpolated in the CI templates. When running locally you can set them in a PowerShell profile or via `dotnet` arguments. +## Development Workflow +- **Build & Verification**: + - Use a PowerShell script to build the solution to ensure continuous compilability. + - Always verify that changes do not leave partial traces of old classes that break compilation. +- **Refactoring Strategy (`MpDataService.cs`)**: + - Use `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tags)` as the standard for all data access. + - Target methods currently using manual `redisDb.StringGetAsync` / `StringSetAsync` patterns. +- **Testing**: + - Check the codebase for existing testing patterns before proposing new ones. -| Variable | Description | Typical value | -|----------|--------------|---------------| -| `SOL_NAME` | Solution name to restore | **MP-STATS.sln** | -| `PROJ_PATH` | Directory containing the main project | **MP.Stats** | -| `APP_NAME` | Main project file name (without `.csproj`) | **MP.Stats** | -| `NUGET_PATH` | NuGet credential file | **`C:\\Users\\samuele.steamw\AppData\Roaming\NuGet\Credentials.config`** | -| `NEXUS_PATH` | Nexus host URL | **https://nexus.steamware.net** | -| `DEST` | Artifacts output folder | **bin\publish** | -| `VERS_MAIN`, `VERS_MAIN_APP`, `VERSSUB` | Version strings used in packaging | **1.0.0** / -| `NEXUS_PASSWD` | Nexus password (secure via CI secret) | *Secret* | - -## Build Pipeline (`buildjob`) – Local Equivalent - -The CI first restores NuGet packages and then builds the solution for the selected `APP_NAME`. - -```powershell -# 1. Restore -#$env:SOL_NAME.sln is resolved by the .nuget-fix script -# In PowerShell: dotnet restore "MP-STATS.sln" - -# 2. Build -# $env:APP_NAME/$env:APP_NAME.csproj points to the project file -# In PowerShell: dotnet build "MP.Stats/MP.Stats.csproj" -``` - -### Helper: `.nuget-fix` -The `.nuget-fix` PowerShell script removes any stale NuGet sources that conflict with the Nexus proxy and re‑adds the latest proxy source with credentials. Ensure this script runs *before* `dotnet restore`. - -## Deploy Pipeline (`deployjob`) – Local Equivalent - -Deployment in CI rebuilds the project, publishes it, hashes the output, and uploads it to Nexus. The same steps can be executed locally. - -```powershell -# 1. Rebuild (same as Build) -# dotnet build "MP.Stats/MP.Stats.csproj" - -# 2. Publish to a local folder -# The `dotnet publish` command mimics the CI publish step. The `-c Release` ensures a Release build. -# In PowerShell: -# dotnet publish "MP.Stats/MP.Stats.csproj" -c Release -o publish - -# 3. Create hashes (MD5 & SHA1) -# The .hashBuild template generates .md5 and .sha1 files alongside the ZIP. A simple replacement can be -# 1. Zip the folder: `Compress-Archive -Path publish -DestinationPath $(APP_NAME).zip` -# 2. Generate hashes: -# (Get-FileHash -Algorithm MD5 "$(APP_NAME).zip").Hash | Out-File "$(APP_NAME).md5" -# (Get-FileHash -Algorithm SHA1 "$(APP_NAME).zip").Hash | Out-File "$(APP_NAME).sha1" - -# 4. Upload to Nexus (requires `curl`) -# Example curl command (CI uses `nexus-curl` script): -# $curl -u $(NUGET_USER):$(NEXUS_PASSWD) "$(NEXUS_PATH)/repository/$(APP_NAME)" -T "$(APP_NAME).zip" -``` - -## Installer & Release -The **installer** template copies the published artifacts to a staging folder and optionally creates installers. The **release** template bumps version numbers, updates the `nuspec`, generates a changelog, and pushes the packages to Nexus. - -Generally these steps are CI‑only, but you can repeat the same `dotnet pack` / `nuget push` commands locally if needed. - -## Common Issues & Fixes - -* _NuGet authentication errors_: Run `.nuget-fix` to reset the sources. -* _Missing SDK_: Verify `dotnet --list-sdks` includes at least one SDK. -* _Hashes not matching_: Ensure the ZIP file is identical to the one CI produced (same path, no hidden files). - -## Quick Start -```powershell -# Restore -.\.nuget-fix - -# Build - -dotnet restore "MP-STATS.sln" -dotnet build "MP.Stats/MP.Stats.csproj" - -# Publish & run - -dotnet publish "MP.Stats/MP.Stats.csproj" -c Release -o publish -dotnet run --project "MP.Stats/MP.Stats.csproj" - -# For hot‑reload during development - -dotnet watch run --project "MP.Stats/MP.Stats.csproj" -``` - ---- - -Feel free to adjust paths or environment variable names if your local setup differs. +## Architecture Notes +- **Multi-Layer Caching**: The system is transitioning from a dual-layer (Redis + DB) to a triple-layer approach via `IFusionCache`. +- **Service Responsibility**: `MpDataService` is the central hub for data access, interacting with `MpSpecController` (EFCore) and `MpMongoController` (MongoDB). +- **Key Management**: Cache keys are heavily managed via `Utils.redis...` constants. diff --git a/AGENTS.pdf b/AGENTS.pdf new file mode 100644 index 0000000000000000000000000000000000000000..be4b911e6068b76cf9e9fb20d459af71d0732ac2 GIT binary patch literal 33556 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

{x0_nWL_z*5DJoBZ?e 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

ZW2Rt1do?JM*FIsOhG{&Rp}!%gVox`|h*( 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 enable MP.SPEC - 8.16.2605.2712 + 8.16.2605.2714 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Articoli.razor b/MP.SPEC/Pages/Articoli.razor index c6c7fb6c..e20b654c 100644 --- a/MP.SPEC/Pages/Articoli.razor +++ b/MP.SPEC/Pages/Articoli.razor @@ -19,10 +19,10 @@

- + - @if (ListAziende != null) { foreach (var item in ListAziende) @@ -31,6 +31,8 @@ } } + +
diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 5cc963d2..f9337c57 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

Versione: 8.16.2605.2712

+

Versione: 8.16.2605.2714


Note di rilascio:
  • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 5daceb39..55b93cf6 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2712 +8.16.2605.2714 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index c715daef..a591e4cf 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2712 + 8.16.2605.2714 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md new file mode 100644 index 00000000..93467761 --- /dev/null +++ b/Refactor_Plan.md @@ -0,0 +1,49 @@ +# Piano di Refactoring: Migrazione a FusionCache in `MpDataService.cs` + +## Obiettivo +Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCache` per implementare un approccio multi-layer (Memory + Redis + DB), standardizzando l'accesso ai dati. + +## Analisi dello stato attuale +- **Classe target**: `MP.SPEC\Data\MpDataService.cs` +- **Pattern attuale**: Molti metodi utilizzano manualmente `redisDb.StringGetAsync` e `redisDb.StringSetAsync` con serializzazione JSON manuale. +- **Metodo Standard**: `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tags)`. + +## Strategia di Migrazione + +### 1. Identificazione Metodi Target +Andrò a mappare tutti i metodi in `MpDataService.cs` che: +- Utilizzano `redisDb` direttamente per la lettura/scrittura. +- Gestiscono manualmente la serializzazione/deserializzazione con `JsonConvert`. +- Gestiscono manualmente il fallback dal Redis al DB. + +### 2. Classificazione Metodi +I metodi verranno suddivisi in: +- **Lettura (Cache-aside)**: Metodi che recuperano dati. Questi saranno i candidati principali per `GetOrFetchAsync`. +- **Scrittura/Invalidazione**: Metodi che aggiornano il DB e devono invalidare la cache (es. `AnagGruppiUpsert`, `ArticoliUpdateRecord`). Questi dovranno utilizzare `_cache.RemoveByTagAsync` o `_cache.RemoveAsync`. + +### 3. Piano di Implementazione (Step-by-Step) + +#### Fase 1: Analisi e Mapping +- [ ] Identificare ogni occorrenza di `redisDb.StringGet` / `StringGetAsync` in `MpDataService.cs`. +- [ ] Verificare se la chiave di cache utilizzata è gestita tramite `Utils.redis...`. + +#### Fase 2: Refactoring Metodi di Lettura +Per ogni metodo di lettura individuato: +- [ ] Sostituire la logica `if (rawData.HasValue) { ... } else { ... }` con la chiamata a `GetOrFetchAsync`. +- [ ] Assicurarsi che il `fetchFunc` esegua la chiamata al `dbController`. +- [ ] Configurare correttamente il `TimeSpan expiration` (usando le costanti esistenti come `redisLongTimeCache` o `redisShortTimeCache`). +- [ ] Aggiungere i tag appropriati per permettere l'invalidazione granulare. + +#### Fase 3: Refactoring Metodi di Scrittura e Invalidazione +- [ ] Sostituire le chiamate manuali a `ExecFlushRedisPattern` o `redisDb.KeyDelete` con i metodi di invalidazione di `IFusionCache`. +- [ ] Utilizzare i tag per invalidare gruppi di dati correlati invece di pattern Redis generici quando possibile. + +#### Fase 4: Verifica +- [ ] Verificare la compilazione della soluzione tramite script PowerShell. +- [ ] Controllare che i log (NLog) continuino a riflettere correttamente le operazioni. + +## Rischi e Mitigazioni +- **Rischio**: Discrepanza nelle chiavi di cache tra vecchio e nuovo sistema. + - *Mitigazione*: Utilizzare rigorosamente le costanti in `Utils.redis...` per garantire che le chiavi siano identiche o gestite dal nuovo sistema. +- **Rischio**: Errori di serializzazione. + - *Mitigazione*: `FusionCache` gestisce la serializzazione, ma è necessario assicurarsi che i tipi di ritorno siano compatibili con le aspettative dei chiamanti. diff --git a/refactor_spec.md b/refactor_spec.md deleted file mode 100644 index 2b8a587c..00000000 --- a/refactor_spec.md +++ /dev/null @@ -1,63 +0,0 @@ -# Refactoring Plan: MpDataService Cache Layer Upgrade - -## Objective -Migrate all data access methods in `MpDataService.cs` to use the unified multi-level cache stack (IMemoryCache via `IFusionCache` + Redis + DB) using the `GetOrFetchAsync` pattern. - -## Current State -- Some methods use a manual "Redis + DB" approach (checking `redisDb.StringGet`, deserializing, and then `StringSet` on miss). -- Some methods use the new `GetOrFetchAsync` pattern (Memory + Redis + DB). -- `GetOrFetchAsync` leverages `IFusionCache`, which handles the multi-level complexity and provides better resiliency (fail-safe). - -## Target Pattern: `GetOrFetchAsync` -All read methods should be refactored to: -1. Use `GetOrFetchAsync` to abstract cache management. -2. Define a `cacheKey` (typically matching the existing Redis key). -3. Provide an `expiration` (TimeSpan). -4. Provide a `fetchFunc` that calls the `dbController` method. - -## Proposed Work Items - -### 1. Analysis & Categorization -Identify all methods in `MpDataService.cs` that currently implement manual Redis caching. - -**Candidates for Refactoring (Redis + DB -> Multi-level):** -- `AnagEventiGeneral` (Lines 166-195) -- `AnagEventiGetByMacch` (Lines 201-230) -- `AnagKeyValGetAll` (Lines 273-302) -- `AnagTipoArtLV` (Lines 347-375) -- `ArticleWithDossier` (Lines 381-410) -- `ConfigGetAll` (Lines 907-936) -- `ConfigGetAllAsync` (Lines 943-970) -- `DbDedupStats` (Lines 1046-1067) -- `ElencoGruppiFase` (Lines 1216-1249) -- `ElencoRepartiDTO` (Lines 1267-1303) -- `FluxLogGetLastFilt` (Lines 1569-1605) -- `FluxLogPareto` (Lines 1609-1640) -- `MacchineRecipeArchive` (Lines 2100-2128) -- `MacchineRecipeConf` (Lines 2131-2163) -- `MacchineWithFlux` (Lines 2171-2200) -- `OdlByBatch` (Lines 2308-2336) -- `OdlListAll` (Lines 2490-2499) - *Currently no cache, needs addition?* -- `OdlListGetFilt` (Lines 2513-2542) -- `OperatoriGetFilt` (Lines 2549-2577) -- `ParametriGetFilt` (Lines 2585-2614) -- `POdlGetByKey` (Lines 2658-2697) -- `POdlGetByOdl` (Lines 2705-2744) -- `POdlListByKitParent` (Lines 2770-2800) -- `POdlListGetFilt` (Lines 2812-2841) -- `TksScore` (Lines 3343-3372) -- `VocabolarioGetAll` (Lines 3445-3477) -- `WipKitFilt` (Lines 3543-3570) - -### 2. Implementation Steps -For each candidate method: -1. **Convert to Async**: If the method is synchronous (e.g., `AnagEventiGeneral`), convert it to `Task` to match the `GetOrFetchAsync` signature. -2. **Map Keys**: Ensure the `cacheKey` passed to `GetOrFetchAsync` is identical to the old Redis key to prevent cache fragmentation. -3. **Set Expiration**: Use appropriate `TimeSpan` (e.g., `redisLongTimeCache` or `redisShortTimeCache` converted to `TimeSpan`). -4. **Cleanup**: Remove manual `JsonConvert` logic and `redisDb.StringGet/Set` calls. -5. **Verify Tracing**: Ensure `ActivitySource` and `LogTrace` are preserved or integrated within the `GetOrFetchAsync` wrapper. - -### 3. Validation -- Ensure all refactored methods are still called correctly by consumers. -- Verify that `GetOrFetchAsync` correctly hits Memory first, then Redis, then DB. -- Confirm that `LogTrace` still reports the correct source (MEMORY, REDIS, or DB).