A production-style Airbnb-inspired rental marketplace with real payments, live search, and a hybrid multi-database architecture.
🔗 Live Demo · 🔧 Backend API
First load may take up to a minute (free-tier hosting spins down when idle) — Subsequent requests are significantly faster once the service has started.
Demo credentials are available below.
- Search & filter properties by city, price range, dates, and guest count, with Redis-cached results
- Property detail pages with an image gallery (zoom/pan lightbox), interactive location map, and live availability calendar
- Secure booking flow with real Razorpay payment integration (test mode)
- Booking management — view history, cancel unpaid bookings
- Leave verified reviews (only for completed stays)
- Full property CRUD with image upload (Cloudinary) and cover-image management
- Interactive map-based location picker (click-to-pin or manual lat/long entry)
- Dashboard for managing listings and viewing bookings received
- Race-condition-safe bookings — double-booking prevention via MySQL transactions with row-level locking on the property row (
SELECT ... FOR UPDATE), closing a gap where sparse availability data alone couldn't guarantee a lock. - Tamper-resistant payments — Razorpay signatures are verified server-side and cross-checked against the specific booking's stored order ID, preventing a valid signature from one payment being replayed against a different booking.
- Targeted cache invalidation — search caches invalidate on every property create/update/delete, not just updates.
- Stateless auth with real logout — JWTs are stateless by design; a Redis-backed blacklist gives genuine token invalidation on logout.
- Latency-aware infrastructure — identified a cross-continental latency bottleneck post-deployment (US backend ↔ India database) and resolved it by re-aligning regions (Singapore ↔ Bangalore), cutting booking-creation latency roughly 3-5x.
- Cloud-safe image handling — in-memory buffer streaming to Cloudinary instead of disk staging, after discovering ephemeral filesystems on PaaS hosts broke a disk-based approach that worked fine locally.
| Layer | Technology |
|---|---|
| Frontend | React (Vite), Redux Toolkit, Tailwind CSS v4, React Router, Leaflet |
| Backend | Node.js, Express — modular monolith |
| Primary DB | MySQL (Aiven) — relational data |
| Secondary DB | MongoDB Atlas — reviews |
| Cache | Redis (Upstash) — search cache, rate limiting, JWT blacklist |
| Payments | Razorpay — order creation + signature verification |
| Images | Cloudinary |
| Auth | JWT + bcrypt |
| Deployment | Vercel · Render · Aiven |
| Containerization | Docker + Docker Compose |
┌─────────────────┐
│ React (Vercel) │
└────────┬────────┘
│ HTTPS
┌────────▼────────┐
│ Express API │
│ (Render) │
└────────┬────────┘
┌──────────────────┼──────────────────┐
┌──────▼──────┐ ┌───────▼───────┐ ┌──────▼───────┐
│ Auth Module │ │Property Module│ │Booking Module│
└──────┬──────┘ └───────┬───────┘ └──────┬───────┘
│ │ │
┌──────▼──────────────────▼───────────────────▼──────┐
│ MySQL (Aiven) — relational │
└────────────────────────────────────────────────────┘
│
┌──────▼──────┐ ┌────────────────┐ ┌─────────────┐
│ MongoDB │ │ Redis(Upstash) │ │ Cloudinary │
│ (reviews) │ │(cache/sessions)│ │ (images) │
└─────────────┘ └────────────────┘ └─────────────┘
Modular monolith, not microservices — each domain (Auth, Property, Booking, Reviews) is self-contained with its own routes/controller/service, deployed as one service. Avoids distributed-systems overhead at a scale that doesn't need it, while staying structured to split out later if it ever does.
📂 View Project Structure (Frontend + Backend)
luxelodging/
├── backend/src/
│ ├── config/ # DB & service connections
│ ├── modules/ # auth, property, booking, reviews
│ ├── middleware/
│ ├── models/ # MySQL + MongoDB models
│ └── utils/
├── frontend/src/
│ ├── pages/
│ ├── components/
│ ├── features/ # Redux slices
│ └── api/
└── docker-compose.yml
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/register |
Create account |
| POST | /api/auth/login |
Authenticate, receive JWT |
| POST | /api/auth/logout |
Blacklist current token |
| GET | /api/properties/search |
Search with filters, Redis-cached |
| GET | /api/properties/:id |
Property detail + images |
| POST | /api/properties |
Create listing (host) |
| POST | /api/properties/:id/images |
Upload images (host) |
| GET | /api/bookings/availability/:propertyId |
Check date availability |
| POST | /api/bookings |
Create booking + Razorpay order (guest) |
| POST | /api/bookings/verify-payment |
Verify payment signature |
| PATCH | /api/bookings/:id/cancel |
Cancel unpaid booking (guest) |
| GET | /api/reviews/:propertyId |
Get reviews + average rating |
| POST | /api/reviews |
Add review (guest, verified booking only) |
- 20+ REST API endpoints
- Authentication & authorization
- Hybrid SQL/NoSQL persistence
- Redis-backed caching
- Real payment integration
- Dockerized deployment
Node.js ≥ 22, MySQL 8+ (or free Aiven instance), free accounts on MongoDB Atlas, Upstash, Cloudinary, Razorpay (test mode)
# Backend
cd backend
npm install
cp .env.example .env # fill in your credentials
mysql -u root -p your_db < src/models/mysql/schema.sql
npm run dev
# Frontend (new terminal)
cd frontend
npm install
cp .env.example .env # set VITE_API_URL
npm run dev| Service | Host | Notes |
|---|---|---|
| Frontend | Vercel | Free tier, auto-deploys on push |
| Backend | Render (Singapore) | Free tier — sleeps after 15 min idle |
| MySQL | Aiven (Bangalore) | Free tier, TLS-required connection |
| MongoDB / Redis / Cloudinary / Razorpay | Managed cloud, free tiers | Unchanged across environments |
Backend and database regions were deliberately co-located (Singapore ↔ Bangalore) after identifying a cross-continental latency bottleneck during initial deployment — see Technical Highlights below.
| Role | Password | |
|---|---|---|
| Guest | Test@Deployed.com | Test@Deployed |
| Host | test1@example.com | test234 |
These accounts are reset periodically for demonstration purposes.
- Offload email notifications using BullMQ and Redis.
- AI concierge chatbot for natural-language property search.
- AI-generated property descriptions for hosts.
AMULYA GUPTA
· GitHub
· LinkedIn
This project was built for educational and portfolio purposes.







