# Property Archetypes & Hospitality Data Models

One of the most important architectural insights in Traveate came from onboarding two real-world Kenyan properties with radically different operating models onto the **exact same canonical data core** with zero property-specific tables:

1. **Hope Homestay (`hope-homestay`, Syokimau, Nairobi Metro)** — A residential **4-Bedroom Homestay / Airbnb entity** sold exclusively as an **"Entire Place" (Whole House)** for `1 to 8 guests` on a per-night basis.
2. **Rock Hyrax Hotel (`rock-hyrax-hotel`, Nakuru)** — A **Full-Service Independent Hotel** with `5` pooled room categories (`26` rooms/cottages), multi-board meal plans (`BB`, `HB`, `FB`), an on-site restaurant (`Rock Hyrax Restaurant & Garden Terrace`), and a `35-delegate` conference hall.

---

## 1. Side-by-Side Comparison of Hospitality Archetypes

| Dimension | Archetype A: Entire-Place Homestay (`Hope Homestay`) | Archetype B: Full-Service Independent Hotel (`Rock Hyrax Hotel`) |
| :--- | :--- | :--- |
| **`Property.type`** | `'homestay'` (also applies to `'villa'`, `'apartment'`) | `'hotel'` (also applies to `'guesthouse'`, `'resort'`) |
| **`Property.inventory_model`** | **`'unique'`** — Single physical whole-house unit (`inventory_count = 1`) | **`'pooled'`** — Multiple identical units per room category (`inventory_count = 3..8`) |
| **Unit Assignment (`Booking.unit_id`)** | **Auto-assigned at booking confirmation** to the physical house (`SEED_IDS.units.room1`) | **Left `null` at confirmation** and assigned at physical check-in |
| **Guest Sharing Rule** | **Never shared by unrelated guests.** Any 1 booking reduces `available_units` from `1` to `0` for those dates. | Multiple unrelated guests book into the same `UnitType` pool simultaneously until `available_units == 0`. |
| **Currency** | `USD` (`$32` – `$60` / night) | `KES` (`KES 7,000` – `KES 18,500` / night) |
| **Pricing Strategy** | **Channel-Specific & Occupancy-Tiered:**<br>• **Airbnb:** Flat `$50/night` + `$10/night` Airbnb fee = `$60/night` total (`1–8` pax)<br>• **Booking.com:** Occupancy-tiered by guest count (`2 pax = $32` up to `8 pax = $60`) | **Room Category + Meal Board Offset:**<br>• **BB (Bed & Breakfast):** Base room rate (`+0`)<br>• **HB (Half Board):** `+KES 2,500/night`<br>• **FB (Full Board):** `+KES 4,500/night` |
| **Dining Facilities** | Self-catering full home kitchen & dining room (`policies.facilities.dining = []`) | Commercial **Rock Hyrax Restaurant & Garden Terrace** (`06:30–22:30`) |
| **Conferencing & Events** | None — quiet residential court rules enforced | **Hyrax Executive Conference & Banquet Hall** (up to `35` delegates, boardroom/classroom/U-shape layouts, day/full-day packages) |

---

## 2. Archetype A Deep Dive: Entire-Place Homestay (`Hope Homestay`)

### Why "Entire Place" Instead of Individual Bedrooms?
At a residential homestay like **Hope Homestay** (4 en-suite bedrooms inside a single home in Syokimau), selling individual bedrooms (`'En-suite Bedroom' × 4`) to different/unrelated guests on the same night creates operational friction — guests share the living room, kitchen, and compound with strangers.

Instead, the property is modeled as a single **"Entire Place" (`inventory_model: 'unique'`, `inventory_count: 1`)**:
- Whether **1 person** books or **8 people** book, they reserve the **Entire Four-Bedroom Homestay** exclusively.
- Once confirmed for a date range, `available_units` drops from `1` to `0`, preventing any overlapping booking on Airbnb, Booking.com, or direct channels.

### Modeling Channel-Specific & Occupancy-Tiered Pricing on One `UnitType`
Hope Homestay uses two distinct `RatePlan` records attached to the `Entire Four-Bedroom Homestay (Whole House)` `UnitType`:

