BR-RPT — Regole di business del dominio Report (ReportCenter / Report Builder)
Registro delle regole di business del dominio Report di Infocad (Descor), ancorato al flusso
FLOW-RPT-001(salvataggio della definizione di un report XML) e verificato sul codice sorgente (web C# + server VB.NET) e sul sorgente Oracle (USER_SOURCE,USER_TRIGGERS,USER_CONSTRAINTS,USER_CONS_COLUMNS).Sistema: Infocad (Descor) — Oracle
INFOCAD_TEST38, ASP.NET Web Forms (code-behind C#) + InfocadServer (VB.NET) via .NET Remoting (Controller → DAO), nessun ORM.Ambito: salvataggio/aggiornamento/cancellazione della definizione di un report XML costruito dal Report Builder, gestione della schedulazione (
DBMS_SCHEDULER) e del pivot associato. Il reporting è prevalentemente in lettura; le regole coprono la scrittura autonoma della definizione più gli aspetti di validazione/esecuzione query rilevanti per la sicurezza.
Legenda
- Enforcement:
UI(solo web/code-behind) ·BL(business layer VB.NET) ·DB(Oracle: procedura/trigger/vincolo) ·mixed. - Confidence:
VERIFIED(codice + sorgente DB concordanti) ·SUPPORTED(una sola fonte diretta) ·INFERRED(interpretazione). - Flag: UI-only (grant non ri-verificati da Remoting/WCF — pattern TD-008), DB-only, magic number, date logic, hidden flag, defect probabile, security.
Tabella riepilogativa
| ID | Regola (sintesi) | Tipo | Enforcement | Confidence | Flag |
|---|---|---|---|---|---|
| BR-RPT-001 | Accesso al ReportCenter: appartenenza all'applicazione ReportCenter o grant VIEW |
access-control | UI | VERIFIED | UI-only |
| BR-RPT-002 | Editing delle azioni report subordinato al grant INSCANC |
access-control | UI | VERIFIED | UI-only |
| BR-RPT-003 | I grant VIEW/INSCANC NON sono ri-verificati dai controller Report invocati via Remoting |
access-control | UI | SUPPORTED | UI-only, defect probabile |
| BR-RPT-004 | Create-vs-update deciso lato applicazione: report esistente per ID_ACTION → Edit, altrimenti → Add |
workflow | mixed | VERIFIED | — |
| BR-RPT-005 | Eccezione su test/EditReport → fallback su AddReport |
error-handling | UI | VERIFIED | defect probabile |
| BR-RPT-006 | Nessun vincolo UNIQUE su ID_ACTION: PK su ID_REPORT surrogato |
data-integrity | DB | VERIFIED | DB-only, defect probabile |
| BR-RPT-007 | ID_REPORT generato dal trigger da SEQ_RPT_XMLRPTSOURCE.NEXTVAL se NULL in INSERT |
data-integrity | DB | VERIFIED | — |
| BR-RPT-008 | RPT_ADDXMLREPORT restituisce ID_ACTION (input), non ID_REPORT surrogato |
data-integrity | DB | VERIFIED | defect probabile |
| BR-RPT-009 | Protezione "non cambiare ID_REPORT" nel trigger è codice morto (trigger solo INSERT/DELETE) |
data-integrity | DB | VERIFIED | DB-only, defect probabile |
| BR-RPT-010 | Il testo query salvato NON è validato da QueryExecutionCheck al salvataggio |
validation | BL | VERIFIED | security |
| BR-RPT-011 | QueryExecutionCheck blocca query con insert/update/delete/alter/drop/exec/create |
validation | BL | VERIFIED | magic number, security |
| BR-RPT-012 | Sorgente dati vincolata a RC / DEM / default (mapping connection string) |
config | BL | VERIFIED | magic number |
| BR-RPT-013 | Report schedulato → schedulazione con nome XMLRPT_<ActionID> |
workflow | BL | VERIFIED | — |
| BR-RPT-014 | RPT_CREATESCHEDULING: drop+CTAS tabella RPT_SCHED_<name> + job DBMS_SCHEDULER enabled=>TRUE |
workflow | DB | VERIFIED | side effect |
| BR-RPT-015 | Reset dati: PRESETDATA=0 → solo INSERT (accodamento); <>0 → DELETE+INSERT |
workflow | mixed | VERIFIED | hidden flag |
| BR-RPT-016 | Esistenza tabella d'appoggio verificata con TABLESPACE_NAME=USER (confronto errato) |
data-integrity | DB | VERIFIED | DB-only, defect probabile |
| BR-RPT-017 | ScheduleMode HOURLY → invio email disabilitato (ScheduleEmails svuotato) |
workflow | UI | VERIFIED | date logic |
| BR-RPT-018 | ScheduleMode serializzato come RRULE DBMS_SCHEDULER; ore/giorni codificati come bitmask |
config | mixed | VERIFIED | magic number |
| BR-RPT-019 | Default ora esecuzione MONTHLY/WEEKLY/DAILY = 2 (02:00) se non specificata | config | mixed | VERIFIED | magic number |
| BR-RPT-020 | EditReport ricostruisce la schedulazione (Edit→drop+create, non-Sched→delete) |
workflow | BL | VERIFIED | — |
| BR-RPT-021 | DeleteReport: elimina prima la schedulazione, poi il report per ID_REPORT |
workflow | mixed | VERIFIED | — |
| BR-RPT-022 | Pivot associato salvato/aggiornato prima del report; PivotGridID=ActionID (o 0) |
workflow | mixed | VERIFIED | — |
| BR-RPT-023 | Pivot su report XML: Query fissata al literal "XMLREPORT" |
config | UI | VERIFIED | magic number |
| BR-RPT-024 | RPT_PIVOTSOURCE ha due trigger che assegnano ID_PIVOT da sequenze diverse |
data-integrity | DB | VERIFIED | DB-only, defect probabile |
| BR-RPT-025 | Vincoli NOT NULL su RPT_PIVOTSOURCE: ID_ACTION, QUERY, COLUMNS, ROWS, SCHEDULED |
data-integrity | DB | VERIFIED | DB-only |
| BR-RPT-026 | Serializzazione aggregati pivot incoerente tra Add (Field) ed Edit (ToString()) |
data-integrity | BL | VERIFIED | defect probabile |
| BR-RPT-027 | Logo tenant salvato su filesystem ~/Logos/rpt_logo_<tenant>.gif + SetPrintLogo |
side-effect | UI | VERIFIED | side effect |
| BR-RPT-028 | Schema/owner delle query determinato da Membership.Provider.ApplicationName (multi-tenant) |
config | BL | VERIFIED | — |
| BR-RPT-029 | Funzioni standard @USER/@ROLES/@YEAR[±N] (N da -10 a +10) sostituite a runtime |
business-logic | BL | VERIFIED | magic number, date logic |
| BR-RPT-030 | Parametri e funzioni iniettati per concatenazione stringa (solo raddoppio apostrofi) | validation | BL | VERIFIED | security, defect probabile |
| BR-RPT-031 | Report schedulato: anteprima/lettura dalla tabella materializzata RPT_SCHED_XMLRPT_<ActionID> |
workflow | BL | VERIFIED | — |
Dettaglio per regola
BR-RPT-001 — Gate di accesso al ReportCenter
Statement: L'accesso alle pagine del ReportCenter richiede che l'utente appartenga all'applicazione ReportCenter oppure possieda il grant VIEW; in caso contrario viene reindirizzato.
Tipo: access-control · Enforcement: UI · Confidence: VERIFIED · Flag: UI-only.
Evidenza: ReportCenterWeb/Classes/ReportCenterPortalPage.cs:17 — if (!WS.SessionProfile.Applications.Contains(...ReportCenter) && !HasUserGrant((int)...ReportSettings.VIEW)) → redirect.
BR-RPT-002 — Editing azioni report vincolato a INSCANC
Statement: Il comando di editing dell'azione report (apertura del builder in modifica) è visibile/abilitato solo con grant INSCANC.
Tipo: access-control · Enforcement: UI · Confidence: VERIFIED · Flag: UI-only.
Evidenza: ReportCenterWeb/ReportBuilderPage.aspx.cs:138 — btnEditAction.Visible = HasUserGrant((int)ReportCenterBaseControl.ReportSettings.INSCANC);
BR-RPT-003 — Grant non ri-verificati oltre il web layer (TD-008)
Statement: I grant VIEW/INSCANC sono controllati solo nel layer web. I controller server (XmlReportController, PivotController) sono attivati via .NET Remoting (DAOFactory) ed espongono AddReport/EditReport/DeleteReport senza ri-verificare i grant utente: chi raggiunge l'endpoint Remoting può scrivere la definizione bypassando i controlli UI.
Tipo: access-control · Enforcement: UI · Confidence: SUPPORTED · Flag: UI-only, defect probabile.
Evidenza: ReportControllers/XmlReportController.vb:8-10,44-46 (nessun check grant, delega diretta al DAO); ReportControllers/DAOFactory.vb:25-26 (Remoting Activator.GetObject). Pattern coerente con TD-008.
BR-RPT-004 — Decisione create-vs-update applicativa
Statement: Al salvataggio, il code-behind interroga GetReport(ActionID): se il report esiste chiama EditReport, altrimenti AddReport. La scelta è puramente applicativa (non c'è UPSERT lato DB).
Tipo: workflow · Enforcement: mixed (UI decide, BL/DB eseguono) · Confidence: VERIFIED.
Evidenza: XmlProcedure.ascx.cs:548-552; DAO_XmlReport.vb:20-56 (GetReport), :179 (AddReport), :141 (EditReport).
BR-RPT-005 — Fallback su AddReport in caso di eccezione
Statement: Se il blocco GetReport/EditReport solleva un'eccezione, questa viene loggata e il salvataggio ripiega comunque su AddReport. Combinato con l'assenza di vincolo UNIQUE (BR-RPT-006), un errore transitorio su EditReport può generare una definizione duplicata per lo stesso ID_ACTION.
Tipo: error-handling · Enforcement: UI · Confidence: VERIFIED · Flag: defect probabile.
Evidenza: XmlProcedure.ascx.cs:554-558 — catch(Exception ex){ ...CreateError(...); ctrl.AddReport(WS.SessionLogin.UserName, _report); }.
BR-RPT-006 — Nessun UNIQUE su ID_ACTION
Statement: RPT_XMLREPORTSOURCE ha PK su ID_REPORT (surrogato) e solo un NOT NULL su ID_ACTION; non esiste vincolo UNIQUE su ID_ACTION. L'unicità "una definizione per azione" è garantita solo dal controllo applicativo GetReport.
Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED · Flag: DB-only, defect probabile.
Evidenza: USER_CONSTRAINTS/USER_CONS_COLUMNS: PK_RPT_XMLREPORTSOURCE_ID_REPO (P) su ID_REPORT; SYS_C001716674 (C) "ID_ACTION" IS NOT NULL. Risolve la Open question #2 di FLOW-RPT-001.
BR-RPT-007 — Generazione ID_REPORT da sequenza (trigger)
Statement: Il trigger TRG_RPT_XMLREPORTSOURCE BEFORE INSERT valorizza :new.ID_REPORT da SEQ_RPT_XMLRPTSOURCE.NEXTVAL quando è NULL.
Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED.
Evidenza: USER_TRIGGERS.TRG_RPT_XMLREPORTSOURCE — IF INSERTING THEN IF (:new.ID_REPORT IS NULL) THEN SELECT SEQ_RPT_XMLRPTSOURCE.NEXTVAL INTO :new.ID_REPORT FROM dual;.
BR-RPT-008 — PIDOUT restituisce ID_ACTION, non ID_REPORT
Statement: RPT_ADDXMLREPORT esegue ... RETURNING ID_ACTION INTO PIDOUT: il valore restituito al chiamante (retVal) è l'ID_ACTION di input, non il surrogato ID_REPORT. Naming (PIDOUT/retVal) fuorviante.
Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED · Flag: defect probabile.
Evidenza: USER_SOURCE.RPT_ADDXMLREPORT — VALUES (...) RETURNING ID_ACTION INTO PIDOUT;; consumo in DAO_XmlReport.vb:207. Risolve la Open question #1 di FLOW-RPT-001. Stesso pattern in RPT_ADDPIVOT.
BR-RPT-009 — Protezione anti-modifica ID_REPORT è codice morto
Statement: Il trigger TRG_RPT_XMLREPORTSOURCE è definito BEFORE INSERT OR DELETE (non UPDATE), ma il corpo contiene un ramo IF UPDATING ... RAISE_APPLICATION_ERROR(-20000, ...) che non può mai attivarsi. La protezione dichiarata contro la modifica di ID_REPORT in UPDATE è di fatto inefficace.
Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED · Flag: DB-only, defect probabile.
Evidenza: USER_TRIGGERS.TRG_RPT_XMLREPORTSOURCE — trigger_type = BEFORE EACH ROW, triggering_event = INSERT OR DELETE; corpo con ramo IF UPDATING. Corregge la sezione "Validazione lato DB" di FLOW-RPT-001. Analogo per i trigger di RPT_PIVOTSOURCE.
BR-RPT-010 — Query non validata al salvataggio
Statement: Il testo della query viene serializzato dentro XmlString e persistito da AddReport/EditReport senza applicare QueryExecutionCheck. Il filtro anti-DML è applicato solo nei percorsi di esecuzione/anteprima (GetReport, ExecuteQuery, ExecuteNonQuery, TestQuery).
Tipo: validation · Enforcement: BL · Confidence: VERIFIED · Flag: security.
Evidenza: DAO_XmlReport.vb:179-200 (AddReport: nessun check); :46 (GetReport applica il check in lettura), :300,:358,:444 (check in esecuzione). Coerente con la Open question #3 di FLOW-RPT-001.
BR-RPT-011 — Blacklist anti-DML di QueryExecutionCheck
Statement: QueryExecutionCheck rifiuta (ritorna False) le query che contengono una delle stringhe insert , update , delete , alter , drop , exec , create (match case-insensitive su substring con spazio finale). È una blacklist ingenua: non copre commenti, ;, merge, truncate, né varianti senza spazio.
Tipo: validation · Enforcement: BL · Confidence: VERIFIED · Flag: magic number, security.
Evidenza: DAO_Base.vb:38-53.
BR-RPT-012 — Sorgente dati: RC / DEM / default
Statement: La connessione del report è vincolata a tre valori logici: "RC" → RequestConnectionName, "DEM" → DEMConnectionName, qualsiasi altro/vuoto → ConnectionName (Infocad). Il mapping è applicato sia in lettura definizione sia in esecuzione.
Tipo: config · Enforcement: BL · Confidence: VERIFIED · Flag: magic number (literal RC/DEM).
Evidenza: DAO_XmlReport.vb:33-41 (GetReport), :289-297 (ExecuteNonQuery), :461-468 (ExecuteQuery).
BR-RPT-013 — Naming della schedulazione XMLRPT_
Statement: Se rpt.Scheduled è TRUE, dopo l'insert della definizione viene creata la schedulazione con chiave "XMLRPT_" & ActionID; gli oggetti Oracle derivati sono RPT_SCHED_XMLRPT_<ActionID>, PRG_..., SCHED_..., JOB_....
Tipo: workflow · Enforcement: BL · Confidence: VERIFIED.
Evidenza: DAO_XmlReport.vb:202-205. (Pivot usa il prefisso PVTRPT_: DAO_Pivot.vb:264.)
BR-RPT-014 — RPT_CREATESCHEDULING: CTAS + job abilitato
Statement: RPT_CREATESCHEDULING (a) droppa la tabella d'appoggio RPT_SCHED_<name> se presente, (b) la ricrea con CREATE TABLE ... AS (SELECT * FROM (<query>)), (c) crea program/schedule/job DBMS_SCHEDULER con enabled => TRUE (il job parte immediatamente, senza scadenza — end_date NULL). La tabella materializzata è quindi sempre creata al momento del salvataggio.
Tipo: workflow · Enforcement: DB · Confidence: VERIFIED · Flag: side effect.
Evidenza: USER_SOURCE.RPT_CREATESCHEDULING (CTAS + DBMS_SCHEDULER.CREATE_PROGRAM/CREATE_SCHEDULE(...,SYSTIMESTAMP,PMODE,NULL)/CREATE_JOB(...,enabled=>TRUE)); chiamata da DAO_Scheduler.vb:29.
BR-RPT-015 — Semantica reset dati (PRESETDATA)
Statement: Il flag resetdata (booleano UI) è convertito in PRESETDATA (SMALLINT). Nel job: PRESETDATA=0 → il program esegue solo INSERT (accodamento incrementale dei dati); PRESETDATA<>0 → il program esegue DELETE + INSERT (azzeramento e ricarica). La checkbox "reset dati" attiva quindi la modalità DELETE+INSERT.
Tipo: workflow · Enforcement: mixed · Confidence: VERIFIED · Flag: hidden flag.
Evidenza: DAO_Scheduler.vb:22 (Convert.ToInt16(resetdata)); USER_SOURCE.RPT_CREATESCHEDULING (IF PRESETDATA = 0 THEN ...INSERT... ELSE ...DELETE...; INSERT...).
BR-RPT-016 — Verifica esistenza tabella con TABLESPACE_NAME=USER (bug)
Statement: Sia RPT_CREATESCHEDULING sia RPT_DELETESCHEDULING verificano l'esistenza della tabella d'appoggio con ... WHERE table_name=:1 AND TABLESPACE_NAME=USER. USER è il nome dello schema corrente, mentre TABLESPACE_NAME è il tablespace: il confronto è quasi sempre falso, quindi il DROP TABLE viene saltato anche quando la tabella esiste. Conseguenza: al secondo salvataggio schedulato la CREATE TABLE può fallire con "name is already used by an existing object" (a meno che il tablespace coincida col nome utente).
Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED · Flag: DB-only, defect probabile.
Evidenza: USER_SOURCE.RPT_CREATESCHEDULING e RPT_DELETESCHEDULING — EXECUTE IMMEDIATE 'SELECT COUNT(TABLE_NAME) FROM user_tables WHERE table_name=:1 AND TABLESPACE_NAME=USER' ....
BR-RPT-017 — HOURLY disabilita l'invio email
Statement: Se la modalità di schedulazione contiene HOURLY, l'invio del report via email è disabilitato: ScheduleEmails è forzato a stringa vuota lato code-behind e i controlli destinatari sono disabilitati nell'UI.
Tipo: workflow · Enforcement: UI · Confidence: VERIFIED · Flag: date logic.
Evidenza: XmlProcedure.ascx.cs:456-459 (if (ScheduleMode.IndexOf("HOURLY"...) < 0) ScheduleEmails = ...; else ScheduleEmails = string.Empty;); Scheduler.ascx.cs:164-171 (disabilita recpAjax per HOURLY).
BR-RPT-018 — ScheduleMode come RRULE DBMS_SCHEDULER con bitmask
Statement: ProcessScheduleMode genera la stringa repeat_interval per DBMS_SCHEDULER: FREQ=HOURLY;BYMINUTE=..., FREQ=DAILY;BYHOUR=..., FREQ=WEEKLY;BYDAY=...;BYHOUR=..., FREQ=MONTHLY;BYMONTHDAY=...;BYHOUR=.... Ore e giorni sono codificati come bitmask a potenze di 2: DaysOfWeekEnum (Lun=1, Mar=2, Mer=4, ... Dom=64), TimeOfDayEnum (H1=1, H2=2, ... H24=8388608). Per DAILY l'ora è passata come Math.Pow(2, ora-1) e ri-decodificata bit a bit.
Tipo: config · Enforcement: mixed · Confidence: VERIFIED · Flag: magic number.
Evidenza: Scheduler.ascx.cs:303-341 (ProcessScheduleMode; Math.Pow(2, hours-1) :311); SchedulerUtils.vb:12-47 (enum bitmask), :152-230 (CreateDaily), :59-142 (CreateMonthly/Weekly), :309-310 (CreateHourly).
BR-RPT-019 — Ora di esecuzione di default = 2 (02:00)
Statement: In assenza di ora selezionata, l'ora di esecuzione di default è 2 (02:00), sia lato code-behind MONTHLY (dayHour = 2) sia come parametro opzionale ExecTime = 2 in CreateMonthly/CreateWeekly.
Tipo: config · Enforcement: mixed · Confidence: VERIFIED · Flag: magic number.
Evidenza: Scheduler.ascx.cs:334 (int dayHour = 2;); SchedulerUtils.vb:59 (Optional ExecTime As Integer = 2), :79, :118.
BR-RPT-020 — EditReport ricostruisce la schedulazione
Statement: EditReport (con rebuildSchedule=True, default) esegue l'UPDATE della definizione (RPT_EDITXMLREPORT per ID_REPORT) e poi: se Scheduled → EditScheduling (drop completo + ricreazione di tabella/job); altrimenti → DeleteScheduling. La modifica di una query schedulata ricrea sempre la tabella materializzata.
Tipo: workflow · Enforcement: BL · Confidence: VERIFIED.
Evidenza: DAO_XmlReport.vb:141-170; RPT_EDITXMLREPORT (USER_SOURCE, UPDATE WHERE ID_REPORT = PIDREPORT); DAO_Scheduler.vb:51-58 (EditScheduling = Delete + Create).
BR-RPT-021 — DeleteReport ordina schedulazione poi definizione
Statement: DeleteReport elimina prima la schedulazione (se Scheduled, via DeleteScheduling → RPT_DELETESCHEDULING) e poi la definizione con RPT_DELETEXMLREPORT per ID_REPORT.
Tipo: workflow · Enforcement: mixed · Confidence: VERIFIED.
Evidenza: DAO_XmlReport.vb:220-234; RPT_DELETEXMLREPORT (USER_SOURCE, DELETE ... WHERE ID_REPORT = PIDREPORT).
BR-RPT-022 — Pivot associato salvato prima del report
Statement: Se la checkbox pivot è attiva, prima di persistere il report viene creato/aggiornato il pivot associato (PivotController.AddReport/EditReport → RPT_ADDPIVOT/RPT_EDITPIVOT), con _report.PivotGridID = ActionID; se disattiva PivotGridID = 0. Il pivot condivide ID_ACTION e ConnectionName del report.
Tipo: workflow · Enforcement: mixed · Confidence: VERIFIED.
Evidenza: XmlProcedure.ascx.cs:491-541; DAO_Pivot.vb:200-267 (Add), :124-198 (Edit); RPT_ADDPIVOT/RPT_EDITPIVOT (USER_SOURCE).
BR-RPT-023 — Query del pivot su report XML fissata a "XMLREPORT"
Statement: Quando il pivot è associato a un report XML, il campo Query del pivot è impostato al literal "XMLREPORT" (segnaposto che indica che la sorgente è il dataset del report, non una query autonoma).
Tipo: config · Enforcement: UI · Confidence: VERIFIED · Flag: magic number.
Evidenza: XmlProcedure.ascx.cs:508 — _pivot.Query = "XMLREPORT";.
BR-RPT-024 — Doppio trigger su RPT_PIVOTSOURCE (sequenze divergenti)
Statement: RPT_PIVOTSOURCE ha due trigger BEFORE INSERT (CNT_PIVOTREPORT e TRG_RPT_PIVOTSOURCE) che assegnano entrambi :new.ID_PIVOT quando NULL, ma da sequenze diverse (INC_PIVOTRPT.NEXTVAL vs SEQ_RPT_PIVOTSOURCE.NEXTVAL). L'ordine di firing non è deterministico: il primo che scatta imposta il valore, il secondo lo salta. Rischio di gap/collisione sulla PK ID_PIVOT.
Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED · Flag: DB-only, defect probabile.
Evidenza: USER_TRIGGERS: CNT_PIVOTREPORT (INC_PIVOTRPT.NEXTVAL) e TRG_RPT_PIVOTSOURCE (SEQ_RPT_PIVOTSOURCE.NEXTVAL), entrambi BEFORE INSERT OR DELETE su RPT_PIVOTSOURCE; PK PK_TMPPIVOTSOURCE su ID_PIVOT.
BR-RPT-025 — Vincoli NOT NULL su RPT_PIVOTSOURCE
Statement: RPT_PIVOTSOURCE impone NOT NULL su ID_ACTION, QUERY, COLUMNS, ROWS, SCHEDULED. Un pivot senza colonne o senza righe non è persistibile a livello DB.
Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED · Flag: DB-only.
Evidenza: USER_CONSTRAINTS/USER_CONS_COLUMNS: SYS_C001715664..668 (C) su ID_ACTION/QUERY/COLUMNS/ROWS/SCHEDULED; PK PK_TMPPIVOTSOURCE su ID_PIVOT.
BR-RPT-026 — Serializzazione aggregati incoerente Add vs Edit
Statement: Nel DAO Pivot, l'Add serializza gli aggregati con f.Field (solo il nome campo), mentre l'Edit usa f.ToString() (rappresentazione completa dell'AggregateField). La stessa definizione salvata con Add o con Edit produce quindi valori diversi in AGGREGATES.
Tipo: data-integrity · Enforcement: BL · Confidence: VERIFIED · Flag: defect probabile.
Evidenza: DAO_Pivot.vb:222 (strAggr & f.Field) vs :146 (strAggr & f.ToString()).
BR-RPT-027 — Salvataggio logo tenant su filesystem
Statement: Se l'immagine del logo è stata modificata, il salvataggio scrive il file ~/Logos/rpt_logo_<TenantID>.gif (e rpt_logo_right_<TenantID>.gif) e aggiorna il logo di stampa via TenantController.SetPrintLogo. È un side effect su filesystem legato al tenant corrente, non alla singola definizione report.
Tipo: side-effect · Enforcement: UI · Confidence: VERIFIED · Flag: side effect.
Evidenza: XmlProcedure.ascx.cs:568-577.
BR-RPT-028 — Owner/schema multi-tenant da ApplicationName
Statement: Le query dirette dei DAO Report qualificano gli oggetti con Owner, risolto a runtime da System.Web.Security.Membership.Provider.ApplicationName (nome tenant/applicazione). L'isolamento tra tenant dipende quindi dal provider di membership.
Tipo: config · Enforcement: BL · Confidence: VERIFIED.
Evidenza: DAO_Base.vb:18-20,32-36; uso in DAO_XmlReport.vb:26 (SELECT * FROM {Owner}.RPT_XMLREPORTSOURCE ...) e DAO_Pivot.vb:69.
BR-RPT-029 — Funzioni standard @USER/@ROLES/@YEAR[±N]
Statement: In esecuzione, il testo query supporta i segnaposto funzione @USER(campo) → lower(campo)=lower('<utente>'), @ROLES(campo) → lower(campo) in (<ruoli>), @YEAR(campo) → to_char(campo,'YYYY')='<anno>', e @YEAR±N(campo) con N da -10 a +10 (anno corrente ± N). Sono sostituzioni testuali applicate prima dell'esecuzione.
Tipo: business-logic · Enforcement: BL · Confidence: VERIFIED · Flag: magic number, date logic.
Evidenza: DAO_Base.vb:16 (elenco StandandardFunctions @YEAR-1..-10, @YEAR+1..+10); DAO_XmlReport.vb:613-656 (loadStandardFx).
BR-RPT-030 — Iniezione parametri per concatenazione (rischio SQLi)
Statement: I parametri di query e le funzioni standard sono sostituiti nel testo SQL per concatenazione/Replace; l'unico escaping è il raddoppio degli apostrofi (sqlEscape). Non si usano bind variables in esecuzione: testo query + valori parametro costituiscono una superficie di SQL injection, aggravata dal fatto che la query è salvata senza validazione (BR-RPT-010).
Tipo: validation · Enforcement: BL · Confidence: VERIFIED · Flag: security, defect probabile.
Evidenza: DAO_XmlReport.vb:527-547 (sqlEscape), :549-611 (loadParameters con sql.Replace(paramTag, valArray(i))), :613-656 (loadStandardFx con sql.Replace).
BR-RPT-031 — Anteprima dei report schedulati dalla tabella materializzata
Statement: Per un report schedulato, TestQuery/ExecuteQuery NON eseguono la query live ma leggono la tabella materializzata RPT_SCHED_XMLRPT_<ActionID>. I dati mostrati riflettono l'ultima esecuzione del job, non lo stato corrente della sorgente.
Tipo: workflow · Enforcement: BL · Confidence: VERIFIED.
Evidenza: DAO_XmlReport.vb:371-374 (TestQuery), :457-459 (ExecuteQuery) — SELECT * FROM RPT_SCHED_XMLRPT_<ActionID>. Analogo per il pivot: DAO_Pivot.vb:105-107 (RPT_SCHED_PVTRPT_<ActionID>).
Note di sintesi e questioni aperte
- Difetti probabili concentrati: doppio trigger su
RPT_PIVOTSOURCE(BR-RPT-024), codice morto anti-UPDATE nei trigger (BR-RPT-009),TABLESPACE_NAME=USER(BR-RPT-016), assenza di UNIQUE suID_ACTION+ fallback ciecо su Add (BR-RPT-006/005), incoerenza aggregati pivot (BR-RPT-026). - Sicurezza: query salvata senza validazione (BR-RPT-010), blacklist ingenua (BR-RPT-011), injection per concatenazione (BR-RPT-030), grant non ri-verificati oltre il web (BR-RPT-003).
- Nessuna regola customer-specific individuata nel percorso di salvataggio: i literal
RC/DEMsono moduli di prodotto (RequestCenter/DEM), non varianti cliente. - Verifica di deployment Remoting (co-locazione servizio ReportManager) non conclusa — vedi Open question #4 di FLOW-RPT-001; incide sulla gravità reale di BR-RPT-003.