Files
prep-step/docs/architettura.md
T
davideandClaude Sonnet 5 35009b5cd3 Aggiungi CreoBom.cs: parser esatto del formato .asm via record binari
Porting C# del reverse engineering della struttura a record del .asm Creo
(sezione "members" + parametro "ConfigName" per le family table): legge
esattamente i componenti diretti e genera la stessa BOM esportata da Creo,
senza le euristiche testuali (conteggio occorrenze) di AssemblyComponentScanner.
Resta uno script di analisi indipendente, non integrato nella GUI.

Aggiorna anche formato-asm.md (non e' piu' vero che "non esiste un parser
strutturale") e architettura.md (script mancante nell'elenco).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 15:41:14 +02:00

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 un Panel per fase, uno solo visibile alla volta (VaiAllaFase); si avanza con "Avanti" solo se AvantiConsentito ritorna vero per la fase corrente. Form1.Designer.cs contiene 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..." → ScegliCartellaLavoro Crea/aggiorna cad_index.db scansionando la share; sceglie/mostra la cartella di lavoro
    2 Importa Distinta Base selezione file → ImportaDistinta → DistintaBaseImporter.ConvertiInCsv Xls/Xml gestionale → CSV componente;descrizione, scritto nella cartella di lavoro
    3 Crea cartella raw "Crea cartella raw" → CreaCartellaRaw TrovaPercorsiCad + CopiaFileTrovati (parallela) → raw/ dentro la cartella di lavoro
    4 Trova componenti referenziati "Trova componenti referenziati" → TrovaPrtReferenziati → RisolviAlberoComponenti Legge i .asm in raw/ con AssemblyComponentScanner, risolve ricorsivamente sotto-assiemi/parti nell'indice, li copia anch'essi in raw/
    5 Verifica completezza "Verifica completezza assiemi" → VerificaCompletezzaAssiemi Completezza ricorsiva sui percorsi in indice. All'ingresso nella fase, AggiornaAnteprimaAsm mostra le icone trascinabili dei .asm della distinta già in raw/, 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 da AssemblyComponentScanner per validare i token generici).
    • CopiaFileTrovati — copia (in parallelo, grado 6) i file trovati in raw/, saltando silenziosamente quelli irraggiungibili (share offline/permessi).
    • PulisciRawEStep — svuota raw/ e step/ nella cartella di lavoro (manutenzione, richiede conferma).
    • InizializzaDatabase / ScegliDatabase — localizzazione del DB (ultimo usato, salvato in %AppData%/PrepStep/ultimo_db.txt, o cad_index.db accanto all'eseguibile).
    • InizializzaCartellaLavoro / ScegliCartellaLavoro — stesso pattern per la cartella di lavoro (ultima_cartella_lavoro.txt), fallback AppContext.BaseDirectory se 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 — ScanAsync cammina tutte le cartelle di primo livello sotto la radice (scoperte dinamicamente, non un elenco fisso) con un walk manuale a stack (Walk, più veloce di EnumerateFiles(..., AllDirectories) su share con centinaia di migliaia di file), esclude le cartelle temp_*, estrae da ogni nome file il pattern Pro-E <codice>.<tipo>.<versione> (ParseFilename, regex), e fa un upsert incrementale riga per riga confrontando percorso_completo + dimensione + data modifica. Progresso riportato via IProgress<ScanProgress> (marshalato sul thread UI). Contiene anche lo schema SQL: tabella files e vista files_ultima_versione (ultima versione per codice+tipo_file via ROW_NUMBER() OVER (...), non self-join+GROUP BY per 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 in docs/formato-asm.md.

Import distinta base

  • DistintaBaseImporter.cs — converte l'export del gestionale (SpreadsheetML XML con estensione .xls/.xml, oppure .xls/.xlsx binario vero, distinti dai primi byte del file) nelle sole colonne Componente/Descrizione, foglio "Distinta Base". Se il nome del file segue la convenzione DBP_<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 da Form1 (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 RisolviAlberoComponenti in 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 con AutoSize+Padding+MinimumSize invece di una Size fissa in pixel indovinata a mano (altrimenti il testo va a capo e si taglia in verticale se non ci sta nella larghezza scelta). Arrotonda applica angoli arrotondati via Region calcolata su SizeChanged (non una volta sola: con AutoSize la 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 in Form1.BuildUi() con Icon.ExtractAssociatedIcon(Application.ExecutablePath) per la titlebar, senza copiare il file .ico nell'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 tabella files/vista files_ultima_versione sopra. Percorso: cercato accanto all'eseguibile o nella working directory all'avvio; altrimenti selezionabile con "Apri DB...". Radice disco di scansione di default X:\ (Form1.RadiceDiscoDefault, hardcoded).
  • Cartella di lavoro — salvata in %AppData%/PrepStep/ultima_cartella_lavoro.txt (stesso meccanismo del DB sopra), proposta di default AppContext.BaseDirectory la 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 da raw/ 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 .asm risolvendo ricorsivamente i sotto-assiemi contro cad_index.db (stessa logica di AssiemeCompleto in 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.
  • CreoBom.cs — indipendente dagli altri: legge esattamente la struttura a record del binario .asm (sezione members + parametro ConfigName, vedi docs/formato-asm-record.md) invece di contare occorrenze di codici nel testo. Risolve i sottoassiemi cercandoli in cartelle locali (-p), non contro cad_index.db. Non sostituisce l'euristica di AssemblyComponentScanner nella GUI né negli altri script.
  • 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.db da riga di comando.

⚠️ Nota importante di sicurezza: se dotnet run viene lanciato dentro PrepStep/ (che contiene un .csproj di tipo WinExe), 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 o scripts/ stessa).

Test

  • PrepStep.Tests/ (xUnit) — riferimento al progetto principale via ProjectReference
    • InternalsVisibleTo (in PrepStep.csproj), così i test chiamano direttamente Indexer.ParseFilename e AssemblyComponentScanner.EstraiCodiciReferenziati senza esporli come API pubblica. File: IndexerParseFilenameTests.cs, AssemblyComponentScannerTests.cs, DistintaBaseImporterTests.cs, CaseInsensitiveLookupIntegrationTests.cs.