# Availability Mechanism Verification Report
**Date:** 2026-08-13
**Purpose:** Verify if the venue availability mechanism used in the web page covers the latest workflow consistency updates
---
## Executive Summary
**CRITICAL FINDING:** The public-facing web availability mechanism does NOT cover the latest workflow consistency updates. There are **two separate availability checking systems** operating in parallel with significant differences in implementation and features.
**Status:** ⚠️ **NOT COVERED** - Public availability uses legacy system, PMS uses updated system
---
## Availability Systems Identified
### System 1: Public Web Availability (WebController)
**Location:** `app/Http/Controllers/WebController.php` (lines 1597-1648)
**Method:** `VenueObject::isBooked()`
**Purpose:** Public-facing venue availability display on web pages
**Implementation:**
```php
// WebController line 1618
$object->is_available_for_dates = !$object->isBooked($startDate, $endDate);
```
**VenueObject::isBooked() Method:**
```php
// app/Models/VenueObject.php lines 231-251
public function isBooked(Carbon $startTime, Carbon $endTime): bool
{
return $this->reservations()
->whereNotIn('status', ['canceled', 'completed'])
->where(function ($query) use ($startTime, $endTime) {
// Date overlap checks against reservation system
})
->exists();
}
```
**Features:**
- ✅ Checks date overlap
- ✅ Filters canceled/completed reservations
- ✅ Supports guest count capacity checking
- ✅ Dynamic pricing integration
- ❌ Uses OLD reservation system (not Stay-based)
- ❌ NO concurrency control
- ❌ NO transaction support
- ❌ NO housekeeping status check
- ❌ NO room history tracking
- ❌ NO expected vs actual dates
- ❌ NO audit logging
### System 2: PMS Internal Availability (RoomChangeManagementService)
**Location:** `app/Services/RoomChangeManagementService.php` (lines 216-242)
**Method:** `isRoomAvailable()`
**Purpose:** Internal PMS room availability checking for assignments
**Implementation:**
```php
// RoomChangeManagementService lines 216-242
public function isRoomAvailable(VenueObject $room, \Carbon\Carbon $from, \Carbon\Carbon $to, ?Stay $excludeStay = null): bool
{
$query = StayRoomAssignment::where('venue_object_id', $room->id)
->whereHas('stay', function ($q) use ($from, $to) {
$q->where(function ($query) use ($from, $to) {
$query->whereBetween('actual_check_in', [$from, $to])
->orWhereBetween('actual_check_out', [$from, $to])
->orWhere(function ($q) use ($from, $to) {
$q->where('actual_check_in', '<=', $from)
->where('actual_check_out', '>=', $to);
});
});
});
if ($excludeStay) {
$query->where('stay_id', '!=', $excludeStay->id);
}
$activeAssignments = $query->whereHas('roomAssignments', function ($q) {
$q->whereNull('checked_out_at');
})->exists();
// Also check room status
$roomReady = $room->housekeeping_status === 'clean' || $room->housekeeping_status === 'inspected';
return !$activeAssignments && $roomReady;
}
```
**Features:**
- ✅ Checks date overlap using NEW Stay-based system
- ✅ Checks housekeeping status (clean/inspected)
- ✅ Supports excluding current stay (for room changes)
- ✅ Uses StayRoomAssignment system
- ✅ Expected vs actual dates support
- ✅ Proper room history tracking
- ✅ Concurrency control in calling methods (lockForUpdate)
- ✅ Transaction support in calling methods
- ✅ Audit logging in calling methods
---
## Comparison Table
| Feature | Web Availability | PMS Availability | Coverage |
|---------|------------------|------------------|----------|
| Data Source | Old Reservations | New StayRoomAssignments | ❌ Different |
| Concurrency Control | ❌ None | ✅ lockForUpdate | ❌ Missing |
| Transaction Support | ❌ None | ✅ DB transactions | ❌ Missing |
| Housekeeping Check | ❌ None | ✅ Clean/Inspected check | ❌ Missing |
| Expected vs Actual Dates | ❌ None | ✅ Supported | ❌ Missing |
| Room History Tracking | ❌ None | ✅ released_at tracking | ❌ Missing |
| Guest Count Capacity | ✅ Supported | ✅ Supported | ✅ Both |
| Dynamic Pricing | ✅ Supported | ❌ Not needed | - |
| Idempotency | ❌ None | ✅ In calling methods | ❌ Missing |
| Audit Logging | ❌ None | ✅ In calling methods | ❌ Missing |
---
## Key Issues Identified
### 1. Dual System Architecture
**Problem:** Two separate availability checking systems operating in parallel
- Web: Uses old reservation-based system
- PMS: Uses new Stay-based system
- **Risk:** Data inconsistency between public display and actual availability
### 2. Missing Concurrency Control
**Problem:** Web availability check does not use `lockForUpdate()`
- Public users could see availability that gets booked by someone else
- No race condition protection during booking process
- **Risk:** Double bookings on public site
### 3. Missing Transaction Support
**Problem:** Web availability check is not wrapped in transactions
- No atomicity guarantees
- No rollback on failure
- **Risk:** Partial data updates
### 4. Missing Housekeeping Status
**Problem:** Web availability does not check room housekeeping status
- Shows rooms as available even if they're dirty/cleaning
- **Risk:** Guests booking unavailable rooms
### 5. Missing Expected vs Actual Dates
**Problem:** Web availability does not separate expected vs actual dates
- Does not preserve original booking dates
- **Risk:** Data inconsistency with PMS workflow
### 6. Missing Audit Logging
**Problem:** Web availability checks are not logged
- No audit trail for availability queries
- **Risk:** No accountability for availability issues
---
## Impact Analysis
### High Impact Issues
1. **Data Inconsistency:** Public availability may not match actual PMS availability
2. **Double Booking Risk:** No concurrency control on public site
3. **Housekeeping Gaps:** Public can book rooms that are dirty/cleaning
### Medium Impact Issues
1. **No Audit Trail:** Cannot track availability queries on public site
2. **No Transaction Safety:** Risk of partial updates during booking
3. **Date Tracking:** Missing expected vs actual date separation
### Low Impact Issues
1. **Code Maintenance:** Two separate systems to maintain
2. **Feature Parity:** Different features between systems
---
## Recommendations
### Immediate Actions (High Priority)
1. **Unify Availability Systems**
- Update WebController to use RoomChangeManagementService::isRoomAvailable()
- Deprecate VenueObject::isBooked() for internal use
- Ensure both systems use the same data source (StayRoomAssignments)
2. **Add Concurrency Control to Web Availability**
- Wrap availability checks in transactions with lockForUpdate()
- Prevent race conditions during booking process
3. **Add Housekeeping Status Check**
- Include housekeeping status in web availability logic
- Prevent booking of dirty/cleaning rooms
### Medium Priority Actions
4. **Add Audit Logging**
- Log all availability queries on public site
- Track who checked availability and when
5. **Add Transaction Support**
- Wrap booking process in DB transactions
- Ensure atomicity of booking operations
6. **Update Date Handling**
- Support expected vs actual dates in web availability
- Align with PMS workflow
### Low Priority Actions
7. **Code Refactoring**
- Remove duplicate availability logic
- Create unified availability service
8. **Performance Optimization**
- Cache availability results
- Optimize database queries
---
## Implementation Plan
### Phase 1: Critical Fixes (Week 1)
1. Create unified availability service
2. Update WebController to use new service
3. Add concurrency control to public availability
4. Add housekeeping status check
### Phase 2: Feature Parity (Week 2)
5. Add audit logging to public availability
6. Add transaction support to booking process
7. Update date handling for expected vs actual
### Phase 3: Cleanup (Week 3)
8. Deprecate old VenueObject::isBooked() method
9. Remove duplicate code
10. Update documentation
---
## Technical Details
### Current Web Availability Flow
```
User Request → WebController → VenueObject::isBooked()
↓
Check reservations (old system)
↓
Return availability status
```
### Recommended Web Availability Flow
```
User Request → WebController → RoomChangeManagementService::isRoomAvailable()
↓
Check StayRoomAssignments (new system)
↓
Check housekeeping status
↓
Use concurrency control (lockForUpdate)
↓
Wrap in transaction
↓
Log availability check
↓
Return availability status
```
---
## Conclusion
The public-facing web availability mechanism does **NOT** cover the latest workflow consistency updates implemented in the PMS system. There are two separate availability checking systems with significant differences in features and implementation.
**Key Finding:** The web availability check uses the legacy reservation-based system while the PMS uses the new Stay-based system with all the workflow consistency improvements (concurrency control, transactions, housekeeping checks, audit logging, etc.).
**Recommendation:** Immediate action required to unify the availability systems and bring the web-facing mechanism up to par with the PMS internal system to prevent data inconsistency and double bookings.
---
**Verification Status:** ⚠️ **NOT COVERED** - Significant gaps identified
**Priority:** **HIGH** - Immediate action required