Booking Lifecycle & the Booking Engine — Technical Reference¶
Part of the Aashray Technical Reference. Pairs with Business Logic — Booking Lifecycle & Engine, which describes the shared "one primary booking + optional add-ons" model and the plain-English life-cycle with no code detail. Related technical detail currently lives inline in: Stay, Food, Travel, Adhyayan & Utsav, Payments, Admin Panel Map, API Reference, Status & Cron (not yet all split out into their own technical files).
This file is 100% derived from reading the backend, admin, and app source on main — no operational/staff-knowledge content lives here (that's in the business-logic companion). It covers exactly how the shared booking pipeline — validate, create, pay, confirm, cancel — is implemented across every booking type: every route, the data model, admin mechanics, edge cases, and known defects.
The backend (backend-main, Node/Express/Sequelize) is the source of truth. The hub of the whole data model is CardDb.cardno — every booking row stores a cardno (whose booking it is) plus a nullable bookedBy (who created it; null when self-booked). Transactions link to a booking by bookingid.
Verification status: audited & anchored per
docs/DOCS-METHODOLOGY.mdon 2026-07-07 againstaashray-backendmain. Every rule carries a[src: …]anchor. One correction was made this pass (flat-constraint enforcement, §2 + Discrepancies); everything else was confirmed against code.
1. What "the booking engine" is¶
There is no single Booking table. Instead each domain has its own booking model (RoomBooking, FlatBooking, FoodDb, TravelDb, ShibirBookingDb for adhyayan, UtsavBooking), and a shared orchestration layer stitches them into one transaction:
- Controllers
controllers/client/mumukshuBooking.controller.js(mumukshuBooking:213,validateBooking:164, internalbook():378) andcontrollers/client/guestBooking.controller.js(guestBooking:160,validateBooking:314,book():363) implement the unified primary+addons pipeline. [src: controllers/client/mumukshuBooking.controller.js:164,213,378; controllers/client/guestBooking.controller.js:160,314,363] - Per-type helpers (
roomBooking.helper.js,foodBooking.helper.js,travelBooking.helper.js,adhyayanBooking.helper.js,utsavBooking.helper.js) do the actual availability checks and record creation. booking.helper.jsmaps between transactioncategorystrings and booking models (getBooking:40,getBookingType:99,getBookingTypeFromBooking:111,ifMigrated:87). [src: helpers/booking.helper.js:40,87,99,111]transactions.helper.jsowns money:createPendingTransaction:29,useCredit:316/addCredit:295(both internal, not exported) /usableCredits:386,generateOrderId:414(Razorpay),cancelTransaction:112,updateRazorpayTransactions:468. [src: helpers/transactions.helper.js:29,112,295,316,386,414,468]controllers/helper.jsholds shared utilities:validateDate,calculateNights,getBlockedDates/validateBlockedDates,checkFlatAlreadyBooked,createGuestsHelper:688/createCardIds:735, and thesendUnifiedEmail/sendUnifiedEmailForBookedByfan-out (email + WhatsApp). [src: controllers/helper.js:688,735]
Category constants (config/constants.js)¶
TYPE_ROOM='room', TYPE_GUEST_ROOM='room', TYPE_FLAT='flat', TYPE_FOOD='food', TYPE_TRAVEL='travel', TYPE_ADHYAYAN='adhyayan', TYPE_UTSAV='utsav'. Guest breakfast/lunch/dinner constants ('breakfast'/'lunch'/'dinner') all fold to TYPE_FOOD via bookingTypeMap. Note room and guest-room share the same category string ('room'), and guest/mumukshu/self all share the same utsav/adhyayan strings (TYPE_GUEST_UTSAV is also the literal 'utsav') — the difference is expressed by cardno vs bookedBy, never by category. [src: config/constants.js:3-13; helpers/booking.helper.js:32-37]
2. The primary + add-ons model (end to end)¶
Every booking the app sends has the shape:
{ primary_booking: { booking_type, details }, addons: [ { booking_type, details }, ... ] }
- The category the user picks in Book Now becomes the primary. On the "Booking Details" screen the user attaches add-ons (extra room/food/adhyayan/travel slices), which ride along on the same server call and are billed as one order.
detailscarries the type-specific payload. Accommodation and travel details carry amumukshuGroup/guestGroup(self- and mumukshu-flows) orguestsarray (guest flow): a list of groups, each group being a set of people who share one config (e.g. three people in one AC room, two in a Non-AC room = two room groups). Self-booking wraps the logged-in user as a one-person mumukshu group.- Adhyayan/utsav details carry
shibir_ids/utsavid+packageidplus the person list (mumukshus/guests).
Flat is special: validateFlatBookingConstraints rejects flat as an add-on and forbids combining a flat primary with room or utsav add-ons. Flat must be a standalone primary. ⚠️ But this check is only actually enforced on the guest path. The function is defined in both controllers (guestBooking.controller.js:932, mumukshuBooking.controller.js:645) but only invoked in the guest flow (guestBooking.controller.js:169); in the mumukshu controller it is dead code, never called — so for self and mumukshu bookings the flat constraints are silently unenforced (see Discrepancies). [src: controllers/client/guestBooking.controller.js:169,932; controllers/client/mumukshuBooking.controller.js:645-672]
3. The three booker contexts and the bookedBy mechanism¶
The same screens serve three "Book for" contexts. They route to different API namespaces but reuse the same helpers:
| Context | Endpoints (validate / create) | Person payload | bookedBy on created rows |
|---|---|---|---|
| Self | POST /api/v1/mumukshu/validate · POST /api/v1/mumukshu/booking |
logged-in user as a 1-person mumukshuGroup |
null (self) |
| Mumukshu (existing member) | POST /api/v1/mumukshu/validate · POST /api/v1/mumukshu/booking |
mumukshuGroup / mumukshus[] of pre-existing cardnos |
booker's cardno when cardno != booker, else null |
| Guest (may be created) | POST /api/v1/guest/validate · POST /api/v1/guest/booking |
guestGroup / guests[]; new guests created at submit |
booker's cardno |
The bookedBy rule is applied uniformly in the helpers: bookedBy = (booker.cardno !== bookeeCardno) ? booker.cardno : null. So a row's cardno is always whose stay/meal/seat it is; bookedBy is populated only when someone booked on behalf of another person. This is what powers "Booked For: {name}" in the app and the dual notifications (notify both the attendee and the booker). [src: helpers/travelBooking.helper.js:181 (same pattern across create helpers)]
Identity lookups feeding the flows:
- GET /api/v1/mumukshu/?mobno= → checkMumukshuOrGuest: finds a card by mobile; rejects unless res_status ∈ {MUMUKSHU, PR, SEVA KUTIR} (401 "User is not a mumukshu"). Mumukshus cannot be created. [src: controllers/client/mumukshuBooking.controller.js:361-372; config/constants.js:61-63]
- GET /api/v1/guest/check/:mobno → checkGuests: returns the card if res_status == GUEST, null if not found (so the app can offer "create new guest"), or 401 "User is not a guest" if the number belongs to a non-guest. [src: controllers/client/guestBooking.controller.js:809,824-834]
- GET /api/v1/guest/ → fetchGuests: last 10 guests linked to the booker via GuestRelationship. [src: controllers/client/guestBooking.controller.js:734-751]
- POST /api/v1/guest/ → createGuests: createGuestsHelper bulk-creates CardDb rows (res_status='GUEST', generated 10-digit cardno via createCardIds → padStart(10,'0')) + GuestRelationship rows, and sends a card_account_created WhatsApp to each new guest. [src: controllers/client/guestBooking.controller.js:760,796; controllers/helper.js:688,704,718,735]
4. validate — availability + charge preview (no writes)¶
POST …/validate (validateBooking) runs the primary and every add-on through a per-type checkAvailability and returns a preview without touching the DB:
{ data: { roomDetails[], flatDetails[], adhyayanDetails[], foodDetails{}, travelDetails{}, utsavDetails[], totalCharge } }
Key behaviors:
- If the primary is utsav, the UtsavDb row is fetched once and threaded into every check (dates around a festival are treated specially — see §7 and Adhyayan & Utsav).
- Charges are computed here and summed into totalCharge. Room/flat/adhyayan/utsav contribute charges; travel and food often preview at ₹0 (travel is always charge:0, status:'awaiting confirmation'; food charge is computed in its own helper).
- Credits are previewed but not spent. usableCredits(tempUser, type, charge) runs against a cloned card.credits object (tempUser = {...user, credits:{...user.credits}}) so the preview shows the post-credit net without mutating anything. Credit pools are keyed by type, and flat folds into the room credit pool (getCreditType: TYPE_FLAT → TYPE_ROOM). [src: helpers/roomBooking.helper.js:650,748; helpers/transactions.helper.js:289-290,386]
- The app calls validate on focus of the Booking-Details and Review screens; any thrown ApiError (blocked dates, already booked, no seats, invalid date) surfaces as a modal and backs the user out. [src: controllers/client/mumukshuBooking.controller.js:458-520]
5. booking — the create transaction¶
POST …/booking (mumukshuBooking / guestBooking) opens one Sequelize transaction and calls the internal book() dispatcher for the primary then each add-on. book() switches on booking_type and calls the per-type book* helper, accumulating a money amount and populating:
userBookingIdMap—{ cardno: { type: [bookingIds] } }, the canonical "what got created for whom" map (built viasetBookingIdMap).waitingBookingCountMap—{ type: { waiting, total } }, populated for adhyayan/utsav/travel when some rows landed on a waitlist (built viasetWaitingBookingCountMap).
What each book* helper does (all inside the shared transaction):
- Room (bookRoomForMumukshus): validates dates/cards, checks overlap + blocked dates, then per person per date-range creates a RoomBooking. Day-visit → bookDayVisit (no charge). Available → bookAvailableRoom (creates a pending Transactions row + applies credits). Waitlisted → bookWaitingRoom (roomno 'NA', status waiting, no transaction). See Stay.
- Flat (bookFlatForMumukshus): finds the booker's flat, creates a FlatBooking per person; owner-of-that-flat stays free & pending checkin, everyone else gets a nac-rate pending transaction.
- Food/Travel/Adhyayan/Utsav: delegate to their helpers (meal rows, travel row + optional bus assignment, ShibirBookingDb, UtsavBooking + reserved seat). Travel & utsav-around-dates may waitlist.
After the primary+addons are created:
- Order creation. If
req.user.country == 'India'andamount > 0, the controller callsgenerateOrderId(amount)(Razorpay order, amount in paise) and thenupdateRazorpayTransactions(retrieveBookingIds(map), transactionIds, order.id, t)to stamprazorpay_order_idon every pending transaction. NRIs (country != 'India') never get an order — their transactions are created ascash pending(createPendingTransactionflipscashAllowed=truefor non-India cards), payable on-prem. [src: controllers/client/mumukshuBooking.controller.js:247; controllers/client/guestBooking.controller.js:214; helpers/transactions.helper.js:38-48] - Commit. The DB transaction commits. Only then are side effects fired.
- Notifications (best-effort, never roll back the booking):
sendUnifiedWhatsAppper attendee + per booker, andsendUnifiedEmail/sendUnifiedEmailForBookedBy(email + WhatsApp) with a "created / pending" template. Failures are logged, not fatal. - Response:
{ message, order|data, waitingBookingCountMap }.messageisMSG_BOOKING_WAITING("Some of the bookings are in waiting list") when anything waitlisted, elseMSG_BOOKING_SUCCESSFUL. If no order was created,orderis{ amount: 0 }.
mumukshuBooking wraps the whole thing in try/catch and rolls back on any error; guestBooking relies on CatchAsync + the request-scoped transaction.
6. Statuses, charges, credits and the money model¶
Booking statuses (accommodation): waiting → payment pending → pending checkin → checkedin → checkedout, plus cancelled / admin cancelled. Non-accommodation bookings use waiting/pending/confirmed/cancelled/admin cancelled (see Status & Cron).
Transaction statuses: pending (online), cash pending (admin/NRI), completed, cash completed, credited, cancelled, admin cancelled, plus Razorpay-mirroring authorized/captured/failed.
Credit application at create time (createPendingTransaction → useCredit): a transaction is created, then if the card holds credits of the matching type they are spent (discount field), reducing amount. If credits cover the whole charge (credits ≥ amount), the transaction flips to completed and the booking is auto-advanced — room/flat → pending checkin, everything else → confirmed — with no Razorpay step. Credits are 1 credit = ₹1, stored in CardDb.credits (JSON keyed by type; empty keys are pruned). [src: helpers/transactions.helper.js:326-358,407-409]
Payment confirmation (POST /api/v1/razorpay/verifyPayment, a Razorpay webhook, no card auth — the route has no validateCard): looks up all pending/failed/authorized/cash-pending transactions for the razorpay_order_id (row-locked). On captured → transaction completed and the linked booking advances (room/flat → pending checkin, others → confirmed; food stays as-is, only its transaction updates). authorized → transaction authorized; failed → transaction failed. Room/flat/travel/utsav status changes then fire WhatsApp + confirmation email. Members can also mint an order for existing dues via POST /api/v1/razorpay/pay and /payv2. [src: controllers/client/payment.controller.js:32,77-89,103,110,123-134,170; routes/client/payment.routes.js:12]
Pay-later & the 24-hour rule: the app can create a booking and defer payment. cron.js runs every 30 min (*/30 * * * *): getPendingTransactions finds pending/failed online transactions older than MAX_APP_PAYMENT_DURATION = 24h for India cards (country='INDIA'), cancelBookings sets those bookings to admin cancelled (and for adhyayan/travel/utsav promotes the next waitlisted person via openAdhyayanSeat/updateWaitingTravelBooking/openUtsavSeat), cancelTransactions(admin=true) cancels the money rows, and cancelMeals drops any food. Room and flat waitlists are not auto-promoted by cron — the cancel switch has no room/flat case; they are moved manually by an admin (§8). [src: cron.js:38,43,164-215; helpers/transactions.helper.js:441-463]
7. Waitlist & auto-open-seat behavior (summary across types)¶
Waitlisting exists for rooms (around a festival boundary), adhyayan, utsav, and travel; food and flat do not waitlist.
- Room around utsav: a single night that begins on a festival's end date or ends on its start date is forced to
waiting(findUtsavOnBoundaryDates). When a booking straddles a festival,getDateRangesDuringUtsav/splitDateRangessplit it so nights outside the festival are confirmed while the boundary night is waitlisted (minNightslogic). Detail in Stay. [src: helpers/utsavBooking.helper.js:501,528,628; helpers/roomBooking.helper.js:671] - Adhyayan / Utsav / Travel: seats are a finite pool; when full, new bookings are
waiting. When a confirmed holder cancels — or the 24h cron cancels an unpaid one — the next waitlisted booking is auto-opened (openAdhyayanSeat,openUtsavSeat,updateWaitingTravelBooking) and an "open booking" email is sent. See Adhyayan & Utsav and Travel. [src: cron.js:170,197,202] - Travel's promotion path is effectively dormant: travel bookings are always created as
awaiting confirmation, neverwaiting(waitingBookingCount:0), soupdateWaitingTravelBookingsearches forwaitingrows that are never created and has nothing to promote in the current code path. Full detail is in the Travel technical reference. [src: helpers/travelBooking.helper.js:182,201; helpers/travelBooking.helper.js:56]
8. Cancellation → status & credit effects¶
Member cancel. There is one per-domain cancel endpoint each (Room/Flat share one; food/travel/adhyayan/utsav have their own — see the per-type files):
- Room/Flat: POST /api/v1/stay/cancel {bookingid} → CancelBooking. Finds a RoomBooking or FlatBooking owned by the caller (cardno or bookedBy) in status waiting/payment pending/pending checkin, runs userCancelBooking → booking becomes cancelled; its transaction is cancelled or, if it was already paid (completed/cash completed), converted to credited (money returns as store credit of the matching type). WhatsApp + email + push to attendee and booker. [src: routes/client/roomBooking.routes.js:13; controllers/client/roomBooking.controller.js:94,102-132,149; helpers/transactions.helper.js:210]
- Credit rules by type (cancelTransaction): for user (non-admin) cancels of travel/utsav, no credits are issued and the transaction is left completed. For adhyayan/utsav and migrated bookings, paid transactions keep completed status (kept for reporting, no credit). Everything else (notably room/flat) credits back amount+discount when paid, or the discount portion when still pending. [src: helpers/transactions.helper.js:166-177,182-212]
Admin cancel. Admins cancel via booking-management/room-management endpoints (§9); admin cancels set booking admin cancelled and can force full-amount credit even on an already-cancelled transaction. The 24h cron cancels as an admin (admin cancelled).
9. Admin: view / modify / cancel¶
Two admin surfaces touch bookings; both require auth + authorizeRoles(officeAdmin, superAdmin, roomAdmin). [src: routes/admin/bookingManagement.routes.js:12-13]
Booking management — routes/admin/bookingManagement.routes.js → bookingManagement.controller.js:
| Method | Path | Auth realm | Purpose | Key params/body |
|---|---|---|---|---|
| PUT | /api/v1/admin/bookings/cancel/:type/:bookingid |
admin (office/super/room) | Cancel a booking as admin (issues credit via adminCancelTransaction, notifies attendee + booker) |
:type (only room is implemented — switch default throws 404 Booking not found), :bookingid [src: controllers/admin/bookingManagement.controller.js:30-54] |
Room/flat management & operations — routes/admin/roomManagement.routes.js. This is the main admin booking surface (check-in/out, create-on-behalf, status transitions, room inventory, RC blocking, reports). Full route table in Stay — Rooms & Flats §Every route. It lets staff: create a room/flat booking for any card, manually check people in/out (with late-checkout fees and early-checkout credit), reassign room numbers, drive waiting → payment pending → pending checkin → admin cancelled transitions (with credit math), block/unblock rooms, block/unblock Research-Centre date ranges, and run occupancy/reservation/day-wise reports.
Members read their own bookings via GET /api/v1/stay/bookings (ViewAllBookings) — a paginated UNION of room_booking + flat_booking rows where cardno = me OR bookedBy = me, joined to the latest room/flat transaction for status.
10. Unified vs per-type endpoints (and the deprecated ones)¶
- The live "unified" pipeline is the mumukshu/guest controllers, not the
/unifiednamespace.routes/client/unifiedBooking.routes.js—POST /api/v1/unified/bookingandPOST /api/v1/unified/validate— is hard-deprecated: it throws410 "Please update Aashray app to continue using it.". [src: routes/client/unifiedBooking.routes.js:7-19] - Per-type flat shortcuts are deprecated too:
POST /api/v1/stay/flat(FlatBookingMumukshu, logsflat_booking_mumukshu_deprecated) andPOST /api/v1/guest/flat(guestBookingFlat, logsguest_booking_flat_deprecated) still work for old clients but log a deprecation warning; new flat bookings go through the unified…/bookingwithprimary_booking.booking_type='flat'. [src: controllers/client/roomBooking.controller.js:209-213; controllers/client/guestBooking.controller.js:616-621; routes/client/guestBooking.routes.js:21] - Self, guest, and mumukshu all converge on the same helper layer; the only real forks are the person payload shape and which credit/notification path fires.
Route table — client booking engine:
| Method | Path | Auth realm | Purpose | Key params/body |
|---|---|---|---|---|
| POST | /api/v1/mumukshu/validate |
member (validateCard) |
Preview availability + charges (self & mumukshu) | primary_booking, addons[] |
| POST | /api/v1/mumukshu/booking |
member | Create booking (self & mumukshu) | primary_booking, addons[] |
| GET | /api/v1/mumukshu/?mobno= |
member | Look up a mumukshu by mobile | mobno |
| POST | /api/v1/guest/validate |
member | Preview (guest flow) | primary_booking, addons[] |
| POST | /api/v1/guest/booking |
member | Create booking (guest flow) | primary_booking, addons[] |
| GET | /api/v1/guest/ |
member | Booker's recent guests | — |
| POST | /api/v1/guest/ |
member | Create guest card(s) | guests[] |
| GET | /api/v1/guest/check/:mobno |
member | Look up a guest by mobile | :mobno |
| POST | /api/v1/guest/flat |
member | Deprecated flat booking (guest) | guests[], startDay, endDay |
| POST | /api/v1/stay/cancel |
member | Cancel a room/flat booking | bookingid |
| POST | /api/v1/stay/flat |
member | Deprecated flat booking (mumukshu) | mumukshus[], startDay, endDay |
| GET | /api/v1/stay/bookings |
member | List my room+flat bookings (paginated) | page, page_size |
| POST | /api/v1/unified/booking |
member | Deprecated → 410 | — |
| POST | /api/v1/unified/validate |
member | Deprecated → 410 | — |
| POST | /api/v1/razorpay/verifyPayment |
Razorpay webhook (no card auth) | Confirm/authorize/fail transactions + advance bookings | Razorpay payload.payment.entity |
| POST | /api/v1/razorpay/pay |
member | Create an order for existing dues | pending booking ids |
| POST | /api/v1/razorpay/payv2 |
member | v2 of the above | — |
11. Data & relationships¶
CardDb(PKcardno) is the hub. IthasManyRoomBooking,FlatBooking,FoodDb,TravelDb,Transactions, etc. bycardno, and again bybookedBy(aliasedroomBookedByCard,flatBookedByCard,shibirBookedByCard,utsavBookedByCard,travelBookedByCard). Deleting a card cascades most bookings;roomBookedByCardusesSET NULL(so a deleted booker doesn't delete the attendee's room).Transactions(bookingid,category,amount,discount,razorpay_order_id,status)belongsToCardDb, andRoomBooking/FlatBookinghasManyTransactions bybookingid(as: 'transactions'). Adhyayan/utsav/travel/food link by matchingbookingid/idviagetBooking/getBookingTyperather than a formal FK.CardDb.res_status ∈ {MUMUKSHU, PR (resident), SEVA KUTIR, GUEST};creditsis a JSON pool spent/earned by the engine.
Discrepancies¶
- Flat constraints unenforced for self/mumukshu bookings.
validateFlatBookingConstraints(flat-can't-be-an-add-on; flat-primary-can't-combine-with-room/utsav) is defined in both booking controllers but only invoked in the guest flow (guestBooking.controller.js:169). InmumukshuBooking.controller.jsthe function is dead code — never called — so a self or mumukshu booking can attach a flat as an add-on, or mix a flat primary with room/utsav add-ons, with no rejection. The stated rule only actually holds on the guest path. [src: controllers/client/guestBooking.controller.js:169,932; controllers/client/mumukshuBooking.controller.js:645-672] - Guest flat double-orders. In the unified guest flow,
bookFlatcallsbookFlatForMumukshus(...)without thecreateOrder=falsearg (mumukshu passesfalse), so the helper generates a Razorpay order and stamps transactions internally, then the guest controller generates another order over the same amount. Worse, guestbookFlatreturnsresult.order.amount(already in paise,amount*100), which the controller then feeds back intogenerateOrderId(×100 again). The mumukshu flat path avoids both by passingcreateOrder=falseand returningresult.amount. [src: controllers/client/guestBooking.controller.js:853-861,216; controllers/client/mumukshuBooking.controller.js:621,624; helpers/roomBooking.helper.js:488,537-539; helpers/transactions.helper.js:421] /unifiednamespace is a misnomer. The endpoints literally named "unified" are dead (410); the actually-unified engine lives under/mumukshuand/guest. [src: routes/client/unifiedBooking.routes.js:7-19]- Admin
bookings/cancel/:typeonly handlesroom. Any othertype(flat, travel, adhyayan, utsav, food) hits theswitchdefault →404. Flat cancel is a different endpoint (/admin/stay/flat_cancel/:bookingid); the others live in their own admin controllers. [src: controllers/admin/bookingManagement.controller.js:30-54] - No credit for user-cancelled travel/utsav.
cancelTransactionreturns{credits:0}and keeps the transactioncompletedwhen a user cancels travel or utsav; only admin cancels credit those. Adhyayan/utsav paid cancels also keepcompleted(no credit) even on the admin path unless forced. This asymmetry vs room/flat (which always credit) is easy to miss. [src: helpers/transactions.helper.js:166-177,196-207] - Flat credit shares the room pool.
getCreditTypefoldsflat → room, so credits earned from a cancelled flat can be spent on a room and vice-versa — intended, but undocumented in the UI. [src: helpers/transactions.helper.js:289-290] amt_typecolumn not modeled. Late-checkout fee transactions are written withamt_type:'late_checkout_room'and queried by raw SQL, but theTransactionsSequelize model does not declareamt_type(relies on the DB column existing). See Stay. [src: controllers/admin/roomManagement.controller.js:110,2160; models/transactions.model.js (column absent)]
How this connects to other domains (technical)¶
This file is the spine; the per-type files hang off it. Stay — Rooms & Flats details room assignment, the 24h room-number reveal, flat ownership and check-in/out. Food, Travel, and Adhyayan & Utsav detail meal cutoffs, bus grouping, and adhyayan/utsav seats — all created through the §5 pipeline. Money mechanics (Razorpay orders, credits, NRI cash-pending, the 24h auto-cancel) are expanded in Payments, Pricing & Credits, and the status vocabulary in Status & Cron. Identity (CardDb, res_status, guest creation) sits in Accounts, Identity & Auth. Admin roles and pages touching bookings are catalogued in the Admin Panel Map.