Table of Contents

FLOW-PRJ-001 — Creazione di un progetto/commessa — Project (ProjectCenter)

Flusso end-to-end di creazione di un nuovo progetto (commessa) del modulo Project / ProjectCenter. Path pilota: wizard ProjectInsert.ascx (inserimento interattivo da parte di un operatore) ospitato nella pagina AddProject.aspx. Backend Oracle INFOCAD_TEST38, accesso via stored procedure ODP.NET PRJ_INSERTPROJECT (nessun ORM). L'entità è persistita nella tabella PROJECT, con orchestrazione lato BL che crea anche stati, storico, team, tag, costi e attività associate.

  • Flow ID: FLOW-PRJ-001
  • Repository: InfocadWeb (ASP.NET Web Forms, code-behind C#, ProjectCenterWeb) + InfocadServer (ProjectControllers → ProjectBL → ProjectDAL, VB.NET)
  • Confidence complessiva: VERIFIED (catena UI → code-behind → controller → BL → DAO → stored procedure, confermata su codice e su sorgente DB USER_SOURCE/USER_DEPENDENCIES)
  • has_standalone_write: true — esiste un path di scrittura autonomo e pulito (creazione progetto).

Obiettivo di business

Consentire a un operatore del ProjectCenter di creare una nuova commessa/progetto compilando un wizard multi-step (Info, Costi, Allegati, Associazioni, Team, Campi custom). Al termine il progetto esiste nella tabella PROJECT con un ID_PROJECT generato, il set standard di stati di workflow (PROJECT_STATUS), la riga di storico iniziale (PROJECT_HISTORY), il team (PROJECT_TEAM), i tag (PROJECT_TAG_ASS), i costi per categoria e le eventuali attività, oltre agli allegati caricati e al codice progetto generato dai parametrici.

Attori

  • Operatore ProjectCenter (utente autenticato, WS.SessionLogin, con IdContact di sessione) — path interattivo wizard ProjectInsert.ascx in AddProject.aspx.
  • Oracle INFOCAD_TEST38 (hub anagrafico Project; procedure PRJ_*), con tipi helper HELPERS.numberlist/MYINTTABLE per il passaggio della lista di tag.

Trigger

Click sul pulsante Finish del wizard di inserimento: evento OnFinishButtonClick del RadWizard InsertProjectRadWizard, dichiarato in ProjectInsert.ascx:55, gestito dal metodo InsertProjectRadWizard_FinishButtonClick in ProjectInsert.ascx.cs:143.

Frontend entry point

  • Pagina: ProjectCenterWeb/WindowsPage/AddProject.aspx (registra e ospita il UserControl, AddProject.aspx:4,46); imposta ProjectInsert.Modality = modality.Insert (AddProject.aspx.cs:36).
  • UserControl wizard: ProjectCenterWeb/UserControls/Project/ProjectInsert.ascx (+ sub-control ProjectInfoUpdate, ProjectCategoriesCosts, AttachementsGrid, ProjectUpdateControlAss, ProjectSettingsUpdate, ProjectCustomFieldUpdate per i vari step).
  • Modalità: modality.Insert propagata a tutti i sub-control (ProjectInsert.ascx.cs:100-108).

Sequenza principale (main sequence)

  1. Operatore apre AddProject.aspx, compila gli step del wizard e preme Finish.
  2. ProjectInsert.ascx.csInsertProjectRadWizard_FinishButtonClick (:143) raccoglie i dati dai sub-control nell'oggetto CurrentProject (InfoBase, Costs, Attachments, Tags, Team, Fields; :149-167), imposta le date di default (:172-173) e chiama prjCtrl.Insert(ref prj, IdContact) (:175).
  3. ProjectController.Insert (ProjectController.vb:102) inoltra alla BL via proxy: DirectCast(Me.DAO, IProject_BL).Insert(prj, idcontact) (:105).
    • Me.DAO è risolto da DAOFactory.CreateDAO(Ctrl_Project) (DAOFactory.vb) → endpoint remoting IProject_BL (server Project_BL).
  4. Project_BL.Insert (Project_BL.vb:293) orchestra la scrittura completa:
    • default ExpectedEndDate = start+1g se non impostata (:300-302);
    • crea il progetto: idPrj = ProjectDALFactory.GetProjectDAL.Insert(prj, idcontact) (:305) e assegna prj.ID_DTO = idPrj (:306);
    • stati standard: InsertProjectStatus(idPrj, idPrjStatus) (:309);
    • storico iniziale: InsertHistory(idPrj, 0, idPrjStatus, idcontact) (:313);
    • team: loop su prj.TeamInsertTeam(...) (:317-323);
    • attività: insertActivity(prj.ActivityList, idPrj, idPrjStatus, idcontact) (:328);
    • costi per categoria: switch su StatusInsert/Update/DeleteCategoryCost (:331-343).
  5. ProjectDAL.Insert (ProjectDAL.vb:221, overload senza dl) apre Using dl As New DataLayer(...), prepara i parametri OracleParameter (PCODE, PNAME, PDESCRIPTION, PNOTE, PEXPECTED_START_DATE, PEXPECTED_END_DATE, PBUDGET, PEXPECTED_MANHOURS, PFIELDS CLOB, PIDTAGLIST come PLSQLAssociativeArray, PID_CATEGORY) + OUT PNEWINDEX (:224-251) e invoca dl.ExecuteNonQueryStoredProcedure("PRJ_INSERTPROJECT") (:253); ritorna PNEWINDEX come nuovo id (:254).
  6. Oracle PRJ_INSERTPROJECT (INFOCAD_TEST38, procedura standalone):
    • se PID_CATEGORY <> 0INSERT INTO PROJECT (... , ID_CATEGORY) VALUES (...) RETURNING ID_PROJECT INTO PNEWINDEX (src:16-21);
    • altrimenti INSERT INTO PROJECT (...) ... RETURNING ID_PROJECT INTO PNEWINDEX (src:22-26);
    • START_DATE/END_DATE sono inizializzate alle date "expected"; CREATED = SYSDATE;
    • poi chiama PRJ_ADDTAGSTOPROJECT(PIDTAGLIST, PNEWINDEX) (src:29) che, se la lista non è {0}, esegue INSERT INTO PROJECT_TAG_ASS (ID_TAG, ID_PROJECT) da TABLE(CAST(... AS MYINTTABLE)) (ADDTAGS src:11-16).
  7. Project_BL prosegue con le SP companion:
    • PRJ_INSERTPROJECTSTATUS: inserisce 8 righe di stato (Bozza..Cancellato) in PROJECT_STATUS, RETURNING ID_PROJECT_STATUS per lo stato "Bozza", e fa UPDATE PROJECT SET ID_PROJECT_STATUS = ... (STATUS src:6-49);
    • PRJ_INSERTPROJECTHISTORY: INSERT INTO PROJECT_HISTORY (con/senza ID_ACTIVITY) (HISTORY src:8-21);
    • PRJ_INSERTPROJECTTEAM: INSERT INTO PROJECT_TEAM (con/senza ID_COMPANY) (TEAM src:13-24).
  8. Tornati alla UI (ProjectInsert.ascx.cs): per ogni file temporaneo caricato → ctrDoc.UploadDocument(...) + prjCtrl.InsertAttachment(prj.ID_DTO, idAtt) (:186-203); se Code vuoto → GetNewCode(...) (parametrico) + UpdateCode(prj.ID_DTO, code) (:207-212).
  9. ScriptManager.RegisterStartupScript(... "CloseWindow()") chiude la finestra (:215). In caso di eccezione: InfocadTraceWrapper.CreateError(...) + RadAlert di errore (:218-222).

API / service

  • Path interattivo: nessun servizio SOAP/WCF sul lato client — postback ASP.NET Web Forms sul wizard.
  • Boundary server: il ProjectController (client) dialoga con Project_BL (server) via .NET Remoting (Activator.GetObject(GetType(IProject_BL), CHANNEL & "://" & SERVERADDRESS & "/" & Service_Project), DAOFactory.vb); Project_BL eredita MarshalByRefObject (Project_BL.vb:22-24).

Backend

  • UI/Code-behind: ProjectInsert.ascx / ProjectInsert.ascx.cs (wizard, C#), AddProject.aspx(.cs).
  • Controller: Descor.Projects.ProjectControllers.ProjectController (ProjectController.vb) → IProject_BL.
  • BL (server, remoting): Descor.Projects.ProjectBL.Project_BL (Project_BL.vb) — orchestratore multi-tabella.
  • DAL: Descor.Projects.ProjectDAL.OracleODP.ProjectDAL (ProjectDAL.vb), via ProjectDALFactory.GetProjectDAL.
  • Pattern DAL: Using dl As New DataLayer(My.Settings.ConnectionName)dl.Parameters.Add(OracleParameter...)dl.ExecuteNonQueryStoredProcedure("PRJ_INSERTPROJECT"); identity via parametro OUT PNEWINDEX.
  • Nota: la lista tag è passata come OracleCollectionType.PLSQLAssociativeArray mappato sul tipo Oracle HELPERS.numberlist (ProjectDAL.vb:194-195, PRJ_INSERTPROJECT src:10).

Query / stored procedure

Passo Stored procedure (Oracle) Chiamata da (DAL)
Insert progetto (INSERT su PROJECT, RETURNING ID_PROJECT) INFOCAD_TEST38.PRJ_INSERTPROJECT (OUT PNEWINDEX) ProjectDAL.vb:212,253
Associazione tag (dentro PRJ_INSERTPROJECT) INFOCAD_TEST38.PRJ_ADDTAGSTOPROJECT PRJ_INSERTPROJECT src:29
Stati workflow standard + update stato iniziale INFOCAD_TEST38.PRJ_INSERTPROJECTSTATUS (OUT PNEWINDEX) ProjectDAL.vb:272,295
Storico progetto INFOCAD_TEST38.PRJ_INSERTPROJECTHISTORY ProjectDAL.vb:366,390
Team progetto INFOCAD_TEST38.PRJ_INSERTPROJECTTEAM ProjectDAL.vb:426,462
Allegato progetto (post-insert) INFOCAD_TEST38.PRJ_INSERTPROJECTATTACHMENT ProjectDAL.vb:342
Aggiornamento codice (parametrico) INFOCAD_TEST38.PRJ_UPDATEPROJECTCODE ProjectDAL.vb:532

Tabelle lette (read)

  • INFOCAD_TEST38: tipo/oggetto HELPERS (PACKAGE) e MYINTTABLE (TYPE) usati per deserializzare la lista tag in PRJ_ADDTAGSTOPROJECT (da USER_DEPENDENCIES).
  • Il progetto appena creato NON viene riletto nel path di insert (nessuna SELECT sul progetto nel flusso).

Tabelle modificate (write)

  • INFOCAD_TEST38: PROJECT (RW — riga-radice del progetto: INSERT con RETURNING ID_PROJECT; UPDATE di ID_PROJECT_STATUS da PRJ_INSERTPROJECTSTATUS), PROJECT_TAG_ASS (INSERT associazioni tag), PROJECT_STATUS (INSERT 8 stati standard), PROJECT_HISTORY (INSERT storico iniziale), PROJECT_TEAM (INSERT membri del team).
  • Effetti collaterali applicativi (stessa transazione logica, SP separate): allegati (PRJ_INSERTPROJECTATTACHMENT → tabella allegati progetto) e codice (PRJ_UPDATEPROJECTCODEPROJECT).
  • Tutte le tabelle target sono VERIFIED via USER_DEPENDENCIES delle rispettive procedure.

Validazione

  • Lato UI/BL: default applicativi — ExpectedEndDate forzata a ExpectedStartDate + 1g se non valorizzata (Project_BL.vb:300-302); StartDate/EndDate = date "expected" (ProjectInsert.ascx.cs:172-173).
  • Lato DB: PRJ_INSERTPROJECT ramifica su PID_CATEGORY <> 0 (con/senza ID_CATEGORY, src:16-27); PRJ_ADDTAGSTOPROJECT salta l'insert se la lista tag è il sentinella {0} (ADDTAGS src:7-9); PRJ_INSERTPROJECTHISTORY/TEAM ramificano su PID_ACTIVITY=0 / PID_COMPANY IS NULL.
  • Gestione errori UI: try/catch globale nel finish handler → log InfocadTraceWrapper.CreateError
    • RadAlert "Errore nell inserimento del progetto" (ProjectInsert.ascx.cs:218-222).
  • Non risultano check di grant espliciti nel path di insert progetto (vedi Open questions).

Side effects

  • Generazione identity ID_PROJECT (sequenza/identity Oracle, esposta via RETURNING ... INTO PNEWINDEX).
  • Popolamento del workflow di stato standard (8 stati) e impostazione dello stato iniziale "Bozza".
  • Scrittura storico, team, tag, costi e attività associate nella stessa orchestrazione BL.
  • Upload documenti in GLOBAL_DOCUMENTS (via DocumentController.UploadDocument) e associazione al progetto.
  • Generazione del codice progetto tramite motore parametrico (Parametric.Project...GenerateProjectCode) quando Code è vuoto (ProjectInsert.ascx.cs:207-212).

Percorsi alternativi / di errore

  • Aggiornamento progetto (path fratello, non insert): wizard/scheda ProjectUpdate.ascxProjectController.Update (ProjectController.vb:111) → Project_BL.Update (Project_BL.vb:361) → ProjectDAL.Update (ProjectDAL.vb:473) → PRJ_UPDATEPROJECT (ProjectDAL.vb:512).
  • Overload transazionale: ProjectDAL.Insert(prj, id_contact, ByRef dl) (ProjectDAL.vb:180) accetta un DataLayer esterno per condividere la connessione/transazione (usato in orchestrazioni composite).
  • Cancellazione logica (controprova non distruttiva): PRJ_LOGICALDELETEPROJECT (ProjectDAL.vb:28).
  • Errore DB / eccezione: propagata da DAL (LogException + Throw) fino al catch UI → alert, nessun CloseWindow (finestra resta aperta).

Diagramma di sequenza

sequenceDiagram
    actor Op as Operatore ProjectCenter
    participant UI as ProjectInsert.ascx (AddProject.aspx)
    participant CB as ProjectInsert.ascx.cs (Finish)
    participant PC as ProjectController.Insert
    participant BL as Project_BL.Insert (remoting)
    participant DAO as ProjectDAL.Insert
    participant DB as Oracle INFOCAD_TEST38

    Op->>UI: compila wizard + click Finish
    UI->>CB: InsertProjectRadWizard_FinishButtonClick
    CB->>CB: raccoglie CurrentProject (Info/Costs/Tags/Team/Fields)
    CB->>PC: Insert(ref prj, IdContact)
    PC->>BL: IProject_BL.Insert(prj, idcontact)
    BL->>DAO: ProjectDAL.Insert(prj, idcontact)
    DAO->>DB: PRJ_INSERTPROJECT (PCODE..PIDTAGLIST, OUT PNEWINDEX)
    DB->>DB: INSERT INTO PROJECT RETURNING ID_PROJECT
    DB->>DB: PRJ_ADDTAGSTOPROJECT -> INSERT PROJECT_TAG_ASS
    DB-->>DAO: PNEWINDEX (nuovo ID_PROJECT)
    DAO-->>BL: idPrj
    BL->>DB: PRJ_INSERTPROJECTSTATUS (8 righe PROJECT_STATUS + UPDATE PROJECT)
    BL->>DB: PRJ_INSERTPROJECTHISTORY (PROJECT_HISTORY)
    BL->>DB: PRJ_INSERTPROJECTTEAM (PROJECT_TEAM) [per membro]
    BL-->>PC: ok
    PC-->>CB: ok
    CB->>DB: UploadDocument + PRJ_INSERTPROJECTATTACHMENT [per file]
    CB->>DB: GetNewCode + PRJ_UPDATEPROJECTCODE [se Code vuoto]
    CB-->>Op: CloseWindow() (progetto creato)

Matrice di tracciabilità

Layer Artefatto Evidenza (file:riga)
UI AddProject.aspx (host) + ProjectInsert.ascx (wizard) AddProject.aspx:4,46 ; ProjectInsert.ascx:47,55
Code-behind InsertProjectRadWizard_FinishButtonClickprjCtrl.Insert ProjectInsert.ascx.cs:143,169,175
Controller ProjectController.InsertIProject_BL.Insert ProjectController.vb:102,105
Factory DAO DAOFactory.CreateDAO(Ctrl_Project) (remoting IProject_BL) DAOFactory.vb (Case Ctrl_Project)
BL (server) Project_BL.Insert (orchestrazione multi-tabella) Project_BL.vb:293,305,309,313,317-323,328
DAO ProjectDAL.InsertPRJ_INSERTPROJECT ProjectDAL.vb:221,224-251,253,254
DAO (companion) InsertProjectStatus/InsertHistory/InsertTeam ProjectDAL.vb:285,377,437
DB PRJ_INSERTPROJECT (INSERT PROJECT + tag) USER_SOURCE PRJ_INSERTPROJECT src:16-29
DB PRJ_ADDTAGSTOPROJECT (PROJECT_TAG_ASS) USER_SOURCE src:11-16
DB PRJ_INSERTPROJECTSTATUS (PROJECT_STATUS + UPDATE PROJECT) USER_SOURCE src:6-49
DB PRJ_INSERTPROJECTHISTORY (PROJECT_HISTORY) USER_SOURCE src:8-21
DB PRJ_INSERTPROJECTTEAM (PROJECT_TEAM) USER_SOURCE src:13-24
DB (deps) target tables via USER_DEPENDENCIES PROJECT, PROJECT_TAG_ASS, PROJECT_STATUS, PROJECT_HISTORY, PROJECT_TEAM

Reverse trace (dal DB/BL ai chiamanti)

  • PRJ_INSERTPROJECT è invocata solo da ProjectDAL.Insert (due overload, ProjectDAL.vb:212,253), a sua volta chiamato da Project_BL.Insert (Project_BL.vb:305) → ProjectController.Insert (ProjectController.vb:105) → wizard ProjectInsert.ascx.cs:175.
  • Project_BL.Insert è il punto di ingresso server della creazione progetto; non risultano altri chiamanti dell'insert progetto oltre al ProjectController (grep su \.Insert( per il dominio Project).
  • Forward e reverse concordano: wizard ProjectInsertInsertPRJ_INSERTPROJECT con INSERT su PROJECT e RETURNING ID_PROJECTNO CONFLICTING.
  • Semantica insert-only: PRJ_INSERTPROJECT è sempre INSERT (nessun ramo update); l'update ha una SP dedicata PRJ_UPDATEPROJECT. Create vs update sono path distinti (wizard ProjectInsert vs ProjectUpdate).
  • Sentinella lista tag: {0} = "nessun tag" (nessun insert in PROJECT_TAG_ASS, ADDTAGS src:7-9).
  • Workflow stati fisso: 8 stati standard hard-coded nella SP (Bozza..Cancellato), progetto sempre creato in Bozza.
  • Binding parametri: la lista id tag passa come HELPERS.numberlist (associative array PL/SQL), non come stringa/XML.

Evidenza (file:line)

Punti chiave (codice): AddProject.aspx:4,46; AddProject.aspx.cs:36; ProjectInsert.ascx:47,55; ProjectInsert.ascx.cs:143,149-167,172-173,175,186-203,207-212,215,218-222; ProjectController.vb:102,105,111; DAOFactory.vb (Case Ctrl_Project); Project_BL.vb:22-24,293,300-302,305,306,309,313,317-323,328,361; ProjectDAL.vb:180,194-195,221,224-251,253,254,285,377,437,473,512,532.

Punti chiave (DB, INFOCAD_TEST38, letti in sola lettura via USER_SOURCE/USER_DEPENDENCIES): PRJ_INSERTPROJECT firma src:1-12; INSERT PROJECT con/senza categoria src:16-27; RETURNING ID_PROJECT INTO PNEWINDEX src:21,26; chiamata tag src:29; PRJ_ADDTAGSTOPROJECT INSERT PROJECT_TAG_ASS src:11-16; PRJ_INSERTPROJECTSTATUS INSERT PROJECT_STATUS + UPDATE PROJECT src:6-49; PRJ_INSERTPROJECTHISTORY INSERT PROJECT_HISTORY src:8-21; PRJ_INSERTPROJECTTEAM INSERT PROJECT_TEAM src:13-24. Dipendenze (USER_DEPENDENCIES): PRJ_INSERTPROJECTPROJECT(TABLE),PRJ_ADDTAGSTOPROJECT(PROC),HELPERS(PKG); PRJ_ADDTAGSTOPROJECTPROJECT_TAG_ASS,MYINTTABLE,HELPERS; PRJ_INSERTPROJECTSTATUSPROJECT,PROJECT_STATUS; PRJ_INSERTPROJECTHISTORYPROJECT_HISTORY; PRJ_INSERTPROJECTTEAMPROJECT_TEAM.

Confidence

  • VERIFIED: catena UI (C#) → controller → BL → DAO → nome stored procedure (letta sui sorgenti) e sorgente di PRJ_INSERTPROJECT (INSERT su PROJECT, RETURNING ID_PROJECT) letto da USER_SOURCE; tabelle target confermate da USER_DEPENDENCIES. Idem per le SP companion (status/history/team/tag).
  • SUPPORTED: boundary .NET Remoting tra ProjectController e Project_BL (dedotto da DAOFactory + MarshalByRefObject), non osservato a runtime; upload allegati e generazione codice parametrico (path presente nel code-behind, non tracciato fino al DB in questo documento).
  • INFERRED: appartenenza dell'intera orchestrazione BL a un'unica transazione DB (le SP companion usano overload senza dl con Using dl As New DataLayer(...) → connessioni potenzialmente distinte).

Open questions

  • Transazionalità: Project_BL.Insert usa gli overload DAL senza DataLayer condiviso (Project_BL.vb:305,309,313,319), quindi ogni SP gira su una propria connessione — un fallimento parziale (es. team) potrebbe lasciare progetto+stati già committati. Da verificare la policy di commit/rollback del DataLayer.
  • Controlli di autorizzazione/grant sulla creazione progetto: non individuati nel path di insert (a differenza del path Property). Da verificare se applicati a monte (menu/pagina) o assenti.
  • Sequenza/identity di ID_PROJECT e ID_PROJECT_STATUS: presumibilmente identity/trigger sulle tabelle PROJECT/PROJECT_STATUS (non ispezionati i trigger).
  • Colonne FIELDS (CLOB createExtraField): formato di serializzazione dei campi custom non ispezionato in dettaglio.
  • Comportamento in PROD (osservato solo ambiente TEST38 / service dev).