Fase 5 now shows the distinta's .asm files already copied to raw/ as draggable icons, so they can be dropped straight onto Creo or Explorer without re-hitting the DB/share. The CSV from fase 2 is now always written to the repo root (found by walking up to CLAUDE.md) instead of next to the input file, wherever that happens to be. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
7.4 KiB
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/.
dotnet build -c Release
dotnet run -c Release
Pubblicazione come eseguibile standalone (single-file, self-contained, Windows x64):
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 inForm1.BuildUi()(nessun designer visuale usato).Form1.Designer.cscontiene solo lo scheletro minimo (InitializeComponent/Dispose) generato dal template. Le fasi, in ordine:- Database — carica/aggiorna l'indice, mostra data ultimo aggiornamento; qui vive anche "Pulisci raw e step" (manutenzione, non fa parte del flusso a valle).
- Importa Distinta Base —
DistintaBaseImporter.ConvertiInCsvgenera il CSV dei componenti; se il nome del file segue la convenzione del gestionale (DBP_<codice>_<timestamp>), 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. Il CSV viene sempre scritto nella root del repo (Form1.TrovaRadiceRepo, che risale daAppContext.BaseDirectoryfino alla cartella che contieneCLAUDE.md), indipendentemente da dove si trova il file.xls/.xmldi input scelto dall'utente. - Crea cartella raw — cerca nell'indice il percorso CAD di ogni componente del CSV
(
TrovaPercorsiCad) e lo copia inraw/(CopiaFileTrovati). - Trova componenti referenziati — legge euristicamente i metadati binari dei
.asmgià inraw/(AssemblyComponentScanner) per risolvere ricorsivamente i sotto-assiemi/parti che contengono (RisolviAlberoComponenti), copiandoli anch'essi inraw/. - Verifica completezza e STEP — appena si entra nella fase,
AggiornaAnteprimaAsmmostra in unaListViewa icone i file.asmdella distinta importata (esclusi i sotto-assiemi di fase 4) già presenti inraw/— letti dal filesystem locale, non dall'indice/share — trascinabili (drag&drop,ItemDrag→DoDragDropconDataFormats.FileDrop) direttamente su Creo o Esplora risorse. "Verifica completezza assiemi" (ricorsivo sui percorsi originali in indice, non suraw/) e "Crea cartella step_finali": solo per i codici della distinta importata dal CSV (non i sotto-componenti di fase 4, che servono solo a completareraw/) cerca instep/il file<codice>.stpe lo copia instep_finali/se lo trova. Per i mancanti distingue, incrociando l'indice CAD,EsitoStep.StepMancante(il CAD c'è, manca solo l'esportazione STEP) daComponenteNonTrovato(il componente non è nemmeno nell'indice) — vediReportStepForm.
- 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 conDirectory.GetDirectories, non un elenco fisso) con un walk manuale a stack (Walk, più veloce diEnumerateFiles(..., AllDirectories)su share di rete con centinaia di migliaia di file), estrae da ogni nome file il pattern Pro-E<codice>.<tipo>.<versione>via regex, e fa un upsert incrementale riga per riga (confronto perpercorso_completo+ dimensione + data modifica). Riporta il progresso tramiteIProgress<ScanProgress>, marshalato automaticamente sul thread UI. Contiene anche lo schema SQL del DB (tabellafiles+ vistafiles_ultima_versione, che seleziona solo l'ultima versione per(cartella_radice, codice, tipo_file)usandoROW_NUMBER() OVER (...)— non un self-join conGROUP 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, solo codici
numerici Pro-E); BomViaDb.cs fa lo stesso ma con la tokenizzazione generica validata contro
il DB, usata per intercettare anche i nomi alfabetici delle parti commerciali (vedi
docs/formato-asm.md); 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; Query.cs
esegue una query SQL ad-hoc contro cad_index.db da riga di comando.
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.