Add front-office system design document
Comprehensive design for hotel front-office modules including room dashboard, reservations, guests, housekeeping, room service, events/venues, employee scheduling, and reports/analytics. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
454
docs/plans/2026-02-15-hotel-front-office-design.md
Normal file
454
docs/plans/2026-02-15-hotel-front-office-design.md
Normal file
@@ -0,0 +1,454 @@
|
||||
# Hotel Front-Office System Design
|
||||
|
||||
**Date**: 2026-02-15
|
||||
**Status**: Approved
|
||||
**Approach**: Module-by-module sequential build (Approach A)
|
||||
|
||||
## Decisions
|
||||
|
||||
| Decision | Choice |
|
||||
|---|---|
|
||||
| Scope | All front-office modules |
|
||||
| UI Style | Dark theme with gold accents (#d4a574) |
|
||||
| Bookings | Channel manager ready (data model supports it, APIs deferred) |
|
||||
| Multi-tenant | Deferred - single-hotel system first |
|
||||
| Auth | Upgrade to JWT with route protection |
|
||||
| Language | Bilingual Spanish/English (react-i18next) |
|
||||
|
||||
## Build Order
|
||||
|
||||
1. Foundation (JWT, i18n, dark theme, DB schema)
|
||||
2. Room Dashboard & Status Management
|
||||
3. Reservations Module
|
||||
4. Guest Management
|
||||
5. Housekeeping
|
||||
6. Room Service
|
||||
7. Events & Venues
|
||||
8. Employee Scheduling
|
||||
9. Reports & Analytics
|
||||
|
||||
---
|
||||
|
||||
## 1. Foundation Layer
|
||||
|
||||
### 1.1 JWT Authentication
|
||||
|
||||
- Add `jsonwebtoken` and `bcryptjs` packages to backend
|
||||
- Create `authMiddleware.js` verifying JWT on all `/api/*` routes except `/api/auth/login` and `/api/auth/refresh`
|
||||
- Access token: 15min expiry, stored in memory (frontend)
|
||||
- Refresh token: 7 days, httpOnly cookie
|
||||
- `POST /api/auth/refresh` endpoint
|
||||
- Frontend Axios interceptor: attach token, auto-refresh on 401
|
||||
- Update `AuthContext` for token lifecycle
|
||||
- DB: `refresh_tokens` table (token, user_id, expires_at, revoked)
|
||||
|
||||
### 1.2 Internationalization
|
||||
|
||||
- Packages: `react-i18next`, `i18next`, `i18next-browser-languagedetector`
|
||||
- Locale files: `/frontend/src/locales/es.json`, `/frontend/src/locales/en.json`
|
||||
- Replace `LenguageContext` with i18next provider
|
||||
- Language switcher component in navbar
|
||||
- New modules use translation keys from start
|
||||
- Existing modules migrated incrementally
|
||||
|
||||
### 1.3 Dark Theme Design System
|
||||
|
||||
CSS custom properties in `theme.css`:
|
||||
- Background: `#0a0a0a` (main), `#1a1a1a` (cards), `#2a2a2a` (elevated)
|
||||
- Accent: `#d4a574` (gold) for primary actions
|
||||
- Text: `#ffffff` (primary), `#a0a0a0` (secondary)
|
||||
- Status: green (available), blue (occupied), yellow (cleaning), red (maintenance)
|
||||
- Success: `#22c55e`, Warning: `#eab308`, Error: `#ef4444`, Info: `#3b82f6`
|
||||
- All new components built with these tokens via Tailwind
|
||||
|
||||
### 1.4 Database Schema
|
||||
|
||||
```sql
|
||||
-- Guest Management
|
||||
CREATE TABLE guests (
|
||||
id SERIAL PRIMARY KEY,
|
||||
first_name VARCHAR(100) NOT NULL,
|
||||
last_name VARCHAR(100) NOT NULL,
|
||||
email VARCHAR(255),
|
||||
phone VARCHAR(50),
|
||||
id_type VARCHAR(50),
|
||||
id_number VARCHAR(100),
|
||||
nationality VARCHAR(100),
|
||||
address TEXT,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Reservations
|
||||
CREATE TABLE reservations (
|
||||
id SERIAL PRIMARY KEY,
|
||||
room_id INTEGER REFERENCES rooms(id),
|
||||
guest_id INTEGER REFERENCES guests(id),
|
||||
check_in DATE NOT NULL,
|
||||
check_out DATE NOT NULL,
|
||||
status VARCHAR(20) DEFAULT 'pending',
|
||||
channel VARCHAR(50),
|
||||
total_amount DECIMAL(12,2),
|
||||
adults INTEGER DEFAULT 1,
|
||||
children INTEGER DEFAULT 0,
|
||||
notes TEXT,
|
||||
created_by INTEGER REFERENCES users(id),
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- status: pending, confirmed, checked_in, checked_out, cancelled
|
||||
-- channel: direct, booking, expedia, airbnb, other
|
||||
|
||||
-- Guest Stay History
|
||||
CREATE TABLE guest_stays (
|
||||
id SERIAL PRIMARY KEY,
|
||||
guest_id INTEGER REFERENCES guests(id),
|
||||
reservation_id INTEGER REFERENCES reservations(id),
|
||||
room_id INTEGER REFERENCES rooms(id),
|
||||
check_in TIMESTAMP,
|
||||
check_out TIMESTAMP,
|
||||
total_charged DECIMAL(12,2),
|
||||
rating INTEGER,
|
||||
feedback TEXT,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Room Status Audit Log
|
||||
CREATE TABLE room_status_log (
|
||||
id SERIAL PRIMARY KEY,
|
||||
room_id INTEGER REFERENCES rooms(id),
|
||||
previous_status VARCHAR(20),
|
||||
new_status VARCHAR(20),
|
||||
changed_by INTEGER REFERENCES users(id),
|
||||
changed_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Housekeeping Tasks
|
||||
CREATE TABLE housekeeping_tasks (
|
||||
id SERIAL PRIMARY KEY,
|
||||
room_id INTEGER REFERENCES rooms(id),
|
||||
assigned_to INTEGER REFERENCES employees(id),
|
||||
priority VARCHAR(10) DEFAULT 'normal',
|
||||
type VARCHAR(20) NOT NULL,
|
||||
status VARCHAR(20) DEFAULT 'pending',
|
||||
notes TEXT,
|
||||
started_at TIMESTAMP,
|
||||
completed_at TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- priority: high, normal, low
|
||||
-- type: checkout, maintenance, deep_clean, turndown
|
||||
-- status: pending, in_progress, completed
|
||||
|
||||
-- Menu Items (Room Service)
|
||||
CREATE TABLE menu_items (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
description TEXT,
|
||||
price DECIMAL(10,2) NOT NULL,
|
||||
category VARCHAR(50),
|
||||
available BOOLEAN DEFAULT TRUE,
|
||||
image_url VARCHAR(500),
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Room Service Orders
|
||||
CREATE TABLE room_service_orders (
|
||||
id SERIAL PRIMARY KEY,
|
||||
room_id INTEGER REFERENCES rooms(id),
|
||||
guest_id INTEGER REFERENCES guests(id),
|
||||
status VARCHAR(20) DEFAULT 'pending',
|
||||
total DECIMAL(10,2),
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- status: pending, preparing, delivering, delivered, cancelled
|
||||
|
||||
-- Order Items
|
||||
CREATE TABLE order_items (
|
||||
id SERIAL PRIMARY KEY,
|
||||
order_id INTEGER REFERENCES room_service_orders(id),
|
||||
menu_item_id INTEGER REFERENCES menu_items(id),
|
||||
quantity INTEGER NOT NULL DEFAULT 1,
|
||||
price DECIMAL(10,2) NOT NULL,
|
||||
notes TEXT
|
||||
);
|
||||
|
||||
-- Venues
|
||||
CREATE TABLE venues (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
capacity INTEGER,
|
||||
area_sqm DECIMAL(8,2),
|
||||
price_per_hour DECIMAL(10,2),
|
||||
amenities JSONB DEFAULT '[]',
|
||||
description TEXT,
|
||||
status VARCHAR(20) DEFAULT 'available',
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Events
|
||||
CREATE TABLE events (
|
||||
id SERIAL PRIMARY KEY,
|
||||
venue_id INTEGER REFERENCES venues(id),
|
||||
name VARCHAR(200) NOT NULL,
|
||||
organizer VARCHAR(200),
|
||||
event_date DATE NOT NULL,
|
||||
start_time TIME NOT NULL,
|
||||
end_time TIME NOT NULL,
|
||||
guest_count INTEGER,
|
||||
status VARCHAR(20) DEFAULT 'confirmed',
|
||||
notes TEXT,
|
||||
total_amount DECIMAL(12,2),
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Employee Schedules
|
||||
CREATE TABLE employee_schedules (
|
||||
id SERIAL PRIMARY KEY,
|
||||
employee_id INTEGER REFERENCES employees(id),
|
||||
schedule_date DATE NOT NULL,
|
||||
shift_type VARCHAR(20) NOT NULL,
|
||||
start_time TIME,
|
||||
end_time TIME,
|
||||
notes TEXT,
|
||||
UNIQUE(employee_id, schedule_date)
|
||||
);
|
||||
-- shift_type: morning (7-15), afternoon (15-23), night (23-7), off
|
||||
|
||||
-- Refresh Tokens (JWT Auth)
|
||||
CREATE TABLE refresh_tokens (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id),
|
||||
token VARCHAR(500) NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
revoked BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
```
|
||||
|
||||
Add `status` column to existing `rooms` table:
|
||||
```sql
|
||||
ALTER TABLE rooms ADD COLUMN status VARCHAR(20) DEFAULT 'available';
|
||||
-- status: available, occupied, cleaning, maintenance
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Room Dashboard & Status Management
|
||||
|
||||
### API Endpoints
|
||||
- `GET /api/rooms/status` - All rooms with current status, guest info, floor
|
||||
- `PUT /api/rooms/:id/status` - Update room status (cascading side effects)
|
||||
- `GET /api/dashboard/kpis` - Occupancy %, available count, check-ins, check-outs, revenue (today)
|
||||
- `GET /api/dashboard/weekly-revenue` - Last 7 days revenue data
|
||||
|
||||
### UI Components
|
||||
- `RoomDashboard.jsx` - Main page with KPI bar and floor grid
|
||||
- `RoomGrid.jsx` - Color-coded room cards organized by floor
|
||||
- `RoomDetailModal.jsx` - Room detail popup (guest, amenities, reservation)
|
||||
- `KPIBar.jsx` - Top bar with 4-5 metric cards
|
||||
- `WeeklyRevenueChart.jsx` - Bar chart component
|
||||
- `ArrivalsDepaturesList.jsx` - Today's arrivals/departures
|
||||
|
||||
### Business Logic
|
||||
- Room status cascade: check-out -> "cleaning", housekeeping done -> "available", check-in -> "occupied"
|
||||
- KPIs calculated from rooms and reservations tables
|
||||
- Floor data derived from room properties
|
||||
|
||||
---
|
||||
|
||||
## 3. Reservations Module
|
||||
|
||||
### API Endpoints
|
||||
- `GET /api/reservations` - List with filters (status, dates, search)
|
||||
- `POST /api/reservations` - Create (validates room availability)
|
||||
- `PUT /api/reservations/:id` - Update details
|
||||
- `PUT /api/reservations/:id/status` - Status transition with validation
|
||||
- `GET /api/reservations/availability` - Room availability for date range
|
||||
|
||||
### UI Components
|
||||
- `Reservations.jsx` - Main page with card grid
|
||||
- `ReservationCard.jsx` - Individual reservation card
|
||||
- `NewReservation.jsx` - Creation form
|
||||
- `ReservationFilters.jsx` - Status/date/search filters
|
||||
|
||||
### State Machine
|
||||
```
|
||||
pending -> confirmed -> checked_in -> checked_out
|
||||
pending -> cancelled
|
||||
confirmed -> cancelled
|
||||
```
|
||||
|
||||
### Business Rules
|
||||
- No double-booking (check availability before creating)
|
||||
- Check-in: updates room status to "occupied", creates guest_stay record
|
||||
- Check-out: updates room status to "cleaning", creates housekeeping task, closes guest_stay
|
||||
- Channel field: direct, booking, expedia, airbnb, other (for future integration)
|
||||
|
||||
---
|
||||
|
||||
## 4. Guest Management
|
||||
|
||||
### API Endpoints
|
||||
- `GET /api/guests` - List with search and pagination
|
||||
- `POST /api/guests` - Create guest profile
|
||||
- `PUT /api/guests/:id` - Update guest
|
||||
- `GET /api/guests/:id` - Guest details with current stay
|
||||
- `GET /api/guests/:id/stays` - Stay history
|
||||
|
||||
### UI Components
|
||||
- `Guests.jsx` - Guest directory with search
|
||||
- `GuestCard.jsx` - Guest card (avatar, contact, current room)
|
||||
- `GuestDetail.jsx` - Full profile with stay history
|
||||
- `NewGuest.jsx` - Guest creation form (also embedded in reservation form)
|
||||
|
||||
---
|
||||
|
||||
## 5. Housekeeping
|
||||
|
||||
### API Endpoints
|
||||
- `GET /api/housekeeping/tasks` - Tasks with filters (status, priority, staff)
|
||||
- `POST /api/housekeeping/tasks` - Create task
|
||||
- `PUT /api/housekeeping/tasks/:id` - Update (assign, start, complete)
|
||||
- `GET /api/housekeeping/staff` - Available housekeeping employees with status
|
||||
|
||||
### UI Components
|
||||
- `Housekeeping.jsx` - Two-column layout (pending + in-progress)
|
||||
- `TaskCard.jsx` - Task card (room, type, priority, staff, actions)
|
||||
- `StaffPanel.jsx` - Staff availability sidebar
|
||||
|
||||
### Automation
|
||||
- Auto-create task on room check-out (type: "checkout", priority: "high")
|
||||
- Task completion sets room to "available"
|
||||
- Staff filtered from employees table by housekeeping department
|
||||
|
||||
---
|
||||
|
||||
## 6. Room Service
|
||||
|
||||
### API Endpoints
|
||||
- `GET /api/room-service/orders` - Active and recent orders
|
||||
- `POST /api/room-service/orders` - Create order
|
||||
- `PUT /api/room-service/orders/:id/status` - Update order status
|
||||
- `GET /api/room-service/menu` - Menu items
|
||||
- `POST /api/room-service/menu` - Add menu item
|
||||
- `PUT /api/room-service/menu/:id` - Update/toggle availability
|
||||
|
||||
### UI Components
|
||||
- `RoomServiceOrders.jsx` - Active orders panel
|
||||
- `OrderCard.jsx` - Order details (room, items, status, total, time)
|
||||
- `MenuManager.jsx` - Menu item management
|
||||
- `NewOrder.jsx` - Create order form
|
||||
|
||||
### Order Flow
|
||||
```
|
||||
pending -> preparing -> delivering -> delivered
|
||||
pending -> cancelled
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Events & Venues
|
||||
|
||||
### API Endpoints
|
||||
- `GET /api/venues` - List all venues
|
||||
- `POST /api/venues` - Create venue
|
||||
- `PUT /api/venues/:id` - Update venue
|
||||
- `GET /api/events` - List events (date filters)
|
||||
- `POST /api/events` - Create event (validate venue availability)
|
||||
- `PUT /api/events/:id` - Update event
|
||||
|
||||
### UI Components
|
||||
- `Venues.jsx` - Venue cards with availability
|
||||
- `VenueCard.jsx` - Venue details (capacity, area, price, amenities)
|
||||
- `Events.jsx` - Event listing and calendar
|
||||
- `NewEvent.jsx` - Event creation form
|
||||
|
||||
---
|
||||
|
||||
## 8. Employee Scheduling
|
||||
|
||||
### API Endpoints
|
||||
- `GET /api/schedules` - Schedules by date range and department
|
||||
- `POST /api/schedules` - Create/update bulk schedule entries
|
||||
- `GET /api/schedules/employee/:id` - Individual schedule
|
||||
|
||||
### UI Components
|
||||
- `Schedules.jsx` - Weekly grid view
|
||||
- `ShiftCell.jsx` - Individual cell (click to edit)
|
||||
- `ScheduleFilters.jsx` - Department/employee filter
|
||||
|
||||
### Shift Types
|
||||
- Morning: 7:00 - 15:00 (yellow)
|
||||
- Afternoon: 15:00 - 23:00 (blue)
|
||||
- Night: 23:00 - 7:00 (purple)
|
||||
- Off: (gray)
|
||||
|
||||
---
|
||||
|
||||
## 9. Reports & Analytics
|
||||
|
||||
### API Endpoints
|
||||
- `GET /api/reports/occupancy` - Occupancy rate by period
|
||||
- `GET /api/reports/revenue` - Revenue by room type and period
|
||||
- `GET /api/reports/booking-sources` - Distribution by channel
|
||||
- `GET /api/reports/satisfaction` - Guest satisfaction (from guest_stays ratings)
|
||||
|
||||
### UI Components
|
||||
- `OperationalReports.jsx` - Main reports page
|
||||
- `PeriodSelector.jsx` - Week/Month/Quarter/Year toggle
|
||||
- `OccupancyChart.jsx` - Trend line chart
|
||||
- `RevenueByTypeChart.jsx` - Bar chart by room type
|
||||
- `BookingSourcesPie.jsx` - Pie chart of booking channels
|
||||
- `SatisfactionCard.jsx` - Rating display
|
||||
|
||||
---
|
||||
|
||||
## Frontend Route Structure (New)
|
||||
|
||||
All under `/app`:
|
||||
```
|
||||
/app/room-dashboard - Room status dashboard
|
||||
/app/reservations - Reservations list
|
||||
/app/reservations/new - New reservation
|
||||
/app/reservations/:id - Reservation detail
|
||||
/app/guests - Guest directory
|
||||
/app/guests/:id - Guest detail
|
||||
/app/housekeeping - Housekeeping tasks
|
||||
/app/room-service - Room service orders
|
||||
/app/room-service/menu - Menu management
|
||||
/app/venues - Venues list
|
||||
/app/events - Events list
|
||||
/app/events/new - New event
|
||||
/app/schedules - Employee scheduling
|
||||
/app/operational-reports - Reports & analytics
|
||||
```
|
||||
|
||||
## Sidebar Navigation Update
|
||||
|
||||
Add new section to sidebar:
|
||||
```
|
||||
Operations (existing)
|
||||
├── Dashboard (existing)
|
||||
├── Room Dashboard (NEW)
|
||||
├── Reservations (NEW)
|
||||
├── Guests (NEW)
|
||||
|
||||
Services (NEW section)
|
||||
├── Housekeeping (NEW)
|
||||
├── Room Service (NEW)
|
||||
├── Events & Venues (NEW)
|
||||
|
||||
Staff (existing section, renamed)
|
||||
├── Employees (existing)
|
||||
├── Contracts (existing)
|
||||
├── Schedules (NEW)
|
||||
├── Payroll (existing)
|
||||
|
||||
Reports (existing)
|
||||
├── Financial Reports (existing)
|
||||
├── Operational Reports (NEW)
|
||||
```
|
||||
Reference in New Issue
Block a user