Reservation Approvals Help

Overview

The Reservation Approvals page lists all pending reservation requests (pending_approval status) and lets a facility owner approve or reject each one.

When a plan's approval_mode is set to manual, reservations created through the host path (reservation-create-host) do not confirm automatically — they wait in this queue until a decision is made.

What you can do on this page:

  • View all reservations awaiting approval
  • Approve a reservation (confirms it)
  • Reject a reservation (a reason is required)

⚠ Important: Implementation status This feature is being rolled out in phases. DB schema / Edge Function / admin approval UI are complete, but the plan-editor toggle for switching to manual mode, the guest-path (reservation-booking) handling of pending_approval, approval notifications, the guest-side "awaiting approval" screen, and approval timeouts are not implemented yet (see Known Limitations). Issue #1127 tracks the full audit.


How to Access

Main menu → select "Reservation Approvals".

If there are no pending reservations, the page shows "No reservations awaiting approval."


Features

Feature 1: Pending Reservation List

Reservations with pending_approval status are displayed as individual cards.

Information shown on each card

Field Description
Guest Name Guest name from reservation metadata (falls back to first 8 chars of reservation ID)
Requested At Timestamp when the reservation was created
Plan ID First 8 chars of the linked plan ID

Sort order is oldest-first by request time. Priority filtering is not supported.


Feature 2: Approve

Confirms the reservation.

Steps

  1. Click "Approve" on the target card
  2. The reservation status changes to confirmed
  3. The decision is recorded in reservation_approvals (decider + timestamp)

⚠ No notification is sent today (Issue #1127 B5). Please notify the guest separately via email, LINE, etc.


Feature 3: Reject

Rejects the reservation. A reason is required.

Steps

  1. Click "Reject" on the target card
  2. A reason input field appears
  3. Enter the rejection reason (required)
  4. Click "Confirm rejection"
  5. The reservation status changes to cancelled
  6. The reason is recorded in reservation_approvals.rejection_reason

To cancel the rejection in progress, click "Cancel" (the reservation stays in the queue).

⚠ Rejection notification is not sent either (Issue #1127 B5). The reason is stored in the DB but the guest is not informed.


How to Enable Manual Approval

The only way to set a plan to approval_mode='manual' in this release is direct DB update:

UPDATE plans SET approval_mode = 'manual' WHERE id = '<plan-id>';

The PricePlanForm admin UI (/plans/:planId) does not yet expose an approval-mode toggle (Issue #1127 B1). Update via Supabase Studio (Platform Admin) for now.

⚠ The guest path (reservation-booking EF) does not yet honor approval_mode (Issue #1127 B2). Only reservations created through the host path (reservation-create-host) currently enter pending_approval. Guests booking through apps/booking still flow through pendingconfirmed even on manual plans.


Known Limitations

Tracked in Issue #1127. Current partial-implementation gaps:

# Item Status
B0 "Always approve / First-time only" mode distinction Schema only supports 'auto' | 'manual'. No column or flag for first-time-only
B1 Plan editor UI for approval_mode toggle Not implemented — SQL update required
B2 Guest path (reservation-booking) handling of pending_approval Not implemented — always enters pending
B3 apps/booking "awaiting approval" screen / status badge Not implemented — guests cannot see pending state
B4 Auto-bind of Default Pending Reservation Form to plans Not implemented — manual attach only (/plans/:planId "Applied forms" section)
B5 Approval / rejection notifications (email / LINE / webhook) Not implemented
B6 Key issuance race reservation-create-host invokes reservation-confirm regardless of approval status, but reservation-confirm/index.ts:159 rejects any non-pending reservation with 400, so no access code is issued before approval. No runtime action needed; long-term cleanup would be to skip the invoke when approval_mode='manual'
B7 Approval timeout Undefined — reservation_approvals has no expiry column; reservation stays pending_approval even past start time

Implementation will be split into separate issues after Issue #1127's Chapter D (membership integration) and Chapter E (¥0 subscription) decisions are recorded in an ADR.


FAQ

Q: How is a guest in pending_approval state notified?

Not implemented today (B3). There is no guest-facing screen showing "awaiting owner approval." Please contact the guest directly.

Q: Are approval / rejection actions logged?

Yes. Each decision is written to reservation_approvals (decided_by / decided_at / rejection_reason).

Q: Is there a priority filter for the pending list?

No. Current sort order is oldest-first by request time. Priority filtering will be added later.

Q: Is the rejection reason emailed to the guest?

No notification is sent today (B5). The reason is stored in the DB but not delivered. Please contact the guest separately.

Q: Is there a "first-time approval only, auto-confirm thereafter" mode?

Not yet (B0). approval_mode is binary ('auto' or 'manual') and there is no per-guest approval history. Issue #1127 Chapter D is discussing integrating this with the membership mechanism (¥0 membership = first-time-approved guest).

Q: What happens if a pending reservation passes its start time?

No automatic handling today (B7). It stays pending_approval. Approve or reject manually. Timeout behavior will be defined later.