Table of Contents

FLOW-BIM-001 — Creazione/aggiornamento di un progetto BIM — BIM Center

Flusso end-to-end di salvataggio di un progetto BIM (create-or-update) del modulo BIM Center. Path pilota: scheda BIMProjectDetails.ascx (editing interattivo da parte di un operatore BIM). Backend Oracle INFOCAD_TEST38, accesso via stored procedure ODP.NET BIM_UPDATEPROJECT (nessun ORM). L'entità è persistita nella tabella BIM_PROJECTS.

  • Flow ID: FLOW-BIM-001
  • Repository: InfocadWeb (ASP.NET Web Forms, C#, BIMCenterWeb + PropertyCenterWeb/CommonWeb) + InfocadServer (C#, BIMControllersBIMDAL)
  • Confidence complessiva: VERIFIED (catena UI → code-behind → controller → DAO → stored procedure, confermata su codice E su sorgente DB) · SUPPORTED (architettura remoting controller→DAL; scritture su tabelle figlie BIM_PROJECTDATA)

Obiettivo di business

Consentire a un operatore BIM di creare un nuovo progetto BIM o aggiornarne i dati (nome, tipo progetto, tipo di federazione, entità/subject di aggancio patrimoniale, tipo sorgente file, percorso radice, impostazioni serializzate) all'interno del BIM Center. Al termine il progetto esiste (o è aggiornato) nella tabella BIM_PROJECTS, con id generato da sequenza, e — se la scheda contiene file di progetto — i relativi record figlio BIM_PROJECTDATA vengono creati/aggiornati.

Attori

  • Operatore BIM (utente autenticato con grant/ACL sull'entità BIMProjects) — path interattivo scheda BIMProjectDetails.ascx.
  • Plugin/servizio IFC (path alternativo programmatico) — IFCController.UpdateProjectIFC_DAL → stessa BIM_UPDATEPROJECT (ingestion Revit/IFC).
  • Oracle INFOCAD_TEST38 (procedura standalone BIM_UPDATEPROJECT; sequenza SEQ_BIM_PROJECTS
    • trigger BIM_PROJECTS per l'identity).

Trigger

Click sul pulsante Salva della toolbar della scheda progetto: RadToolBarButton ... Value="Save" (BIMProjectDetails.ascx:151). Il click è gestito dalla classe base EntityBase (VB, ereditata via EntityBaseEx) che invoca l'override Save(...) del code-behind (BIMProjectDetails.ascx.cs:764). Il gestore locale RadToolBar1_ButtonClick (:170) intercetta gli altri comandi (aggiunta file, elimina, permessi) e richiama ManageEditing(..., SystemFields.BIMProjectsEntity, ...) (:176) per il lock ottimistico.

Frontend entry point

  • Shell / pagina: BIMCenterWeb/Default.aspx (modello shell CASSANDRA con UserControl dinamici).
  • Control scheda: BIMCenterWeb/UserControls/BIMProjectDetails.ascx (+ .ascx.cs), classe Descor.BIMCenterWeb.UserControls.BIMProjectDetails : EntityBaseEx.
  • Base editing: PropertyCenterWeb/Classes/EntityBaseEx.vbDescor.CommonWeb.EntityBase (stessa base editing del flusso Property FLOW-PROP-001).
  • Gate di accesso: ACL per progetto (CurrentProject.ACL.CanDelete/canEdit) che pilotano la visibilità dei pulsanti toolbar (:512-514); lock via ManageEditing (:176).

Sequenza principale (main sequence)

  1. Operatore apre la scheda progetto (nuovo o esistente), compila i campi e preme Salva.
  2. La base EntityBase (dispatch pulsante Value="Save") invoca l'override BIMProjectDetails.Save(SaveHistory) (BIMProjectDetails.ascx.cs:764).
  3. Save esegue CheckInsertDataValue() (:773, warning tipologia dismessa) e poi SaveObj(changedDate) (:777).
  4. SaveObj (:809) chiama SaveHistory() (:830).
  5. SaveHistory:
    • se CurrentProject == null || IdProject < 0creazione: costruisce un BimProject con IdProject = 0 e i campi della scheda (Name, Path, SourceType, FederationType, EntityID, Entity, ModifiedBy, Modified) e chiama BIMCtrl.UpdateProject(bimProjectNew) (:838-847);
    • altrimenti ⇒ aggiornamento: aggiorna i campi di CurrentProject e chiama BIMCtrl.UpdateProject(this.CurrentProject) (:851-857).
  6. BIMController.UpdateProject (BIMController.cs:184) inoltra al DAO: ((IBIM)this.DAO).UpdateProject(bp) (:186). Il DAO è un proxy .NET Remoting ottenuto da DAOFactory.CreateDAO(Ctrl_BIM) via Activator.GetObject(typeof(IBIM), ... Service_BIM) (DAOFactory.cs:17-18); l'implementazione server è BIM_DAL (: DAL : Base_DAL : MarshalByRefObject).
  7. BIM_DAL.UpdateProject (BIM_DAL.cs:151):
    • crea 12 parametri IN (PIDPROJECT, PNAME, PPROJECTTYPE, PFEDERATED, PENTITY, PENTITYID, PSOURCETYPE, PPATH, PMODIFIED, PMODIFIEDBY, PHOST, PSETTINGS CLOB) e un OUT POUT (Int64) (:157-189);
    • serializza bp.Settings in JSON nel CLOB PSETTINGS (:170);
    • invoca dl.ExecuteNonQueryStoredProcedure("BIM_UPDATEPROJECT") (:191);
    • ritorna ((OracleDecimal)pout.Value).ToInt64() (:193).
  8. Oracle BIM_UPDATEPROJECT (INFOCAD_TEST38, PROCEDURE standalone, VALID):
    • IF PIDPROJECT IS NULL OR PIDPROJECT <= 0INSERT INTO BIM_PROJECTS (...) VALUES (...) RETURNING IDPROJECT INTO POUT (src:16-19);
    • ELSEUPDATE BIM_PROJECTS SET ... WHERE IDPROJECT = PIDPROJECT, poi POUT := SQL%ROWCOUNT (src:23-37);
    • EXCEPTION: DUP_VAL_ON_INDEXPOUT := -100; OTHERSPOUT := -1 (src:41-43).
    • Sull'INSERT l'identity IDPROJECT è generata dal trigger BEFORE INSERT BIM_PROJECTS (SEQ_BIM_PROJECTS.NEXTVAL se NULL); in UPDATE il trigger vieta di cambiare IDPROJECT (RAISE_APPLICATION_ERROR(-20000, ...)).
  9. Il DAO restituisce POUT (nuovo id su create; conteggio righe su update; -1/-100 su errore), propagato al controller e a SaveHistory (returnID).
  10. Post-salvataggio (returnID > 0): se la scheda contiene file, itera CurrentProject.Items chiamando BIMCtrl.UpdateProjectData(itm) (:870) e cancella i file flaggati con BIMCtrl.DeleteProjectData(...) (:882); infine Reload() (:919) ricostruisce il tree e IsEdit = false.

API / service

  • Path interattivo: nessun servizio SOAP/WCF — postback ASP.NET Web Forms diretto sulla scheda; il controller server è raggiunto in-process nel web app ma con DAO via .NET Remoting verso il servizio Service_BIM (DAOFactory.cs:18).
  • Path programmatico (alternativo): IFCController.UpdateProject(p) (IFCController.cs:35) → IFC_DAL → stessa BIM_UPDATEPROJECT (IFC_DAL.cs:157).
  • WCF di lettura: BIMCenterWeb/WebServices/BIMServicesWCF.svc espone metodi JSON di sola lettura sui progetti (GetBIMProjectByID, GetBIMProjectByEntity, GetBIMEntityProjects, IBIMServicesWCF.cs:20-37); non espone UpdateProject.

Backend

  • UI/Code-behind: BIMProjectDetails.ascx.cs (scheda progetto).
  • Classe base editing: EntityBaseEx.vbDescor.CommonWeb.EntityBase.
  • Controller server: Descor.BIM.BIMControllers.BIMController (InfocadServer/BIMControllers/Controllers/BIMController.cs), inoltra al DAO via Ctrl_Base.DAO.
  • DAO: Descor.BIM.BIM_DAL (InfocadServer/BIMDAL/OracleODP/BIM_DAL.cs), partial class BIM_DAL : DAL, IBIM; base Base_DAL : MarshalByRefObject (BIMDAL/Base_DAL.cs:9).
  • Pattern DAL: using (DataLayer dl = new DataLayer(ConnectionName))dl.Parameters.Add(new OracleParameter(...))dl.ExecuteNonQueryStoredProcedure("BIM_UPDATEPROJECT"); identity/ritorno via parametro OUT POUT (Int64), letto come OracleDecimal.
  • Nota architetturale: a differenza dei controller Property (in-process), i controller BIM risolvono il DAO tramite .NET Remoting (Activator.GetObject(typeof(IBIM), CHANNEL://SERVER/Service_BIM), DAOFactory.cs:18); l'implementazione è MarshalByRefObject.

Query / stored procedure

Passo Stored procedure (Oracle) Chiamata da (DAL)
Upsert progetto (INSERT/UPDATE su BIM_PROJECTS) INFOCAD_TEST38.BIM_UPDATEPROJECT (OUT POUT NUMBER) BIM_DAL.cs:191
Upsert progetto — path IFC/plugin INFOCAD_TEST38.BIM_UPDATEPROJECT IFC_DAL.cs:157
Upsert file/versioni di progetto (side effect) INFOCAD_TEST38.BIM_UPDATEPROJECTDATA BIM_DAL.cs:511, IFC_DAL.cs:383
Cancellazione progetto (path alternativo) INFOCAD_TEST38.BIM_DELETEPROJECT BIM_DAL.cs:221
Load scheda progetto (READ-ONLY) INFOCAD_TEST38.BIM_GETPROJECTS / BIM_GETPROJECTBYUID BIM_DAL.cs:99,61

Tabelle lette (read)

  • INFOCAD_TEST38: la procedura BIM_UPDATEPROJECT non legge tabelle di business (dipendenza statica: solo BIM_PROJECTS come target — USER_DEPENDENCIES). Sull'INSERT viene letta la sequenza SEQ_BIM_PROJECTS (via trigger BIM_PROJECTS, SEQ_BIM_PROJECTS.NEXTVAL FROM DUAL).

Tabelle modificate (write)

  • INFOCAD_TEST38: BIM_PROJECTS (RW — tabella-radice del progetto BIM: INSERT con RETURNING IDPROJECT, oppure UPDATE WHERE IDPROJECT = :id; VERIFIED su sorgente USER_SOURCE e su USER_TAB_COLUMNS).
  • Effetto indiretto (side effect, stesso postback scheda): BIM_PROJECTDATA via UpdateProjectData/DeleteProjectData per i file/versioni figli (BIMProjectDetails.ascx.cs:870,882BIM_UPDATEPROJECTDATA, BIM_DAL.cs:511).

Validazione

  • Lato UI: CheckInsertDataValue() (:773) valida i valori inseriti (avviso su tipologia dismessa) prima del salvataggio; lock ottimistico via EntityBase.ManageEditing(..., SystemFields.BIMProjectsEntity, ...) (:176); ACL per progetto (ACL.CanDelete, canEdit) che pilotano l'abilitazione dei comandi toolbar (:512-514).
  • Lato base editing: Save distingue Result.SUCCESS / Result.VALIDATION_ERROR / Result.DB_ERROR; su DB_ERROR mostra DB_ERROR_MESSAGE, altrimenti SaveProjectError (:783-789).
  • Lato DB: BIM_UPDATEPROJECT cattura DUP_VAL_ON_INDEX (violazione unique) restituendo POUT = -100 e ogni altra eccezione con POUT = -1 (src:42-43); il trigger BIM_PROJECTS impedisce di modificare IDPROJECT in UPDATE (RAISE_APPLICATION_ERROR -20000).

Side effects

  • Generazione identity IDPROJECT da SEQ_BIM_PROJECTS (trigger BEFORE INSERT su create).
  • Stamping MODIFIED/MODIFIEDBY (valorizzati dal code-behind con DateTime.Now/UserName, :845-846,855-856); HOST propagato dal DTO.
  • Persistenza delle impostazioni di progetto come JSON nel CLOB SETTINGS (BIM_DAL.cs:170).
  • Creazione/aggiornamento dei file figli su BIM_PROJECTDATA e cancellazione fisica dei file flaggati (:870,882).
  • Refresh UI: Reload() ricostruisce il project tree e riporta la scheda in sola lettura (:919).

Percorsi alternativi / di errore

  • Path IFC/plugin: IFCController.UpdateProject (IFCController.cs:35) → IFC_DAL.UpdateProject (IFC_DAL.cs:157) → stessa BIM_UPDATEPROJECT (ingestion/aggancio da Revit/IFC).
  • Errore DB: ritorno POUT negativo (-1 generico, -100 unique) o eccezione ODP.NET loggata da ExceptionLogger.LogException e ri-sollevata (BIM_DAL.cs:196-199); il code-behind intercetta e mostra SaveProjectError (:785-789,896,903).
  • Progetto non individuato dopo il salvataggio: returnID <= 0 ⇒ messaggio "Progetto non individuato" e return false (:895-898).
  • Cancellazione progetto (controprova non distruttiva sul dominio): BIM_DELETEPROJECT (BIM_DAL.cs:221).

Diagramma di sequenza

sequenceDiagram
    actor Op as Operatore BIM
    participant UI as BIMProjectDetails.ascx (Default.aspx shell)
    participant CB as BIMProjectDetails.ascx.cs (Save/SaveHistory)
    participant BC as BIMController.UpdateProject
    participant RM as .NET Remoting (Service_BIM)
    participant DAO as BIM_DAL.UpdateProject
    participant DB as Oracle INFOCAD_TEST38 (BIM_UPDATEPROJECT)

    Op->>UI: compila scheda + click Salva (Value="Save")
    UI->>CB: EntityBase dispatch -> Save() -> SaveObj -> SaveHistory
    CB->>CB: build BimProject (IdProject=0 create | esistente update)
    CB->>BC: UpdateProject(bp)
    BC->>RM: ((IBIM)DAO).UpdateProject(bp)
    RM->>DAO: UpdateProject(bp)
    DAO->>DAO: serialize Settings -> JSON CLOB; 12 IN + POUT
    DAO->>DB: BIM_UPDATEPROJECT (PIDPROJECT, ..., PSETTINGS, OUT POUT)
    alt PIDPROJECT NULL/<=0 (create)
        DB->>DB: INSERT INTO BIM_PROJECTS RETURNING IDPROJECT INTO POUT
        DB->>DB: trigger BEFORE INSERT -> SEQ_BIM_PROJECTS.NEXTVAL
    else PIDPROJECT > 0 (update)
        DB->>DB: UPDATE BIM_PROJECTS SET ... WHERE IDPROJECT = :id
        DB->>DB: POUT := SQL%ROWCOUNT
    end
    DB-->>DAO: POUT (id nuovo | rowcount | -1/-100)
    DAO-->>BC: Int64
    BC-->>CB: returnID
    opt returnID > 0 e scheda con file
        CB->>BC: UpdateProjectData / DeleteProjectData (BIM_PROJECTDATA)
    end
    CB-->>Op: Reload scheda (progetto salvato)

Matrice di tracciabilità

Layer Artefatto Evidenza (file:riga)
UI BIMProjectDetails.ascx (pulsante Salva Value="Save") BIMCenterWeb/UserControls/BIMProjectDetails.ascx:151
Code-behind Save (override) → SaveObjSaveHistory BIMProjectDetails.ascx.cs:764,809,830
Code-behind create (IdProject=0) / update → UpdateProject BIMProjectDetails.ascx.cs:838-847,851-857
Base editing EntityBaseExCommonWeb.EntityBase (dispatch Salva, ManageEditing) EntityBaseEx.vb:8-9 ; BIMProjectDetails.ascx.cs:176
Controller BIMController.UpdateProject((IBIM)DAO) BIMController.cs:184,186
DAO factory DAOFactory.CreateDAO(Ctrl_BIM) (remoting Service_BIM) DAOFactory.cs:17-18
DAO BIM_DAL.UpdateProjectBIM_UPDATEPROJECT BIM_DAL.cs:151,170,191,193
DAO (base remoting) Base_DAL : MarshalByRefObject BIMDAL/Base_DAL.cs:9
DB BIM_UPDATEPROJECT (INSERT/UPDATE su BIM_PROJECTS) USER_SOURCE BIM_UPDATEPROJECT src:16-19,23-37,41-43
DB Trigger identity BIM_PROJECTS (SEQ_BIM_PROJECTS) USER_TRIGGERS BIM_PROJECTS (BEFORE INSERT)
DB (schema) BIM_PROJECTS colonne IDPROJECT(NUMBER NN), NAME, PROJECTTYPE, FEDERATED, ENTITY, ENTITYID, SOURCETYPE, ROOTPATH, MODIFIED, MODIFIEDBY, HOST, CANCELLED, SETTINGS(CLOB) USER_TAB_COLUMNS
Side effect UpdateProjectData/DeleteProjectDataBIM_PROJECTDATA BIMProjectDetails.ascx.cs:870,882 ; BIM_DAL.cs:511

Reverse trace (dal DB/controller ai chiamanti)

  • BIM_UPDATEPROJECT (procedura) è raggiunta da due sole call-site nel codice server: BIM_DAL.UpdateProject (BIM_DAL.cs:191) e IFC_DAL.UpdateProject (IFC_DAL.cs:157).
  • IBIM.UpdateProject è chiamato da: il code-behind della scheda (BIMProjectDetails.ascx.cs:847,857), il BIMController (:186) e l'IFCController (:35, via IIFC.UpdateProject). Nessun altro chiamante di .UpdateProject( in InfocadWeb/InfocadServer.
  • Il WCF BIMServicesWCF usa BIMController solo per operazioni di lettura (IBIMServicesWCF.cs).
  • Forward e reverse concordano: la scheda progetto → UpdateProjectBIM_UPDATEPROJECT con upsert su BIM_PROJECTS (IDPROJECT); create/update pilotato da PIDPROJECT (0/NULL ⇒ INSERT; >0 ⇒ UPDATE) → NO CONFLICTING.
  • Semantica create vs update pilotata da PIDPROJECT (<= 0/NULL ⇒ INSERT; > 0 ⇒ UPDATE) — BIM_UPDATEPROJECT src:16-21; lato UI il create imposta IdProject = 0 (:838).
  • Identity gestita da sequenza + trigger (SEQ_BIM_PROJECTS), non da colonna IDENTITY; il trigger vieta la mutazione di IDPROJECT in UPDATE.
  • Convenzione tabelle BIM: prefisso BIM_ (BIM_PROJECTS, BIM_PROJECTDATA), diversa dal suffisso _ delle entità spaziali Property.
  • Le impostazioni progetto viaggiano come JSON serializzato nel CLOB SETTINGS (Descor.Common.Serialization.JSon.SerializeToString, BIM_DAL.cs:170).

Evidenza (file:line)

Punti chiave (codice): BIMProjectDetails.ascx:151; BIMProjectDetails.ascx.cs:170,176,512-514,764,773,809,830,838-847,851-857,870,882,919; EntityBaseEx.vb:8-9; BIMController.cs:184,186; DAOFactory.cs:17-18; Base_DAL.cs:9; BIM_DAL.cs:151,157-189,170,191,193; path alternativo IFCController.cs:35 + IFC_DAL.cs:157.

Punti chiave (DB, INFOCAD_TEST38, letti in sola lettura via USER_OBJECTS/USER_SOURCE/USER_TAB_COLUMNS/USER_TRIGGERS/USER_DEPENDENCIES): BIM_UPDATEPROJECT è PROCEDURE VALID; firma src:1-13; decisione INSERT/UPDATE src:16-21; INSERT + RETURNING IDPROJECT INTO POUT src:18-19; UPDATE + POUT := SQL%ROWCOUNT src:23-37; EXCEPTION src:41-43. Trigger BIM_PROJECTS BEFORE INSERT → SEQ_BIM_PROJECTS.NEXTVAL; UPDATE vieta cambio IDPROJECT. USER_DEPENDENCIES(BIM_UPDATEPROJECT)BIM_PROJECTS (TABLE). BIM_PROJECTS colonne verificate da USER_TAB_COLUMNS.

Confidence

  • VERIFIED: catena UI → code-behind → controller → DAO → nome stored procedure (letta sui sorgenti) e sorgente della stored procedure BIM_UPDATEPROJECT (INSERT/UPDATE su BIM_PROJECTS, RETURNING IDPROJECT) letto da USER_SOURCE; esistenza tabella/colonne, trigger identity e dipendenze da catalogo (tre tipi di evidenza indipendenti: codice, sorgente DB, catalogo DB).
  • SUPPORTED: risoluzione del DAO via .NET Remoting (DAOFactory + MarshalByRefObject) e scritture indiretta su BIM_PROJECTDATA (stesso postback, procedura BIM_UPDATEPROJECTDATA confermata per nome ma non ispezionata nel sorgente in questo flusso).
  • INFERRED: comportamento runtime del canale remoting nel deployment web (potrebbe essere configurato in-process); consumo effettivo del CLOB SETTINGS lato applicativo.

Open questions

  • Se, nel deployment reale del web, il canale Service_BIM sia un processo separato (Windows service) o risolto in-process (osservato solo DAOFactory con Activator.GetObject).
  • Colonne/campi effettivamente valorizzati in SETTINGS (JSON variabile per tipo progetto/tenant).
  • Dettaglio del sorgente di BIM_UPDATEPROJECTDATA (file/versioni figli) non ispezionato in questo flusso.
  • Grant/permessi applicativi puntuali richiesti per BIMProjects (codici grant) oltre all'ACL di scheda.
  • Comportamento in configurazioni PROD (osservato solo ambiente TEST38).