Table of Contents

FLOW-BOOK-001 — Creazione di una prenotazione (Booking / Prenotazioni)

Flusso end-to-end di creazione prenotazione nel modulo BookCenter. Path pilota: inserimento di un appuntamento sul calendario (RadScheduler) di Schedule.ascx (BookCenterWeb) da parte di un utente autenticato. Il flusso crea la domanda di prenotazione (BOOK_DEMAND) e la relativa occorrenza pianificata (BOOK_SCHEDULE), agganciando quest'ultima a un elemento di workflow DEM. Backend Oracle INFOCAD_TEST38 (procedure top-level BOOK_*, nessun ORM) + cross-schema DEM_TEST38 per l'elemento di workflow.

  • Flow ID: FLOW-BOOK-001
  • Repository: InfocadWeb (BookCenterWeb, C# Web Forms) + InfocadServer (BookControllers/BookDAL, servizio BookManager via .NET Remoting)
  • Confidence complessiva: VERIFIED (catena UI → code-behind → controller → DAL → nome stored procedure → sorgente PL/SQL letto sul DB) · VERIFIED (mappa procedura→tabelle da USER_SOURCE/USER_DEPENDENCIES)

Obiettivo di business

Consentire a un utente autorizzato del modulo BookCenter di prenotare un'entità spaziale (es. sala/postazione) per un intervallo temporale, eventualmente con regola di ricorrenza. L'operazione registra la domanda di prenotazione (soggetto, descrizione, entità, tipo orario, ricorrenza, utente) e una o più occorrenze pianificate (start/end), ciascuna collegata a un elemento di workflow DEM che ne governa lo stato (Prenotato / Approvato / Confermato …). Al termine la prenotazione è persistita in stato iniziale sul calendario.

Attori

  • Utente BookCenter (autenticato, sessione Cassandra WS.SessionLogin) — path interattivo Schedule.ascx / Scheduler.ascx.
  • App mobile / integrazione — WCF BookingReaderWCF.svc (NewBooking JSON), che condivide lo stesso entry point BL BookController.InsertDemand + InsertScheduleWithElement.
  • Oracle INFOCAD_TEST38 (hub del flusso: procedure BOOK_*, tabelle BOOK_DEMAND/BOOK_SCHEDULE), DEM_TEST38 (elemento di workflow, cross-schema).
  • Servizio Windows BookManager (host della BL/DAL, raggiunto in .NET Remoting dal controller lato web).

Trigger

Inserimento di un appuntamento nel calendario Telerik RadScheduler (schedBook): evento OnAppointmentInsert → handler schedBook_AppointmentInsert (Schedule.ascx.cs:578, wiring in Schedule.ascx:73).

Frontend entry point

  • UserControl: BookCenterWeb/UserControl/Schedule.ascx (RadScheduler schedBook, Schedule.ascx:71), code-behind Schedule.ascx.cs (Inherits Descor.BookCenterWeb..., using Descor.Book.BookControllers).
  • Variante equivalente: Scheduler.ascx (stesso pattern, insert a Scheduler.ascx.cs:1104).
  • Contesto: pagine Book.aspx / BookCentres.aspx sotto la virtual directory BookCenterWeb (shell Cassandra); sessione WS.SessionLogin (base BookingBasePage).

Sequenza principale (main sequence)

  1. L'utente trascina/crea un appuntamento sul calendario → postback evento schedBook_AppointmentInsert (Schedule.ascx.cs:578).
  2. Validazione risorse UI: entità spaziale (GroupEntity) e tipo orario (GroupTime) obbligatori; altrimenti e.Cancel = true e radalert (:580-651).
  3. Anti-sovrapposizione: GetScheduleByEntity(...) + ExistsOccurenceInRangeDates(...) sulle occorrenze già in stato Booked/Approved/Confirmed; in caso di conflitto e.Cancel = true (:602-651).
  4. Costruzione DemandDTO (Username, Subject, Description, Entity, IdEntity, IdTimeType, RecurrenceRule, BookingTable) (:654-665).
  5. Insert domanda: demand.IdDemand = ctrl.InsertDemand(demand) (:666) → BookController.InsertDemand (BookController.cs:259) → Remoting → BookDAL.InsertDemand (BookDAL.cs:1664) → BOOK_INSERTDEMAND (OUT PIDDEMAND).
  6. Determinazione attività/attore di workflow: GetActivityToAddBook(idContact, idActorlist, out idActor) (:675, Workflow.cs:164) cerca l'attività DEM di tipo Create.
  7. Per ogni occorrenza (singola o espansa dalla RecurrenceRule):
    • schedule.IdElement = Resources.Workflow.GetElementAddedToBook(activity, idActor) (:686/:695, Workflow.cs:150) → crea l'elemento di workflow DEM (DEM.WorkflowCreatingActivity.Run(idActor), Workflow.cs:158) e ne restituisce l'id.
    • Insert occorrenza: ctrl.InsertScheduleWithElement(schedule) (:688/:697) → BookDAL.InsertScheduleWithElement (BookDAL.cs:844) → BOOK_INSERTSCHEDULEWITHELEMENT (OUT PID_SCHEDULE), che inserisce l'occorrenza e il link occorrenza↔elemento.
  8. schedBook_Binding() (:699) ricarica il calendario; l'appuntamento appare in stato iniziale.

API / service

  • Path interattivo: nessun servizio SOAP — postback ASP.NET Web Forms diretto (evento RadScheduler).
  • Il controller web BookController è un proxy .NET Remoting verso il servizio BookManager: Activator.GetObject(typeof(IBook), CHANNEL://SERVERADDRESS/Service_Book) (BookControllers/DAOFactory.cs:18); costruttore DaoActivate(enControllers.Ctrl_Book) (BookController.cs:15).
  • Path programmatico equivalente (stesso BL): WCF BookingReaderWCF.svc.vb — deserializza un NewBooking JSON e chiama ctrl.InsertDemand + ctrl.InsertScheduleWithElement (BookingReaderWCF.svc.vb:282,300).

Backend

  • Controller/BL (proxy): Descor.Book.BookControllers.BookController (InfocadServer/BookControllers/BookController.cs), interfaccia Descor.Book.BookInterface.IBook (IBook.cs:66).
  • DAL: Descor.Book.BookDAL.BookDAL (InfocadServer/BookDAL/OracleODP/BookDAL.cs, Oracle.DataAccess / ODP.NET), ospitato nel servizio Windows BookManager (BookManager/BookingManager.csproj).
  • Wrapper DB: Descor.Infrastructure.ArchiveManager.DataLayer.ExecuteNonQueryStoredProcedure(name) (ArchiveManager/DataLayer.cs:586) — imposta CommandText = name e CommandType = StoredProcedure senza prefisso di package/schema (:589-591); quindi BOOK_INSERTDEMAND / BOOK_INSERTSCHEDULEWITHELEMENT sono procedure top-level nello schema connesso.
  • Connessione: ConnectionName = "MainConnection" (BookManager/app.config:10, BookDAL.cs:1669) → schema hub INFOCAD_TEST38.

Query / stored procedure

Passo Stored procedure (Oracle) Chiamata da (DAL)
Insert domanda prenotazione INFOCAD_TEST38.BOOK_INSERTDEMAND (OUT PIDDEMAND) BookDAL.cs:1693
Insert occorrenza + link elemento WF INFOCAD_TEST38.BOOK_INSERTSCHEDULEWITHELEMENT (OUT PID_SCHEDULE) BookDAL.cs:875
Creazione elemento workflow DEM DEM_TEST38.DEM_DOCREATEACTIVITY (via DEM.WorkflowCreatingActivity.Run) Workflow.cs:158 (cross-schema, cfr. FLOW-REQ-001)
Anti-sovrapposizione (lettura) BOOK_GETSCHEDULEBYENTITY (via GetScheduleByEntity) Schedule.ascx.cs:603

Tabelle lette (read)

  • INFOCAD_TEST38: BOOK_DEMAND, BOOK_SCHEDULE (in lettura tramite BOOK_GETSCHEDULEBYENTITY per il controllo di sovrapposizione).
  • DEM_TEST38: catalogo attività/workflow (ACTIVITY, stato elemento) per GetActivityToAddBook / Run (cross-schema, cfr. FLOW-REQ-001).

Tabelle modificate (write)

Da USER_SOURCE delle due procedure (VERIFIED — sorgente PL/SQL letto sul DB):

  • INFOCAD_TEST38.BOOK_DEMAND (INSERT, PTABLE=1 / Current) oppure BOOK_DEMAND_HISTORY (INSERT, PTABLE=2 / Stored), id da sequence SEQ_BOOK_ID_DEMANDBOOK_INSERTDEMAND.
  • INFOCAD_TEST38.BOOK_SCHEDULE (INSERT, PTABLE=1) oppure BOOK_SCHEDULE_HISTORY (INSERT, PTABLE=2), id da sequence SEQ_BOOK_ID_SCHEDULEBOOK_INSERTSCHEDULEWITHELEMENT.
  • INFOCAD_TEST38.BOOK_SCHEDULE_WF_INTERFACE (INSERT del link ID_SCHEDULEID_ELEMENT, in entrambi i rami) — BOOK_INSERTSCHEDULEWITHELEMENT.
  • DEM_TEST38: elemento di workflow creato da DEM.WorkflowCreatingActivity.Run (stato/ELEMENTWORKFLOWSTATE/ELEMENTWORKFLOWHISTORY, cfr. FLOW-REQ-001) — cross-schema, side effect.

Nel flusso interattivo BookingTable = BookTable.Current = 1 (Enumeration.cs:12), quindi si scrive sul ramo Current (BOOK_DEMAND + BOOK_SCHEDULE + BOOK_SCHEDULE_WF_INTERFACE).

Validazione

  • Lato UI (schedBook_AppointmentInsert): entità spaziale obbligatoria (GroupEntity), tipo orario obbligatorio (GroupTime); anti-sovrapposizione sulle occorrenze (ExistsOccurenceInRangeDates); coerenza data-inizio ≤ fine ricorrenza (parsedRule.Range.RecursUntil). In caso di violazione: e.Cancel = true + radalert, nessuna scrittura.
  • Lato DB: BOOK_INSERTDEMAND è priva di validazione (INSERT diretto, id da sequence); BOOK_INSERTSCHEDULEWITHELEMENT racchiude gli INSERT in SAVEPOINT start_tran con EXCEPTION WHEN OTHERS THEN ROLLBACK TO start_tran; RAISE (rollback locale dell'occorrenza in errore).

Side effects

  • Creazione di un elemento di workflow DEM per ogni occorrenza (DEM.WorkflowCreatingActivity.Run) in stato iniziale (cross-schema DEM_TEST38).
  • Inserimento del legame occorrenza↔elemento in BOOK_SCHEDULE_WF_INTERFACE.
  • Espansione della RecurrenceRule: N occorrenze ⇒ N righe BOOK_SCHEDULE + N elementi DEM + N righe di interfaccia, tutte legate all'unica BOOK_DEMAND.
  • Notifiche mail (percorsi NotifyApproved/NotifyAlert in Schedule.ascx.cs) sono su transizioni di stato successive, non parte della creazione.

Percorsi alternativi / di errore

  • Validazione UI fallita (entità/orario mancante, sovrapposizione, range ricorrenza) → e.Cancel = true, nessuna transazione DB.
  • Fallimento parziale: InsertDemand e InsertScheduleWithElement sono chiamate Remoting/procedure autonome distinte, non racchiuse in un'unica transazione distribuita lato applicazione. Un errore in InsertScheduleWithElement esegue solo il ROLLBACK TO start_tran della singola occorrenza; la BOOK_DEMAND già inserita resta persistita (possibile domanda senza occorrenze). → open question sul cleanup.
  • Ramo storico (PTABLE=2 / Stored): scrittura su BOOK_DEMAND_HISTORY / BOOK_SCHEDULE_HISTORY (es. import da Excel / archiviazione), stesso codice DAL con BookingTable=2.
  • Path mobile/WCF (BookingReaderWCF.svc.vb:282): stesso BL, elemento DEM creato via RunCreateActivity(idWorkflow, idActivity, idActor).

Diagramma di sequenza

sequenceDiagram
    actor U as Utente BookCenter
    participant UI as Schedule.ascx (RadScheduler schedBook)
    participant CB as Schedule.ascx.cs (schedBook_AppointmentInsert)
    participant WF as Resources.Workflow
    participant CT as BookController (proxy Remoting)
    participant DAL as BookDAL (BookManager svc)
    participant IC as Oracle INFOCAD_TEST38
    participant DEM as Oracle DEM_TEST38

    U->>UI: crea appuntamento (OnAppointmentInsert)
    UI->>CB: schedBook_AppointmentInsert(e)
    CB->>CB: valida entità/orario + anti-sovrapposizione
    CB->>CT: InsertDemand(DemandDTO)
    CT->>DAL: InsertDemand(...)
    DAL->>IC: BOOK_INSERTDEMAND (OUT PIDDEMAND)
    IC-->>DAL: idDemand (SEQ_BOOK_ID_DEMAND)
    DAL-->>CB: idDemand
    CB->>WF: GetActivityToAddBook(...)
    loop per ogni occorrenza (RecurrenceRule)
        CB->>WF: GetElementAddedToBook(activity, idActor)
        WF->>DEM: WorkflowCreatingActivity.Run -> DEM_DOCREATEACTIVITY
        DEM-->>WF: idElement
        CB->>CT: InsertScheduleWithElement(ScheduleDTO)
        CT->>DAL: InsertScheduleWithElement(...)
        DAL->>IC: BOOK_INSERTSCHEDULEWITHELEMENT (OUT PID_SCHEDULE)
        IC-->>DAL: BOOK_SCHEDULE + BOOK_SCHEDULE_WF_INTERFACE
    end
    CB->>UI: schedBook_Binding() (refresh calendario)
    UI-->>U: prenotazione visibile in stato iniziale

Matrice di tracciabilità

Layer Artefatto Evidenza (file:riga)
UI RadScheduler schedBook + wiring evento .../BookCenterWeb/UserControl/Schedule.ascx:71,73
Code-behind schedBook_AppointmentInsert Schedule.ascx.cs:578
Code-behind DemandDTO + InsertDemand Schedule.ascx.cs:654-666
Code-behind GetActivityToAddBook / GetElementAddedToBook / InsertScheduleWithElement Schedule.ascx.cs:675,686,688,695,697
Helper WF GetElementAddedToBookWorkflowCreatingActivity.Run Resources/Workflow.cs:150,158
Controller BookController.InsertDemand BookControllers/BookController.cs:259-261
Controller binding DAO via Remoting BookControllers/DAOFactory.cs:18
Interface IBook.InsertDemand BookInterface/IBook.cs:66
DAL InsertDemandBOOK_INSERTDEMAND BookDAL/OracleODP/BookDAL.cs:1664,1693
DAL InsertScheduleWithElementBOOK_INSERTSCHEDULEWITHELEMENT BookDAL/OracleODP/BookDAL.cs:844,875
Wrapper ExecuteNonQueryStoredProcedure (StoredProcedure, no prefix) ArchiveManager/DataLayer.cs:586-591
Config ConnectionName = MainConnection BookManager/app.config:10
DB (source) BOOK_INSERTDEMAND → INSERT BOOK_DEMAND/BOOK_DEMAND_HISTORY USER_SOURCE INFOCAD_TEST38
DB (source) BOOK_INSERTSCHEDULEWITHELEMENT → INSERT BOOK_SCHEDULE(+HISTORY) + BOOK_SCHEDULE_WF_INTERFACE USER_SOURCE INFOCAD_TEST38
DB (deps) dipendenze procedura→tabella/sequence USER_DEPENDENCIES INFOCAD_TEST38

Reverse trace (dallo stored procedure / BL ai chiamanti)

  • Codicegrep ".InsertDemand(" conferma che lo stesso entry point BL (BookController.InsertDemand) è condiviso da: scheduler interattivo (Schedule.ascx.cs:666), scheduler alternativo (Scheduler.ascx.cs:1104), WCF mobile (BookingReaderWCF.svc.vb:282).
  • DBUSER_DEPENDENCIES (reverse su BOOK_DEMAND/BOOK_SCHEDULE/BOOK_SCHEDULE_WF_INTERFACE): le uniche procedure che scrivono queste tabelle sono le BOOK_INSERT* (BOOK_INSERTDEMAND, BOOK_INSERTDEMANDPUTIDDEMAND, BOOK_INSERTSCHEDULE, BOOK_INSERTSCHEDULEWITHELEMENT, BOOK_INSERTELEMENT); le altre (BOOK_GET*, BOOK_DELETE*, BOOK_UPDATE*) sono lettura o altre operazioni. Forward e reverse concordano → NO CONFLICTING.
  • BookTable (Enumeration.cs:12): Current=1 (dato operativo) vs Stored=2 (storico) selezionano il ramo di INSERT nelle procedure (PTABLE).
  • Tipo attività DEM di Create (DEM.Constants.ActivityTypes.Create) filtra l'attività usata per generare l'elemento di workflow (Workflow.cs:173).
  • Ricorrenza (RecurrenceRule Telerik): espansa lato UI in N occorrenze, ciascuna con proprio elemento DEM.
  • Stati prenotazione (Resources.Workflow.Status: Booked/Approved/Confirmed/…) usati per l'anti-sovrapposizione.

Evidenza (file:line)

Catena codice (VERIFIED): Schedule.ascx:71,73; Schedule.ascx.cs:578,602-603,654-666,675,686,688,695,697,699; Resources/Workflow.cs:150,158,164,173; Resources/Enumeration.cs:12; BookControllers/BookController.cs:15,259-261; BookControllers/DAOFactory.cs:18; BookInterface/IBook.cs:66; BookDAL/OracleODP/BookDAL.cs:1664,1669,1693,844,849,875; ArchiveManager/DataLayer.cs:586-591; BookManager/app.config:10.

Reverse codice: Scheduler.ascx.cs:1104; BookingReaderWCF.svc.vb:282,300.

Evidenza DB (VERIFIED — bounded read-only su INFOCAD_TEST38, USER_OBJECTS/USER_SOURCE/USER_DEPENDENCIES):

  • USER_OBJECTS: BOOK_INSERTDEMAND (PROCEDURE, VALID), BOOK_INSERTSCHEDULEWITHELEMENT (PROCEDURE, VALID).
  • USER_SOURCE BOOK_INSERTDEMAND: PIDDEMAND := SEQ_BOOK_ID_DEMAND.NEXTVAL; poi INSERT INTO BOOK_DEMAND(...) se PTABLE=1, INSERT INTO BOOK_DEMAND_HISTORY(...) se PTABLE=2.
  • USER_SOURCE BOOK_INSERTSCHEDULEWITHELEMENT: SAVEPOINT start_tran; PID_SCHEDULE := SEQ_BOOK_ID_SCHEDULE.NEXTVAL; poi INSERT INTO BOOK_SCHEDULE(...) + INSERT INTO BOOK_SCHEDULE_WF_INTERFACE(...) (PTABLE=1) / BOOK_SCHEDULE_HISTORY + BOOK_SCHEDULE_WF_INTERFACE (PTABLE=2); EXCEPTION WHEN OTHERS THEN ROLLBACK TO start_tran; RAISE.
  • USER_DEPENDENCIES (forward): BOOK_INSERTDEMANDBOOK_DEMAND, BOOK_DEMAND_HISTORY, SEQ_BOOK_ID_DEMAND; BOOK_INSERTSCHEDULEWITHELEMENTBOOK_SCHEDULE, BOOK_SCHEDULE_HISTORY, BOOK_SCHEDULE_WF_INTERFACE, SEQ_BOOK_ID_SCHEDULE.

Confidence

  • VERIFIED: catena UI → code-behind → controller (proxy Remoting) → DAL → nome stored procedure (letto sul sorgente C#) → sorgente PL/SQL della procedura (letto sul DB).
  • VERIFIED: mappa procedura → tabelle scritte (INSERT diretti in USER_SOURCE, confermati da USER_DEPENDENCIES).
  • SUPPORTED: side effect DEM (elemento di workflow) per analogia documentata con FLOW-REQ-001 (DEM.WorkflowCreatingActivity.RunDEM_DOCREATEACTIVITY); non ri-ispezionato il sorgente DEM in questo flusso.
  • INFERRED: assenza di transazione applicativa unica tra InsertDemand e InsertScheduleWithElement (dedotta dalla struttura a chiamate Remoting separate, non da un test runtime).

Open questions

  • Il modulo Booking* (BookingManager/BookingDAL/BookingControllers + BookingManagerXNET net8) indicato negli hint gestisce amministrazione/configurazione (categorie, ruoli, permessi, calendari di disponibilità, servizi) e usa DAO DAOBooking*non è il path di creazione prenotazione. La creazione runtime della prenotazione passa dal modulo Book* (BookController/BookDAL, servizio BookManager) qui documentato. Da confermare se le due famiglie condividano lo stesso schema/tabelle o se Booking* sia una riscrittura in corso.
  • Cleanup della BOOK_DEMAND in caso di fallimento di InsertScheduleWithElement (nessuna transazione applicativa unica): comportamento reale da verificare a runtime.
  • Tabelle DEM precise coinvolte da WorkflowCreatingActivity.Run in questo flusso (assunte per analogia con FLOW-REQ-001).
  • Valore effettivo di IdUser/IdCdp popolati sul DemandDTO nel path interattivo (nel WCF sono valorizzati esplicitamente; in Schedule.ascx.cs IdUser/IdCdp non risultano impostati prima dell'insert).