#### 1. Airbnb Flat Rate + Channel Fee (`RatePlan.metadata.channel_fee`)
On Airbnb (`listing_id: 797494517027686373`), the host charges a flat **`$50 / night`** regardless of guest count (`1–8` guests), and the guest pays **`$60 / night` inclusive of Airbnb fees (`$10 / night`)**:

```json
{
  "name": "Airbnb — Entire Place Flat Rate ($50/night + $10 Airbnb Fee = $60 Total)",
  "currency": "USD",
  "base_price_cents": 5000,
  "meal_plan": "room_only",
  "metadata": {
    "channel": "airbnb",
    "pricing_model": "flat_entire_place",
    "channel_fee": {
      "code": "AIRBNB_SERVICE_FEE",
      "name": "Airbnb Service Fee ($10/night)",
      "rate_pct": 20,
      "per_night_cents": 1000
    }
  }
}
```

#### 2. Booking.com Occupancy-Tiered Rate (`RatePlan.metadata.occupancy_pricing`)
On Booking.com (`hotel/ke/hope-homestay-syokimau`, property ID `9457016`), the property still sells the **Entire Four-Bedroom House**, but the nightly rate scales with the number of guests (`pax = adults + children`):

```json
{
  "name": "Booking.com — Entire Place (Occupancy-Based 1–8 Pax)",
  "currency": "USD",
  "base_price_cents": 3200,
  "meal_plan": "room_only",
  "metadata": {
    "channel": "booking_com",
    "pricing_model": "occupancy_tiered",
    "occupancy_pricing": {
      "1": 3200,
      "2": 3200,
      "3": 3500,
      "4": 4000,
      "5": 4500,
      "6": 5000,
      "7": 5500,
      "8": 6000
    }
  }
}
```

When an AI agent or booking engine calls `get_availability` with `adults: 4, children: 1` (`5 pax`), Traveate's pricing engine (`src/core/availability.ts`) automatically resolves `$45.00 / night` (`4500` cents) on the Booking.com rate plan and `$50.00 + $10.00 = $60.00 / night` (`6000` cents) on the Airbnb rate plan.

---

## 3. Archetype B Deep Dive: Full-Service Independent Hotel (`Rock Hyrax Hotel`)

### Multi-Category Pooled Inventory + Multi-Board Rate Plans
An independent hotel like **Rock Hyrax Hotel** (`https://rockhyraxhotel.com`) operates `5` room categories across `26` rooms (`Standard Double`, `Superior Double`, `Standard Twin`, `Superior Twin`, `Executive Suite`). Each room category has `3` rate plans (`BB`, `HB`, `FB`) using `RatePlan.metadata.price_offset_cents`:
- **Bed & Breakfast (`BB`):** `meal_plan: 'breakfast'`, `price_offset_cents: 0`
- **Half Board (`HB`):** `meal_plan: 'half_board'`, `price_offset_cents: 250000` (`+KES 2,500/night`)
- **Full Board (`FB`):** `meal_plan: 'full_board'`, `price_offset_cents: 450000` (`+KES 4,500/night`)

### Autonomous Agent Onboarding & Owner Dashboard Verification
Many hotel owners do not want to fill out 50 form fields to onboard their property. Instead, they give the agent a **hotel name**, **website URL** (`https://rockhyraxhotel.com`), **Booking.com link**, or **Google Maps link**:
1. **Agent Research & Onboarding (`onboard_property_preview` → `onboard_property_confirm`):**
   - The agent researches the property online, extracts room categories, amenities, restaurant hours, and conference hall capacity, and records `policies.onboarding_provenance.verification_status = 'pending_owner_review'`.
2. **Owner Verification & Correction (`/dashboard`):**
   - The owner opens `http://localhost:3456/dashboard?property_id=rock-hyrax-hotel`, inspects the **Agent Onboarding Provenance** badge, edits any room rate/inventory count or conference capacity via `/api/v1/properties/:id/verify-update` and `/api/v1/unit-types/:id/verify-update`, and marks the property **`verified_by_owner`** (logged to `audit_logs`).
