Table of Contents

FLOW-RPT-001 — Salvataggio della definizione di un report XML (Report Builder) — Report

Flusso end-to-end di salvataggio (create) della definizione di un report XML del modulo Report / ReportCenter. Il reporting Infocad è prevalentemente in lettura (esecuzione di query e rendering); l'operazione di scrittura autonoma rappresentativa è il salvataggio della definizione di un report costruito dal Report Builder (query, layout, grafico, eventuale schedulazione). Path pilota: UserControl XmlProcedure.ascx (Report Builder interattivo). Backend Oracle INFOCAD_TEST38, accesso via stored procedure ODP.NET RPT_ADDXMLREPORT (nessun ORM). L'entità è persistita nella tabella RPT_XMLREPORTSOURCE.

  • Flow ID: FLOW-RPT-001
  • Repository: InfocadWeb (ASP.NET Web Forms, ReportCenterWeb, code-behind C#) + InfocadServer (ReportControllers/ReportManager, VB.NET)
  • Operazione WRITE rappresentativa: AddReportRPT_ADDXMLREPORT (INSERT su RPT_XMLREPORTSOURCE)
  • has_standalone_write: true (il dominio Report possiede un percorso di scrittura autonomo pulito: salvataggio definizione report)
  • Confidence complessiva: VERIFIED (catena UI → code-behind → controller → DAO → stored procedure, confermata su codice E su sorgente DB USER_SOURCE/USER_DEPENDENCIES/USER_TAB_COLUMNS)

Obiettivo di business

Consentire a un operatore del ReportCenter di creare (o aggiornare) la definizione di un report XML costruito interattivamente: testo della query SQL, connessione dati (RC/DEM/default), provider, layout di stampa, grafico, pivot ed eventuale schedulazione con salvataggio dati periodico. Al termine la definizione esiste nella tabella RPT_XMLREPORTSOURCE (una riga per ID_ACTION), con ID_REPORT surrogato generato da sequenza; se il report è schedulato viene inoltre creato un job Oracle DBMS_SCHEDULER con relativa tabella di appoggio.

Attori

  • Operatore ReportCenter (utente autenticato con applicazione ReportCenter o grant VIEW; la modifica delle azioni richiede grant INSCANC) — path interattivo Report Builder.
  • Oracle INFOCAD_TEST38 (hub reporting; procedure RPT_ADDXMLREPORT, RPT_CREATESCHEDULING; sequenza SEQ_RPT_XMLRPTSOURCE; trigger TRG_RPT_XMLREPORTSOURCE; sottosistema DBMS_SCHEDULER).

Trigger

Click sul pulsante Salva del Report Builder: evento btnSave_Click (XmlProcedure.ascx.cs:1412), che invoca SetData() (:1414).

Frontend entry point

  • Pagina host: ReportCenterWeb/ReportBuilderPage.aspx (ReportBuilderPage.aspx.cs, deriva da ReportCenterPortalPage); apre il builder via openXmlReportBuilder(actionID, mode) (ReportBuilderPage.aspx.cs:60).
  • UserControl builder: ReportCenterWeb/UserControls/XmlProcedure.ascx (+ Common/QueryBuilder.ascx per la query, Scheduler1 per la schedulazione, PivotBuilder1).
  • Gate di accesso: ReportCenterPortalPage verifica l'appartenenza all'applicazione ReportCenter o HasUserGrant(ReportSettings.VIEW) (ReportCenterPortalPage.cs:17); il tasto di editing azione è vincolato a HasUserGrant(ReportSettings.INSCANC) (ReportBuilderPage.aspx.cs:138).

Sequenza principale (main sequence)

  1. Operatore costruisce/modifica il report (query, layout, grafico, pivot, schedulazione) e preme Salva.
  2. XmlProcedure.ascx.csbtnSave_Click (:1412) → SetData() (:425) popola il DTO _report (XmlReport) dai campi UI: Title, Description, ConnectionName, QueryText, scheduling (Scheduled, ScheduleMode, ScheduleStart, ScheduleEmails, ScheduleDataReset), layout/chart/pivot (:429-541).
  3. Decisione create-vs-update lato web: ctrl.GetReport(_report.ActionID) (:548); se esiste → EditReport (:550), altrimenti → AddReport(WS.SessionLogin.UserName, _report) (:552); in caso di eccezione, fallback su AddReport (:558).
  4. XmlReportController.AddReport (XmlReportController.vb:44) inoltra al DAO: DirectCast(Me.DAO, IDAO_XmlReport).AddReport(username, rpt) (:46). Il DAO è risolto in New XmlReportController()DaoActivate(enControllers.Ctrl_XmlReport) (XmlReportController.vb:9) → DAOFactory.CreateDAO (DAOFactory.vb:25) che usa .NET Remoting (Activator.GetObject(GetType(IDAO_XmlReport), … Service_XmlReport), DAOFactory.vb:26) verso il servizio ReportManager.
  5. DAO_XmlReport.AddReport (DAO_XmlReport.vb:179) prepara i parametri PIDACTION=ActionID, PCONNECTION, PPROVIDER, PXML (CLOB = rpt.XmlString, XML serializzato in XmlReport.vb:831), PIDOUT (OUT NUMBER) ed esegue RPT_ADDXMLREPORT via dl.ExecuteNonQueryStoredProcedure("RPT_ADDXMLREPORT", False) (:200).
  6. Oracle RPT_ADDXMLREPORT (INFOCAD_TEST38): INSERT INTO RPT_XMLREPORTSOURCE (ID_ACTION, CONNECTION, PROVIDER, XML) VALUES (…) RETURNING ID_ACTION INTO PIDOUT (src:9-12). Il trigger TRG_RPT_XMLREPORTSOURCE BEFORE INSERT valorizza ID_REPORT da SEQ_RPT_XMLRPTSOURCE.NEXTVAL se NULL (trg:6-13).
  7. Se rpt.Scheduled è TRUE: DAO_XmlReport istanzia DAO_Scheduler e chiama CreateScheduling("XMLRPT_" & ActionID, QueryText, ScheduleMode, ScheduleDataReset, ScheduleStart) (DAO_XmlReport.vb:202-205) → RPT_CREATESCHEDULING (DAO_Scheduler.vb:29): droppa/crea la tabella di appoggio RPT_SCHED_XMLRPT_<ActionID> (CREATE TABLE … AS (SELECT * FROM (query)), src:16-21) e crea program/schedule/job via DBMS_SCHEDULER (src:26-33).
  8. Il DAO legge PIDOUT (OracleDecimal.ToInt32) e lo restituisce come retVal (DAO_XmlReport.vb:207); il controller lo propaga al code-behind.
  9. Post-salvataggio: btnSave_Click risolve l'azione (ActionsController.GetAction) e reindirizza alla pagina di visualizzazione del report (XmlProcedure.ascx.cs:1419-1430).

API / service

  • Path interattivo: postback ASP.NET Web Forms diretto sul builder (nessun SOAP/WCF sul salvataggio).
  • Layer server: invocazione dei controller Report tramite .NET Remoting (canale configurato in SettingsManager.CHANNEL/SERVERADDRESS, dictionary Service_XmlReport), non in-process (DAOFactory.vb:26) — diversamente dai controller Property (in-process).

Backend

  • UI/Code-behind: ReportBuilderPage.aspx.cs (host), UserControls/XmlProcedure.ascx.cs (builder).
  • DTO: Descor.BI.ReportSharedObjects.XmlReport (InfocadServer/ReportSharedObjects/XmlReport.vb) — serializzazione XmlString (:831).
  • Controller server: Descor.BI.ReportControllers.XmlReportController (InfocadServer/ReportControllers/XmlReportController.vb), deriva da Ctrl_Base, inoltra al DAO.
  • DAO: Descor.BI.ReportManager.DAO_XmlReport (InfocadServer/ReportManager/DAO_XmlReport.vb) e DAO_Scheduler (.../DAO_Scheduler.vb), base DAO_Base (QueryExecutionCheck).
  • Pattern DAL: Dim dl As New DataLayer(My.Settings.ConnectionName)dl.Parameters.Add(OracleParameter…)dl.ExecuteNonQueryStoredProcedure("RPT_ADDXMLREPORT", False); identity/ritorno via parametro OUT PIDOUT.

Query / stored procedure

Passo Stored procedure (Oracle) Chiamata da (DAL)
Insert definizione report (INSERT su RPT_XMLREPORTSOURCE, OUT PIDOUT) INFOCAD_TEST38.RPT_ADDXMLREPORT DAO_XmlReport.vb:200
Update definizione report INFOCAD_TEST38.RPT_EDITXMLREPORT DAO_XmlReport.vb:160
Cancellazione definizione report INFOCAD_TEST38.RPT_DELETEXMLREPORT DAO_XmlReport.vb:234
Creazione schedulazione (DDL + DBMS_SCHEDULER) INFOCAD_TEST38.RPT_CREATESCHEDULING DAO_Scheduler.vb:29
Cancellazione schedulazione INFOCAD_TEST38.RPT_DELETESCHEDULING DAO_Scheduler.vb:76
Load definizione report (READ-ONLY) query diretta SELECT * FROM RPT_XMLREPORTSOURCE WHERE ID_ACTION=… DAO_XmlReport.vb:26

Tabelle lette (read)

  • INFOCAD_TEST38: RPT_XMLREPORTSOURCE (verifica esistenza pre-insert via XmlReportController.GetReport, DAO_XmlReport.vb:26); USER_TABLES (verifica tabella di appoggio in RPT_CREATESCHEDULING, src:11).

Tabelle modificate (write)

  • INFOCAD_TEST38: RPT_XMLREPORTSOURCE (RW — tabella-radice della definizione report: INSERT con RETURNING ID_ACTION; VERIFIED su sorgente USER_SOURCE e su USER_TAB_COLUMNS colonne ID_REPORT, ID_ACTION, CONNECTION, PROVIDER, XML).
  • SEQ_RPT_XMLRPTSOURCE (sequenza — NEXTVAL per ID_REPORT, consumata dal trigger).
  • Se schedulato: tabella dinamica RPT_SCHED_XMLRPT_<ActionID> (DDL CREATE/DROP TABLE) e oggetti DBMS_SCHEDULER (PRG_…, SCHED_…, JOB_…) creati da RPT_CREATESCHEDULING (src:16-33).

(La tabella RPT_XMLREPORTSOURCE è confermata come dipendenza statica di RPT_ADDXMLREPORT in USER_DEPENDENCIES; RPT_CREATESCHEDULING dipende dal synonym DBMS_SCHEDULER e usa DDL dinamico per le tabelle RPT_SCHED_*, che non compaiono nelle dipendenze statiche.)

Validazione

  • Lato UI/pagina: gate applicazione ReportCenter o grant VIEW (ReportCenterPortalPage.cs:17); editing azioni vincolato a grant INSCANC (ReportBuilderPage.aspx.cs:138).
  • Lato business (esecuzione query, non salvataggio): DAO_Base.QueryExecutionCheck (DAO_Base.vb:38) blocca query contenenti insert/update/delete/alter/drop/exec/create — applicato nei path di esecuzione/anteprima (GetReport :46, ExecuteNonQuery/TestQuery), NON al momento del salvataggio della definizione: AddReport persiste il testo query come XML senza validarne il contenuto (vedi Open questions).
  • Lato DB: trigger TRG_RPT_XMLREPORTSOURCE impedisce la modifica di ID_REPORT in UPDATE (RAISE_APPLICATION_ERROR(-20000, …), trg:15-23).

Side effects

  • Assegnazione ID_REPORT surrogato da SEQ_RPT_XMLRPTSOURCE (trigger).
  • Se schedulato: creazione tabella di appoggio RPT_SCHED_XMLRPT_<ActionID> e di un job Oracle abilitato (DBMS_SCHEDULER.CREATE_JOB … enabled => TRUE, RPT_CREATESCHEDULING src:33), che materializza periodicamente il dataset; invio email programmato gestito dallo scheduler (ReportManager/Scheduler/ReportEmailSender.vb) sulla base di ScheduleEmails.
  • Salvataggio logo tenant su filesystem/SetPrintLogo se caricata immagine (XmlProcedure.ascx.cs:568-577).

Percorsi alternativi / di errore

  • Aggiornamento definizione: report già esistente → XmlReportController.EditReport (XmlReportController.vb:36) → DAO_XmlReport.EditReport (:141) → RPT_EDITXMLREPORT (:160), con ricostruzione/eliminazione schedulazione (EditScheduling/DeleteScheduling, :162-168).
  • Cancellazione: DAO_XmlReport.DeleteReport (:220) → RPT_DELETEXMLREPORT (:234), previa DeleteScheduling se schedulato.
  • Pivot associato: se chkPivot attivo, prima dell'insert report viene creato/aggiornato il pivot via PivotController.AddReport/EditReport (XmlProcedure.ascx.cs:531-533) → RPT_ADDPIVOT/RPT_EDITPIVOT.
  • Errore DB: eccezione loggata da LogManager.ExceptionLogger.LogException e ri-sollevata (DAO_XmlReport.vb:211-213); il code-behind intercetta l'eccezione della EditReport e ritenta con AddReport (XmlProcedure.ascx.cs:554-558).

Diagramma di sequenza

sequenceDiagram
    actor Op as Operatore ReportCenter
    participant UI as XmlProcedure.ascx (ReportBuilderPage)
    participant CB as XmlProcedure.ascx.cs (btnSave_Click/SetData)
    participant XC as XmlReportController.AddReport
    participant DAO as DAO_XmlReport.AddReport
    participant SCH as DAO_Scheduler.CreateScheduling
    participant DB as Oracle INFOCAD_TEST38

    Op->>UI: costruisce report + click Salva
    UI->>CB: btnSave_Click -> SetData()
    CB->>CB: popola _report (XmlReport) dai campi UI
    CB->>XC: GetReport(ActionID) [test esistenza]
    alt non esiste (create)
        CB->>XC: AddReport(user, _report)
        XC->>DAO: AddReport(user, rpt) [.NET Remoting]
        DAO->>DB: RPT_ADDXMLREPORT (PXML CLOB, OUT PIDOUT)
        DB->>DB: INSERT RPT_XMLREPORTSOURCE + TRG (ID_REPORT da SEQ)
        opt rpt.Scheduled
            DAO->>SCH: CreateScheduling("XMLRPT_"&ActionID, ...)
            SCH->>DB: RPT_CREATESCHEDULING (CREATE TABLE RPT_SCHED_* + DBMS_SCHEDULER JOB)
        end
        DB-->>DAO: PIDOUT
    else esiste (update)
        CB->>XC: EditReport(_report)
        XC->>DAO: EditReport -> RPT_EDITXMLREPORT
    end
    CB->>UI: Response.Redirect(pagina report)

Matrice di tracciabilità (file:riga)

Layer Artefatto Evidenza
Trigger UI btnSave_Click InfocadWeb/…/ReportCenterWeb/UserControls/XmlProcedure.ascx.cs:1412
Raccolta dati SetData() XmlProcedure.ascx.cs:425
Create-vs-update GetReport/AddReport XmlProcedure.ascx.cs:548,552,558
Host page + grant ReportBuilderPage ReportBuilderPage.aspx.cs:60,138; ReportCenterPortalPage.cs:17
Controller XmlReportController.AddReport InfocadServer/ReportControllers/XmlReportController.vb:44
DAO factory (Remoting) DAOFactory.CreateDAO InfocadServer/ReportControllers/DAOFactory.vb:25-26
DAO write DAO_XmlReport.AddReport InfocadServer/ReportManager/DAO_XmlReport.vb:179,200,204,207
DAO scheduling DAO_Scheduler.CreateScheduling InfocadServer/ReportManager/DAO_Scheduler.vb:29
DTO serializzazione XmlReport.XmlString InfocadServer/ReportSharedObjects/XmlReport.vb:831
Validazione query DAO_Base.QueryExecutionCheck InfocadServer/ReportManager/DAO_Base.vb:38
Stored procedure RPT_ADDXMLREPORT Oracle USER_SOURCE (INSERT RPT_XMLREPORTSOURCE RETURNING)
Trigger DB TRG_RPT_XMLREPORTSOURCE Oracle USER_SOURCE/USER_TRIGGERS (ID_REPORT da SEQ_RPT_XMLRPTSOURCE)
Stored procedure RPT_CREATESCHEDULING Oracle USER_SOURCE (CREATE TABLE + DBMS_SCHEDULER)

Evidenza (INLINE)

Vedi la sezione dedicata restituita come evidence_markdown.

Confidence

VERIFIED per l'intera catena UI → code-behind → controller → DAO → stored procedure:

  • Codice sorgente letto direttamente (web C# + server VB.NET).
  • Sorgente stored procedure e trigger letti da Oracle USER_SOURCE/USER_TRIGGERS.
  • Dipendenze confermate da USER_DEPENDENCIES; struttura tabella da USER_TAB_COLUMNS.
  • Forward e reverse concordano (RPT_ADDXMLREPORT scrive solo RPT_XMLREPORTSOURCE ed è chiamata solo da DAO_XmlReport.AddReport).

Open questions

  1. PIDOUT restituisce ID_ACTION, non ID_REPORT: RPT_ADDXMLREPORT fa RETURNING ID_ACTION INTO PIDOUT, quindi il valore restituito al chiamante è l'ID_ACTION in input, non il surrogato ID_REPORT generato dal trigger SEQ_RPT_XMLRPTSOURCE.NEXTVAL. Probabilmente intenzionale (chiave logica = azione), ma il nome PIDOUT/retVal è fuorviante.
  2. Nessuna protezione anti-duplicato a livello DB: l'unicità "una definizione per ID_ACTION" è garantita solo dal controllo applicativo GetReport lato web; non è stata verificata l'esistenza di un vincolo UNIQUE su ID_ACTION in RPT_XMLREPORTSOURCE.
  3. QueryExecutionCheck non applicato al salvataggio: il testo della query viene persistito come XML senza il filtro anti-DML che è invece applicato nei path di esecuzione — potenziale superficie di rischio se la query viene poi eseguita con privilegi elevati (da approfondire con la sicurezza).
  4. Modello di deployment: DAOFactory usa .NET Remoting verso il servizio ReportManager; non è stato verificato se in produzione il servizio sia co-locato (loopback) o remoto.