# Room Allocation (Bookings) – Feature Spec

**Purpose:** Single source of truth for the EMS Room Allocation / Bookings feature. Use for implementation and acceptance.

**Route:** `/ems/bookings` — component: `RoomsInformation.js`  
**Last updated:** From requirements discussion (Feb 2025).

---

## 1. Scope

- **In scope:** UI and behaviour for viewing room availability and allocating rooms to participants over a date range, with pricing and allocation-type (Standard / Athlete / Private).
- **Out of scope (for this spec):** Travel, billing, check-in/out, and reporting. Backend auth on EMS routes is assumed to be added separately.

---

## 2. Requirements Summary

| # | Requirement | Status |
|---|-------------|--------|
| 1 | Select a hotel | Locked |
| 2 | View all rooms from several dates | Locked |
| 3 | Select multiple dates and allocate a room for a user (respecting bed count) | Locked |
| 4 | Different pricing for various users and for different dates | Locked (high level) |
| 5 | Allocate multiple rooms for the same person (same or different dates) | Locked |

---

## 3. Requirement 1 – Select a Hotel

### 3.1 Behaviour

- A **“Select Hotel”** dropdown is shown at the top of the Rooms information page.
- The dropdown lists **all global hotels** (from the GlobalHotels model / API).
- When **no hotel is selected** (e.g. first load), the app **auto-selects the first hotel** so the grid always shows data (no empty state on initial load).

### 3.2 Data

- **Source:** GlobalHotels (or existing API that returns global hotels).
- **Display:** Hotel name (e.g. `global_hotel_name`). Value can be `_id` or `global_hotel_id` as needed by the backend.

### 3.3 UI

- Dropdown placed in the top bar next to the “Rooms information” title (current design).
- After selection (or auto-selection), the grid shows **rooms and allocations for the selected hotel only**.

---

## 4. Requirement 2 – View All Rooms from Several Dates

### 4.1 Behaviour

- The main content is a **grid**: rows = rooms, columns = dates.
- **Room column (left):** Shows room identifier and **bed count** (e.g. “01”, “Beds: 2”).
- **Date columns:** Show a contiguous range of dates (e.g. 12 days).
- **Date range:** Restricted to the **active competition’s date range** (competition `start_date` / `end_date`). User cannot navigate outside this range.
- **Date navigation:** Left/right arrows (« ») move the visible window by **7 days** (one week). Arrows are placed **in the table header**, next to the “Room” column label.
- **Rooms list:** Show **all rooms** that belong to the selected hotel (no filtering by room type). Room–hotel relationship comes from the Room model (e.g. `hotel_id` array includes the selected hotel).

### 4.2 Parameters

| Parameter | Value |
|-----------|--------|
| Number of dates visible | 12 |
| Navigation step | 7 days |
| Date range constraint | Active competition start_date → end_date |
| Rooms shown | All rooms for selected hotel |

### 4.3 Data

- **Rooms:** From Room model, filtered by selected hotel (and optionally active competition).
- **Competition dates:** From Competition model (`start_date`, `end_date`) for the active competition.
- **Active competition:** To be defined by the app (e.g. context, dropdown, or default competition). Spec does not mandate how “active” is chosen.

---

## 5. Requirement 3 – Select Multiple Dates and Allocate (Respecting Bed Count)

### 5.1 Selection Flow

- User **clicks one or more empty (available) cells** in the grid. Each cell = one (room, date).
- Multi-select: e.g. click first cell, then shift-click last cell for a range; or click multiple cells. Exact interaction (click vs shift-click) is an implementation detail.
- After selecting cells, a **modal (or side panel)** opens where the user:
  - Chooses the **participant** (person to allocate).
  - Chooses **allocation type:** **Standard** or **Private** (user choice; Athlete is not offered in this flow).
  - Optionally sets **price** and **guests** (if required by data model).
- On confirm, the allocation is saved and the grid refreshes.

### 5.2 Who Can Be Allocated

- **Participants** linked to the **active competition** (Participant model, `competition_id` includes active competition).
- **Exclude athletes:** The participant list in the allocation modal must **exclude** participants who belong to the **Athletes** group. Identification of “Athletes” is by **Group** (e.g. `group_id` or group name “Athletes” — exact rule to be consistent with existing Groups usage).

### 5.3 Bed Count Rule

- **One guest per bed:** The maximum number of guests for a given (room, date) equals the room’s **bed count**.
- **Multiple allocations per (room, date) allowed:** Different people can share the same room on the same date (e.g. two 1-guest allocations in a 2-bed room).
- **Validation:** When creating an allocation (or multiple allocations), the **total guests** for that room on that date must not exceed the room’s bed count. If the user tries to over-allocate, show an error and do not save.

### 5.4 Allocation Type (Standard / Private)

