FLOW-CHK-001 — Registrazione di una verifica (CheckItem) — Check
Flusso end-to-end di creazione di una verifica/controllo (CheckItem) del dominio Check (distinto da QualityCheck). Path pilota: scheda
CheckItemDetail.ascxdel CheckCenter (editing interattivo da parte di un operatore). Backend OracleINFOCAD_TEST38, accesso via stored procedure ODP.NET (CHK_CREATECHECKITEM), con hop applicativo intermedio via .NET Remoting (controller Web → BL nel Windows service). Nessun ORM. L'entità è persistita nella tabellaCHECK_ITEM.
- Flow ID: FLOW-CHK-001
- Operazione: WRITE — INSERT di un nuovo CheckItem
- Repository: InfocadWeb (ASP.NET Web Forms, VB.NET — CheckCenter) + InfocadServer (CheckControllers → CheckBL → CheckDAL, VB.NET)
- has_standalone_write:
true— esiste un path di scrittura autonomo e pulito (registrazione di una verifica) - Confidence complessiva: VERIFIED (catena UI → controller → BL → DAL → stored procedure → tabelle, confermata su codice E su sorgente DB, forward/reverse concordi)
Obiettivo di business
Consentire a un operatore autenticato del CheckCenter di registrare una nuova verifica/controllo
(CheckItem) associata a un elemento del patrimonio (comprensorio/edificio/piano/vano o elemento
generico via TABLENAME/ID_ELEMENT) e a un CheckType. Al termine la verifica esiste nella tabella
CHECK_ITEM con protocollo generato, stato iniziale OPEN assegnato automaticamente, id progressivo
da sequenza e una riga di storico creata su CHECK_HISTORY.
Attori
- Operatore CheckCenter — utente autenticato con grant applicativo
14020(verificato in UI:CheckItemDetail.ascx.vb:392) oppure super-admin. - Windows service InfocadServer (Business host) — espone il BL
CheckItem_BLcome oggetto .NET Remoting well-known (Start.vb:888). - Oracle
INFOCAD_TEST38— hub dati Check (procedureCHK_CREATECHECKITEM,CHK_GETNEWCHECKITEMPROTOCOL; tabelleCHECK_ITEM,CHECK_HISTORY,CHECK_STATE,CHECK_PROTOCOLFORMAT).
Trigger
Click sul pulsante Salva della scheda verifica: evento btnUpdate.Click gestito da
btnUpdate_Click (CheckItemDetail.ascx.vb:415). Se ID_DTO = 0 (nuovo) instrada su Insert()
(:419); altrimenti su Update().
Frontend entry point
- Control scheda:
InfocadWeb/WebMachine/CASSANDRA/CommonWeb/CheckCenter/UserControls/CheckItemDetail.ascx(+ code-behind.ascx.vb). - Griglia elenco verifiche (path correlato):
CheckCenter/UserControls/CheckGrid.ascx. - Gate di accesso:
Me.CanEdit = HasUserGrant("14020") Or WS.SessionProfile.SuperAdmin(CheckItemDetail.ascx.vb:392) →InitControls(CanEdit)abilita/disabilita i controlli di editing.
Sequenza principale (main sequence)
- Operatore apre la scheda di una nuova verifica, compila protocollo/tipo/stato/posizione/data/nota/score e preme Salva.
CheckItemDetail.ascx.vb→btnUpdate_Click(:415); essendoID_DTO = 0chiamaInsert()(:419).Insert()(:461) costruisce un DTOCheckItem, popolandoProtocol,RefModule(New Guid(ControlRefModule)),CheckType.ID_DTO,State.ID_DTO,DistrinctID,BuildingID,FloorID,RoomID,ExtimatedCheckDate,Note,Score(:465-486).- Invoca il controller:
checkItemCTRL.Insert(check, WS.SessionLogin.UserName)(:488). CheckItemController(istanziato conDaoActivate(enControllers.Ctrl_CheckItem),CheckItemController.vb:9) inoltra:Insert(dto, username)(:60) →DirectCast(Me.DAO, ICheckItem_BL).Insert(dto, username).- .NET Remoting:
Me.DAOè risolto daDAOFactory.CreateDAOcome proxy remotoActivator.GetObject(GetType(ICheckItem_BL), CHANNEL://SERVERADDRESS/CheckItem_BL.rem)(DAOFactory.vb:9). Il tipo concretoCheckItem_BLè registrato lato server comeWellKnownObjectMode.SingleCall(Start.vb:888). La chiamata attraversa quindi il confine di processo verso il Windows service. CheckItem_BL.Insert(dto, username)(CheckItem_BL.vb:88) fa il cast aCheckIteme chiamaCheckDALFactory.GetCheckItemDAL.Insert(...)passando i campi del DTO +username(:90-108).CheckItem_DAL.Insert(...)(CheckItem_DAL.vb:282):- Genera il protocollo: aggiunge i 4 parametri OUT e chiama
CHK_GETNEWCHECKITEMPROTOCOL(:310); componesProtocol = CInt(PPROTOCOL).ToString(regex) & suffix(:312-315), poiClearParameter()(:317). - Prepara ~20
OracleParameterdi input (protocollo, refprotocol, refmod RAW 16 byte, checktype/district/building/floor/room/controller id, tablename, idelement, date, note, score, checkresult, limitvalue, docid, username) +PNEWINDEXOUT (:321-378). - Chiama
dl.ExecuteNonQueryStoredProcedure("CHK_CREATECHECKITEM")(:380) e ritornaPNEWINDEX(nuovo id) (:382).
- Genera il protocollo: aggiunge i 4 parametri OUT e chiama
- Oracle
CHK_CREATECHECKITEM(INFOCAD_TEST38):- legge lo stato iniziale:
SELECT ID_STATE INTO TMP_START_STATE FROM CHECK_STATE WHERE STATE='OPEN'(src:27-30); - esegue
INSERT INTO CHECK_ITEM (...) VALUES (...) RETURNING ID_CHECK_ITEM INTO PNEWINDEXconSTATE_ID = TMP_START_STATE,LAST_UPDATED_BY = PUSERNAME,LAST_UPDATE_DATE = SYSDATE(src:32-35).
- legge lo stato iniziale:
- Trigger DB (side effects sincroni sull'INSERT):
CHECK_ITEM(BEFORE INSERT FOR EACH ROW): seID_CHECK_ITEMè NULL assegnaSEQ_CHECK_ITEM.NEXTVAL; altrimenti allinea la sequenza (src trigger:3-8);CHECK_ITEM_HISTORY_INS(AFTER INSERT FOR EACH ROW):INSERT INTO CHECK_HISTORY(CHECK_ID, STATE_ID, DATE_TIME, USERNAME, NOTE)(src trigger:3-6).
- Il DAL riporta il nuovo id fino alla UI;
CheckItemDetail.InsertimpostaUpdated = (newID > 0)e, se> 0, ricarica il protocollo conGetProtocolByCheckIyemID(newID)(:491-492), faRadGrid1.Rebind()e mostra il messaggio di successo (:494-496).
API / service
- Path interattivo: postback ASP.NET Web Forms diretto sulla scheda (nessun SOAP/WCF).
- Hop applicativo: .NET Remoting — il controller Web (
CheckItemController) è un proxy che invoca il BLCheckItem_BLospitato nel Windows service InfocadServer (endpoint well-knownCheckItem_BL.rem,SingleCall).
Backend
- UI/Code-behind:
CheckItemDetail.ascx.vb(scheda verifica). - Controller:
Descor.Check.CheckControllers.CheckItemController(CheckItemController.vb),Inherits Ctrl_EntityBase,Implements ICheckItem_BL— inoltra tutto aMe.DAO(proxy remoting risolto daDAOFactory). - BL:
Descor.Check.CheckBL.CheckItem_BL(CheckItem_BL.vb),Inherits MarshalByRefObject— mappa il DTO sui parametri e delega al DAL viaCheckDALFactory.GetCheckItemDAL. - DAL:
Descor.Check.CheckDAL.ODP.CheckItem_DAL(CheckItem_DAL.vb). - Pattern DAL:
Dim dl As New DataLayer(My.Settings.ConnectionName)→dl.Parameters.Add(New OracleParameter(...))→dl.ExecuteNonQueryStoredProcedure("CHK_CREATECHECKITEM"); id di ritorno via parametro OUTPNEWINDEX;dl.Kill()nelFinally. - DTO:
Descor.Check.CheckSharedObjects.Objects.CheckItem(CheckItem.vb).
Query / stored procedure
| Passo | Stored procedure (Oracle) | Chiamata da (DAL) |
|---|---|---|
| Generazione protocollo verifica (OUT protocollo/regex/suffix) | INFOCAD_TEST38.CHK_GETNEWCHECKITEMPROTOCOL |
CheckItem_DAL.vb:310 |
INSERT nuovo CheckItem (OUT PNEWINDEX = nuovo id) |
INFOCAD_TEST38.CHK_CREATECHECKITEM |
CheckItem_DAL.vb:380 |
| Recupero protocollo per id (post-insert, UI) | INFOCAD_TEST38.CHK_GETPROTOCOLBYCHECKITEMID |
CheckItem_DAL.vb:527 |
Tabelle lette (read)
INFOCAD_TEST38.CHECK_STATE— risoluzione stato inizialeOPEN(CHK_CREATECHECKITEM src:27-30;USER_DEPENDENCIES:CHK_CREATECHECKITEM → CHECK_STATE).INFOCAD_TEST38.CHECK_PROTOCOLFORMAT— formula/regex/suffix del protocollo (CHK_GETNEWCHECKITEMPROTOCOL src:17-23;USER_DEPENDENCIES:CHK_GETNEWCHECKITEMPROTOCOL → CHECK_PROTOCOLFORMAT).SYS.USER_SEQUENCES— allineamento sequenza nel trigger BEFORE INSERT (trigger CHECK_ITEM src:5-6).
Tabelle modificate (write)
INFOCAD_TEST38.CHECK_ITEM(RW/INSERT — tabella-radice della verifica; INSERT conRETURNING ID_CHECK_ITEM; VERIFIED su sorgente SP e suUSER_DEPENDENCIES).INFOCAD_TEST38.CHECK_HISTORY(INSERT indiretto — riga di storico creata dal trigger AFTER INSERTCHECK_ITEM_HISTORY_INS; VERIFIED su sorgente trigger).INFOCAD_TEST38.SEQ_CHECK_ITEM(sequenza —NEXTVALconsumato dal trigger BEFORE INSERT per l'id).
Validazione
- Lato UI: grant
14020/ super-admin →CanEdit; se assente i controlli di editing sono disabilitati (CheckItemDetail.ascx.vb:392-393). Salvataggio inTry/Catchcon messaggio a video (:498-502). - Lato BL/DAL: nessuna validazione di dominio esplicita; eccezioni loggate con
Descor.Infrastructure.LogManager.ExceptionLogger.LogExceptione ri-lanciate (CheckItem_DAL.vb:384-386). - Lato DB: lo stato iniziale è forzato a
OPENvia lookup suCHECK_STATE(non parametrizzato in insert); l'id è garantito univoco dal trigger/sequenza. Nessun controllo di esistenza tabella/colonna (SQL statico).
Side effects
- Assegnazione id:
SEQ_CHECK_ITEM.NEXTVAL(trigger BEFORE INSERTCHECK_ITEM). - Storico: nuova riga su
CHECK_HISTORYcon stato/utente/nota/data (trigger AFTER INSERTCHECK_ITEM_HISTORY_INS). - Protocollo: generato server-side da
CHK_GETNEWCHECKITEMPROTOCOL(formato/regex/suffix daCHECK_PROTOCOLFORMAT) e ri-letto in UI post-insert. - Audit inline:
LAST_UPDATED_BY = username,LAST_UPDATE_DATE = SYSDATE, stato =OPEN. - Nota:
CheckItemDetail.Page_Loadesegue incondizionatamentechkCTRL.DeleteHistoryByCheckID(21)(:395-396) — chiamata sospetta/di debug non correlata all'insert (vedi Open questions).
Percorsi alternativi / di errore
- Update verifica esistente:
ID_DTO > 0→Update()(CheckItemDetail.ascx.vb:423) →CheckItemController.Update(dto, username)→CheckItem_BL.Update(:170) →CheckItem_DAL.Update→ SPCHK_UPDATECHECKITEM(CheckItem_DAL.vb:480). Il cambio di stato attiva il trigger UPDATECHECK_ITEM_HISTORY_UPD(storico). - Cancellazione logica / definitiva / restore: SP
CHK_LOGICALDELETECHECKITEM(:171),CHK_FINALDELETECHECKITEM(:151),CHK_RESTORECHEKITEM(:192). - Errore DB/eccezione: loggata e ri-lanciata dal DAL; in UI catturata e mostrata in
ttMessage(:498-500); nessuna riga persistita (INSERT unico, transazione della SP). - Overload Insert senza username (
CheckItem_BL.vb:195): stessa SP conusername = String.Empty(non usato dal path UI interattivo).
Diagramma di sequenza
sequenceDiagram
actor Op as Operatore CheckCenter
participant UI as CheckItemDetail.ascx.vb (Insert)
participant CT as CheckItemController (proxy)
participant RM as .NET Remoting (CheckItem_BL.rem)
participant BL as CheckItem_BL.Insert
participant DAL as CheckItem_DAL.Insert
participant DB as Oracle INFOCAD_TEST38
Op->>UI: compila scheda + click Salva
UI->>UI: btnUpdate_Click -> ID_DTO=0 -> Insert()
UI->>CT: checkItemCTRL.Insert(check, username)
CT->>RM: DirectCast(DAO, ICheckItem_BL).Insert(...)
RM->>BL: Insert(dto, username) [SingleCall]
BL->>DAL: CheckDALFactory.GetCheckItemDAL.Insert(...)
DAL->>DB: CHK_GETNEWCHECKITEMPROTOCOL (OUT protocollo)
DB->>DB: SELECT da CHECK_PROTOCOLFORMAT
DAL->>DB: CHK_CREATECHECKITEM (OUT PNEWINDEX)
DB->>DB: SELECT stato OPEN da CHECK_STATE
DB->>DB: INSERT INTO CHECK_ITEM RETURNING ID_CHECK_ITEM
Note over DB: trig BEFORE INSERT -> SEQ_CHECK_ITEM.NEXTVAL
Note over DB: trig AFTER INSERT -> INSERT CHECK_HISTORY
DB-->>DAL: PNEWINDEX (nuovo id)
DAL-->>BL: newID
BL-->>CT: newID
CT-->>UI: newID
UI->>DB: GetProtocolByCheckIyemID(newID) (ri-lettura protocollo)
UI-->>Op: "Salvataggio effettuato con successo!"
Matrice di tracciabilità (file:riga)
| # | Livello | Artefatto | Evidenza (file:riga) |
|---|---|---|---|
| 1 | UI gate | Grant 14020/super-admin |
InfocadWeb/.../CheckCenter/UserControls/CheckItemDetail.ascx.vb:392 |
| 2 | UI trigger | btnUpdate_Click → Insert() |
CheckItemDetail.ascx.vb:415,419 |
| 3 | UI build DTO + chiamata | Insert() → checkItemCTRL.Insert(check, username) |
CheckItemDetail.ascx.vb:461,488 |
| 4 | Controller | Insert(dto, username) → Me.DAO |
InfocadServer/CheckControllers/CheckItemController.vb:60 |
| 5 | Attivazione DAO | DaoActivate(Ctrl_CheckItem) |
CheckItemController.vb:9 |
| 6 | Remoting | Activator.GetObject(ICheckItem_BL, .../CheckItem_BL.rem) |
CheckControllers/serv/DAOFactory.vb:9 |
| 7 | Registrazione server | RegisterWellKnownServiceType(CheckItem_BL, "CheckItem_BL.rem", SingleCall) |
InfocadServer/Business/Start.vb:888 |
| 8 | BL | Insert(dto, username) → GetCheckItemDAL.Insert(...) |
InfocadServer/CheckBL/CheckItem_BL.vb:88,90 |
| 9 | DAL protocollo | ExecuteNonQueryStoredProcedure("CHK_GETNEWCHECKITEMPROTOCOL") |
InfocadServer/CheckDAL/OracleODP/CheckItem_DAL.vb:310 |
| 10 | DAL insert | ExecuteNonQueryStoredProcedure("CHK_CREATECHECKITEM") → PNEWINDEX |
CheckItem_DAL.vb:380,382 |
| 11 | SP insert | INSERT INTO CHECK_ITEM ... RETURNING ID_CHECK_ITEM |
CHK_CREATECHECKITEM src:32-35 |
| 12 | SP read stato | SELECT ID_STATE FROM CHECK_STATE WHERE STATE='OPEN' |
CHK_CREATECHECKITEM src:27-30 |
| 13 | SP protocollo read | SELECT ... FROM CHECK_PROTOCOLFORMAT |
CHK_GETNEWCHECKITEMPROTOCOL src:17-23 |
| 14 | Trigger id | BEFORE INSERT CHECK_ITEM → SEQ_CHECK_ITEM.NEXTVAL |
trigger CHECK_ITEM src:3-8 |
| 15 | Trigger storico | AFTER INSERT CHECK_ITEM_HISTORY_INS → INSERT CHECK_HISTORY |
trigger CHECK_ITEM_HISTORY_INS src:3-6 |
Evidenza (INLINE)
Vedi la sezione evidence_markdown restituita dal worker (corpo evidenza con estratti di codice e sorgente DB).
Confidence
- Catena applicativa UI → Controller → (Remoting) → BL → DAL → SP: VERIFIED (codice letto riga per riga).
- SP → tabelle (
CHECK_ITEM,CHECK_STATE) e protocollo (CHECK_PROTOCOLFORMAT): VERIFIED (sorgenteUSER_SOURCE+USER_DEPENDENCIES). - Side effects trigger (
SEQ_CHECK_ITEM,CHECK_HISTORY): VERIFIED (sorgente trigger daUSER_SOURCE/USER_TRIGGERS). - Forward vs reverse: CONCORDI — il forward (INSERT su
CHECK_ITEM, id da OUT) coincide con il reverse (SP scriveCHECK_ITEM, trigger popolano id eCHECK_HISTORY).
Open questions
- Anomalia mapping BL (path attivo):
CheckItem_BL.Insert(dto, username)passaci.BuildingIDdue volte (CheckItem_BL.vb:95e:97); l'8° argomento del DAL èroomId, quindi la stanza ricevuta dalla SP (PROOMID) coincide con ilBuildingID. L'overload senza username (:204) passa correttamenteci.RoomID. Poiché la UI usa l'overload con username (:488), ilROOM_IDsalvato potrebbe essere errato. Da verificare se voluto o bug. DeleteHistoryByCheckID(21)inPage_Load(CheckItemDetail.ascx.vb:395-396): chiamata con id hard-coded eseguita a ogni caricamento pagina — sembra codice di debug residuo con effetto di scrittura (cancella storico del check id 21). Da confermare/rimuovere.CheckResult,LimitValue,DocumentID,ControllerID,TableName,IdElement,EffectiveCheckDatenon vengono valorizzati dalla scheda inInsert(): assumono i default del DTO. Confermare se è il comportamento atteso per la registrazione manuale.