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 OracleINFOCAD_TEST38(procedure top-levelBOOK_*, nessun ORM) + cross-schemaDEM_TEST38per l'elemento di workflow.
- Flow ID: FLOW-BOOK-001
- Repository: InfocadWeb (
BookCenterWeb, C# Web Forms) + InfocadServer (BookControllers/BookDAL, servizioBookManagervia .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 interattivoSchedule.ascx/Scheduler.ascx. - App mobile / integrazione — WCF
BookingReaderWCF.svc(NewBookingJSON), che condivide lo stesso entry point BLBookController.InsertDemand+InsertScheduleWithElement. - Oracle
INFOCAD_TEST38(hub del flusso: procedureBOOK_*, tabelleBOOK_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(RadSchedulerschedBook,Schedule.ascx:71), code-behindSchedule.ascx.cs(InheritsDescor.BookCenterWeb...,using Descor.Book.BookControllers). - Variante equivalente:
Scheduler.ascx(stesso pattern, insert aScheduler.ascx.cs:1104). - Contesto: pagine
Book.aspx/BookCentres.aspxsotto la virtual directoryBookCenterWeb(shell Cassandra); sessioneWS.SessionLogin(baseBookingBasePage).
Sequenza principale (main sequence)
- L'utente trascina/crea un appuntamento sul calendario → postback evento
schedBook_AppointmentInsert(Schedule.ascx.cs:578). - Validazione risorse UI: entità spaziale (
GroupEntity) e tipo orario (GroupTime) obbligatori; altrimentie.Cancel = trueeradalert(:580-651). - Anti-sovrapposizione:
GetScheduleByEntity(...)+ExistsOccurenceInRangeDates(...)sulle occorrenze già in stato Booked/Approved/Confirmed; in caso di conflittoe.Cancel = true(:602-651). - Costruzione
DemandDTO(Username,Subject,Description,Entity,IdEntity,IdTimeType,RecurrenceRule,BookingTable) (:654-665). - Insert domanda:
demand.IdDemand = ctrl.InsertDemand(demand)(:666) →BookController.InsertDemand(BookController.cs:259) → Remoting →BookDAL.InsertDemand(BookDAL.cs:1664) →BOOK_INSERTDEMAND(OUTPIDDEMAND). - Determinazione attività/attore di workflow:
GetActivityToAddBook(idContact, idActorlist, out idActor)(:675,Workflow.cs:164) cerca l'attività DEM di tipo Create. - 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(OUTPID_SCHEDULE), che inserisce l'occorrenza e il link occorrenza↔elemento.
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 servizioBookManager:Activator.GetObject(typeof(IBook), CHANNEL://SERVERADDRESS/Service_Book)(BookControllers/DAOFactory.cs:18); costruttoreDaoActivate(enControllers.Ctrl_Book)(BookController.cs:15). - Path programmatico equivalente (stesso BL): WCF
BookingReaderWCF.svc.vb— deserializza unNewBookingJSON e chiamactrl.InsertDemand+ctrl.InsertScheduleWithElement(BookingReaderWCF.svc.vb:282,300).
Backend
- Controller/BL (proxy):
Descor.Book.BookControllers.BookController(InfocadServer/BookControllers/BookController.cs), interfacciaDescor.Book.BookInterface.IBook(IBook.cs:66). - DAL:
Descor.Book.BookDAL.BookDAL(InfocadServer/BookDAL/OracleODP/BookDAL.cs,Oracle.DataAccess/ ODP.NET), ospitato nel servizio WindowsBookManager(BookManager/BookingManager.csproj). - Wrapper DB:
Descor.Infrastructure.ArchiveManager.DataLayer.ExecuteNonQueryStoredProcedure(name)(ArchiveManager/DataLayer.cs:586) — impostaCommandText = nameeCommandType = StoredProceduresenza prefisso di package/schema (:589-591); quindiBOOK_INSERTDEMAND/BOOK_INSERTSCHEDULEWITHELEMENTsono procedure top-level nello schema connesso. - Connessione:
ConnectionName = "MainConnection"(BookManager/app.config:10,BookDAL.cs:1669) → schema hubINFOCAD_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 tramiteBOOK_GETSCHEDULEBYENTITYper il controllo di sovrapposizione).DEM_TEST38: catalogo attività/workflow (ACTIVITY, stato elemento) perGetActivityToAddBook/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) oppureBOOK_DEMAND_HISTORY(INSERT,PTABLE=2/ Stored), id da sequenceSEQ_BOOK_ID_DEMAND—BOOK_INSERTDEMAND.INFOCAD_TEST38.BOOK_SCHEDULE(INSERT,PTABLE=1) oppureBOOK_SCHEDULE_HISTORY(INSERT,PTABLE=2), id da sequenceSEQ_BOOK_ID_SCHEDULE—BOOK_INSERTSCHEDULEWITHELEMENT.INFOCAD_TEST38.BOOK_SCHEDULE_WF_INTERFACE(INSERT del linkID_SCHEDULE↔ID_ELEMENT, in entrambi i rami) —BOOK_INSERTSCHEDULEWITHELEMENT.DEM_TEST38: elemento di workflow creato daDEM.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_INSERTSCHEDULEWITHELEMENTracchiude gli INSERT inSAVEPOINT start_tranconEXCEPTION 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-schemaDEM_TEST38). - Inserimento del legame occorrenza↔elemento in
BOOK_SCHEDULE_WF_INTERFACE. - Espansione della
RecurrenceRule: N occorrenze ⇒ N righeBOOK_SCHEDULE+ N elementi DEM + N righe di interfaccia, tutte legate all'unicaBOOK_DEMAND. - Notifiche mail (percorsi
NotifyApproved/NotifyAlertinSchedule.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:
InsertDemandeInsertScheduleWithElementsono chiamate Remoting/procedure autonome distinte, non racchiuse in un'unica transazione distribuita lato applicazione. Un errore inInsertScheduleWithElementesegue solo ilROLLBACK TO start_trandella singola occorrenza; laBOOK_DEMANDgià inserita resta persistita (possibile domanda senza occorrenze). → open question sul cleanup. - Ramo storico (
PTABLE=2/ Stored): scrittura suBOOK_DEMAND_HISTORY/BOOK_SCHEDULE_HISTORY(es. import da Excel / archiviazione), stesso codice DAL conBookingTable=2. - Path mobile/WCF (
BookingReaderWCF.svc.vb:282): stesso BL, elemento DEM creato viaRunCreateActivity(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 | GetElementAddedToBook → WorkflowCreatingActivity.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 | InsertDemand → BOOK_INSERTDEMAND |
BookDAL/OracleODP/BookDAL.cs:1664,1693 |
| DAL | InsertScheduleWithElement → BOOK_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)
- Codice —
grep ".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). - DB —
USER_DEPENDENCIES(reverse suBOOK_DEMAND/BOOK_SCHEDULE/BOOK_SCHEDULE_WF_INTERFACE): le uniche procedure che scrivono queste tabelle sono leBOOK_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.
Regole correlate (related rules)
BookTable(Enumeration.cs:12):Current=1(dato operativo) vsStored=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 (
RecurrenceRuleTelerik): 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_SOURCEBOOK_INSERTDEMAND:PIDDEMAND := SEQ_BOOK_ID_DEMAND.NEXTVAL;poiINSERT INTO BOOK_DEMAND(...)sePTABLE=1,INSERT INTO BOOK_DEMAND_HISTORY(...)sePTABLE=2.USER_SOURCEBOOK_INSERTSCHEDULEWITHELEMENT:SAVEPOINT start_tran; PID_SCHEDULE := SEQ_BOOK_ID_SCHEDULE.NEXTVAL;poiINSERT 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_INSERTDEMAND→BOOK_DEMAND,BOOK_DEMAND_HISTORY,SEQ_BOOK_ID_DEMAND;BOOK_INSERTSCHEDULEWITHELEMENT→BOOK_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 daUSER_DEPENDENCIES). - SUPPORTED: side effect DEM (elemento di workflow) per analogia documentata con FLOW-REQ-001 (
DEM.WorkflowCreatingActivity.Run→DEM_DOCREATEACTIVITY); non ri-ispezionato il sorgente DEM in questo flusso. - INFERRED: assenza di transazione applicativa unica tra
InsertDemandeInsertScheduleWithElement(dedotta dalla struttura a chiamate Remoting separate, non da un test runtime).
Open questions
- Il modulo Booking* (
BookingManager/BookingDAL/BookingControllers+BookingManagerXNETnet8) indicato negli hint gestisce amministrazione/configurazione (categorie, ruoli, permessi, calendari di disponibilità, servizi) e usa DAODAOBooking*— non è il path di creazione prenotazione. La creazione runtime della prenotazione passa dal modulo Book* (BookController/BookDAL, servizioBookManager) qui documentato. Da confermare se le due famiglie condividano lo stesso schema/tabelle o seBooking*sia una riscrittura in corso. - Cleanup della
BOOK_DEMANDin caso di fallimento diInsertScheduleWithElement(nessuna transazione applicativa unica): comportamento reale da verificare a runtime. - Tabelle DEM precise coinvolte da
WorkflowCreatingActivity.Runin questo flusso (assunte per analogia con FLOW-REQ-001). - Valore effettivo di
IdUser/IdCdppopolati sulDemandDTOnel path interattivo (nel WCF sono valorizzati esplicitamente; inSchedule.ascx.csIdUser/IdCdpnon risultano impostati prima dell'insert).