Table of Contents

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.ascx del CheckCenter (editing interattivo da parte di un operatore). Backend Oracle INFOCAD_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 tabella CHECK_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_BL come oggetto .NET Remoting well-known (Start.vb:888).
  • Oracle INFOCAD_TEST38 — hub dati Check (procedure CHK_CREATECHECKITEM, CHK_GETNEWCHECKITEMPROTOCOL; tabelle CHECK_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)

  1. Operatore apre la scheda di una nuova verifica, compila protocollo/tipo/stato/posizione/data/nota/score e preme Salva.
  2. CheckItemDetail.ascx.vbbtnUpdate_Click (:415); essendo ID_DTO = 0 chiama Insert() (:419).
  3. Insert() (:461) costruisce un DTO CheckItem, popolando Protocol, RefModule (New Guid(ControlRefModule)), CheckType.ID_DTO, State.ID_DTO, DistrinctID, BuildingID, FloorID, RoomID, ExtimatedCheckDate, Note, Score (:465-486).
  4. Invoca il controller: checkItemCTRL.Insert(check, WS.SessionLogin.UserName) (:488).
  5. CheckItemController (istanziato con DaoActivate(enControllers.Ctrl_CheckItem), CheckItemController.vb:9) inoltra: Insert(dto, username) (:60) → DirectCast(Me.DAO, ICheckItem_BL).Insert(dto, username).
  6. .NET Remoting: Me.DAO è risolto da DAOFactory.CreateDAO come proxy remoto Activator.GetObject(GetType(ICheckItem_BL), CHANNEL://SERVERADDRESS/CheckItem_BL.rem) (DAOFactory.vb:9). Il tipo concreto CheckItem_BL è registrato lato server come WellKnownObjectMode.SingleCall (Start.vb:888). La chiamata attraversa quindi il confine di processo verso il Windows service.
  7. CheckItem_BL.Insert(dto, username) (CheckItem_BL.vb:88) fa il cast a CheckItem e chiama CheckDALFactory.GetCheckItemDAL.Insert(...) passando i campi del DTO + username (:90-108).
  8. CheckItem_DAL.Insert(...) (CheckItem_DAL.vb:282):
    • Genera il protocollo: aggiunge i 4 parametri OUT e chiama CHK_GETNEWCHECKITEMPROTOCOL (:310); compone sProtocol = CInt(PPROTOCOL).ToString(regex) & suffix (:312-315), poi ClearParameter() (:317).
    • Prepara ~20 OracleParameter di input (protocollo, refprotocol, refmod RAW 16 byte, checktype/district/building/floor/room/controller id, tablename, idelement, date, note, score, checkresult, limitvalue, docid, username) + PNEWINDEX OUT (:321-378).
    • Chiama dl.ExecuteNonQueryStoredProcedure("CHK_CREATECHECKITEM") (:380) e ritorna PNEWINDEX (nuovo id) (:382).
  9. 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 PNEWINDEX con STATE_ID = TMP_START_STATE, LAST_UPDATED_BY = PUSERNAME, LAST_UPDATE_DATE = SYSDATE (src:32-35).
  10. Trigger DB (side effects sincroni sull'INSERT):
    • CHECK_ITEM (BEFORE INSERT FOR EACH ROW): se ID_CHECK_ITEM è NULL assegna SEQ_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).
  11. Il DAL riporta il nuovo id fino alla UI; CheckItemDetail.Insert imposta Updated = (newID > 0) e, se > 0, ricarica il protocollo con GetProtocolByCheckIyemID(newID) (:491-492), fa RadGrid1.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 BL CheckItem_BL ospitato nel Windows service InfocadServer (endpoint well-known CheckItem_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 a Me.DAO (proxy remoting risolto da DAOFactory).
  • BL: Descor.Check.CheckBL.CheckItem_BL (CheckItem_BL.vb), Inherits MarshalByRefObject — mappa il DTO sui parametri e delega al DAL via CheckDALFactory.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 OUT PNEWINDEX; dl.Kill() nel Finally.
  • 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 iniziale OPEN (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 con RETURNING ID_CHECK_ITEM; VERIFIED su sorgente SP e su USER_DEPENDENCIES).
  • INFOCAD_TEST38.CHECK_HISTORY (INSERT indiretto — riga di storico creata dal trigger AFTER INSERT CHECK_ITEM_HISTORY_INS; VERIFIED su sorgente trigger).
  • INFOCAD_TEST38.SEQ_CHECK_ITEM (sequenzaNEXTVAL consumato 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 in Try/Catch con messaggio a video (:498-502).
  • Lato BL/DAL: nessuna validazione di dominio esplicita; eccezioni loggate con Descor.Infrastructure.LogManager.ExceptionLogger.LogException e ri-lanciate (CheckItem_DAL.vb:384-386).
  • Lato DB: lo stato iniziale è forzato a OPEN via lookup su CHECK_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 INSERT CHECK_ITEM).
  • Storico: nuova riga su CHECK_HISTORY con stato/utente/nota/data (trigger AFTER INSERT CHECK_ITEM_HISTORY_INS).
  • Protocollo: generato server-side da CHK_GETNEWCHECKITEMPROTOCOL (formato/regex/suffix da CHECK_PROTOCOLFORMAT) e ri-letto in UI post-insert.
  • Audit inline: LAST_UPDATED_BY = username, LAST_UPDATE_DATE = SYSDATE, stato = OPEN.
  • Nota: CheckItemDetail.Page_Load esegue incondizionatamente chkCTRL.DeleteHistoryByCheckID(21) (:395-396) — chiamata sospetta/di debug non correlata all'insert (vedi Open questions).

Percorsi alternativi / di errore

  • Update verifica esistente: ID_DTO > 0Update() (CheckItemDetail.ascx.vb:423) → CheckItemController.Update(dto, username)CheckItem_BL.Update (:170) → CheckItem_DAL.Update → SP CHK_UPDATECHECKITEM (CheckItem_DAL.vb:480). Il cambio di stato attiva il trigger UPDATE CHECK_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 con username = 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_ClickInsert() 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_ITEMSEQ_CHECK_ITEM.NEXTVAL trigger CHECK_ITEM src:3-8
15 Trigger storico AFTER INSERT CHECK_ITEM_HISTORY_INSINSERT 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 (sorgente USER_SOURCE + USER_DEPENDENCIES).
  • Side effects trigger (SEQ_CHECK_ITEM, CHECK_HISTORY): VERIFIED (sorgente trigger da USER_SOURCE/USER_TRIGGERS).
  • Forward vs reverse: CONCORDI — il forward (INSERT su CHECK_ITEM, id da OUT) coincide con il reverse (SP scrive CHECK_ITEM, trigger popolano id e CHECK_HISTORY).

Open questions

  1. Anomalia mapping BL (path attivo): CheckItem_BL.Insert(dto, username) passa ci.BuildingID due volte (CheckItem_BL.vb:95 e :97); l'8° argomento del DAL è roomId, quindi la stanza ricevuta dalla SP (PROOMID) coincide con il BuildingID. L'overload senza username (:204) passa correttamente ci.RoomID. Poiché la UI usa l'overload con username (:488), il ROOM_ID salvato potrebbe essere errato. Da verificare se voluto o bug.
  2. DeleteHistoryByCheckID(21) in Page_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.
  3. CheckResult, LimitValue, DocumentID, ControllerID, TableName, IdElement, EffectiveCheckDate non vengono valorizzati dalla scheda in Insert(): assumono i default del DTO. Confermare se è il comportamento atteso per la registrazione manuale.