# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Cos'è questo progetto `CadSearchGui` è un'app Windows Forms (.NET 10, WinForms) che indicizza e permette di cercare i file CAD Pro-ENGINEER/Creo contenuti in tutte le cartelle di primo livello di un disco/share di rete (radice di default `X:\`), salvando i metadati in un DB SQLite locale (`cad_index.db`). ## Comandi Tutti da eseguire dentro `CadSearchGui/`. ```powershell dotnet build -c Release dotnet run -c Release ``` Pubblicazione come eseguibile standalone (single-file, self-contained, Windows x64): ```powershell dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o publish ``` `CadSearchGui.Tests/` (xUnit) contiene unit e integration test — vedi `dotnet test` da dentro quella cartella. Riferimento al progetto principale via `ProjectReference` + `InternalsVisibleTo` (in `CadSearchGui.csproj`), così i test possono chiamare direttamente `Indexer.ParseFilename` e `AssemblyComponentScanner.EstraiCodiciReferenziati` senza esporli come API pubblica. ## Architettura Il programma è tutto in `CadSearchGui/` (nessun altro progetto nella solution — in passato esisteva anche una CLI separata e uno script Python di indicizzazione, entrambi rimossi: ora l'unico programma è questo, con GUI e indicizzazione integrate). - **Program.cs** — entry point WinForms standard, avvia `Form1`. - **Form1.cs** / **Form1.Designer.cs** — finestra principale, costruita come wizard: una sola fase alla volta occupa tutta la finestra (`_panelFasi[]`/`NomiFasi`), si avanza con "Avanti" solo quando la fase corrente è pronta (`AvantiConsentito`). La UI è costruita interamente in codice in `Form1.BuildUi()` (nessun designer visuale usato). `Form1.Designer.cs` contiene solo lo scheletro minimo (`InitializeComponent`/`Dispose`) generato dal template. Le fasi, in ordine: 1. **Database** — carica/aggiorna l'indice, mostra data ultimo aggiornamento; qui vive anche "Pulisci raw e step" (manutenzione, non fa parte del flusso a valle). 2. **Importa Distinta Base** — `DistintaBaseImporter.ConvertiInCsv` genera il CSV dei componenti; se il nome del file segue la convenzione del gestionale (`DBP__`), l'assieme generale viene aggiunto come riga in più nel CSV stesso (il foglio elenca solo i componenti sotto l'assieme, non l'assieme in sé). Da qui in avanti l'assieme generale è un componente come tutti gli altri, nessun caso speciale nel resto del codice. 3. **Crea cartella raw** — cerca nell'indice il percorso CAD di ogni componente del CSV (`TrovaPercorsiCad`) e lo copia in `raw/` (`CopiaFileTrovati`). 4. **Trova componenti referenziati** — legge euristicamente i metadati binari dei `.asm` già in `raw/` (`AssemblyComponentScanner`) per risolvere ricorsivamente i sotto-assiemi/parti che contengono (`RisolviAlberoComponenti`), copiandoli anch'essi in `raw/`. 5. **Verifica completezza e STEP** — "Verifica completezza assiemi" (ricorsivo sui percorsi originali in indice, non su `raw/`) e "Crea cartella step_finali": unisce i codici della distinta con quelli risolti in fase 4 (`_componentiRisolti`), cerca in `step/` il file `.stp` di ciascuno, lo copia in `step_finali/` se lo trova e mostra l'esito (creato/mancante) in `ReportStepForm`. - **Indexer.cs** — logica di scansione del disco e scrittura/aggiornamento del DB SQLite (`Indexer.ScanAsync`). Cammina tutte le cartelle di primo livello trovate sotto la radice (scoperte dinamicamente con `Directory.GetDirectories`, non un elenco fisso) con un walk manuale a stack (`Walk`, più veloce di `EnumerateFiles(..., AllDirectories)` su share di rete con centinaia di migliaia di file), estrae da ogni nome file il pattern Pro-E `..` via regex, e fa un upsert incrementale riga per riga (confronto per `percorso_completo` + dimensione + data modifica). Riporta il progresso tramite `IProgress`, marshalato automaticamente sul thread UI. Contiene anche lo schema SQL del DB (tabella `files` + vista `files_ultima_versione`, che seleziona solo l'ultima versione per `(cartella_radice, codice, tipo_file)` usando `ROW_NUMBER() OVER (...)` — non un self-join con `GROUP BY`, che su ~200k righe degenera in tempi quasi quadratici). - **ProgressForm.cs** — dialog modale mostrato durante l'aggiornamento indice: barra di progresso, conteggi nuovi/aggiornati/invariati/rimossi, tempo trascorso e stima del tempo rimanente (calcolata dal ritmo file/secondo rispetto al totale atteso, preso dal conteggio della scansione precedente salvato nel DB). ### Schema del DB (`cad_index.db`) Tabella `files`: un record per ogni file trovato, con `percorso_completo` (chiave univoca), `cartella_radice`, `famiglia` (primo livello di sottocartella), `codice`/`tipo_file`/`versione` estratti dal nome file, dimensione, data modifica e timestamp dell'ultima scansione (`scansionato_il`, usato per rilevare ed eliminare i file non più presenti su disco a fine scansione). Vista `files_ultima_versione`: stessa struttura, filtrata alla sola versione più recente per codice+tipo. ### Percorso del DB All'avvio la app cerca `cad_index.db` accanto all'eseguibile o nella working directory corrente; se non lo trova, l'utente può selezionarlo con "Apri DB...". Il bottone "Aggiorna indice" rilancia `Indexer.ScanAsync` sullo stesso path (radice disco di default `X:\`, hardcoded in `Form1.RadiceDiscoDefault`). ## Script standalone (`scripts/`) `scripts/` contiene C# file-based apps (.NET 10, `dotnet run scripts/Nome.cs -- arg1 arg2`), senza csproj — dipendenze NuGet extra si aggiungono con `#:package Nome@versione` in cima al file. `ExtractCreoStrings.cs` estrae la BOM di un `.asm` risolvendo ricorsivamente i sotto-assiemi contro `cad_index.db` (stessa logica di `Form1.AssiemeCompleto`); `Analyze.cs` dumpa il contesto testo/hex attorno a un pattern in un file binario, per investigare a mano nuovi falsi positivi prima di toccare la regex. Il formato binario `.asm`, l'euristica di estrazione codici e i falsi positivi noti (ID vista `ModelView#`, self-reference, riferimenti fantasma a codici superati/rinominati — sintatticamente identici a un componente vero, non filtrabili in modo affidabile) sono documentati in `docs/formato-asm.md`.