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