Not needed anymore: the app no longer copies matched .stp files from step/ into a separate step_finali/ folder, or reports which distinta codes are still missing a STEP. Removed the "Crea cartella step_finali" button, GeneraReportStep, and ReportStepForm/EsitoStep. Phase 5 keeps "Verifica completezza assiemi" and the drag&drop .asm list (still how files get sent to Creo Distributed Batch); renamed from "Verifica completezza e STEP" to "Verifica completezza" since it's no longer about STEP output. PulisciRawEStep now only clears raw/ and step/. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
11 KiB
Architettura di PrepStep (Cevolani StepPrep)
Panoramica di tutti i file sorgente e di come collaborano. PrepStep è il nome
tecnico del progetto (cartella, namespace, csproj, eseguibile PrepStep.exe);
Cevolani StepPrep è il nome mostrato all'utente finale (titolo finestra, icona,
versione — vedi <Version>/<Product> in PrepStep.csproj). Per il "come si usa" vedi il README.md in root; per il
formato binario .asm vedi docs/formato-asm.md; per la parallelizzazione della
copia in raw/ vedi docs/copia-raw-parallela.md.
Vista d'insieme
Un solo eseguibile WinForms (nessuna CLI, nessun processo esterno): indicizza i file CAD di
una share di rete in un DB SQLite locale, poi guida l'utente in un wizard a 5 fasi che, a
partire da una distinta base esportata dal gestionale, raccoglie in locale (raw/) tutti i
file CAD dei componenti e dei loro sotto-assiemi e verifica che l'indice li copra, come
pre-process prima dell'esportazione STEP con Creo Distributed Batch (manuale, fuori
dall'app: i file esportati finiscono in step/, dentro la cartella di lavoro).
Distinta (.xls/.xml) → CSV (componente;descrizione) → raw/ (CAD copiati dall'indice)
│
scansione .asm ─────┘ (sotto-assiemi/parti mancanti)
│
drag&drop .asm su Creo → Distributed Batch → step/ (esportazione manuale)
Entry point
- Program.cs —
Main()standard WinForms:Application.Run(new Form1()). Nessuna logica.
Finestra principale (wizard)
-
Form1.cs — tutta la UI è costruita in codice (
BuildUi/BuildFase*), non con il designer visuale. È un wizard:_panelFasi[]contiene unPanelper fase, uno solo visibile alla volta (VaiAllaFase); si avanza con "Avanti" solo seAvantiConsentitoritorna vero per la fase corrente.Form1.Designer.cscontiene solo lo scheletro minimo generato dal template (InitializeComponent/Dispose), non è usato per costruire i controlli.Le 5 fasi e i metodi principali dietro ciascuna:
# Fase Bottone → metodo Cosa fa 1 Database "Aggiorna indice" → Indexer.ScanAsync; "Cambia cartella..." →ScegliCartellaLavoroCrea/aggiorna cad_index.dbscansionando la share; sceglie/mostra la cartella di lavoro2 Importa Distinta Base selezione file → ImportaDistinta→DistintaBaseImporter.ConvertiInCsvXls/Xml gestionale → CSV componente;descrizione, scritto nella cartella di lavoro 3 Crea cartella raw "Crea cartella raw" → CreaCartellaRawTrovaPercorsiCad+CopiaFileTrovati(parallela) →raw/dentro la cartella di lavoro4 Trova componenti referenziati "Trova componenti referenziati" → TrovaPrtReferenziati→RisolviAlberoComponentiLegge i .asminraw/conAssemblyComponentScanner, risolve ricorsivamente sotto-assiemi/parti nell'indice, li copia anch'essi inraw/5 Verifica completezza "Verifica completezza assiemi" → VerificaCompletezzaAssiemiCompletezza ricorsiva sui percorsi in indice. All'ingresso nella fase, AggiornaAnteprimaAsmmostra le icone trascinabili dei.asmdella distinta già inraw/, da trascinare su Creo per l'esportazione STEP (Distributed Batch)Stato condiviso tra le fasi (campi privati di
Form1):_dbPath,_cartellaLavoro,_percorsoInputCorrente,_righeCorrenti(righe del CSV),_ultimaVerifica(cache percorsi CAD),_ultimaCartellaRaw.Altre responsabilità in Form1.cs:
TrovaPercorsiCad/CaricaCodiciNoti— query sul DB (files_ultima_versione), la seconda carica tutti i codici prt/asm noti in un colpo solo (usata sia per risolvere i componenti sia daAssemblyComponentScannerper validare i token generici).CopiaFileTrovati— copia (in parallelo, grado 6) i file trovati inraw/, saltando silenziosamente quelli irraggiungibili (share offline/permessi).PulisciRawEStep— svuotaraw/estep/nella cartella di lavoro (manutenzione, richiede conferma).InizializzaDatabase/ScegliDatabase— localizzazione del DB (ultimo usato, salvato in%AppData%/PrepStep/ultimo_db.txt, ocad_index.dbaccanto all'eseguibile).InizializzaCartellaLavoro/ScegliCartellaLavoro— stesso pattern per la cartella di lavoro (ultima_cartella_lavoro.txt), fallbackAppContext.BaseDirectoryse non c'è ancora nulla di salvato: nessuna dipendenza da un marker di repo, funziona identica sull'exe pubblicato standalone spostato su un'altra macchina.
Indicizzazione
- Indexer.cs —
ScanAsynccammina tutte le cartelle di primo livello sotto la radice (scoperte dinamicamente, non un elenco fisso) con un walk manuale a stack (Walk, più veloce diEnumerateFiles(..., AllDirectories)su share con centinaia di migliaia di file), esclude le cartelletemp_*, estrae da ogni nome file il pattern Pro-E<codice>.<tipo>.<versione>(ParseFilename, regex), e fa un upsert incrementale riga per riga confrontandopercorso_completo+ dimensione + data modifica. Progresso riportato viaIProgress<ScanProgress>(marshalato sul thread UI). Contiene anche lo schema SQL: tabellafilese vistafiles_ultima_versione(ultima versione percodice+tipo_fileviaROW_NUMBER() OVER (...), non self-join+GROUP BYper evitare tempi quasi quadratici su ~200k righe).
Scansione binaria dei .asm
- AssemblyComponentScanner.cs — estrae euristicamente i codici componente referenziati
dentro un
.asm(formato per lo più binario, codici come stringhe ASCII leggibili al suo interno). Due strategie: codici numerici Pro-E riconosciuti da soli via regex (come nei nomi file), e nomi alfabetici di parti commerciali tokenizzati genericamente e validati contro l'elenco di codici noti del DB (altrimenti il rumore binario sarebbe ingestibile). Dettagli sul formato, l'euristica e i falsi positivi noti indocs/formato-asm.md.
Import distinta base
- DistintaBaseImporter.cs — converte l'export del gestionale (SpreadsheetML XML con
estensione
.xls/.xml, oppure.xls/.xlsxbinario vero, distinti dai primi byte del file) nelle sole colonne Componente/Descrizione, foglio"Distinta Base". Se il nome del file segue la convenzioneDBP_<codice>_<timestamp>, aggiunge l'assieme generale come riga in più (il foglio elenca solo i componenti sotto l'assieme). Scrive il CSV nella cartella passata daForm1(la cartella di lavoro scelta in fase 1), non necessariamente accanto al file di input.
Finestre di dialogo (modali, mostrate a fine step)
- ProgressForm.cs — durante l'aggiornamento indice: barra di progresso, conteggi nuovi/aggiornati/invariati/rimossi, tempo trascorso e stima del tempo rimanente (dal ritmo file/secondo rispetto al totale atteso, preso dal conteggio della scansione precedente salvato nel DB).
- ProgressoComponentiForm.cs — dialog minimale (etichetta + barra) durante
RisolviAlberoComponentiin fase 4.
Stile UI condiviso
- UiStile.cs —
Primario/Secondario: stile piatto per i bottoni (bordo sottile per i secondari, blu pieno per l'azione principale di ogni fase), entrambi conAutoSize+Padding+MinimumSizeinvece di unaSizefissa in pixel indovinata a mano (altrimenti il testo va a capo e si taglia in verticale se non ci sta nella larghezza scelta).Arrotondaapplica angoli arrotondati viaRegioncalcolata suSizeChanged(non una volta sola: conAutoSizela dimensione finale del bottone si conosce solo a layout avvenuto), usata sui bottoni "Avanti"/"Indietro" del wizard. - app.ico — icona dell'app, referenziata da
<ApplicationIcon>nel csproj (icona dell'exe in Esplora risorse/taskbar) e riletta esplicitamente inForm1.BuildUi()conIcon.ExtractAssociatedIcon(Application.ExecutablePath)per la titlebar, senza copiare il file.iconell'output. Sfondo trasparente (nessuna card bianca), 7 risoluzioni da 16 a 256px. - PrtMancantiForm.cs — esito della risoluzione ricorsiva dell'albero componenti: PRT e
sotto-assiemi trovati e copiati in
raw/, più i codici referenziati che non corrispondono a nessun file indicizzato (possono essere disegni, componenti davvero mancanti, o falsi positivi della scansione.asm). - ReportCompletezzaForm.cs — per ogni assieme della distinta, se tutti i suoi componenti (ricorsivamente fino ai PRT) sono nell'indice (✓/✗/? per "non trovato").
Persistenza
- DB (
cad_index.db, SQLite) — vedi tabellafiles/vistafiles_ultima_versionesopra. Percorso: cercato accanto all'eseguibile o nella working directory all'avvio; altrimenti selezionabile con "Apri DB...". Radice disco di scansione di defaultX:\(Form1.RadiceDiscoDefault, hardcoded). - Cartella di lavoro — salvata in
%AppData%/PrepStep/ultima_cartella_lavoro.txt(stesso meccanismo del DB sopra), proposta di defaultAppContext.BaseDirectoryla prima volta; selezionabile/cambiabile con "Cambia cartella..." in fase 1. Tutti i file generati a valle ci finiscono dentro: il CSV della distinta,raw/(CAD dei componenti e sotto-componenti);step/non è scritta dall'app ma è dove l'utente esporta gli STEP a mano con Creo Distributed Batch, a partire dai file trascinati daraw/in fase 5.
Script standalone (scripts/)
C# file-based apps (.NET 10, dotnet run scripts/Nome.cs -- arg1 arg2, nessun .csproj,
dipendenze extra con #:package Nome@versione in testa al file):
- ExtractCreoStrings.cs — BOM di un
.asmrisolvendo ricorsivamente i sotto-assiemi controcad_index.db(stessa logica diAssiemeCompletoin Form1, solo codici numerici Pro-E). - BomViaDb.cs — come sopra ma con la tokenizzazione generica validata contro il DB, per intercettare anche i nomi alfabetici delle parti commerciali.
- Analyze.cs — dump del contesto testo/hex attorno a un pattern in un file binario, per
investigare a mano nuovi falsi positivi prima di toccare la regex di
AssemblyComponentScanner. - Query.cs — query SQL ad-hoc contro
cad_index.dbda riga di comando.
⚠️ Nota importante di sicurezza: se
dotnet runviene lanciato dentroPrepStep/(che contiene un.csprojdi tipoWinExe), esegue l'app GUI vera invece dello script standalone e resta bloccato in attesa che una finestra si chiuda. Lanciare gli script da una cartella senza.csproj(es. la root del repo oscripts/stessa).
Test
- PrepStep.Tests/ (xUnit) — riferimento al progetto principale via
ProjectReferenceInternalsVisibleTo(inPrepStep.csproj), così i test chiamano direttamenteIndexer.ParseFilenameeAssemblyComponentScanner.EstraiCodiciReferenziatisenza esporli come API pubblica. File:IndexerParseFilenameTests.cs,AssemblyComponentScannerTests.cs,DistintaBaseImporterTests.cs,CaseInsensitiveLookupIntegrationTests.cs.