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 OracleINFOCAD_TEST38, accesso via stored procedure ODP.NETBIM_UPDATEPROJECT(nessun ORM). L'entità è persistita nella tabellaBIM_PROJECTS.
- Flow ID: FLOW-BIM-001
- Repository: InfocadWeb (ASP.NET Web Forms, C#,
BIMCenterWeb+PropertyCenterWeb/CommonWeb) + InfocadServer (C#,BIMControllers→BIMDAL) - 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 schedaBIMProjectDetails.ascx. - Plugin/servizio IFC (path alternativo programmatico) —
IFCController.UpdateProject→IFC_DAL→ stessaBIM_UPDATEPROJECT(ingestion Revit/IFC). - Oracle
INFOCAD_TEST38(procedura standaloneBIM_UPDATEPROJECT; sequenzaSEQ_BIM_PROJECTS- trigger
BIM_PROJECTSper l'identity).
- trigger
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), classeDescor.BIMCenterWeb.UserControls.BIMProjectDetails : EntityBaseEx. - Base editing:
PropertyCenterWeb/Classes/EntityBaseEx.vb→Descor.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 viaManageEditing(:176).
Sequenza principale (main sequence)
- Operatore apre la scheda progetto (nuovo o esistente), compila i campi e preme Salva.
- La base
EntityBase(dispatch pulsanteValue="Save") invoca l'overrideBIMProjectDetails.Save(SaveHistory)(BIMProjectDetails.ascx.cs:764). SaveesegueCheckInsertDataValue()(:773, warning tipologia dismessa) e poiSaveObj(changedDate)(:777).SaveObj(:809) chiamaSaveHistory()(:830).SaveHistory:- se
CurrentProject == null || IdProject < 0⇒ creazione: costruisce unBimProjectconIdProject = 0e i campi della scheda (Name,Path,SourceType,FederationType,EntityID,Entity,ModifiedBy,Modified) e chiamaBIMCtrl.UpdateProject(bimProjectNew)(:838-847); - altrimenti ⇒ aggiornamento: aggiorna i campi di
CurrentProjecte chiamaBIMCtrl.UpdateProject(this.CurrentProject)(:851-857).
- se
BIMController.UpdateProject(BIMController.cs:184) inoltra al DAO:((IBIM)this.DAO).UpdateProject(bp)(:186). Il DAO è un proxy .NET Remoting ottenuto daDAOFactory.CreateDAO(Ctrl_BIM)viaActivator.GetObject(typeof(IBIM), ... Service_BIM)(DAOFactory.cs:17-18); l'implementazione server èBIM_DAL(: DAL : Base_DAL : MarshalByRefObject).BIM_DAL.UpdateProject(BIM_DAL.cs:151):- crea 12 parametri IN (
PIDPROJECT,PNAME,PPROJECTTYPE,PFEDERATED,PENTITY,PENTITYID,PSOURCETYPE,PPATH,PMODIFIED,PMODIFIEDBY,PHOST,PSETTINGSCLOB) e un OUTPOUT(Int64) (:157-189); - serializza
bp.Settingsin JSON nel CLOBPSETTINGS(:170); - invoca
dl.ExecuteNonQueryStoredProcedure("BIM_UPDATEPROJECT")(:191); - ritorna
((OracleDecimal)pout.Value).ToInt64()(:193).
- crea 12 parametri IN (
- Oracle
BIM_UPDATEPROJECT(INFOCAD_TEST38, PROCEDURE standalone, VALID):IF PIDPROJECT IS NULL OR PIDPROJECT <= 0⇒ INSERT INTO BIM_PROJECTS (...) VALUES (...) RETURNING IDPROJECT INTO POUT (src:16-19);ELSE⇒ UPDATE BIM_PROJECTS SET ... WHERE IDPROJECT = PIDPROJECT, poiPOUT := SQL%ROWCOUNT(src:23-37);EXCEPTION:DUP_VAL_ON_INDEX⇒POUT := -100;OTHERS⇒POUT := -1(src:41-43).- Sull'INSERT l'identity
IDPROJECTè generata dal trigger BEFORE INSERTBIM_PROJECTS(SEQ_BIM_PROJECTS.NEXTVALse NULL); in UPDATE il trigger vieta di cambiareIDPROJECT(RAISE_APPLICATION_ERROR(-20000, ...)).
- Il DAO restituisce
POUT(nuovo id su create; conteggio righe su update;-1/-100su errore), propagato al controller e aSaveHistory(returnID). - Post-salvataggio (
returnID > 0): se la scheda contiene file, iteraCurrentProject.ItemschiamandoBIMCtrl.UpdateProjectData(itm)(:870) e cancella i file flaggati conBIMCtrl.DeleteProjectData(...)(:882); infineReload()(:919) ricostruisce il tree eIsEdit = 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→ stessaBIM_UPDATEPROJECT(IFC_DAL.cs:157). - WCF di lettura:
BIMCenterWeb/WebServices/BIMServicesWCF.svcespone metodi JSON di sola lettura sui progetti (GetBIMProjectByID,GetBIMProjectByEntity,GetBIMEntityProjects,IBIMServicesWCF.cs:20-37); non esponeUpdateProject.
Backend
- UI/Code-behind:
BIMProjectDetails.ascx.cs(scheda progetto). - Classe base editing:
EntityBaseEx.vb→Descor.CommonWeb.EntityBase. - Controller server:
Descor.BIM.BIMControllers.BIMController(InfocadServer/BIMControllers/Controllers/BIMController.cs), inoltra al DAO viaCtrl_Base.DAO. - DAO:
Descor.BIM.BIM_DAL(InfocadServer/BIMDAL/OracleODP/BIM_DAL.cs),partial class BIM_DAL : DAL, IBIM; baseBase_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 OUTPOUT(Int64), letto comeOracleDecimal. - 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 proceduraBIM_UPDATEPROJECTnon legge tabelle di business (dipendenza statica: soloBIM_PROJECTScome target —USER_DEPENDENCIES). Sull'INSERT viene letta la sequenzaSEQ_BIM_PROJECTS(via triggerBIM_PROJECTS,SEQ_BIM_PROJECTS.NEXTVAL FROM DUAL).
Tabelle modificate (write)
INFOCAD_TEST38:BIM_PROJECTS(RW — tabella-radice del progetto BIM: INSERT conRETURNING IDPROJECT, oppure UPDATEWHERE IDPROJECT = :id; VERIFIED su sorgenteUSER_SOURCEe suUSER_TAB_COLUMNS).- Effetto indiretto (side effect, stesso postback scheda):
BIM_PROJECTDATAviaUpdateProjectData/DeleteProjectDataper i file/versioni figli (BIMProjectDetails.ascx.cs:870,882→BIM_UPDATEPROJECTDATA,BIM_DAL.cs:511).
Validazione
- Lato UI:
CheckInsertDataValue()(:773) valida i valori inseriti (avviso su tipologia dismessa) prima del salvataggio; lock ottimistico viaEntityBase.ManageEditing(..., SystemFields.BIMProjectsEntity, ...)(:176); ACL per progetto (ACL.CanDelete,canEdit) che pilotano l'abilitazione dei comandi toolbar (:512-514). - Lato base editing:
SavedistingueResult.SUCCESS/Result.VALIDATION_ERROR/Result.DB_ERROR; suDB_ERRORmostraDB_ERROR_MESSAGE, altrimentiSaveProjectError(:783-789). - Lato DB:
BIM_UPDATEPROJECTcatturaDUP_VAL_ON_INDEX(violazione unique) restituendoPOUT = -100e ogni altra eccezione conPOUT = -1(src:42-43); il triggerBIM_PROJECTSimpedisce di modificareIDPROJECTin UPDATE (RAISE_APPLICATION_ERROR -20000).
Side effects
- Generazione identity
IDPROJECTdaSEQ_BIM_PROJECTS(trigger BEFORE INSERT su create). - Stamping
MODIFIED/MODIFIEDBY(valorizzati dal code-behind conDateTime.Now/UserName,:845-846,855-856);HOSTpropagato dal DTO. - Persistenza delle impostazioni di progetto come JSON nel CLOB
SETTINGS(BIM_DAL.cs:170). - Creazione/aggiornamento dei file figli su
BIM_PROJECTDATAe 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) → stessaBIM_UPDATEPROJECT(ingestion/aggancio da Revit/IFC). - Errore DB: ritorno
POUTnegativo (-1generico,-100unique) o eccezione ODP.NET loggata daExceptionLogger.LogExceptione ri-sollevata (BIM_DAL.cs:196-199); il code-behind intercetta e mostraSaveProjectError(:785-789,896,903). - Progetto non individuato dopo il salvataggio:
returnID <= 0⇒ messaggio "Progetto non individuato" ereturn 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) → SaveObj → SaveHistory |
BIMProjectDetails.ascx.cs:764,809,830 |
| Code-behind | create (IdProject=0) / update → UpdateProject |
BIMProjectDetails.ascx.cs:838-847,851-857 |
| Base editing | EntityBaseEx → CommonWeb.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.UpdateProject → BIM_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/DeleteProjectData → BIM_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) eIFC_DAL.UpdateProject(IFC_DAL.cs:157).IBIM.UpdateProjectè chiamato da: il code-behind della scheda (BIMProjectDetails.ascx.cs:847,857), ilBIMController(:186) e l'IFCController(:35, viaIIFC.UpdateProject). Nessun altro chiamante di.UpdateProject(in InfocadWeb/InfocadServer.- Il WCF
BIMServicesWCFusaBIMControllersolo per operazioni di lettura (IBIMServicesWCF.cs). - Forward e reverse concordano: la scheda progetto →
UpdateProject→BIM_UPDATEPROJECTcon upsert suBIM_PROJECTS(IDPROJECT); create/update pilotato daPIDPROJECT(0/NULL ⇒ INSERT;>0⇒ UPDATE) → NO CONFLICTING.
Regole correlate (related rules)
- Semantica create vs update pilotata da
PIDPROJECT(<= 0/NULL ⇒ INSERT;> 0⇒ UPDATE) —BIM_UPDATEPROJECT src:16-21; lato UI il create impostaIdProject = 0(:838). - Identity gestita da sequenza + trigger (
SEQ_BIM_PROJECTS), non da colonna IDENTITY; il trigger vieta la mutazione diIDPROJECTin 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 suBIM_PROJECTS,RETURNING IDPROJECT) letto daUSER_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 suBIM_PROJECTDATA(stesso postback, proceduraBIM_UPDATEPROJECTDATAconfermata 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
SETTINGSlato applicativo.
Open questions
- Se, nel deployment reale del web, il canale
Service_BIMsia un processo separato (Windows service) o risolto in-process (osservato soloDAOFactoryconActivator.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).