- **User chooses** at allocation time: **Standard** or **Private** (e.g. radio or dropdown in the modal).
- **Display:** Standard → green cell; Private → pink/red cell. Athlete allocations (if ever shown from another flow) → green cell with yellow badge on “(Athlete)” name only.

### 5.5 Data Model Implications

- Current **AssignRoom** model: `hotel_id`, `room_id`, `participant_ids`, `number_of_rooms`. It does not have per-**date** or allocation **type** (Standard/Private).
- To support room×date allocation with type and pricing, one of:
  - **New model** (e.g. RoomAllocation / Booking): `room_id`, `date` (or `start_date`/`end_date`), `person_id`, `allocation_type` (enum: standard | private | athlete), `price`, `guests`, competition/hotel context as needed; **or**
  - **Extend AssignRoom** with date range and type (may require multiple documents per room for different dates).
- Bed count: available from Room (e.g. derive from `no_of_rooms` or add a `bed_count` / `beds` field if not present). Validation must use this for the “total guests ≤ beds” rule.

---

## 6. Requirement 4 – Different Pricing for Various Users and Dates

### 6.1 Behaviour

- The system must support **different prices** for:
  - Different **dates** (e.g. base price per room per date).
  - Different **users / allocation types** (e.g. athlete rate vs standard rate vs private).
- **Unallocated cells** show an **available price** (e.g. “100$”, “85$”) that can vary by room and date.
- **Allocated cells** show the **price for that allocation**, which may differ from the unallocated price and may vary by participant or type.

### 6.2 Implementation Note

- Exact fields (e.g. `price` on allocation, default price per room/date) and UI for editing prices are left to implementation. This spec only requires that the data model and UI support per-date and per-user/type pricing.

---

## 7. Requirement 5 – Multiple Rooms for Same Person

### 7.1 Behaviour

- The same person (participant) **can be allocated** to:
  - **Multiple rooms** on the **same date** (e.g. Room 01 and Room 03 on Mon 17-JUL-28).
  - **Multiple rooms** on **different dates**.
  - The **same room** on **multiple consecutive (or non-consecutive) dates** (e.g. John Smith in Room 01 from Mon to Fri).
- No restriction is placed on “one room per person” or “one allocation per person”. Validation is only: per (room, date), total guests ≤ bed count.

---

## 8. UI Reference (Current Design)

- **Page:** “Rooms information” title; “Select Hotel” dropdown (top right).
- **Grid header:** « » arrows next to “Room”; then date columns (day name + date, e.g. “Sun 16-JUL-28”).
- **Room column:** Room number + “Beds: X” (with or without bed icon per design).
- **Cells:**
  - **Available:** White background; price only (e.g. “100$”).
  - **Standard:** Green background; name, team, price, guests/extras, “Required”, beds.
  - **Athlete:** Green background; “(Athlete)” with yellow name badge; same detail layout.
  - **Private:** Pink/red background; same detail layout; “Private” status.
- **Interaction:** Empty cells are clickable for allocation; selection state and modal content as per Requirement 3.

---

## 9. Existing Codebase References

| Area | Location / Model |
|------|------------------|
| Page component | `src/components/ems/RoomsInformation.js` |
| Styles | `src/components/css/RoomsInformation.css` |
| Route | `/ems/bookings` in `src/App.js` |
| Sidebar | “Bookings” in `src/components/ems/EmsDashboardLayout.js` |
| Global hotels | `dashboard/models/GlobalHotels.js`, `dashboard/Routes/GlobalHotelRoutes.js` |
| Hotel (competition link) | `dashboard/models/Hotel.js`, `dashboard/Routes/HotelRoutes.js` |
| Rooms | `dashboard/models/Room.js`, `dashboard/Routes/RoomRoutes.js` |
| Assignments | `dashboard/models/AssignRoom.js`, `dashboard/Routes/AssignRoomRoutes.js` |
| Participants | `dashboard/models/Participant.js` (person_id, competition_id, group_id) |
| Competition | `dashboard/models/Competition.js` (start_date, end_date) |
| Groups | `dashboard/models/Group.js` (group_name — e.g. “Athletes”) |

---

## 10. Implementation Phases (Suggested)

1. **Data & API** — Endpoints (or reuse) for: global hotels list; rooms by hotel (and competition); competition dates; participants for competition excluding Athletes group; create/read room allocations (room + date + person + type + price). New or extended model for room×date allocation if needed.
2. **Wire current UI** — Replace mock data: hotel dropdown → real hotels; grid dates → competition range; grid rooms → rooms for selected hotel; cells → real availability and allocations.
3. **Allocation flow** — Multi-select empty cells → open modal → participant picker (non-athletes), Standard/Private, price/guests → validate bed count → save and refresh.
4. **Pricing** — Per-date and per-allocation price storage and display; any UI for editing default or allocation prices.
5. **Polish** — Empty states, loading, errors, and edge cases (e.g. no active competition, no rooms for hotel).

---

*End of spec.*
