Danger: RETIRED AT THE JULY-10 LAUNCH — no new-stack equivalent. Table reservations existed only in the legacy
haafai.app.foodopsmonolith, which is fully retired at launch. As of 2026-06-29, a recursive search offoodops.counter.app,foodops-admin-app, andhubits-api-sales(all prodmain) found zero reservation/booking code. There is no reservations feature in the new stack — if a customer asks about table bookings post-launch, the honest answer is that it is not currently available (it was a legacy-only feature). This is a product gap to flag, not a working feature. The description below documents the retired monolith behaviour for historical reference.
Plain-English summary
Reservations is where upcoming table bookings are managed — a contact name, phone number, number of covers (party size), a dine-in table, and a from/to time window. Bookings are shown on a calendar timeline with one row per table (day, week or month view), so the host can see at a glance which tables are held when. New bookings start as Reserved; they can be edited, checked in, or cancelled. This feature lived ONLY in the legacy web back-office (haafai.app.foodops) and was never ported to the React counter app, the new admin app, or the sales API — so with the monolith retired at launch, reservations is not available in the new stack. There was never a customer-facing self-booking flow.
When you'd use this
- Taking a phone reservation and entering it for later
- Front-of-house checking today's bookings before service
- Rebooking a walk-in customer for next visit
- Spotting double-booked tables on the timeline
How to access
RETIRED. The reservations surface below existed only in the legacy monolith, which is gone at launch. There is no
/reservationsroute in the new stack.
- URL (RETIRED legacy back-office):
/reservations— page title "Reservations" using the counter layout. [code: haafai.app.foodops/Haafai.Restaurant.App/Views/Reservations/Index.cshtml:4-6 — monolith, retired] - Required the Reservations.View role; create/edit/cancel required Reservations.Create / Edit / Delete respectively. [code: Haafai.Restaurant.App/Controllers/ReservationsController.cs:18,42,72,143]
- Not available in any new-stack surface — no reservations route or component exists in the counter app,
foodops-admin-app, orhubits-api-salesas of 2026-06-29. [code: verified-absent — recursive tree of foodops.counter.app@main, foodops-admin-app@main, and hubits-api-sales@main has zero reservation/booking paths]
Walkthrough
Verified against the Razor views/controller at
haafai.app.foodops@f06cdd9(prodmain).
The reservations calendar
- Open
/reservations. The page renders a FullCalendar resource timeline (scheduler v5.11.5): rows are dine-in Tables (resource header "Tables", each row labelled "Table {name}"), columns are time slots from 07:00 to 24:00, with Day / Week / Month view toggles top-right. [code: Views/Reservations/Index.cshtml:59-79; ReservationsController.cs:25-39] - Bookings render as blocks titled with the contact name. Colour encodes status: Reserved = orange (
#f0ad4e), any other status (e.g. checked-in) = green (#5cb85c). [code: ReservationsController.cs:117-133] - The calendar is editable — selecting a free slot on a table row opens the Add modal pre-filled with that table and time window. [code: Index.cshtml:64 (
selectable:true),74 (editable:true); select handler 78-100 POSTs reservationStartDate/EndDate/restaurantTableId to Add]
Adding a reservation
- Select a slot (or use the add action). The Add Reservation modal opens. [code: Views/Reservations/_Add.cshtml]
- Fields: Contact Name, Phone Number, Number of Covers, Table (dropdown of dine-in tables; required row), From and To date-times (format
dd/MM/yyyy hh:mm tt). [code: ViewModels/PointOfSales/RestaurantReservations/AddEditRestaurantReservation.cs:14-36] - Submit — "Reservation created successfully." The booking is created with status Reserved. [code: ReservationsController.cs:63-68; Services/Restaurants/RestaurantReservationHelper.cs:20]
Viewing, editing, cancelling
- Click a booking block → Reservation Details slide-in panel: status badge, date + time window, Table, Customer, Phone, Covers. [code: Views/Reservations/_Details.cshtml:15-37]
- Footer actions (role-gated): Edit (re-opens the form) and Cancel. Cancelling sets status to Cancelled and logs the state change; cancelled bookings drop off the active calendar query. [code: ReservationsController.cs:143-156; RestaurantReservationHelper.cs:60]
Key concepts
- Reservation statuses — Waitlist (1), Reserved (2), CheckedIn (3), Cancelled (4). The create path always starts at Reserved; cancel is the only status transition exposed by this controller — no Waitlist or CheckedIn action exists in
ReservationsControlleras of 2026-06-14 (the statuses are defined in the shared domain and may be set by other flows). [code: haafai.domain/haafai.domain/Haafai.Models/Constants/ModelConstants.cs:RestaurantReservationStatus@staging:35-41 — identical content on frozen main] - Tables as resources — only dine-in tables (RestaurantOrderType = DineIn) appear as calendar rows; a reservation holds exactly one table (or none — the FK is nullable, though the form marks the field required via a CSS
requiredclass on the markup, not a[Required]validator). [code: ReservationsController.GetTables:25-29; AddEditRestaurantReservation.cs:RestaurantTableId@36 (Guid?, no [Required]); _Add.cshtml:50 (form-group row required)] - Order linkage — the domain entity carries a nullable
SalesOrderId, i.e. a reservation can be linked to a sales order (seating the party against the booking), but no code in the reservations controller or helper populates it; treat the link as dormant. [code: haafai.domain/haafai.domain/Haafai.Models/Entities/RestaurantManagement/RestaurantReservation.cs:SalesOrderId@22 (staging); ReservationsController/RestaurantReservationHelper never set it] - Covers — free-text party size (
NumberOfCoversis a string, not a number — no validation attribute that it's numeric). [code: AddEditRestaurantReservation.cs:NumberOfCovers@20-21 (string, no validation); domain RestaurantReservation.cs:NumberOfCovers@28 (string)] - Legacy-only surface — the counter app has no reservations module; the table layout modal on the POS does not read reservation state. [code: verified-absent — foodops.counter.app@main
src/components/orders/TableLayoutModal.tsxandsrc/features/dinein/components/FloorPlanCanvas.tsxcontain zeroreserv|bookingreferences as of 2026-06-14]
Common questions
Q: Where do I manage reservations — the POS or the back-office? A: As of the July-10 launch, nowhere — reservations existed only in the legacy back-office, which is retired. The new stack (counter app, admin app, sales API) has no reservations screen. Table bookings are not a currently available feature.
Q: Can customers book a table themselves online?
A: No — the online ordering site has no booking flow; reservations are staff-entered only, in the legacy back-office. [code: verified-absent — foodops.ordering.app@main recursive tree has zero reserv|booking paths as of 2026-06-14] (User story US-SET-011 envisions customer-made reservations; the implemented feature is the staff-side half.)
Q: What information does a booking hold? A: Contact name, phone, number of covers, one dine-in table, and a from/to time window. No deposit, no special-requests field, no email. [code: AddEditRestaurantReservation.cs]
Q: What do the colours on the calendar mean? A: Orange = Reserved; green = any other (non-cancelled) status. Cancelled bookings are excluded from the calendar feed. [code: ReservationsController.cs:127; RestaurantReservationHelper.cs:60]
Q: How do I mark a party as arrived/seated? A: A CheckedIn status exists in the domain, but the reservations screen itself only exposes Edit and Cancel — no check-in button was found in the current views. Verify-and-note: if hosts need arrival tracking, confirm the live UI before promising it.
Q: Does a reservation block the table in the POS? A: No evidence of enforcement — the POS table layout doesn't consult reservations, so seating a walk-in at a reserved table is not prevented by the system. [code: verified-absent — foodops.counter.app@main TableLayoutModal.tsx / FloorPlanCanvas.tsx have no reservation references; haafai.app.pos@master has no table-reservation logic (only unrelated StockReservation inventory code) as of 2026-06-14]
Q: Can I double-book a table?
A: The calendar makes overlaps visible, but no server-side availability/conflict check exists in the create path — Create only maps the view-model, stamps the org/Reserved status, and adds the row; no overlap query. Treat the timeline as the conflict guard. [code: RestaurantReservationHelper.cs:Create@14-25 — no overlap/availability query]
Q: Can I delete a reservation outright? A: No hard delete — Cancel sets the Cancelled status (soft removal from the calendar). [code: ReservationsController.cs:143-156]
Q: Does cancelling notify the customer?
A: No — no notification hook exists on reservation create or cancel; neither RestaurantReservationHelper.Create/Update nor ReservationsController.Cancel calls any notification/dispatch service. [code: RestaurantReservationHelper.cs:Create@14-25,Update@28-47; ReservationsController.cs:Cancel@143-156 — no notify call]
Q: Which roles can use reservations?
A: View/Create/Edit/Delete are separate role grants under Roles.Reservations.*; a host needs at least View + Create. [code: ReservationsController.cs:18,42,72,143 (the four [Authorize(Roles=...)] gates); haafai.domain ModelConstants.Roles.Reservations@1712-1716 (staging) — four distinct constants]
Q: What timezone does the calendar use?
A: The logged-in user's timezone (CallContext.TimeZone is passed to FullCalendar; times render via moment-timezone). [code: Index.cshtml:61 (timeZone: '@CallContext.TimeZone'),42 (moment-timezone)]
Edge cases and known issues
- No availability check — overlapping bookings on the same table are accepted server-side; rely on the visual timeline. Symptom: two blocks stacked on one table row.
- Covers is free text — "6", "six", or "6 + highchair" are all stored as-is; reports cannot safely sum party sizes.
- Time window is informational — nothing releases the table or flags no-shows when the To time passes; stale Reserved blocks must be cancelled manually.
- Module dormant since 2026-04-15 watermark — zero commits to the reservations views/controller; behaviour is stable but receives no active development. The React rewrite has not picked it up.
- POST-reload quirk — the Index view reloads itself after modal POSTs (a full
location.reload()on POST), so expect a page refresh after adding a booking. [code: Index.cshtml:44-52]
Related
- Tables (Dine-In) — tables, floors and seating (the resources the calendar rows come from)
- Outlets — where tables/floors are configured
- Customers — reservations do NOT link to customer records (contact name/phone are free text)
What changed since 2026-04-15 (NEW 2026-05)
No reservation-specific changes since the watermark. Reservations live entirely in the legacy monolith (haafai.app.foodops) under Haafai.Restaurant.App/Views/Reservations/{Index, _Add, _Details, _Edit}.cshtml and Haafai.Restaurant.App/Controllers/ReservationsController.cs. The foodops.counter.app React rewrite has not yet ported the reservations module — there is no src/pages/ReservationsPage.tsx or src/components/reservations/** in counter.app.
Drift detector v2 ranked this entry HIGH-rank #22 only via fallback to all 191 foodops.counter.app commits — those commits do not affect reservations because reservations don't exist in counter.app. With the curated single-repo glob, this entry should drop to LOW on the next sweep.
Verified_by:
codebase· Last verified: 2026-05-04 Glob curated toHaafai.Restaurant.App/Views/Reservations/**;Haafai.Restaurant.App/Controllers/ReservationsController.cs(legacy monolith only — reservations have not been ported to counter.app). The previous globs (foodops.counter.app: src/reservations/**andfoodops.api: Controllers/Reservations*/**) matched no real files in either repo, causing the drift detector to fall back to "any commit in repo" and inflating the score. With the curated glob, the legacy monolith Reservations views/controller have 0 commits since 2026-04-15 — entry is genuinely LOW-drift, not HIGH. Awaiting playwright walkthrough to lift from stub.
2026-06-11 — codebase: promoted stub → draft against
haafai.app.foodops@f06cdd9(prodmain) + domain constants fromhaafai.domain@main. This is an honest THIN-FEATURE entry: full surface is one FullCalendar resource-timeline page (tables × time), an add/edit modal (Contact Name / Phone / Covers / Table / From / To), a details panel, and cancel. Statuses Waitlist/Reserved/CheckedIn/Cancelled exist in the domain but only Reserved (create) and Cancelled (cancel) are reachable from this screen. Verified ABSENT: counter-app port, customer self-booking, availability/overlap checks, POS table-blocking, notifications, customer-record linkage. Confidencemediumfor what exists; the feature itself is small.2026-06-14 — codebase TRUTH AUDIT (chat-widget/voice grounding pass): re-read every cited source at current prod HEADs (
haafai.app.foodops@main40624ca; controller/helper/views/view-model line-for-line) and grounded the previously-uncited "verified-absent" claims with concrete searches: counter.app@main (df086e4) + foodops-admin-app@main = zeroreserv|bookingpaths; ordering.app@main = no booking flow; counter.app TableLayoutModal.tsx/FloorPlanCanvas.tsx = no reservation refs; haafai.app.pos@master = only unrelated StockReservation inventory code. Domain citations re-pointed tohaafai.domain@staging(a2bd90e) —mainis FROZEN since 2025-12-25 per repo-prod-branches.md; status constants (35-41) and Roles.Reservations (1712-1716) are byte-identical on both branches. Corrected/tightened off-by-a-few line cites (timezone 60→61, select handler, color 127). Net: NO false claims found — entry was already honest; this pass converts hedged "not found in current code" prose into provable verified-absent citations so the assistant serves it grounded.2026-06-29 — codebase: NEW-STACK launch re-verification (July-10). MAJOR FINDING: Reservations has no new-stack equivalent and is RETIRED with the monolith at launch. Recursive
gh apitree searches forreserv|bookingreturned zero reservation/booking paths infoodops.counter.app@main(32669a9f3a),foodops-admin-app@main(f6ffd0b19d), orhubits-api-sales@main(19190b9a04) — the only hits were unrelated payment/UoM service files. The feature lived solely inhaafai.app.foodops(ReservationsController+Views/Reservations/**), which is fully retired at launch. Updated the entry to lead with a retirement banner, flipped status → needs-review + tagretired-at-launch, and corrected the access section + the "where do I manage reservations" Q&A to state the feature is unavailable. PRODUCT GAP to flag for the launch: there is no reservations/table-booking capability in the new stack. (The detailed monolith behaviour is retained below as historical reference.)
Additional verification events are appended here by the weekly KB sync and by manual re-verification passes. See _meta/failure-log.md for the global failure index.