Files
prep-step/CLAUDE.md
T
davideandClaude Sonnet 5 13798ad47c Add explicit working folder; rename project from CadSearchGui to PrepStep
Working folder (phase 1): CSV/raw/step/step_finali all used to live split
across two different implicit locations (CSV in the "repo root" found by
walking up for CLAUDE.md, raw/step next to the input distinta file) with
neither shown to the user. That repo-root lookup also silently breaks once
the app runs as a standalone published exe on a machine with no repo/
CLAUDE.md at all. Replaced both with one explicit "cartella di lavoro",
auto-suggested (last used, remembered the same way as the DB path) and
changeable from phase 1, with no dependency on any repo marker file.

Rename: CadSearchGui was the working name from before the app had a
product identity; renamed folders, csproj files, namespace and the
AppData settings folder to PrepStep throughout, matching the exe name
already in use. Product-facing name stays "Cevolani StepPrep".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 11:18:43 +02:00

147 lines
9.1 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Cos'è questo progetto
`PrepStep` è il nome tecnico del progetto (cartella, namespace, csproj, eseguibile
`PrepStep.exe`); il nome mostrato all'utente finale è **Cevolani StepPrep** (`<Product>`/
`<AssemblyTitle>` in `PrepStep/PrepStep.csproj`, usato nel titolo della finestra insieme
alla versione, `<Version>`, attualmente `0.1.0`). È 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`). Il flusso a valle (fasi 2-5, vedi sotto) prepara i file
`raw/` da passare a Creo Distributed Batch per l'esportazione STEP: la app è quindi un
pre-processo per quel passaggio, non lo sostituisce.
## Comandi
Tutti da eseguire dentro `PrepStep/`.
```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
```
`PrepStep.Tests/` (xUnit) contiene unit e integration test — vedi
`dotnet test` da dentro quella cartella. Riferimento al progetto principale
via `ProjectReference` + `InternalsVisibleTo` (in `PrepStep.csproj`), così
i test possono chiamare direttamente `Indexer.ParseFilename` e
`AssemblyComponentScanner.EstraiCodiciReferenziati` senza esporli come API
pubblica.
## Architettura
Il programma è tutto in `PrepStep/` (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 la **cartella di lavoro** (`_cartellaLavoro`, mostrata in `_lblCartellaLavoro`,
cambiabile con "Cambia cartella..." → `ScegliCartellaLavoro`): destinazione di CSV,
`raw/`, `step/`, `step_finali/` per tutte le fasi successive. All'avvio
`InizializzaCartellaLavoro` propone l'ultima usata (ricordata in
`%AppData%/PrepStep/ultima_cartella_lavoro.txt`, stesso pattern di
`ultimo_db.txt` per il DB) se esiste ancora, altrimenti `AppContext.BaseDirectory`
— non dipende da un marker di repo (niente più `CLAUDE.md`/`TrovaRadiceRepo`),
quindi funziona identica anche sull'exe pubblicato standalone (`PrepStep.exe`)
copiato su un'altra macchina. 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 nella cartella di lavoro; 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.
3. **Crea cartella raw** — cerca nell'indice il percorso CAD di ogni componente del CSV
(`TrovaPercorsiCad`) e lo copia in `raw/` dentro la cartella di lavoro
(`CopiaFileTrovati`, parallela — vedi `docs/copia-raw-parallela.md`).
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** — appena si entra nella fase, `AggiornaAnteprimaAsm`
mostra in una `ListView` a icone i file `.asm` della distinta importata (esclusi i
sotto-assiemi di fase 4) già presenti in `raw/` — letti dal filesystem locale, non
dall'indice/share — trascinabili (drag&drop, `ItemDrag` → `DoDragDrop` con
`DataFormats.FileDrop`) direttamente su Creo o Esplora risorse. "Verifica completezza
assiemi" (ricorsivo sui percorsi originali in indice, non su `raw/`) 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 completare `raw/`) cerca in `step/` il
file `<codice>.stp` e lo copia in `step_finali/` se lo trova. Per i mancanti distingue,
incrociando l'indice CAD, `EsitoStep.StepMancante` (il CAD c'è, manca solo
l'esportazione STEP) da `ComponenteNonTrovato` (il componente non è nemmeno
nell'indice) — vedi `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 `<codice>.<tipo>.<versione>` via regex, e fa un upsert incrementale
riga per riga (confronto per `percorso_completo` + dimensione + data modifica).
Riporta il progresso tramite `IProgress<ScanProgress>`, 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).
- **UiStile.cs** — stile bottoni condiviso da `Form1` e dai dialog secondari
(`Primario`/`Secondario`, entrambi `AutoSize` col padding invece di una `Size` fissa
in pixel, per evitare che il testo vada a capo e si tagli quando non ci sta) e
`Arrotonda` per gli angoli dei bottoni "Avanti"/"Indietro" del wizard.
- **app.ico** — icona dell'app (logo Cevolani + pezzo + STEP, sfondo trasparente),
referenziata da `<ApplicationIcon>` in `PrepStep.csproj` e riletta a runtime in
`Form1.BuildUi()` via `Icon.ExtractAssociatedIcon(Application.ExecutablePath)` per
la titlebar (stessa icona dell'exe, nessun file duplicato nell'output).
### 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`.