BR-PRJ — Regole di business del dominio Project / Commessa
Regole di business estratte dal flusso pilota FLOW-PRJ-001 (creazione di un nuovo progetto/commessa dal wizard
ProjectInsert) e dai sorgenti correlati. Il dominio Project (ProjectCenter) gestisce il ciclo di vita della commessa: anagrafica progetto, codice, workflow di stato, storico, team, tag, categorie di costo, attività, allegati e campi custom.La creazione passa dalla procedura Oracle standalone
PRJ_INSERTPROJECT(INSERT suPROJECT,RETURNING ID_PROJECT), orchestrata lato BL daProject_BL.Insert, che invoca una serie di SP companion (PRJ_INSERTPROJECTSTATUS,PRJ_INSERTPROJECTHISTORY,PRJ_INSERTPROJECTTEAM,PRJ_INSERTPROJECTATTACHMENT,PRJ_ADDTAGSTOPROJECT,PRJ_UPDATEPROJECTCODE). Nessun ORM; accesso via ODP.NET (DataLayer+OracleParameter).Sistema: Infocad (Descor) — backend Oracle
INFOCAD_TEST38, UI ASP.NET Web Forms (code-behind C#, ProjectCenterWeb) + boundary .NET Remoting traProjectController(client) eProject_BL(server,MarshalByRefObject).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/ProjectBL/Project_BL.vb:305). - Evidenza DB: letta in sola lettura da
USER_SOURCE(sorgente procedure/trigger),USER_CONSTRAINTS(vincoli),USER_TRIGGERS(trigger),USER_TAB_COLUMNS(default colonne) suINFOCAD_TEST38, limitatamente aPRJ_INSERTPROJECTe SP companion, al triggerCNT_PROJECTe alla tabellaPROJECT. Nessuna lettura di dati applicativi, nessuna DML/DDL. Le righe delle procedure/trigger sono indicate comePRJ_INSERTPROJECT src:NN(numerazioneUSER_SOURCE). - La verifica DB conferma diverse regole che nel flusso pilota erano solo SUPPORTED e ne emerge un
gruppo di regole enforced SOLO in SQL (trigger
CNT_PROJECT, vincoli NOT NULL, default colonna, workflow di stato hard-coded) non visibili dal codice applicativo. - Flag rilevanti: assenza di controlli di grant nel path di insert (boundary Remoting non ri-verificato, pattern TD-008), transazionalità non garantita, doppia generazione del codice (trigger DB + parametrico UI), magic number nel workflow di stato.
Registro delle regole (register)
| id | regola | tipo | enforcement | conf |
|---|---|---|---|---|
| BR-PRJ-001 | La creazione progetto è INSERT-only (PRJ_INSERTPROJECT); create e update sono path distinti (wizard ProjectInsert vs ProjectUpdate, SP PRJ_UPDATEPROJECT) |
process | mixed | VERIFIED |
| BR-PRJ-002 | ID_PROJECT è assegnato dalla sequence SEQ_PRJ_PROJECT se NULL (trigger CNT_PROJECT BEFORE INSERT) |
calculation | DB | VERIFIED |
| BR-PRJ-003 | Se il codice è NULL all'insert, il trigger CNT_PROJECT genera PRJ-<YYYY>-<NNNNN> (anno + currval seq a 5 cifre) |
calculation | DB | VERIFIED |
| BR-PRJ-004 | Se Code è vuoto, dopo l'insert la UI genera il codice via motore parametrico (GenerateProjectCode + GetNewCode) e lo sovrascrive con PRJ_UPDATEPROJECTCODE |
calculation | mixed | SUPPORTED |
| BR-PRJ-005 | CODE è obbligatorio a DB (SYS_C001719758 NOT NULL) |
validation | DB | VERIFIED |
| BR-PRJ-006 | NAME è obbligatorio (constraint DB SYS_C001719759 + RequiredFieldValidator UI) |
validation | mixed | VERIFIED |
| BR-PRJ-007 | EXPECTED_START_DATE e EXPECTED_END_DATE sono obbligatorie (constraint DB + RequiredFieldValidator UI) |
validation | mixed | VERIFIED |
| BR-PRJ-008 | Se ExpectedEndDate non impostata, la BL la forza a ExpectedStartDate + 1 giorno |
date-logic | BL | VERIFIED |
| BR-PRJ-009 | START_DATE/END_DATE sono inizializzate alle date "expected" (sia in UI sia dalla SP che copia i parametri expected) |
calculation | mixed | VERIFIED |
| BR-PRJ-010 | Validazione lato client della conformità date (fine > inizio) via CustomValidator (validateExDate/validateDate) |
validation | UI | SUPPORTED |
| BR-PRJ-011 | CREATED è impostata a SYSDATE all'insert del progetto |
calculation | DB | VERIFIED |
| BR-PRJ-012 | EFFECTIVE_COST è NOT NULL con default DB 0 (la SP non lo valorizza) |
validation | DB | VERIFIED |
| BR-PRJ-013 | Ogni progetto nasce con 8 stati standard hard-coded in PROJECT_STATUS (Bozza..Cancellato) e stato iniziale sempre "Bozza" (ID_STATUS=0) |
state-transition | DB | VERIFIED |
| BR-PRJ-014 | L'ORDER_ID di visualizzazione degli stati NON coincide con ID_STATUS (mapping fisso Bozza=3, Cancellato=0, Annullato=1, Sospeso=2, Pubblicato=4, Approvato=5, In Corso=6, Eseguito=7) |
config-flag | DB | VERIFIED |
| BR-PRJ-015 | Alla creazione viene scritta una riga di storico iniziale in PROJECT_HISTORY (MODIFIED=SYSDATE, stato = Bozza, ID_ACTIVITY omesso se attività = 0) |
process | mixed | VERIFIED |
| BR-PRJ-016 | I membri del team sono inseriti in loop (PRJ_INSERTPROJECTTEAM); i due rami del confronto team.IdContact = idcontact producono lo stesso insert (logica ridondante) |
process | BL | VERIFIED |
| BR-PRJ-017 | Il membro team senza ID_COMPANY (NULL) viene inserito senza la colonna azienda (ramo condizionale nella SP) |
config-flag | DB | VERIFIED |
| BR-PRJ-018 | I tag sono associati da PRJ_ADDTAGSTOPROJECT dentro l'insert; se la lista è il sentinella {0} (COUNT=1 e valore 0) non viene inserito alcun tag |
validation | DB | VERIFIED |
| BR-PRJ-019 | La lista id tag è passata come HELPERS.numberlist (associative array PL/SQL), non come stringa/XML |
process | mixed | VERIFIED |
| BR-PRJ-020 | La categoria è opzionale: PID_CATEGORY <> 0 seleziona il ramo INSERT con ID_CATEGORY, altrimenti senza (0 = nessuna categoria) |
config-flag | DB | VERIFIED |
| BR-PRJ-021 | Le categorie di costo sono gestite per Status del DTO: Empty→Delete, NewObject→Insert, OnDBModifiedOject→Update |
process | BL | VERIFIED |
| BR-PRJ-022 | Gli allegati sono gestiti post-insert: upload dei file temporanei in GLOBAL_DOCUMENTS, PRJ_INSERTPROJECTATTACHMENT e cancellazione del file temporaneo |
process | mixed | SUPPORTED |
| BR-PRJ-023 | I campi custom sono serializzati nella colonna FIELDS (CLOB) via createExtraField(prj.Fields) |
process | BL | SUPPORTED |
| BR-PRJ-024 | Nel path di insert progetto NON esistono controlli di grant/autorizzazione (né UI code-behind né BL); il boundary Remoting non ri-verifica i grant | permission | none/UI | INFERRED |
| BR-PRJ-025 | L'orchestrazione BL usa overload DAL SENZA DataLayer condiviso: ogni SP gira su connessione propria, quindi un fallimento parziale (es. team) può lasciare progetto+stati committati |
process | BL | INFERRED |
| BR-PRJ-026 | ID_PROJECT è immutabile: un UPDATE che lo modifica solleva ORA-20000 (trigger CNT_PROJECT) |
validation | DB | VERIFIED |
| BR-PRJ-027 | In update progetto viene sempre scritta una riga di storico (InsertHistory) per storicizzare lo stato corrente |
process | mixed | VERIFIED |
Dettaglio delle regole
BR-PRJ-001 — Creazione INSERT-only, path create/update distinti
- Tipo: process · Enforcement: mixed (BL + DB) · Confidence: VERIFIED · Customer-specific: no
- Statement: La creazione di una commessa è sempre un INSERT eseguito da
PRJ_INSERTPROJECT; non esiste ramo di update nella procedura di insert. La modifica ha una SP dedicata (PRJ_UPDATEPROJECT) e un wizard distinto (ProjectUpdate). Create e update non condividono il codice. - Evidenza:
Project_BL.vb:305(ProjectDALFactory.GetProjectDAL.Insert),ProjectDAL.vb:253(ExecuteNonQueryStoredProcedure("PRJ_INSERTPROJECT"));ProjectDAL.vb:512(PRJ_UPDATEPROJECT);PRJ_INSERTPROJECT src:18-26(solo INSERT).
BR-PRJ-002 — Identity da sequence via trigger
- Tipo: calculation · Enforcement: DB · Confidence: VERIFIED · Customer-specific: no
- Statement:
ID_PROJECTnon è passato dall'applicazione; il triggerCNT_PROJECT(BEFORE INSERT, FOR EACH ROW) lo popola daSEQ_PRJ_PROJECT.NEXTVALse:new.ID_PROJECT IS NULL. L'id è restituito all'app viaRETURNING ID_PROJECT INTO PNEWINDEX. - Evidenza:
CNT_PROJECT src:11-15(SEQ_PRJ_PROJECT.NEXTVAL);PRJ_INSERTPROJECT src:21,26(RETURNING ID_PROJECT INTO PNEWINDEX);ProjectDAL.vb:254(ritornoPNEWINDEX).
BR-PRJ-003 — Codice auto-generato dal trigger (magic format)
- Tipo: calculation · Enforcement: DB · Confidence: VERIFIED · Customer-specific: no
- Statement: Se
CODEè NULL all'insert, il triggerCNT_PROJECTgenera un codice nel formatoPRJ-<YYYY>-<NNNNN>(letteralmente'PRJ-' || EXTRACT(YEAR FROM SYSDATE) || '-' || TRIM(TO_CHAR(SEQ_PRJ_PROJECT.CURRVAL, '00000')), cioè seq corrente su 5 cifre con zero-padding). Magic: prefissoPRJ-e maschera00000hard-coded nel trigger. - Evidenza:
CNT_PROJECT src:16-21.
BR-PRJ-004 — Codice parametrico UI sovrascrive il codice generato (interazione/ridondanza)
- Tipo: calculation · Enforcement: mixed (UI + DB) · Confidence: SUPPORTED · Customer-specific: sì
- Statement: Dopo l'insert, se
Codeè vuoto la UI chiama il motore parametrico (Parametric.Project.Project.GenerateProjectCode+prjCtrl.GetNewCode) e sovrascrive il codice conPRJ_UPDATEPROJECTCODE. Il motore parametrico è configurabile per cliente. Interazione / probabile ridondanza: poichéPCODEè passato NULL quando vuoto, il triggerCNT_PROJECT(BR-PRJ-003) ha già assegnato un codicePRJ-YYYY-NNNNN; la UI lo rimpiazza subito con quello parametrico. Il codice del trigger è quindi transitorio quando la UI genera il proprio. - Evidenza:
ProjectInsert.ascx.cs:207-212;ProjectDAL.vb:532(PRJ_UPDATEPROJECTCODE);PRJ_UPDATEPROJECTCODE src:5-7(UPDATE PROJECT SET CODE = PCODE). Il motore parametrico non è tracciato fino al DB in questo documento (⇒ SUPPORTED).
BR-PRJ-005 — CODE obbligatorio (DB)
- Tipo: validation · Enforcement: DB · Confidence: VERIFIED · Customer-specific: no
- Statement: La colonna
CODEè NOT NULL. Un insert con codice NULL è ammesso solo perché il triggerCNT_PROJECTlo valorizza prima della scrittura (BR-PRJ-003). - Evidenza: constraint
SYS_C001719758("CODE" IS NOT NULL) suPROJECT.
BR-PRJ-006 — NAME obbligatorio
- Tipo: validation · Enforcement: mixed (UI + DB) · Confidence: VERIFIED · Customer-specific: no
- Statement: Il nome progetto è obbligatorio, enforced sia a UI (
RequiredFieldValidatorcon labelNameLabelRequired) sia a DB (constraint NOT NULL). - Evidenza:
ProjectInfoUpdate.ascx:180(label required); constraintSYS_C001719759("NAME" IS NOT NULL) suPROJECT.
BR-PRJ-007 — Date previste obbligatorie
- Tipo: validation · Enforcement: mixed (UI + DB) · Confidence: VERIFIED · Customer-specific: no
- Statement:
EXPECTED_START_DATEedEXPECTED_END_DATEsono obbligatorie:RequiredFieldValidatora UI ("Data Inizio Prevista obbligatoria" / "Data Fine Prevista obbligatoria") e constraint NOT NULL a DB. - Evidenza:
ProjectInfoUpdate.ascx:223-230,282-289; constraintSYS_C001719760("EXPECTED_START_DATE" IS NOT NULL),SYS_C001719761("EXPECTED_END_DATE" IS NOT NULL).
BR-PRJ-008 — Default ExpectedEndDate = start + 1 giorno (date-logic, magic number)
- Tipo: date-logic · Enforcement: BL · Confidence: VERIFIED · Customer-specific: no
- Statement: Se
ExpectedEndDateèDateTime.MinValue(non impostata), la BL la forza aExpectedStartDate.AddDays(1). Magic number:+1giorno. - Evidenza:
Project_BL.vb:300-302.
BR-PRJ-009 — START_DATE/END_DATE inizializzate alle date previste
- Tipo: calculation · Enforcement: mixed (UI + DB) · Confidence: VERIFIED · Customer-specific: no
- Statement: Le date effettive di inizio/fine sono inizializzate a quelle previste. La UI setta
prj.InfoBase.StartDate = ExpectedStartDateeEndDate = ExpectedEndDate; la SP inserisce comunqueSTART_DATE = PEXPECTED_START_DATE,END_DATE = PEXPECTED_END_DATE(copia dei parametri expected, ignora i valori Start/End passati nell'insert — la SP di insert non ha parametri Start/End dedicati). - Evidenza:
ProjectInsert.ascx.cs:172-173;PRJ_INSERTPROJECT src:21,26(VALUES usanoPEXPECTED_START_DATE/PEXPECTED_END_DATEnelle posizioni START_DATE/END_DATE).
BR-PRJ-010 — Validazione client conformità date
- Tipo: validation · Enforcement: UI (client-side) · Confidence: SUPPORTED · Customer-specific: no
- Statement: La coerenza tra data inizio e fine (previste ed effettive) è controllata lato client
da
CustomValidatorconClientValidationFunctionvalidateExDate/validateDate(messaggio "Data inizio e fine ... non conformi"). Flag UI-only: nessun controllo equivalente a BL/DB (nessun constraint CHECK end>start suPROJECT); un chiamante non-UI (es. import/WCF) può creare un progetto con date incoerenti. - Evidenza:
ProjectInfoUpdate.ascx:216-222,246-252,275-281,308-314. Le funzioni JS non sono ispezionate in dettaglio (⇒ SUPPORTED).
BR-PRJ-011 — CREATED = SYSDATE
- Tipo: calculation · Enforcement: DB · Confidence: VERIFIED · Customer-specific: no
- Statement: La data di creazione è impostata dalla SP a
SYSDATE(server-side, non dal client). La colonna è NOT NULL. - Evidenza:
PRJ_INSERTPROJECT src:21,26(... CREATED ... VALUES (... SYSDATE ...)); constraintSYS_C001719763("CREATED" IS NOT NULL).
BR-PRJ-012 — EFFECTIVE_COST NOT NULL con default 0 (DB-only)
- Tipo: validation · Enforcement: DB · Confidence: VERIFIED · Customer-specific: no
- Statement:
EFFECTIVE_COSTè NOT NULL ma non è tra le colonne dell'INSERT della SP; il valore è fornito dal default di colonna0. Rule enforced solo in SQL, invisibile dal codice applicativo. - Evidenza: constraint
SYS_C001719762("EFFECTIVE_COST" IS NOT NULL);USER_TAB_COLUMNSPROJECT.EFFECTIVE_COSTnullable=N, data_default=0;PRJ_INSERTPROJECT src:18-26(colonna assente).
BR-PRJ-013 — Workflow di 8 stati standard + stato iniziale Bozza (magic numbers)
- Tipo: state-transition · Enforcement: DB · Confidence: VERIFIED · Customer-specific: no
- Statement:
PRJ_INSERTPROJECTSTATUSinserisce sempre 8 righe fisse inPROJECT_STATUS: Bozza(0), Pubblicato(1), In Corso(2), Approvato(3), Eseguito(4), Annullato(5), Sospeso(6), Cancellato(7). La riga "Bozza" restituisceID_PROJECT_STATUS(OUTPNEWINDEX), usato perUPDATE PROJECT SET ID_PROJECT_STATUS = <Bozza>. Ogni progetto nasce in stato "Bozza". I nomi degli stati sono hard-coded (magic strings/numbers) nella procedura. - Evidenza:
PRJ_INSERTPROJECTSTATUS src:6-9(Bozza + RETURNING),src:11-44(altri 7 stati),src:47-49(UPDATE PROJECT SET ID_PROJECT_STATUS = PNEWINDEX);Project_BL.vb:309.
BR-PRJ-014 — ORDER_ID di visualizzazione disallineato da ID_STATUS (hidden mapping)
- Tipo: config-flag · Enforcement: DB · Confidence: VERIFIED · Customer-specific: no
- Statement: L'ordinamento di visualizzazione (
ORDER_ID) non segue l'enumID_STATUS. Mapping fisso: Bozza→3, Pubblicato→4, In Corso→6, Approvato→5, Eseguito→7, Annullato→1, Sospeso→2, Cancellato→0. Magic numbers hard-coded; l'ordine visuale (Cancellato=0 primo, Eseguito=7 ultimo) differisce dall'ordine logico dell'enum. - Evidenza:
PRJ_INSERTPROJECTSTATUS src:9,14,19,24,29,34,39,44(valoriORDER_ID).
BR-PRJ-015 — Storico iniziale alla creazione
- Tipo: process · Enforcement: mixed (BL + DB) · Confidence: VERIFIED · Customer-specific: no
- Statement: Subito dopo la creazione degli stati, la BL scrive una riga iniziale in
PROJECT_HISTORYconInsertHistory(idPrj, 0, idPrjStatus, idcontact). La SP impostaMODIFIED = SYSDATE; conPID_ACTIVITY = 0inserisce senza colonnaID_ACTIVITY, altrimenti la include. Registra lo stato Bozza e il contatto operatore. - Evidenza:
Project_BL.vb:313;PRJ_INSERTPROJECTHISTORY src:8-21.
BR-PRJ-016 — Inserimento team in loop (ramo ridondante — probabile difetto)
- Tipo: process · Enforcement: BL · Confidence: VERIFIED · Customer-specific: no
- Statement: Ogni membro di
prj.Teamè inserito conPRJ_INSERTPROJECTTEAM. Il codice ramifica suIf Not team.IdContact = idcontact ... Else ..., ma entrambi i rami chiamanoInsertTeamcon gli stessi identici argomenti (nel ramo Elseidcontactcoincide conteam.IdContact). Probabile difetto/dead branch: la condizione non produce comportamento differente ed è logica ridondante. - Evidenza:
Project_BL.vb:317-323.
BR-PRJ-017 — ID_COMPANY del team opzionale (ramo condizionale DB)
- Tipo: config-flag · Enforcement: DB · Confidence: VERIFIED · Customer-specific: no
- Statement:
PRJ_INSERTPROJECTTEAMinserisce senza colonnaID_COMPANYquandoPID_COMPANY IS NULL, altrimenti la include. L'azienda del membro è quindi opzionale. - Evidenza:
PRJ_INSERTPROJECTTEAM src:13-24.
BR-PRJ-018 — Associazione tag con sentinella {0}
- Tipo: validation · Enforcement: DB · Confidence: VERIFIED · Customer-specific: no
- Statement:
PRJ_ADDTAGSTOPROJECT(chiamata dentroPRJ_INSERTPROJECT) inserisce le associazioni inPROJECT_TAG_ASSsolo se la lista NON è il sentinella{0}(COUNT = 1 AND (1) = 0). Con lista{0}(nessun tag selezionato) non viene inserito alcun tag. Magic/sentinel:0= "nessun tag". - Evidenza:
PRJ_INSERTPROJECT src:29;PRJ_ADDTAGSTOPROJECT src:7-9(skip),src:11-16(INSERT daTABLE(CAST(tmplist AS MYINTTABLE))).
BR-PRJ-019 — Lista tag come associative array PL/SQL
- Tipo: process · Enforcement: mixed (BL + DB) · Confidence: VERIFIED · Customer-specific: no
- Statement: La lista di id tag è passata come
OracleCollectionType.PLSQLAssociativeArraymappato sul tipo OracleHELPERS.numberlist, deserializzato inMYINTTABLEdaHELPERS.numberlist2TBL; non è una stringa CSV/XML. - Evidenza:
ProjectDAL.vb:194-195(CollectionType = PLSQLAssociativeArray);PRJ_INSERTPROJECT src:10(PIDTAGLIST IN HELPERS.numberlist);PRJ_ADDTAGSTOPROJECT src:4(HELPERS.numberlist2TBL).
BR-PRJ-020 — Categoria opzionale (sentinella 0)
- Tipo: config-flag · Enforcement: DB · Confidence: VERIFIED · Customer-specific: no
- Statement: La procedura ramifica su
PID_CATEGORY <> 0: se diverso da 0 esegue l'INSERT con colonnaID_CATEGORY, altrimenti l'INSERT senza categoria. Sentinel:0= nessuna categoria. Il parametro è alimentato daprj.Category.ID_DTO. - Evidenza:
PRJ_INSERTPROJECT src:16-27;ProjectDAL.vb:233(PID_CATEGORY=prj.Category.ID_DTO).
BR-PRJ-021 — Costi per categoria gestiti per Status del DTO
- Tipo: process · Enforcement: BL · Confidence: VERIFIED · Customer-specific: no
- Statement: Per ogni
ProjectCategoryCostla BL sceglie l'operazione in base acc.Status:Status.Empty→DeleteCategoryCost,Status.NewObject→InsertCategoryCost,Status.OnDBModifiedOject→UpdateCategoryCost. Stessa logica riusata in insert e update (in creazione ci si attende prevalentementeNewObject). - Evidenza:
Project_BL.vb:331-343.
BR-PRJ-022 — Allegati gestiti post-insert
- Tipo: process · Enforcement: mixed (UI + DB) · Confidence: SUPPORTED · Customer-specific: no
- Statement: Dopo la creazione del progetto, la UI itera i file temporanei
(
~/App_Data/ProjectTmpAttachs/<UserName>), li carica inGLOBAL_DOCUMENTS(ctrDoc.UploadDocument), li associa conprjCtrl.InsertAttachment→PRJ_INSERTPROJECTATTACHMENT(INSERT inPROJECT_ATTACHMENTS), poi cancella il file temporaneo. - Evidenza:
ProjectInsert.ascx.cs:181-203;ProjectDAL.vb:342;PRJ_INSERTPROJECTATTACHMENT src:5-8.
BR-PRJ-023 — Campi custom serializzati nel CLOB FIELDS
- Tipo: process · Enforcement: BL · Confidence: SUPPORTED · Customer-specific: no
- Statement: I campi custom (
prj.Fields) sono serializzati dacreateExtraField(prj.Fields)e passati come parametro CLOBPFIELDS, memorizzato nella colonnaFIELDS. Il formato di serializzazione non è ispezionato in dettaglio. - Evidenza:
ProjectDAL.vb:191,232(PFIELDS ... createExtraField(prj.Fields));PRJ_INSERTPROJECT src:9(PFIELDS IN CLOB).
BR-PRJ-024 — Assenza di controlli di grant nel path di insert (security flag)
- Tipo: permission · Enforcement: none / UI-a-monte · Confidence: INFERRED · Customer-specific: no
- Statement: Nel path di creazione progetto NON risultano check di autorizzazione/grant né nel
code-behind (
ProjectInsert.ascx.cs) né nella BL (Project_BL.Insert), a differenza del dominio Property (che richiede grantADD_DELETE/tenancy). Flag: l'unica barriera è l'accesso alla pagina/menu (UI-a-monte, non verificato). Il boundary .NET Remoting traProjectControllereProject_BLnon ri-verifica i grant (pattern TD-008): un chiamante che raggiunge l'endpointIProject_BLpuò creare progetti senza controllo di permessi lato server. - Evidenza: assenza di grep hit per
grant|permission|authorizinProjectInsert.ascx.cseAddProject.aspx.cs;Project_BL.vb:293-350(nessun controllo grant); boundary RemotingDAOFactory.vb(CaseCtrl_Project,Activator.GetObject(GetType(IProject_BL), ...));Project_BL.vb:22-24(Inherits MarshalByRefObject).
BR-PRJ-025 — Transazionalità non garantita (probabile difetto)
- Tipo: process · Enforcement: BL · Confidence: INFERRED · Customer-specific: no
- Statement:
Project_BL.Insertinvoca gli overload DAL senzaDataLayercondiviso (Insert,InsertProjectStatus,InsertHistory,InsertTeamaprono ciascunoUsing dl As New DataLayer(...)), quindi ogni SP gira su una connessione/transazione propria. Probabile difetto: un fallimento parziale (es. durante l'inserimento del team o delle attività) può lasciare committati progetto + stati + storico, con stato incoerente. Esiste un overload transazionale (Insert(..., ByRef dl)) ma non è usato in questa orchestrazione. - Evidenza:
Project_BL.vb:305,309,313,319(overload senzadl);ProjectDAL.vb:223,287(Using dl As New DataLayer(My.Settings.ConnectionName)); overload transazionale disponibile aProjectDAL.vb:180,262,353.
BR-PRJ-026 — ID_PROJECT immutabile in update
- Tipo: validation · Enforcement: DB · Confidence: VERIFIED · Customer-specific: no
- Statement: Il trigger
CNT_PROJECTsul ramo UPDATE sollevaRAISE_APPLICATION_ERROR(-20000, 'Non posso cambiare il contatore per la tabella PROJECT')se:new.ID_PROJECT <> :old.ID_PROJECT. La chiave primaria del progetto è quindi immutabile. - Evidenza:
CNT_PROJECT src:25-33.
BR-PRJ-027 — Storicizzazione ad ogni update
- Tipo: process · Enforcement: mixed (BL + DB) · Confidence: VERIFIED · Customer-specific: no
- Statement: In
Project_BL.Update, dopo la modifica del progetto viene sempre scritta una riga di storico (InsertHistory(prj.ID_DTO, 0, prj.InfoBase.InternalStatus.ID_DTO, idcontact)) per registrare lo stato corrente al momento della modifica. La BL rilegge prima lo stato precedente (SelectById) per diffare team e costi. - Evidenza:
Project_BL.vb:363-370;PRJ_INSERTPROJECTHISTORY src:8-21.
Open questions / follow-up
- Doppia generazione codice (BR-PRJ-003 vs BR-PRJ-004): verificare se il codice del trigger e
quello parametrico possano divergere e se il parametrico è sempre attivo (dipende dalla config
cliente del motore
Parametric.Project). - Transazionalità (BR-PRJ-025): confermare la policy commit/rollback del
DataLayer(autocommit perExecuteNonQueryStoredProcedure?) per stabilire la reale estensione del rischio di stato parziale. - Grant (BR-PRJ-024): verificare se esiste un controllo di accesso a monte (menu/pagina) o se la creazione progetto è effettivamente priva di autorizzazione lato server.
- Date incoerenti (BR-PRJ-010): assenza di constraint DB end>start; valutare se path non-UI possano introdurre date incoerenti.
- BUDGET Int32: il parametro
PBUDGETè passato comeOracleDbType.Int32mentre la colonna èNUMBER— potenziale troncamento di budget con decimali (ProjectDAL.vb:189). Da confermare il tipo diprj.Costs.Budget.