BR-DOC — Regole di business del dominio Document (documentale core / DocCenter)
Regole estratte dal dominio Document (entità core del documentale, tabelle
DOCS_*dello schema OracleINFOCAD_TEST38), ancorate al flusso pilotaFLOW-DOC-001(creazione di un documento con allegato principale, tag, attributi custom, protocollo di sistema) e ai percorsi di aggiornamento, rinnovo e revisione. Sistema: Infocad (Descor), backend Oracle, front-end ASP.NET Web Forms (VB.NET) suDocCenterWeb, serverDocumentController → Document_BL → Document_DAL, comunicazione controller↔BL via .NET Remoting, nessun ORM (stored procedureDOC_*invocate viaExecuteNonQueryStoredProcedure).Distinzione: qui si documenta la scrittura sull'entità documento core (
DOCS_DOCUMENTe satelliti). Il salvataggio del file fisico su ECM esterno (Alfresco/OpenText/Docs) è un percorso separato coperto daBR-ECM; la relazione tra i due è nella regola BR-DOC-028.
Legenda enforcement: UI = validato solo lato interfaccia/code-behind · BL = logica applicativa (code-behind/BL) · DB = vincolo/logica in stored procedure, constraint o trigger · mixed = più livelli. Legenda confidence: VERIFIED = catena di codice + controprova indipendente (sorgente DB o secondo artefatto) · SUPPORTED = evidenza di codice coerente ma un anello non eseguibile/non isolato · INFERRED = dedotto.
Le stored procedure DOC_*, i vincoli, i default di colonna e i trigger citati sono stati confermati
con lookup read-only bounded su USER_SOURCE, USER_TRIGGERS e sul catalogo colonne/constraint
dello schema INFOCAD_TEST38 (driver oracledb thin, sola lettura del testo di procedure/trigger e
dei metadati di tabella — nessun accesso a dati di business, nessuna DML/DDL).
Registro regole
| ID | Regola (sintesi) | Tipo | Enforcement | Conf. | Cust. |
|---|---|---|---|---|---|
| BR-DOC-001 | Il protocollo di sistema è generato eseguendo una formula SQL dinamica letta da DOCS_PROTOCOLFORMAT, non da una sequence |
calculation | mixed (DB/BL) | VERIFIED | no |
| BR-DOC-002 | Il protocollo finale = CInt(numero).ToString(FORMAT) + SUFFIX; la colonna REGEXPRESSION è in realtà una stringa di formato .NET |
calculation | BL | VERIFIED | no |
| BR-DOC-003 | DOCS_PROTOCOLFORMAT è letta con SELECT INTO senza WHERE: attesa riga singola (>1 riga → TOO_MANY_ROWS) |
data-integrity | DB | VERIFIED | no |
| BR-DOC-004 | Nessun incremento atomico del progressivo di protocollo (SEQ_DOCS_PROTOCOL commentata) → rischio collisione su concorrenza |
defect/concurrency | DB | SUPPORTED | no |
| BR-DOC-005 | Anti-duplicato in creazione: confronto descrizione + nome file + data + categoria + scadenze; saltato se descrizione vuota | validation | UI-only | VERIFIED | no |
| BR-DOC-006 | L'allegato principale viene creato solo se il BLOB non è nullo (IF NOT PDOCUMENTFILE IS NULL) |
state-transition | DB | VERIFIED | no |
| BR-DOC-007 | ID_DOCUMENT / ID_ATTACHMENT assegnati da trigger BEFORE INSERT via SEQ_DOCS_DOCUMENT / SEQ_DOCS_ATTACHMENT |
calculation | DB | VERIFIED | no |
| BR-DOC-008 | Colonne NOT NULL di DOCS_DOCUMENT: DESCRIPTION, IS_LAST_VERSION, RELATION_TYPE(def 0), ISVALID(def 0), VERSION(def 1), CREATED(def SYSDATE) |
data-integrity | DB | VERIFIED | no |
| BR-DOC-009 | Colonne NOT NULL di DOCS_ATTACHMENT: FILE_SIZE, FILE_EXTENSION, FILE_NAME, DOCUMENT_FILE |
data-integrity | DB | VERIFIED | no |
| BR-DOC-010 | La categoria non è obbligatoria a DB (ID_CATEGORY nullable); la DAL converte idCategory = 0 in NULL |
validation | mixed (DB/BL) | VERIFIED | no |
| BR-DOC-011 | I tag sono associati in blocco (bulk insert da array PL/SQL) via DOC_ADDTAGSTODOCUMENT |
state-transition | DB | VERIFIED | no |
| BR-DOC-012 | DOCS_TAG_DOCUMENT non ha PK né unique → possibili associazioni tag↔documento duplicate |
data-integrity | DB | VERIFIED | no |
| BR-DOC-013 | Il ricalcolo del peso tag (DOC_REFRESHTAGWEIGHT) è commentato → peso non aggiornato in creazione |
defect | DB | VERIFIED | no |
| BR-DOC-014 | Gli attributi custom sono inseriti fuori dalla transazione del documento (Try isolato, log-only): fallimento parziale = documento senza attributi | error-handling | BL | VERIFIED | no |
| BR-DOC-015 | Attributi custom in 4 tipi (STRING/LIST/NUMBER/DATE); il valore DATE è letto dal campo RadDate_<id> |
calculation | BL | VERIFIED | no |
| BR-DOC-016 | Gli attributi specifici sono presi dalla categoria padre (GetAttributesByCategory(Category.IdParent)), non dalla categoria stessa |
calculation | BL | SUPPORTED | no |
| BR-DOC-017 | L'update del documento sostituisce integralmente i tag (DOC_REMOVEALLTAGSFROMDOCUMENT + DOC_ADDTAGSTODOCUMENT) |
state-transition | DB | VERIFIED | no |
| BR-DOC-018 | L'update non modifica SYS_PROTOCOL né VERSION (protocollo e versione di sistema immutabili in update) |
data-integrity | DB | VERIFIED | no |
| BR-DOC-019 | In update, se non c'è nuovo file e PIDATTACHMENT è 0/NULL, ID_ATTACHMENT viene azzerato a NULL (sgancio allegato) |
data-integrity | DB | VERIFIED | no |
| BR-DOC-020 | Rinnovo (DOC_RENEWDOCUMENT): crea un documento figlio con ID_PARENT = vecchio, RELATION_TYPE = 0; il vecchio non viene toccato |
state-transition | DB | VERIFIED | no |
| BR-DOC-021 | Revisione (DOC_REVIEWDOCUMENT): nuova versione con ID_PREVIOUS_VERSION = vecchio, RELATION_TYPE = 1, VERSION = old+1; il vecchio → IS_LAST_VERSION = 0, ID_NEXT_VERSION = nuovo |
state-transition | DB | VERIFIED | no |
| BR-DOC-022 | Magic number RELATION_TYPE: 0 = creazione/rinnovo, 1 = revisione/versione |
magic-number | DB | VERIFIED | no |
| BR-DOC-023 | Il documento creato dal wizard ha IS_LAST_VERSION = 0 (DTO default False, mai impostato in creazione) |
defect | mixed (BL/DB) | SUPPORTED | no |
| BR-DOC-024 | Stamping alla creazione: START_DATE = SYSDATE, END_DATE = NULL, CREATEDBY = SessionContact.ID_DTO |
calculation | mixed (BL/DB) | VERIFIED | no |
| BR-DOC-025 | Se il workflow non trova il contatto, il documento appena creato viene cancellato fisicamente (DOC_PHYSICALDELETEDOCUMENT) + scadenze |
error-handling/state | mixed | VERIFIED | no |
| BR-DOC-026 | Inserimento "da cancellato": se InsertCancelled il documento è messo subito in delete logico dopo l'insert |
state-transition | BL | VERIFIED | sì |
| BR-DOC-027 | Tenancy del documento assegnata con permesso hard-coded 2 sul tenant corrente |
magic-number | BL | VERIFIED | no |
| BR-DOC-028 | La creazione core non invoca l'ECM esterno; l'aggancio ECM avviene solo in pubblicazione (vedi BR-ECM) | integration | mixed | SUPPORTED | no |
| BR-DOC-029 | Il wiring DocumentController → IDocument_BL è via .NET Remoting: i grant/autorizzazioni UI non sono ri-verificati dal servizio (pattern TD-008) |
security | BL | SUPPORTED | no |
Dettaglio regole
BR-DOC-001 — Protocollo di sistema da formula dinamica (non da sequence)
- Regola: il progressivo/protocollo di sistema non è generato da una sequence Oracle ma eseguendo dinamicamente (
DBMS_SQL) la formula SQL memorizzata nella colonnaPROTOCOLFORMULAdiDOCS_PROTOCOLFORMAT; il risultato è il numero grezzo del protocollo. La stessa procedura è chiamata da Insert, Renew e Review. - Tipo: calculation · Enforcement: mixed (DB/BL) · Confidence: VERIFIED · customer_specific: false
- Evidenza:
Document_DAL.vb:359(ExecuteNonQueryStoredProcedure("DOC_GETNEWDOCPROTOCOL")), analoghi:1680,:1816; controprova DB (USER_SOURCE)DOC_GETNEWDOCPROTOCOL:SELECT PROTOCOLFORMULA, REGEXPRESSION, SUFFIX INTO SQLSTR, PPROTOCOLREGEX, PSUFFIX FROM DOCS_PROTOCOLFORMAT;poiDBMS_SQL.PARSE(EXEC_CURSOR, SQLSTR, ...)/EXECUTE_AND_FETCH→PPROTOCOL. - Note: il "numero" dipende interamente dalla query configurata in
PROTOCOLFORMULA(tipicamente unMAX(...)+1o simile): logica di numerazione spostata nei dati, non nel codice.
BR-DOC-002 — Composizione del protocollo (format .NET + suffisso)
- Regola: il protocollo finale è composto lato DAL come
String.Format("{0}{1}", CInt(numeroGrezzo).ToString(Expression), Suffix), doveExpressionproviene dalla colonnaREGEXPRESSION(usata come stringa di formato numerico .NET, es. padding/zeri) eSuffixdalla colonnaSUFFIX. - Tipo: calculation · Enforcement: BL · Confidence: VERIFIED · customer_specific: false
- Evidenza:
Document_DAL.vb:361-364(Protocol = String.Format("{0}{1}", CInt(Protocol).ToString(Expression), Suffix)); ripetuto identico in Renew:1685e Review:1821. - Note: naming fuorviante — la colonna si chiama
REGEXPRESSIONma è consumata come format string diInteger.ToString(...), non come regex.CInt(Protocol)presuppone che il numero grezzo sia un intero valido: una formula che restituisca non-numerico solleva eccezione.
BR-DOC-003 — DOCS_PROTOCOLFORMAT atteso come riga singola
- Regola: la configurazione di protocollo è letta con
SELECT ... INTO ... FROM DOCS_PROTOCOLFORMATsenza clausola WHERE: la procedura assume una sola riga di configurazione; con più di una riga Oracle sollevaTOO_MANY_ROWS, con zero righeNO_DATA_FOUND. - Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza: controprova DB
DOC_GETNEWDOCPROTOCOL(USER_SOURCE):SELECT PROTOCOLFORMULA, REGEXPRESSION, SUFFIX INTO ... FROM DOCS_PROTOCOLFORMAT;(nessun predicato). - Note: singleton di configurazione implicito, non protetto da vincolo.
BR-DOC-004 — Nessun incremento atomico del progressivo (rischio concorrenza)
- Regola: l'incremento del progressivo tramite sequence dedicata (
SEQ_DOCS_PROTOCOL.NEXTVAL) è commentato; il numero deriva dall'esecuzione della formula (BR-DOC-001). Non essendoci né sequence né lock, due creazioni concorrenti che eseguono la stessa formula (MAX+1) possono ottenere lo stesso protocollo. - Tipo: defect/concurrency · Enforcement: DB · Confidence: SUPPORTED · customer_specific: false
- Evidenza: controprova DB
DOC_GETNEWDOCPROTOCOL:--SELECT SEQ_DOCS_PROTOCOL.NEXTVAL INTO tmpNextVal FROM DUAL;(commentata) e--tmpNextVal NUMBER;. - Note: probable defect — nessun
UNIQUEsuSYS_PROTOCOLinDOCS_DOCUMENT(vedi elenco constraint BR-DOC-008) a difesa della collisione. Coerente con l'open question di FLOW-DOC-001.
BR-DOC-005 — Controllo anti-duplicato in creazione (solo UI)
- Regola: prima dell'insert, se la descrizione è valorizzata,
checkNoExistDocumentrecupera i documenti con stessa descrizione (SelectByDescription) e considera duplicato quello con stessa descrizione + stesso nome file (upper) + stessaDocumentDate+ stesso codice categoria + stesse scadenze; se duplicato, l'insert non viene eseguito e si mostraDocExistMessage. Con descrizione vuota il controllo è saltato (noExistDocument = True). - Tipo: validation · Enforcement: UI-only · Confidence: VERIFIED · customer_specific: false
- Evidenza:
DocumentCreateControl.ascx.vb:321-323(skip se descrizione vuota),:417-459(checkNoExistDocument, confronto descrizione/filename/data/categoria/deadline),:326-327(insert solo senoExistDocument),:396-398(ramo duplicato). - Note: regola solo UI — bypassabile da percorsi non interattivi (upload massivo, custom): nessun vincolo DB impedisce documenti "gemelli".
BR-DOC-006 — Allegato principale creato solo con BLOB presente
- Regola:
DOC_CREATEDOCUMENTinserisce inDOCS_ATTACHMENT(viaDOC_CREATEATTACHMENT) solo se il BLOBPDOCUMENTFILEnon è nullo; altrimentiID_ATTACHMENTdel documento resta nullo. Stessa condizione in Renew, Review e (con logica estesa) Update. - Tipo: state-transition · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza: controprova DB
DOC_CREATEDOCUMENT:IF NOT PDOCUMENTFILE IS NULL THEN DOC_CREATEATTACHMENT(...); END IF;; identico inDOC_RENEWDOCUMENT,DOC_REVIEWDOCUMENT;DOC_UPDATEDOCUMENTIF PDOCUMENTFILE IS NOT NULL THEN ....
BR-DOC-007 — Chiavi surrogate da trigger BEFORE INSERT
- Regola:
ID_DOCUMENTeID_ATTACHMENTsono assegnati da triggerBEFORE INSERTche, se la chiave arriva NULL, prendeSEQ_DOCS_DOCUMENT.NEXTVAL/SEQ_DOCS_ATTACHMENT.NEXTVAL; se la chiave arriva valorizzata, il trigger fa avanzare la sequence fino a superare il valore inserito (protezione contro import con id espliciti). - Tipo: calculation · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza: controprova DB (
USER_TRIGGERS) triggerDOCS_DOCUMENT:IF (:NEW."ID_DOCUMENT" IS NULL) THEN SELECT "SEQ_DOCS_DOCUMENT".NEXTVAL INTO :NEW."ID_DOCUMENT" FROM DUAL; ELSE ... WHILE (last_InsertID > last_Sequence) LOOP ... NEXTVAL ...; trigger analogo suDOCS_ATTACHMENTconSEQ_DOCS_ATTACHMENT. Le SP usanoRETURNING ID_DOCUMENT/ID_ATTACHMENT INTO PNEWINDEX. - Note: il ciclo
WHILEdi riallineamento sequence è O(n) sul gap → costoso se si inserisce un id molto maggiore del corrente.
BR-DOC-008 — Vincoli NOT NULL e default di DOCS_DOCUMENT
- Regola:
DOCS_DOCUMENTimpone NOT NULL suDESCRIPTION,IS_LAST_VERSION,RELATION_TYPE,ISVALID,VERSION,CREATED(oltre aID_DOCUMENT). Default di colonna:RELATION_TYPE = 0,ISCANCELLED = 0,ID_DOC_SITE = 0,ISVALID = 0,VERSION = 1,CREATED = SYSDATE,NUM_ATTACH = 0. - Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza: catalogo constraint
INFOCAD_TEST38.DOCS_DOCUMENT— check"DESCRIPTION" IS NOT NULL,"IS_LAST_VERSION" IS NOT NULL,"RELATION_TYPE" IS NOT NULL,"ISVALID" IS NOT NULL,"VERSION" IS NOT NULL,"CREATED" IS NOT NULL; default colonneRELATION_TYPE=0,ISVALID=0,VERSION=1,CREATED=SYSDATE(dadocs/_generated/db-detail.json, verificato su metadati DB). - Note:
SYS_PROTOCOL/USER_PROTOCOL/USER_VERSIONsono nullable e senza UNIQUE (rilevante per BR-DOC-004). Self-FKID_PARENT,ID_PREVIOUS_VERSION,ID_NEXT_VERSIONsostengono le relazioni di versione/rinnovo.
BR-DOC-009 — Vincoli NOT NULL di DOCS_ATTACHMENT
- Regola:
DOCS_ATTACHMENTimpone NOT NULL suFILE_SIZE,FILE_EXTENSION,FILE_NAME,DOCUMENT_FILE(oltre aID_ATTACHMENT). Un allegato senza estensione, nome, dimensione o contenuto binario è rifiutato a livello DB. - Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza: catalogo constraint
INFOCAD_TEST38.DOCS_ATTACHMENT— check"FILE_SIZE" IS NOT NULL,"FILE_EXTENSION" IS NOT NULL,"FILE_NAME" IS NOT NULL,"DOCUMENT_FILE" IS NOT NULL(dadb-detail.json).CONTENT_TYPEè nullable. - Note: la creazione dell'attachment è condizionata alla presenza del BLOB (BR-DOC-006), quindi in pratica questi campi arrivano valorizzati; ma un allegato con
FileSize = 0/estensione vuota fallirebbe qui.
BR-DOC-010 — Categoria non obbligatoria a DB; 0 → NULL
- Regola:
ID_CATEGORYè nullable inDOCS_DOCUMENT; la DAL, prima di invocare la SP, converteidCategory = 0(o assente) inDBNull.Value. L'eventuale obbligatorietà della categoria è imposta solo lato UI (vedi BR-ECM-016). - Tipo: validation · Enforcement: mixed (DB/BL) · Confidence: VERIFIED · customer_specific: false
- Evidenza:
Document_DAL.vb:418-427(Insert:If idCategory = 0 Then idcategoryparam.Value = DBNull.Value), analogo Renew:1732-1741; controprova DBDOC_RENEWDOCUMENT/DOC_REVIEWDOCUMENT/DOC_UPDATEDOCUMENT:IF PNULLABLECATEGORY IS NULL OR PNULLABLECATEGORY = 0 THEN PNULLABLECATEGORY := NULL;; colonnaID_CATEGORYnullable (catalogo). - Note: percorsi che bypassano la validazione UI possono creare documenti senza categoria.
BR-DOC-011 — Associazione tag in blocco
- Regola: i tag selezionati sono passati come array PL/SQL (
PIDTAGLIST,PLSQLAssociativeArray) e inseriti in blocco inDOCS_TAG_DOCUMENTdaDOC_ADDTAGSTODOCUMENTcon un unicoINSERT ... SELECTdall'array; una riga(ID_TAG, ID_DOCUMENT)per ciascun tag. - Tipo: state-transition · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza:
Document_DAL.vb:396-397(PIDTAGLIST,CollectionType = OracleCollectionType.PLSQLAssociativeArray); controprova DBDOC_ADDTAGSTODOCUMENT:INSERT INTO DOCS_TAG_DOCUMENT (ID_TAG, ID_DOCUMENT) (SELECT ASR.*, PIDDOCUMENT FROM (SELECT * FROM TABLE(CAST(tmplist AS MYINTTABLE))) ASR);.
BR-DOC-012 — DOCS_TAG_DOCUMENT senza PK/unique (duplicati possibili)
- Regola: la tabella di associazione
DOCS_TAG_DOCUMENTnon ha primary key né unique; le colonneID_TAG/ID_DOCUMENTsono anche nullable. Nulla impedisce a livello DB associazioni tag↔documento duplicate. - Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza: catalogo
INFOCAD_TEST38.DOCS_TAG_DOCUMENT—pk: [],uniques: [], colonneID_TAG/ID_DOCUMENTnullable, con sole FK versoDOCS_TAGeDOCS_DOCUMENT(dadb-detail.json). - Note: in update la pulizia integrale (BR-DOC-017) mitiga l'accumulo, ma un doppio invio in creazione o inserimenti concorrenti possono duplicare le righe.
BR-DOC-013 — Peso dei tag non ricalcolato in creazione
- Regola: il ricalcolo del "peso" dei tag (
DOC_REFRESHTAGWEIGHT) all'interno diDOC_ADDTAGSTODOCUMENTè commentato: creando/associando tag il loro peso non viene aggiornato. - Tipo: defect · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza: controprova DB
DOC_ADDTAGSTODOCUMENT: blocco-- FOR I IN PIDTAGLIST.FIRST..PIDTAGLIST.LAST LOOP -- DOC_REFRESHTAGWEIGHT(PIDTAGLIST(I)); -- END LOOP;interamente commentato. - Note: coerente con l'open question di FLOW-DOC-001; comportamento probabilmente disattivato di proposito ma non documentato.
BR-DOC-014 — Attributi custom fuori transazione (log-only)
- Regola: nel BL, l'inserimento degli attributi custom (generici e specifici) avviene in un
Try/Catchseparato rispetto all'insert del documento: un errore sugli attributi viene solo loggato (ExceptionLogger.LogException) e non annulla il documento già creato. Stesso pattern inInsert,Renew,Review. - Tipo: error-handling · Enforcement: BL · Confidence: VERIFIED · customer_specific: false
- Evidenza:
Document_BL.vb:57-79(Insert: attributi inTryisolato,Catch ... LogException),:81(Return idDoc); analoghi Renew:816-838, Review:881-903. - Note: probable data-integrity gap — documento persistito senza i suoi attributi in caso di errore parziale; nessuna atomicità con
DOCS_DOCUMENT.
BR-DOC-015 — Tipizzazione degli attributi custom
- Regola: gli attributi custom sono classificati per
Typein quattro categorie (STRING,LIST,NUMBER,DATE, confronto in upper-case); per il tipoDATEil valore è letto da un campo di form denominatoRadDate_<idAttributo>, per gli altri da un campo<idAttributo>. PerLISTun valore vuoto è salvato comeNothing. - Tipo: calculation · Enforcement: BL · Confidence: VERIFIED · customer_specific: false
- Evidenza:
DocumentCreateControl.ascx.vb:231-268(attributi generici,RadDate_a:267),:275-312(attributi specifici,RadDate_a:311). - Note: la SP
DOC_ADDDOCATTRIBUTEdichiaraPIDDOCUMENT IN VARCHAR2(non NUMBER) — piccola incoerenza di tipo lato DB, l'id documento è passato come stringa e usato inINSERT INTO DOCS_DOCUMENT_ATTRIBUTE.
BR-DOC-016 — Attributi specifici presi dalla categoria padre
- Regola: gli attributi custom "specifici" del documento sono caricati con
docCtrl.GetAttributesByCategory(doc.Category.IdParent), cioè in base alla categoria padre della categoria selezionata, non alla categoria foglia direttamente. - Tipo: calculation · Enforcement: BL · Confidence: SUPPORTED · customer_specific: false
- Evidenza:
DocumentCreateControl.ascx.vb:273-274(If doc.Category IsNot Nothing Then For Each attribute ... In docCtrl.GetAttributesByCategory(CInt(doc.Category.IdParent))). - Note: possibile anomalia o convenzione (attributi ereditati dal livello padre); da confermare con il modello categorie. Se la categoria selezionata è radice (
IdParent = 0/nullo) il set specifico può risultare vuoto.
BR-DOC-017 — Update = sostituzione integrale dei tag
- Regola: l'aggiornamento di un documento rimuove tutti i tag esistenti e reinserisce quelli passati dal client:
DOC_UPDATEDOCUMENTchiamaDOC_REMOVEALLTAGSFROMDOCUMENT(PIDDOCUMENT)seguito daDOC_ADDTAGSTODOCUMENT(PIDTAGLIST, PIDDOCUMENT). Analogamente nel BL gli attributi custom sono cancellati e reinseriti (DeleteDocAttribute+AddDocAttribute). - Tipo: state-transition · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza: controprova DB
DOC_UPDATEDOCUMENT:DOC_REMOVEALLTAGSFROMDOCUMENT(PIDDOCUMENT); DOC_ADDTAGSTODOCUMENT(PIDTAGLIST, PIDDOCUMENT);; BL attributiDocument_BL.vb:135-154(DeleteDocAttribute+ re-AddDocAttribute). - Note: nessun merge — un tag non presente nella lista passata viene perso. (Coerente con BR-ECM-019.)
BR-DOC-018 — Update non tocca SYS_PROTOCOL né VERSION
- Regola: la
UPDATE DOCS_DOCUMENTdiDOC_UPDATEDOCUMENTaggiorna descrizione, note, ubicazione, validità, categoria,USER_PROTOCOLeUSER_VERSION, ma non modificaSYS_PROTOCOLnéVERSION: protocollo di sistema e numero di versione restano quelli assegnati alla creazione. - Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza: controprova DB
DOC_UPDATEDOCUMENT: laSET ...elencaUSER_PROTOCOL = PUSERPROTOCOL, USER_VERSION = PUSERVERSIONma nonSYS_PROTOCOLnéVERSION. La DAL Update (Document_DAL.vb:1395-1500) non passa alcun parametroPSYSPROTOCOL. - Note: solo la revisione (BR-DOC-021) incrementa
VERSION; l'update in-place è "silente" sulla versione di sistema.
BR-DOC-019 — Update: sgancio dell'allegato se assente
- Regola: in
DOC_UPDATEDOCUMENT, se non viene passato un nuovo BLOB ePIDATTACHMENTè0/NULL, la colonnaID_ATTACHMENTdel documento viene impostata aNULL(allegato scollegato). Il BL, quando il DTO non ha allegato, forzaAttachment.ID_DTO = 0eDocumentFile = Nothing, innescando questo ramo. - Tipo: data-integrity · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza: controprova DB
DOC_UPDATEDOCUMENT:ELSIF PIDATTACHMENT = 0 OR PIDATTACHMENT IS NULL THEN IDATTACHMENT := NULL;eSET ... ID_ATTACHMENT = IDATTACHMENT; BLDocument_BL.vb:99-103(If doc.Attachment Is Nothing Then ... ID_DTO = 0 : DocumentFile = Nothing). - Note: probable defect — un update che non ri-carica l'allegato può sganciare silenziosamente il file dal documento; la riga in
DOCS_ATTACHMENTnon viene cancellata (resta orfana).
BR-DOC-020 — Rinnovo = nuovo documento figlio (RELATION_TYPE 0)
- Regola:
DOC_RENEWDOCUMENTinserisce un nuovo documento conID_PARENT = PIDOLDDOCUMENTeRELATION_TYPE = 0, riprendendo anagrafica/allegato/tag dal DTO; il documento di partenza non viene modificato (nessun aggiornamento diIS_LAST_VERSION/ID_NEXT_VERSION). Il nuovo documento riceve un nuovo protocollo di sistema. - Tipo: state-transition · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza: controprova DB
DOC_RENEWDOCUMENT:INSERT INTO DOCS_DOCUMENT (... ID_PARENT, RELATION_TYPE ...) VALUES (... PIDOLDDOCUMENT, 0, ...) RETURNING ID_DOCUMENT INTO PNEWINDEX; DOC_ADDTAGSTODOCUMENT(PIDTAGLIST, PNEWINDEX);; DALDocument_DAL.vb:1649-1773, BLDocument_BL.vb:785-814(doc.ParentID). - Note: il rinnovo è una relazione padre-figlio (
ID_PARENT), distinta dalla catena di versione della revisione (BR-DOC-021).
BR-DOC-021 — Revisione = nuova versione in catena (RELATION_TYPE 1)
- Regola:
DOC_REVIEWDOCUMENTcalcolaNEWVERSION = VERSION_vecchio + 1, inserisce un nuovo documento conID_PREVIOUS_VERSION = PIDOLDDOCUMENT,RELATION_TYPE = 1,VERSION = NEWVERSION, poi aggiorna il documento precedente ponendoIS_LAST_VERSION = 0eID_NEXT_VERSION = <nuovo>. Il nuovo documento riceve un nuovo protocollo di sistema. - Tipo: state-transition · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza: controprova DB
DOC_REVIEWDOCUMENT:SELECT (VERSION + 1) INTO NEWVERSION FROM DOCS_DOCUMENT WHERE ID_DOCUMENT = PIDOLDDOCUMENT;→INSERT ... (ID_PREVIOUS_VERSION, RELATION_TYPE, VERSION ...) VALUES (... PIDOLDDOCUMENT, 1, NEWVERSION ...)→UPDATE DOCS_DOCUMENT SET IS_LAST_VERSION = 0, ID_NEXT_VERSION = PNEWINDEX WHERE ID_DOCUMENT = PIDOLDDOCUMENT;; DALDocument_DAL.vb:1785-1904, BLDocument_BL.vb:849-905(doc.PreviousVersionID). - Note: la catena di versione è una lista concatenata (
ID_PREVIOUS_VERSION/ID_NEXT_VERSION). Il flagIS_LAST_VERSIONdel nuovo documento è quello passato dal client (PISLASTVERSION): se il client non lo imposta a 1, la catena può restare senza "ultima versione" valorizzata (vedi BR-DOC-023).
BR-DOC-022 — Magic number RELATION_TYPE
- Regola: la colonna
RELATION_TYPEcodifica il tipo di relazione del documento:0= documento standalone / rinnovo (creazione eDOC_RENEWDOCUMENT),1= revisione/versione (DOC_REVIEWDOCUMENT). - Tipo: magic-number · Enforcement: DB · Confidence: VERIFIED · customer_specific: false
- Evidenza:
DOC_CREATEDOCUMENTnon valorizzaRELATION_TYPE→ default0;DOC_RENEWDOCUMENTinserisceRELATION_TYPE = 0;DOC_REVIEWDOCUMENTinserisceRELATION_TYPE = 1(controprova DBUSER_SOURCE); default colonnaRELATION_TYPE = 0(catalogo). - Note: valori numerici hard-coded nel PL/SQL senza tabella di lookup; il significato è desumibile solo dal codice.
BR-DOC-023 — Documento creato con IS_LAST_VERSION = 0
- Regola: il wizard di creazione istanzia
New Objects.Documente non imposta maidoc.IsLastVersion; la property VB.NET default èFalse, quindi la DAL passaPISLASTVERSION = 0e il documento viene creato conIS_LAST_VERSION = 0. - Tipo: defect · Enforcement: mixed (BL/DB) · Confidence: SUPPORTED · customer_specific: false
- Evidenza:
DocumentCreateControl.ascx.vb:180(Dim doc As New Objects.Document) — nessuna assegnazione adoc.IsLastVersionnel percorsoInsertDocument(:174-320); DTODocumentSharedObjects/Objects/Document.vb:13(Private _IsLastVersion As Boolean, defaultFalse); DALDocument_DAL.vb:372(PISLASTVERSIONdaisLastVersion). - Note: probable defect — un documento appena creato risulterebbe "non ultima versione". Da verificare se un percorso a valle (workflow/pubblicazione) corregge il flag; altrimenti le viste che filtrano
IS_LAST_VERSION = 1non mostrerebbero i documenti nuovi.
BR-DOC-024 — Stamping alla creazione
- Regola: alla creazione il documento riceve
START_DATE = SYSDATE,END_DATE = NULLeCREATEDBY = WS.SessionContact.ID_DTO(l'utente autenticato).CREATEDè valorizzata dal default di colonna (SYSDATE). - Tipo: calculation · Enforcement: mixed (BL/DB) · Confidence: VERIFIED · customer_specific: false
- Evidenza:
DocumentCreateControl.ascx.vb:181(doc.CreatedBy = WS.SessionContact.ID_DTO); controprova DBDOC_CREATEDOCUMENT:INSERT ... (START_DATE, END_DATE, ... CREATEDBY ...) VALUES (... SYSDATE(), NULL, ... PCREATEDBY ...); default colonnaCREATED = SYSDATE(catalogo).
BR-DOC-025 — Rollback fisico se manca il contatto workflow
- Regola: dopo l'insert, l'ingresso in workflow (
CreateWorkFlowEntryPoint) può fallire se non trova il contatto; in tal caso il documento appena creato viene cancellato fisicamente (docCtrl.FinalDelete→DOC_PHYSICALDELETEDOCUMENT) e le relative scadenze eliminate. - Tipo: error-handling/state · Enforcement: mixed · Confidence: VERIFIED · customer_specific: false
- Evidenza:
DocumentCreateControl.ascx.vb:358(CreateWorkFlowEntryPoint),:360(checkActionResult),:378-384(ramo else:docCtrl.FinalDelete(newDocID)+deadCtrl.DeleteByIdDocument(newDocID)); DALDocument_DAL.vb:21-28(FinalDelete→DOC_PHYSICALDELETEDOCUMENT). - Note: cancellazione fisica (non logica) del documento e dell'allegato; compensazione applicativa, non transazione DB.
BR-DOC-026 — Inserimento "da cancellato"
- Regola: se la proprietà
InsertCancelledè vera (accesso da RequestCenter/link al documentale o esigenze custom da property), subito dopo l'insert riuscito il documento viene messo in cancellazione logica (docCtrl.LogicalDelete→DOC_LOGICALDELETEDOCUMENT). - Tipo: state-transition · Enforcement: BL · Confidence: VERIFIED · customer_specific: true
- Evidenza:
DocumentCreateControl.ascx.vb:364-365(commento "gestione di inserimento da cancellato se effettuo da RequestCenter…" +If InsertCancelled Then docCtrl.LogicalDelete(newDocID)); property:161(Public Property InsertCancelled As Boolean); DALDocument_DAL.vb:38-45(DOC_LOGICALDELETEDOCUMENT). - Note: variante di comportamento cliente-specifica (integrazione RequestCenter); il documento nasce già cancellato logicamente.
BR-DOC-027 — Tenancy con permesso hard-coded 2
- Regola: alla creazione, il documento è assegnato al tenant corrente (
WS.CurrentTenant.ID_DTO) con livello di permesso2codificato in modo fisso, tramiteSetDocumentTenancies("DOCUMENT", newDocID, ...). - Tipo: magic-number · Enforcement: BL · Confidence: VERIFIED · customer_specific: false
- Evidenza:
DocumentCreateControl.ascx.vb:347-351(tenancyIDs.Add(WS.CurrentTenant.ID_DTO),perms.Add(2),docCtrl.SetDocumentTenancies("DOCUMENT", newDocID, tenancyIDs, perms, True)); DALDocument_DAL.vb:2606(DOC_SETDOCUMENTTENANTS). - Note: magic number
2(significato del livello permesso non esplicitato) e stringa entità"DOCUMENT"hard-coded.
BR-DOC-028 — Relazione con l'ECM esterno
- Regola: la creazione dell'entità core (
DOC_CREATEDOCUMENT) persiste il file come BLOB in Oracle (DOCS_ATTACHMENT) e non invoca alcun ECM esterno. La delega del file a un ECM esterno (Alfresco/OpenText/Docs) e la scrittura diUSER_PROTOCOLcon l'ID esterno avvengono solo nel flusso di pubblicazione (vediBR-ECM, BR-ECM-001/003/007), condizionati al flagSaveAttachExtMode. - Tipo: integration · Enforcement: mixed · Confidence: SUPPORTED · customer_specific: false
- Evidenza:
DOC_CREATEDOCUMENT(controprova DB) inserisce l'allegato solo localmente viaDOC_CREATEATTACHMENT; nel percorsoInsertDocument(DocumentCreateControl.ascx.vb:174-399) non c'è alcuna chiamata a provider ECM; cross-ref BR-ECM-001 (SaveAttachExtMode) e BR-ECM-007 (USER_PROTOCOL). - Note: la colonna
USER_PROTOCOL(nullable) è il punto di aggancio riusato dall'ECM in pubblicazione; alla creazione contiene il "protocollo utente" digitato dall'operatore o resta vuota.
BR-DOC-029 — Wiring via .NET Remoting, grant UI non ri-verificati
- Regola:
DocumentController.Insertdelega aIDocument_BLrisolto a runtime viaDAOFactoryconActivator.GetObject(...)sul canale RemotingService_Document; l'implementazioneDocument_BLereditaMarshalByRefObject. I controlli di autorizzazione/grant applicati lato UI non risultano ri-verificati dal servizio server (pattern TD-008). - Tipo: security · Enforcement: BL · Confidence: SUPPORTED · customer_specific: false
- Evidenza:
DocumentController.vb:16-17(Return DirectCast(Me.DAO, IDocument_BL).Insert(dto));DAOFactory.vb:14-15(Case enControllers.Ctrl_Document ... Activator.GetObject(GetType(IDocument_BL), ... Service_Document));Document_BL.vb:12-14(Inherits MarshalByRefObject,Implements IDocument_BL). - Note: flag UI-only — un chiamante che raggiunga direttamente il canale Remoting/BL non passa per la validazione del wizard (BR-DOC-005, categoria obbligatoria, ecc.).
Rischi trasversali (sintesi)
- Regole solo-UI (bypassabili da percorsi non-UI, upload massivo, Remoting diretto): BR-DOC-005 (anti-duplicato), obbligatorietà categoria (BR-ECM-016), e in generale i controlli del wizard non ri-verificati dal BL (BR-DOC-029).
- Regole solo-DB (logica interna alle procedure/trigger, non visibile dal codice VB): BR-DOC-006, BR-DOC-007, BR-DOC-011, BR-DOC-017, BR-DOC-018, BR-DOC-019, BR-DOC-020, BR-DOC-021.
- Magic number:
RELATION_TYPE0/1 (BR-DOC-022), permesso tenancy2(BR-DOC-027), defaultVERSION = 1,ISVALID = 0(BR-DOC-008). - Numerazione/protocollo: formula dinamica in dati (BR-DOC-001/002), singleton implicito (BR-DOC-003), assenza di sequence e di UNIQUE su
SYS_PROTOCOL→ rischio collisione (BR-DOC-004). - Integrità dati / probable defect: attributi fuori transazione (BR-DOC-014), sgancio allegato in update (BR-DOC-019),
IS_LAST_VERSION = 0alla creazione (BR-DOC-023), duplicati tag (BR-DOC-012), peso tag non aggiornato (BR-DOC-013). - Date logic:
START_DATE/CREATED = SYSDATE,END_DATE = NULL(BR-DOC-024);DATE_DOCUMENTopzionale (nullable). - Varianti cliente: inserimento da cancellato (BR-DOC-026, RequestCenter/custom).
- Hidden flag / dipendenze:
InsertCancelled(BR-DOC-026),autoPublish(Salva vs Salva e pubblica), relazione conSaveAttachExtModedell'ECM (BR-DOC-028).
Domande aperte
- Come viene effettivamente incrementato il progressivo di protocollo, se
SEQ_DOCS_PROTOCOLè commentata? La formula inDOCS_PROTOCOLFORMATfaMAX+1(soggetto a race) o altro? (BR-DOC-001/004) - Il documento appena creato con
IS_LAST_VERSION = 0viene corretto da un passo a valle (workflow/pubblicazione) o è un difetto? (BR-DOC-023) - Perché gli attributi specifici sono letti dalla categoria padre e non dalla categoria selezionata? È eredità voluta? (BR-DOC-016)
- In caso di update senza ri-upload dell'allegato, lo sgancio di
ID_ATTACHMENTè intenzionale? Chi ripulisce la riga orfana inDOCS_ATTACHMENT? (BR-DOC-019) - Il canale .NET Remoting
Service_Documentapplica una qualche autorizzazione lato server o si affida interamente alla UI? (BR-DOC-029, TD-008)