Overview
StayForge is a full-featured hotel booking and management platform built on Laravel 12. It ships with a guest-facing booking site and a completely separate admin panel, dual AI providers (OpenAI and Anthropic Claude) that can be toggled feature-by-feature, and four payment gateways that admins can enable independently.
Architecture
The codebase follows standard Laravel conventions with a few dedicated service layers so that AI providers and payment gateways can be swapped or extended without touching controllers:
App\Services\AI\AIManagerโ single entry point for every AI call. Reads the global switch, the per-feature switch, and the chosen provider before delegating toOpenAIServiceorAnthropicService.App\Services\Payment\PaymentManagerโ resolves which payment gateways are enabled and exposes a commonPaymentGatewayInterfaceto the checkout flow.App\Services\UploadServiceโ the single place every file upload passes through, writing to theuploadsdisk (public/uploads).App\Models\Settingโ a generic key/value store (grouped byai,payment,mail,site) that backs every admin-editable setting, with optional encryption for secrets.
Data Model
| Table | Purpose |
|---|---|
hotels | One row per property; supports draft/published/suspended status and an optional owner (hotel manager). |
rooms | Belongs to a hotel; tracks base price, AI-suggested price, and total inventory units. |
room_rate_calendar | Per-date price overrides and blackout dates for a room. |
bookings | Guest reservation with full price breakdown (subtotal, tax, discount, total) and a status pipeline. |
payments | One row per payment attempt, tagged with the gateway used and its raw response payload. |
reviews | Guest reviews with admin moderation status, owner replies, and an AI-generated sentiment tag. |
coupons | Percent or fixed discounts, optionally scoped to one hotel, with usage limits. |
settings | Grouped key/value store for every admin-configurable option (AI, payments, email, site). |
ai_conversations / ai_messages | Chat history for the guest-facing AI assistant, keyed by session. |
Search & Booking
Guests search by city, dates, price range and star rating. Availability is computed by checking each room's total inventory against overlapping bookings in pending, confirmed, or checked_in status โ no separate availability cron job required.
Booking a room calculates nights, subtotal, tax, and any coupon discount server-side before creating the booking record, then hands off to the selected payment gateway.
Payments
The checkout page only ever shows gateways the admin has switched on. Each gateway implements the same three-method interface:
| Method | Purpose |
|---|---|
initiate() | Creates the payment record and returns either a redirect URL (Stripe, PayPal, Manual) or the data a JS widget needs (Razorpay). |
handleCallback() | Confirms a payment after redirect, marking the booking confirmed and paid. |
key() / label() | Identifies the gateway to the settings screen and checkout form. |
Account Features
- My Bookings โ view, cancel, and revisit the AI trip summary for any past or upcoming stay.
- Wishlist โ one-click save/unsave on any hotel page.
- Reviews โ post-stay ratings and comments, auto-analyzed for sentiment.
Hotels & Rooms
Admins (or scoped hotel managers) create hotels and rooms, assign amenities, upload galleries, and optionally generate descriptions or price suggestions with one click using AI. Every image uploaded here lands in public/uploads/hotels/ or public/uploads/rooms/.
Bookings & Reviews
The bookings table supports filtering by status and hotel, with an inline status-change dropdown for the full pipeline: pending โ confirmed โ checked_in โ checked_out (plus cancelled / no_show). The reviews screen shows the AI sentiment tag next to each review and lets admins approve, reject, or reply.
Reports
Revenue-by-hotel and occupancy (bookings / room-nights) reports are available for any date range, computed directly from completed payments and confirmed bookings.
How AI Is Wired
Every AI-powered feature calls AIManager::chat($feature, $messages). Internally this:
- Checks the global
ai.enabledsetting โ if off, returnsnullimmediately. - Checks the feature-level setting (e.g.
ai.feature_chatbot_enabled) โ if off, returnsnull. - Resolves the provider: a per-feature override if set, otherwise the global default (OpenAI or Anthropic).
- Calls the provider's HTTP API directly (no SDK lock-in) and returns plain text, or
nullon failure โ callers always handle a null response gracefully (e.g. recommendations fall back to popularity ranking).
Feature Reference
| Feature key | Where it runs | Fallback when disabled |
|---|---|---|
chatbot | Floating widget, all guest pages | Widget reports itself unavailable |
description_generator | Admin hotel/room forms | "Generate with AI" button shows an error |
dynamic_pricing | Admin room list | Only the deterministic demand calculation runs, no AI rationale |
recommendations | Guest homepage | Falls back to top-rated/most-popular hotels |
review_sentiment | On review submission | Sentiment estimated from star rating only |
trip_summary | Booking confirmation page & email | Summary block simply doesn't appear |
AI Settings
Located at Admin โ Settings โ AI. Configure the global switch, default provider, both providers' API keys and models, and per-feature enable + provider-override toggles. Keys are stored encrypted in the settings table.
Payment Settings
Located at Admin โ Settings โ Payments. Enable/disable Manual, Stripe, PayPal and Razorpay independently, each with its own credential fields. Multiple gateways can be active simultaneously.
Email Settings
Located at Admin โ Settings โ Email. Set mailer type (SMTP/Sendmail/Log), host, port, credentials and encryption, plus a from-address and from-name. A DynamicSettingsServiceProvider applies these over config/mail.php at runtime โ no .env edit or redeploy needed. A "Send Test Email" button confirms the configuration instantly.
Uploads
All uploads โ hotel/room images, avatars โ pass through App\Services\UploadService, which writes to the uploads filesystem disk (mapped to public/uploads). No storage:link symlink is required, which makes this compatible with shared hosting environments that don't allow symlinks.
Route Reference
| Route | Description |
|---|---|
GET / | Homepage with featured & AI-recommended hotels |
GET /search | Filtered hotel search |
GET /hotels/{slug} | Hotel detail with rooms and reviews |
POST /rooms/{room}/book | Create a booking and initiate payment |
GET /payments/{gateway}/callback/{booking} | Payment gateway redirect handler |
POST /ai/chat | Chatbot message endpoint |
/admin/* | Full admin panel, gated by the access-admin gate |
Extending the Platform
Add a new payment gateway by implementing PaymentGatewayInterface and registering it in PaymentManager::__construct() โ it appears in checkout and the settings screen automatically. Add a new AI provider the same way via AIProviderInterface. New languages/currencies are just rows in the languages / currencies tables.