Table of Contents

BR-IEM — Regole di business del dominio IEM (Infocad Entity Manager)

Regole di business estratte dal flusso pilota FLOW-IEM-001 (creazione di una nuova tabella/entità del modello dati) e dai sorgenti correlati. IEM = Infocad Entity Manager: il modulo di amministrazione/design del modello dati. Non gestisce dati anagrafici di business ma la struttura del database applicativo e i suoi metadati (repository IEM_OBJECTS, GLOBAL_TAB_COLUMNS). L'operazione WRITE pilota è la creazione di una tabella tramite la procedura standalone Oracle IEM_CREATETABLE, che emette DDL dinamico (CREATE TABLE), registra l'entità nel repository dei metadati e — a seconda dei flag — crea trigger/sequence di conteggio del campo chiave.

Sistema: Infocad (Descor) — backend Oracle INFOCAD_TEST38, ASP.NET Web Forms (C#, web CASSANDRA/IEMWeb) + business layer server Descor.IEM.IEMControllers / IEM_BL risolti via .NET Remoting (endpoint IEM_BL.rem, host IEMService/IEMServer); nessun ORM (stored procedure via DAL Execute*StoredProcedure, esito su parametro OUT POUT 0/1).

Le regole sono classificate per tipo, enforcement point (UI / BL / DB / mixed) e confidence (VERIFIED / SUPPORTED / INFERRED). Gli identificatori tecnici NON sono tradotti.

Note di metodo e provenienza dell'evidenza

  • Evidenza di codice: percorsi relativi alla radice del repository Documentation/ (es. InfocadServer/IEMDAL/OracleODP/IEM_DAL.vb:523).
  • Evidenza DB: letta in sola lettura da ALL_SOURCE su INFOCAD_TEST38, limitatamente alle procedure/funzioni toccate dalle regole (IEM_CREATETABLE, IEM_EXISTSTAB, IEM_CREATEFIELD). Nessuna lettura di dati applicativi, nessuna DML/DDL. Le righe della procedura sono indicate come IEM_CREATETABLE:NNN (numerazione ALL_SOURCE, IEM_CREATETABLE = 183 righe totali).
  • Il path pilota è la pagina AddTable.aspx (CASSANDRA/IEMWeb); esiste una copia legacy identica in WebMachine/IEM/.../AddTable.aspx.cs (stesso pattern) — quale sia mappata a runtime in IIS resta open question.

Registro delle regole (register)

id regola tipo enforcement conf
BR-IEM-001 Accesso alla funzione IEM soggetto ad autenticazione (base CassandraPage) permission mixed SUPPORTED
BR-IEM-002 Nome tabella deve essere univoco: pre-check UI TableExistsIEM_EXISTSTAB; a livello DB duplicato ⇒ POUT=0 silente validation mixed VERIFIED
BR-IEM-003 Naming campo chiave: regex ^[A-Z]{1,1}[A-Z0-9#_$]{1,30}$ (maiuscolo, inizia con lettera, set Oracle) validation UI VERIFIED
BR-IEM-004 Tipi dato selezionabili limitati a VARCHAR2 e NUMBER (RowFilter combo) validation UI VERIFIED
BR-IEM-005 Default dimensioni per tipo nella UI (VARCHAR2 length=255; NUMBER precision=1, scale=0) config-flag UI VERIFIED
BR-IEM-006 isAutomaticCount=1 SSE il tipo del campo chiave è NUMBER (⇒ trigger CNT_<t>) business-rule mixed VERIFIED
BR-IEM-007 Dal path AddTable i flag sono forzati: primaryKey=1, systemTable=0, nullValues=0, isCountFromSequence=0, defaultVal="" config-flag BL VERIFIED
BR-IEM-008 Costruzione DDL per tipo: VARCHAR2/NVARCHAR2/NCHAR/CHAR→(len); NUMBER/DECIMAL→(prec,scale); altrimenti tipo nudo calculation DB VERIFIED
BR-IEM-009 Vincolo PK creato con naming convention <TABLE><FIELD>PK quando PPRIMARYKEY=1 calculation DB VERIFIED
BR-IEM-010 Semantica invertita PNULLVALUES: =1NOT NULL; dal path UI vale 0⇒colonna nullable validation DB VERIFIED
BR-IEM-011 Gestione valore DEFAULT: attivo se PDEFAULTVALUE <> ' '; DATE via TO_DATE(...,'DD/MM/YYYY') calculation DB VERIFIED
BR-IEM-012 Registrazione entità in IEM_OBJECTS: ID_N=MAX(ID_N)+1, PARENTID=1, OBJECTTYPE='TABLE', ISSYSTEM=PSYSTEMTABLE, ISVISIBLE=1 calculation DB VERIFIED
BR-IEM-013 Trigger conteggio automatico CNT_<t> (auto-increment NVL(MAX(campo),0)+1) se PISAUTOMATICCOUNT=1 calculation DB VERIFIED
BR-IEM-014 Ramo sequence (PISCOUNTFROMSEQ=1): crea SEQ_<t> se assente (IEM.SEQUEXISTS) + trigger da NEXTVAL calculation DB VERIFIED
BR-IEM-015 Registrazione campo chiave in GLOBAL_TAB_COLUMNS: SYSTEM_FIELD='Y', FIELD_ORDER=1, FIELD_NULLABLE='N', IS_PRIMARY='N' calculation DB VERIFIED
BR-IEM-016 Non-atomicità: COMMIT dopo ogni step ⇒ un errore tardivo lascia stato parziale state-transition DB VERIFIED
BR-IEM-017 Esito e feedback: POUT=1 successo / WHEN OTHERS ⇒ POUT=0 (errore silente); UI chiude modale solo se res==1 state-transition mixed VERIFIED
BR-IEM-018 Audit: ogni DDL/trigger loggato in GLOBAL_DEBUG_LOG (USER, tag, SQL, SYSDATE) audit DB VERIFIED
BR-IEM-019 IEM_EXISTSTAB(nome) delega a IEM.TABEXISTS e ritorna 1/0 validation DB VERIFIED
BR-IEM-020 IEM_CREATEFIELD (aggiunta campo): ALTER TABLE ADD; PK con nome fisso constraint_pk; DEFAULT varchar NON quotato calculation DB VERIFIED

Dettaglio delle regole

BR-IEM-001 — Accesso alla funzione IEM soggetto ad autenticazione

  • Regola: la pagina AddTable.aspx eredita da CassandraPage, che impone l'autenticazione sulla shell CASSANDRA (redirect al login se assente). L'infrastruttura espone anche HasUserGrant(...) per i grant di funzione.
  • Tipo: permission · Enforcement: mixed (UI/BL infrastruttura) · Confidence: SUPPORTED
  • Evidenza (UI): public partial class AddTable : Descor.Cassandra.InfocadSecurity.CassandraPageInfocadWeb/WebMachine/CASSANDRA/IEMWeb/FunctionPages/DataManagement/AddTable.aspx.cs:18; base auth/grant — CASSANDRA/Authentication/CassandraPage.cs:22,152,290.
  • Flag: HasUserGrant non risulta invocato in AddTable.aspx.cs → l'unico presidio verificato è l'autenticazione di base, non un grant specifico di funzione IEM (open question sul controllo di ruolo fine).

BR-IEM-002 — Univocità del nome tabella

  • Regola: prima del salvataggio la UI verifica che la tabella non esista già (ctrl.TableExists(nome.ToUpper())), altrimenti blocca con "Nome tabella già esistente". Il controllo passa dalla funzione DB IEM_EXISTSTAB. La procedura IEM_CREATETABLE non ripete il controllo: un CREATE TABLE su nome esistente fallisce a runtime e viene assorbito da WHEN OTHERS ⇒ POUT=0 (silente).
  • Tipo: validation · Enforcement: mixed (UI pre-check + DB implicito silente) · Confidence: VERIFIED
  • Evidenza (UI): if (ctrl.TableExists(args.Value.ToUpper())) { args.IsValid = false; cv.ErrorMessage = "Nome tabella già esistente."; }AddTable.aspx.cs:316-320; CustomValidator cvTableNameAddTable.aspx:115.
  • Evidenza (DAL/DB): IEM_DAL.TableExistsExecuteNonQueryStoredProcedure("IEM_EXISTSTAB") con ReturnValue — IEM_DAL.vb:194-209; nessun controllo esistenza nel corpo di IEM_CREATETABLE (vedi BR-IEM-017).
  • Flag: controllo effettivo UI-only; sul path DB l'errore di duplicato è mascherato (POUT=0 senza messaggio). Il confronto è case-insensitive lato UI (ToUpper()).

BR-IEM-003 — Naming del campo chiave (regex Oracle-compatibile)

  • Regola: il nome del campo chiave deve rispettare la regex ^[A-Z]{1,1}[A-Z0-9#_$]{1,30}$: maiuscolo, inizia con una lettera, seguito da lettere/cifre/#/_/$; altrimenti "Invalid Input".
  • Tipo: validation · Enforcement: UI · Confidence: VERIFIED
  • Evidenza (UI): string pattern = @"^[A-Z]{1,1}[A-Z0-9#_$]{1,30}$"; Match result = Regex.Match(args.Value.ToUpper(), pattern);AddTable.aspx.cs:332-333; CustomValidator cvFieldNameAddTable.aspx:124.
  • Flag: controllo UI-only (la procedura non valida il nome). La regex ammette 1 + 1..30 = fino a 31 caratteri, mentre l'identificatore Oracle classico è limitato a 30 → un nome di 31 char passa la UI ma può eccedere il limite Oracle e finire in POUT=0. Il nome tabella (rtbTableName) non ha questa regex, solo RequiredFieldValidator + univocità (BR-IEM-002).

BR-IEM-004 — Tipi dato selezionabili limitati a VARCHAR2 e NUMBER

  • Regola: la combo dei tipi dato è filtrata a VARCHAR2 e NUMBER tramite RowFilter sul risultato di GetPropertiesField(); gli altri tipi (DATE, BLOB, ...) non sono selezionabili dall'operatore su questa pagina.
  • Tipo: validation · Enforcement: UI · Confidence: VERIFIED
  • Evidenza (UI): view.RowFilter = "DataType IN ('VARCHAR2','NUMBER')";AddTable.aspx.cs:232; sorgente combo ctrl.GetPropertiesField()IEM_GETPROPERTIESFIELDIEM_DAL.vb:152.
  • Flag: restrizione UI-only. La procedura IEM_CREATETABLE supporta invece NVARCHAR2/NCHAR/CHAR/DECIMAL/DATE (BR-IEM-008/011); la restrizione è quindi solo di interfaccia, non del backend. Il ramo SetDataDefault gestisce anche DATE/BLOB (codice morto rispetto al filtro).

BR-IEM-005 — Default dimensioni per tipo nella UI

  • Regola: alla selezione del tipo la UI precompila length/precision/scale: VARCHAR2 ⇒ length=255 (precision=1, scale=0, disabilitati); NUMBER ⇒ length=0, precision=1, scale=0 (precision/scale abilitati); DATE ⇒ length=7; BLOB ⇒ length=0.
  • Tipo: config-flag · Enforcement: UI · Confidence: VERIFIED
  • Evidenza (UI): SetDataDefault(...)AddTable.aspx.cs:239-303 (VARCHAR2 :248-251, NUMBER :276-278).
  • Flag: magic numbers hard-coded (255, 7, 1, 0) come default di dimensionamento; solo suggerimenti UI, sovrascrivibili dall'operatore prima del salvataggio.

BR-IEM-006 — isAutomaticCount attivo solo per campo chiave NUMBER

  • Regola: il flag isAutomaticCount è impostato a 1 se e solo se il tipo del campo chiave selezionato è NUMBER; altrimenti 0. Quando =1, la procedura crea il trigger di conteggio automatico CNT_<tabella> (BR-IEM-013).
  • Tipo: business-rule · Enforcement: mixed (UI decide il flag, DB crea il trigger) · Confidence: VERIFIED
  • Evidenza (UI): byte isAutomaticCount = 0; if (rcbDataType.Text == "NUMBER") isAutomaticCount = 1;AddTable.aspx.cs:159-161; propagato in ctrl.CreateTable(...):173.
  • Evidenza (DB): IF PISAUTOMATICCOUNT = 1 THEN ... crea trigger — IEM_CREATETABLE:96-121.
  • Flag: la scelta dell'auto-conteggio non è esposta all'operatore ma dedotta implicitamente dal tipo dato (hidden flag): ogni chiave NUMBER diventa auto-incrementante.

BR-IEM-007 — Flag forzati dal path AddTable

  • Regola: dal path pilota AddTable, la chiamata CreateTable forza valori costanti: defaultVal="", nullValues=0, primaryKey=1, systemTable=0, isCountFromSequence=0 (solo isAutomaticCount varia, BR-IEM-006). Quindi ogni tabella creata dalla pagina ha sempre il campo chiave come PK, non è tabella di sistema, non usa sequence.
  • Tipo: config-flag · Enforcement: BL (code-behind) · Confidence: VERIFIED
  • Evidenza (BL): ctrl.CreateTable(rtbTableName.Text, rtbFieldName.Text, rcbDataType.Text, dataLength, dataPrecision, dataScale, "", Convert.ToByte(0), Convert.ToByte(1), Convert.ToByte(0), Convert.ToByte(isAutomaticCount), Convert.ToByte(0))AddTable.aspx.cs:163-175; firma DAL — IEM_DAL.vb:490-501.
  • Flag: il ramo sequence non è mai esercitato da questa pagina (isCountFromSequence sempre 0) → BR-IEM-014 è codice raggiungibile solo da altri chiamanti/parametri. systemTable=0 hard-coded ⇒ nessuna tabella di sistema creabile da UI.

BR-IEM-008 — Costruzione DDL dinamico per tipo dato

  • Regola: la procedura costruisce il DDL CREATE TABLE <tab> (<campo> <tipo>...) per concatenazione: per VARCHAR2/NVARCHAR2/NCHAR/CHAR aggiunge (PDATALENGTH); per NUMBER/DECIMAL aggiunge (PDATAPRECISION,PDATASCALE); per gli altri tipi (es. DATE) usa il tipo nudo.
  • Tipo: calculation · Enforcement: DB · Confidence: VERIFIED
  • Evidenza (DB): SQLEXEC := 'CREATE TABLE' || ' ' || PTABLENAME || ' (' ; ... IF PDATATYPE IN ('VARCHAR2','NVARCHAR2','NCHAR','CHAR') THEN ...(PDATALENGTH)... ELSIF PDATATYPE IN ('NUMBER','DECIMAL') THEN ...(PDATAPRECISION,PDATASCALE)... ELSE ...tipo nudoIEM_CREATETABLE:30-41; EXECUTE IMMEDIATE SQLEXEC:75.
  • Flag: DDL per concatenazione di stringhe (nessun bind) → dipende interamente dalle validazioni UI (BR-IEM-002/003) per evitare nomi malformati/injection; il DB non ri-valida.

BR-IEM-009 — Naming convention del vincolo PRIMARY KEY

  • Regola: se PPRIMARYKEY=1 la procedura aggiunge un vincolo CONSTRAINT <PTABLENAME><PFIELDNAME>PK PRIMARY KEY (<PFIELDNAME>) (nome = concatenazione tabella+campo+PK).
  • Tipo: calculation (naming) · Enforcement: DB · Confidence: VERIFIED
  • Evidenza (DB): IF PPRIMARYKEY = 1 THEN SQLEXEC := SQLEXEC || ',' ; SQLEXEC := SQLEXEC || ' CONSTRAINT ' || PTABLENAME || PFIELDNAME || 'PK' || ' PRIMARY KEY (' || PFIELDNAME || ')';IEM_CREATETABLE:63-67.
  • Flag: il nome del vincolo può eccedere i 30 caratteri Oracle se tabella+campo sono lunghi (<tab><campo>PK) → possibile POUT=0 silente su nomi lunghi. Convenzione diversa da IEM_CREATEFIELD che usa nome fisso constraint_pk (BR-IEM-020).

BR-IEM-010 — Semantica invertita di PNULLVALUES

  • Regola: nel corpo procedura PNULLVALUES = 1 aggiunge NOT NULL alla colonna; PNULLVALUES = 0 (default dal path UI) lascia la colonna nullable a livello di colonna. Il nome del parametro ("null values") è quindi fuorviante: 1 significa "non ammette null".
  • Tipo: validation · Enforcement: DB · Confidence: VERIFIED
  • Evidenza (DB): IF PNULLVALUES = 1 THEN SQLEXEC := SQLEXEC || ' NOT NULL'; END IF;IEM_CREATETABLE:58-61; dal path UI nullValues=0AddTable.aspx.cs:170.
  • Flag: naming ingannevole / hidden semantics. Dal path AddTable la colonna chiave è creata nullable a livello colonna ma resa non-null di fatto dal vincolo PK (BR-IEM-009). Discrepanza con il metadato FIELD_NULLABLE='N' scritto in GLOBAL_TAB_COLUMNS (BR-IEM-015).

BR-IEM-011 — Gestione del valore di DEFAULT

  • Regola: il DEFAULT è aggiunto solo se PDEFAULTVALUE <> ' ' (confronto con spazio singolo, non stringa vuota). Per stringhe il valore è racchiuso tra apici; per NUMBER/DECIMAL nudo; per DATE tramite TO_DATE(<val>, 'DD/MM/YYYY').
  • Tipo: calculation · Enforcement: DB · Confidence: VERIFIED
  • Evidenza (DB): IF PDEFAULTVALUE <> ' ' THEN ... VARCHAR ⇒ ' DEFAULT ''' || PDEFAULTVALUE || '''' ; NUMBER ⇒ ' DEFAULT ' || PDEFAULTVALUE ; DATE ⇒ ' DEFAULT TO_DATE('...', ''DD/MM/YYYY'')'IEM_CREATETABLE:44-56.
  • Flag: date-logic con formato DD/MM/YYYY hard-coded (dipendenza da formato locale italiano). Dal path AddTable defaultVal="" (stringa vuota, non spazio) ⇒ la condizione <> ' ' è comunque vera per la stringa vuota, ma i rami interni non producono DEFAULT utile (ramo non esercitato con valore reale da questa pagina).

BR-IEM-012 — Registrazione entità nel repository IEM_OBJECTS

  • Regola: dopo il CREATE TABLE la procedura registra l'entità in IEM_OBJECTS con ID_N = MAX(ID_N)+1, PARENTID=1, OBJECTNAME=PTABLENAME, OBJECTTYPE='TABLE', IMAGEURL fisso, ISSYSTEM=PSYSTEMTABLE, ISVISIBLE=1. È il passaggio che fa comparire la tabella nell'albero oggetti IEM.
  • Tipo: calculation (side effect metadati) · Enforcement: DB · Confidence: VERIFIED
  • Evidenza (DB): SELECT MAX(ID_N)+1 INTO CONTATORE FROM IEM_OBJECTS; INSERT INTO IEM_OBJECTS (...) SELECT CONTATORE, 1, PTABLENAME, 'TABLE', '~/App_Themes/DescorMetroSD/Images/favouritessmall.png', PSYSTEMTABLE, 1 FROM DUAL;IEM_CREATETABLE:79-93.
  • Flag: ID via MAX(ID_N)+1 ⇒ non concorrenza-safe (due creazioni simultanee possono collidere). Magic constants hard-coded: PARENTID=1, ISVISIBLE=1, path immagine. Su IEM_OBJECTS vuoto MAX(ID_N) è NULL ⇒ CONTATORE NULL (edge case).

BR-IEM-013 — Trigger di conteggio automatico CNT_

  • Regola: se PISAUTOMATICCOUNT=1 la procedura crea (via EXECUTE IMMEDIATE) un trigger CNT_<tabella> BEFORE INSERT ... FOR EACH ROW che, se il campo chiave è NULL, lo valorizza con NVL(MAX(<campo>),0)+1 letto dalla tabella stessa.
  • Tipo: calculation · Enforcement: DB · Confidence: VERIFIED
  • Evidenza (DB): costruzione 'CREATE OR REPLACE TRIGGER ' || OWNERNAME || '.CNT_' || PTABLENAME ... 'BEFORE INSERT' ... 'IF (:new.'||PFIELDNAME||' IS NULL) THEN SELECT NVL(MAX('||PFIELDNAME||'),0) INTO CONTATORE FROM ...; :new.'||PFIELDNAME||' := CONTATORE + 1;'IEM_CREATETABLE:96-118.
  • Flag: auto-increment via MAX+1 (non sequence) ⇒ race condition su insert concorrenti / buchi non riutilizzati. Naming convention CNT_<tabella>. Magic number -20000 per l'eccezione non_posso_cambiare (guardia mai raggiunta nel ramo INSERT). Trigger e sequence-trigger condividono lo stesso nome CNT_<tabella> (BR-IEM-014) ⇒ mutuamente esclusivi.

BR-IEM-014 — Ramo sequence: SEQ_ + trigger da NEXTVAL

  • Regola: se PISCOUNTFROMSEQ=1, la procedura crea la sequence SEQ_<tabella> (solo se IEM.SEQUEXISTS('SEQ_'||tabella)=FALSE) con parametri fissi INCREMENT BY 1 START WITH 1 MAXVALUE 1.0E28 MINVALUE 1 NOCYCLE NOCACHE NOORDER, poi un trigger CNT_<tabella> che valorizza il campo chiave da SEQ_<tabella>.NEXTVAL.
  • Tipo: calculation · Enforcement: DB · Confidence: VERIFIED
  • Evidenza (DB): IF PISCOUNTFROMSEQ = 1 THEN IF IEM.SEQUEXISTS('SEQ_'||PTABLENAME||'') = FALSE THEN 'CREATE OR REPLACE SEQUENCE SEQ_'||PTABLENAME... ; ... trigger 'SELECT SEQ_'||PTABLENAME||'.NEXTVAL INTO :new.'||PFIELDNAMEIEM_CREATETABLE:125-162; funzione IEM.SEQUEXISTS:129.
  • Flag: ramo mai esercitato dal path AddTable (isCountFromSequence sempre 0, BR-IEM-007). Parametri sequence hard-coded (MAXVALUE 1.0E28, NOCACHE). NOCACHE penalizza le performance. In caso di PISAUTOMATICCOUNT=1 e PISCOUNTFROMSEQ=1 insieme, il secondo trigger CNT_<t> sovrascrive (CREATE OR REPLACE) il primo.

BR-IEM-015 — Registrazione campo chiave in GLOBAL_TAB_COLUMNS

  • Regola: la procedura registra il campo chiave nel metamodello GLOBAL_TAB_COLUMNS con valori: SYSTEM_FIELD='Y', FIELD_ORDER=1, FIELD_NULLABLE='N', IS_PRIMARY='N', IS_UNIQUE='N', IS_LIST='N', e le dimensioni passate.
  • Tipo: calculation (metadati) · Enforcement: DB · Confidence: VERIFIED
  • Evidenza (DB): INSERT INTO GLOBAL_TAB_COLUMNS (...) VALUES (PTABLENAME, PFIELDNAME, PDATATYPE, PDATALENGTH, PDATAPRECISION, PDATASCALE, NULL, 1, 'N', 'Y', NULL, 'N', 'N', 'N', NULL, NULL, NULL);IEM_CREATETABLE:166-169.
  • Flag: IS_PRIMARY='N' hard-coded benché il campo sia la PRIMARY KEY fisica (BR-IEM-009) ⇒ discrepanza metamodello vs schema fisico. FIELD_NULLABLE='N' hard-coded benché a livello colonna la chiave sia nullable (PNULLVALUES=0, BR-IEM-010) ⇒ ulteriore incoerenza tra metadato e definizione fisica. SYSTEM_FIELD='Y': il campo chiave è sempre marcato di sistema.

BR-IEM-016 — Non-atomicità dell'operazione (COMMIT multipli)

  • Regola: la procedura esegue un COMMIT dopo ogni step (log, DDL tabella, INSERT IEM_OBJECTS, log/DDL trigger, log/DDL trigger-seq). L'operazione non è atomica: un errore tardivo può lasciare la tabella creata ma i metadati parziali.
  • Tipo: state-transition · Enforcement: DB · Confidence: VERIFIED
  • Evidenza (DB): COMMIT; a IEM_CREATETABLE:72,76,93,115,119,158,161.
  • Flag: assenza di transazione unica / compensazione. Es.: se il CREATE TABLE (:75) riesce ma l'INSERT IEM_OBJECTS (:82) fallisce, la tabella fisica resta orfana senza voce nel repository IEM. La gestione errori (BR-IEM-017) restituisce POUT=0 senza rollback dei commit già eseguiti.

BR-IEM-017 — Esito POUT e feedback UI

  • Regola: la procedura ritorna POUT=1 in caso di successo; qualsiasi eccezione (WHEN OTHERS) imposta POUT=0, senza risollevare l'errore. Il code-behind interpreta: res==1 ⇒ chiude la modale (Close()); altrimenti la modale resta aperta.
  • Tipo: state-transition · Enforcement: mixed (DB esito + UI interpretazione) · Confidence: VERIFIED
  • Evidenza (DB): SELECT 1 INTO POUT FROM DUAL; (IEM_CREATETABLE:173-175); EXCEPTION WHEN OTHERS THEN SELECT 0 INTO POUT FROM DUAL; (:177-181).
  • Evidenza (UI/DAL): DAL legge POUTIEM_DAL.vb:523-524; if (res == 1) ClientScript...("Close();")AddTable.aspx.cs:178-179.
  • Flag: WHEN OTHERS maschera la causa reale (nome duplicato, privilegi, limiti identificatore): tutto appiattito su 0. Nessun messaggio d'errore esplicito all'utente quando res!=0: la modale resta aperta senza spiegazione (INFERRED sul comportamento percepito). Magic values 0/1.

BR-IEM-018 — Audit del DDL in GLOBAL_DEBUG_LOG

  • Regola: prima di ogni EXECUTE IMMEDIATE di DDL (tabella e trigger) la procedura logga in GLOBAL_DEBUG_LOG una riga con utente, tag operazione e lo statement SQL generato e data.
  • Tipo: audit · Enforcement: DB · Confidence: VERIFIED
  • Evidenza (DB): EXECUTE IMMEDIATE 'INSERT INTO GLOBAL_DEBUG_LOG VALUES(:1,:2,:3,:4)' USING USER, 'IEM_CREATE_TABLE', SQLEXEC, SYSDATE;IEM_CREATETABLE:70-71; tag 'IEM_CREATE_TRIGGER' per i trigger — :113-114,156-157.
  • Flag: log del DDL della tabella e dei trigger; l'INSERT su IEM_OBJECTS/GLOBAL_TAB_COLUMNS non è loggato. IEM_CREATEFIELD ha invece il logging commentato (BR-IEM-020) ⇒ audit incompleto/incoerente tra operazioni.

BR-IEM-019 — Funzione IEM_EXISTSTAB

  • Regola: la funzione IEM_EXISTSTAB(NOMETABELLA) restituisce 1 se la tabella esiste (delega a IEM.TABEXISTS), altrimenti 0. È il presidio DB del pre-check di univocità (BR-IEM-002).
  • Tipo: validation · Enforcement: DB · Confidence: VERIFIED
  • Evidenza (DB): IF IEM.TABEXISTS(NOMETABELLA) THEN RETURN 1; ELSE RETURN 0; END IF;IEM_EXISTSTAB:8-13; chiamata DAL IEM_DAL.vb:206.
  • Flag: la logica interna di IEM.TABEXISTS (package IEM) non è stata ispezionata riga per riga (INFERRED sul dettaglio del catalogo interrogato).

BR-IEM-020 — IEM_CREATEFIELD: aggiunta campo (variante DDL)

  • Regola: l'operazione di aggiunta campo (CreateField) usa IEM_CREATEFIELD che emette ALTER TABLE <tab> ADD (<campo> <tipo>...). Tipizzazione simile a IEM_CREATETABLE con una differenza: NUMBER/DECIMAL con PDATAPRECISION=0 genera il tipo nudo (NUMBER senza precisione). Se PPRIMARYKEY=1 aggiunge CONSTRAINT constraint_pk PRIMARY KEY(...) con nome fisso. Esito POUT=1/0 con WHEN OTHERS.
  • Tipo: calculation · Enforcement: DB · Confidence: VERIFIED
  • Evidenza (DB): ALTER TABLE ... ADD (...)IEM_CREATEFIELD:20; NUMBER prec=0 nudo — :30-35; DEFAULT varchar ' DEFAULT ' || '' || PDEFAULTVALUE || '' (senza apici) — :46; PK CONSTRAINT constraint_pk PRIMARY KEY:81; esito :85-93. Chiamata DAL — IEM_DAL.vb:1138,1157.
  • Flag: nome vincolo fisso constraint_pk ⇒ collisione se usato per più tabelle/campi nello stesso schema (a differenza di BR-IEM-009 che parametrizza il nome). DEFAULT varchar NON quotato ('' || PDEFAULTVALUE || '', apici vuoti) ⇒ potenziale errore/injection sui default stringa, incoerente con IEM_CREATETABLE:48 che quota. Logging DDL commentato (:71-73) ⇒ nessun audit dell'ALTER. IEM_CREATEFIELD non aggiorna IEM_OBJECTS/GLOBAL_TAB_COLUMNS (la registrazione metadati è responsabilità di altre procedure, es. IEM_MODIFYFIELD/IEM_MANAGE).

Sintesi dei rischi e flag

Regole enforced SOLO nell'UI (rischio: bypassabili da altri chiamanti)

  • BR-IEM-002 (univocità nome, pre-check), BR-IEM-003 (regex campo), BR-IEM-004 (tipi limitati), BR-IEM-005 (default dimensioni): tutte lato pagina AddTable. La procedura IEM_CREATETABLE non ri-valida nome/tipo → chiamanti diversi (o la copia legacy WebMachine/IEM) potrebbero passare valori non validati; l'errore risale solo come POUT=0 silente (BR-IEM-017).

Regole enforced SOLO in SQL (invisibili al codice applicativo)

  • BR-IEM-008/009/010/011 (costruzione DDL, PK naming, semantica NULL, DEFAULT), BR-IEM-012 (id MAX+1), BR-IEM-013/014 (trigger/sequence), BR-IEM-015 (metadati campo), BR-IEM-016 (COMMIT multipli), BR-IEM-018 (audit).

Magic number / valori hard-coded

  • POUT 0/1 (BR-IEM-017); PARENTID=1, ISVISIBLE=1, path immagine favouritessmall.png (BR-IEM-012); -20000 eccezione trigger (BR-IEM-013); parametri sequence MAXVALUE 1.0E28, NOCACHE (BR-IEM-014); default dimensioni UI 255/7/1/0 (BR-IEM-005); nome fisso constraint_pk (BR-IEM-020).

Date-logic / naming / hidden flags

  • BR-IEM-011 — formato DATE DD/MM/YYYY hard-coded.
  • BR-IEM-006isAutomaticCount dedotto implicitamente dal tipo NUMBER (flag nascosto, non esposto all'operatore).
  • BR-IEM-010PNULLVALUES semantica invertita (1=NOT NULL).
  • Naming convention: PK <TABLE><FIELD>PK (BR-IEM-009), trigger CNT_<t> / sequence SEQ_<t> (BR-IEM-013/014).

Incoerenze / discrepanze

  • BR-IEM-015IS_PRIMARY='N' e FIELD_NULLABLE='N' nel metamodello contraddicono la PK fisica e la colonna nullable → metadati non allineati allo schema reale.
  • BR-IEM-020 vs BR-IEM-009 — naming del vincolo PK divergente tra IEM_CREATEFIELD (fisso) e IEM_CREATETABLE (parametrico); DEFAULT varchar quotato in una, non nell'altra; audit presente in una, commentato nell'altra.
  • BR-IEM-016/017 — non-atomicità + WHEN OTHERS silente: possibile stato parziale senza feedback né rollback.

Rami non esercitati dal path pilota

  • BR-IEM-014 (sequence) — isCountFromSequence sempre 0 da AddTable (BR-IEM-007).
  • BR-IEM-004 — rami DATE/BLOB in SetDataDefault non raggiungibili (combo filtrata a VARCHAR2/NUMBER).

Open questions

  • Grant/ruolo specifico per l'accesso alla funzione IEM oltre all'autenticazione base (HasUserGrant non invocato in AddTable.aspx.cs) — BR-IEM-001.
  • Feedback all'utente quando IEM_CREATETABLE ritorna POUT=0 (errore DDL): non si è individuato un messaggio d'errore esplicito, la modale resta semplicemente aperta — BR-IEM-017.
  • Gestione/compensazione dello stato parziale prodotto dai COMMIT intermedi (tabella creata + metadati incompleti) — BR-IEM-016.
  • Coesistenza tra il web CASSANDRA/IEMWeb e la copia legacy WebMachine/IEM (quale mappata in IIS a runtime).
  • Intenzionalità di IS_PRIMARY='N'/FIELD_NULLABLE='N' in GLOBAL_TAB_COLUMNS per il campo chiave (impatto su come il metamodello IEM interpreta la chiave) — BR-IEM-015.
  • Logica interna di IEM.TABEXISTS/IEM.SEQUEXISTS (package IEM) non ispezionata riga per riga — BR-IEM-014/019.
  • Comportamento in configurazioni PROD (osservato solo su ambiente TEST38).