HMS Anyaman is a full-featured Hotel Management System I built and maintained over ~2 years. It covers the complete hotel operations lifecycle — from room booking and front desk management to housekeeping scheduling, dynamic rate optimization, event management, and financial reporting.
In this case study, I walk through the architecture, key technical decisions, the recent backend migration from Laravel to Node.js, and lessons learned from building a system with 186 database tables and 80+ API endpoints.
Next.js React.js Laravel Node.js Express TypeScript MySQL PostgreSQL Prisma ORM PHP REST API Tailwind CSS GitLab CI/CD Nginx Ubuntu
The core booking engine handles reservation creation, modification, cancellation, and check-in/check-out workflows. It supports drag-and-drop room assignment on a visual floor plan, making it intuitive for front desk staff to manage room availability in real-time.
A dedicated housekeeping module tracks room status (clean, dirty, inspected, out-of-order), assigns cleaning tasks to staff, and logs room status history. The scheduler provides a timeline view for coordinating housekeeping shifts.
The rate engine supports configurable pricing rules based on occupancy, seasonality, and market segments. I built a dynamic rate simulator that forecasts ADR (Average Daily Rate) and helps revenue managers optimize pricing strategies.
A granular permission system with menu-level CRUD flags and custom transaction actions. Each role (developer, administrator, receptionist, etc.) can be configured with specific view/add/edit/delete permissions per menu item. The permission tree is cached and resolved at login.
// Permission structure example
{
"permissions": [{
"key": ["Front", "Desk"],
"label": ["Front", "Desk"],
"isaccess": true,
"access": [{ "view": true, "add": true, "edit": true, "delete": false }]
}]
}
Integrated with STAAH (an OTA channel manager) to synchronize room inventory and rates across multiple booking platforms. The integration ensures that when a booking is made on any connected OTA, the system updates availability in real-time to prevent overbooking.
Real-time dashboards display key metrics: revenue, occupancy rates, ADR, RevPAR, and booking trends. The reporting module covers profit & loss statements, trial balance reports, and market segment analysis.
When I joined the project, the backend was built with Laravel (PHP) + MySQL. The frontend was Next.js. During my tenure, I planned and initiated a migration of the backend to Node.js (Express + TypeScript) + PostgreSQL, while maintaining 100% API compatibility so the frontend required zero changes.
Key constraint: every API response must match the Laravel format exactly — including the { success, data, message, meta } envelope — so the Next.js frontend works without a single line change.
I built automation scripts for the migration: a connection tester, data migrator (MySQL → PostgreSQL), and data verifier with row-count validation. Phase 1 (Database Migration) was completed successfully.
The frontend uses Next.js with a custom permission-aware component system. Every page and UI element conditionally renders based on the user's role and CRUD permissions. The app also has a Capacitor wrapper for mobile deployment via Android WebView.
State management uses Redux with persisted auth tokens. The sidebar and navigation are dynamically generated from the menu tree returned by the backend permission system.