diff --git a/Backend/backups/backup_hotel_booking_dev_20251202_232932.json b/Backend/backups/backup_hotel_booking_dev_20251202_232932.json new file mode 100644 index 00000000..d5b5619b --- /dev/null +++ b/Backend/backups/backup_hotel_booking_dev_20251202_232932.json @@ -0,0 +1,9 @@ +{ + "filename": "backup_hotel_booking_dev_20251202_232932.sql", + "path": "backups/backup_hotel_booking_dev_20251202_232932.sql", + "size_bytes": 526399, + "size_mb": 0.5, + "created_at": "2025-12-02T23:29:32.937870", + "database": "hotel_booking_dev", + "status": "success" +} \ No newline at end of file diff --git a/Backend/backups/backup_hotel_booking_dev_20251202_232932.sql b/Backend/backups/backup_hotel_booking_dev_20251202_232932.sql new file mode 100644 index 00000000..58a75795 --- /dev/null +++ b/Backend/backups/backup_hotel_booking_dev_20251202_232932.sql @@ -0,0 +1,3995 @@ +-- MySQL dump 10.13 Distrib 8.0.44, for Linux (x86_64) +-- +-- Host: localhost Database: hotel_booking_dev +-- ------------------------------------------------------ +-- Server version 8.0.44 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!50503 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `ai_conversation_feedbacks` +-- + +DROP TABLE IF EXISTS `ai_conversation_feedbacks`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ai_conversation_feedbacks` ( + `id` int NOT NULL AUTO_INCREMENT, + `conversation_id` int NOT NULL, + `user_id` int NOT NULL, + `rating` int DEFAULT NULL, + `is_helpful` tinyint(1) DEFAULT NULL, + `is_correct` tinyint(1) DEFAULT NULL, + `feedback_text` text, + `correction` text, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `user_id` (`user_id`), + KEY `ix_ai_conversation_feedbacks_id` (`id`), + KEY `ix_ai_conversation_feedbacks_conversation_id` (`conversation_id`), + CONSTRAINT `ai_conversation_feedbacks_ibfk_1` FOREIGN KEY (`conversation_id`) REFERENCES `ai_conversations` (`id`), + CONSTRAINT `ai_conversation_feedbacks_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `ai_conversation_feedbacks` +-- + +LOCK TABLES `ai_conversation_feedbacks` WRITE; +/*!40000 ALTER TABLE `ai_conversation_feedbacks` DISABLE KEYS */; +/*!40000 ALTER TABLE `ai_conversation_feedbacks` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `ai_conversations` +-- + +DROP TABLE IF EXISTS `ai_conversations`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ai_conversations` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `session_id` varchar(100) DEFAULT NULL, + `user_query` text NOT NULL, + `ai_response` text NOT NULL, + `intent` varchar(100) DEFAULT NULL, + `context_used` json DEFAULT NULL, + `user_role` varchar(50) DEFAULT NULL, + `response_time_ms` int DEFAULT NULL, + `is_helpful` tinyint(1) DEFAULT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `idx_ai_conv_intent` (`intent`), + KEY `idx_ai_conv_session` (`session_id`), + KEY `idx_ai_conv_user_date` (`user_id`,`created_at`), + KEY `ix_ai_conversations_user_id` (`user_id`), + KEY `ix_ai_conversations_created_at` (`created_at`), + KEY `ix_ai_conversations_intent` (`intent`), + KEY `ix_ai_conversations_user_role` (`user_role`), + KEY `ix_ai_conversations_id` (`id`), + KEY `ix_ai_conversations_session_id` (`session_id`), + CONSTRAINT `ai_conversations_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `ai_conversations` +-- + +LOCK TABLES `ai_conversations` WRITE; +/*!40000 ALTER TABLE `ai_conversations` DISABLE KEYS */; +INSERT INTO `ai_conversations` VALUES (1,3,NULL,'what is this platform about','📊 Hotel Status Overview:\n\n🏨 ROOMS:\n• Total: 50\n• Available: 40\n• Occupied: 5\n• Cleaning: 2\n• Maintenance: 3\n• Occupancy Rate: 10.0%\n\n📅 BOOKINGS:\n• Active: 0\n• Upcoming Check-ins: 0\n• Upcoming Check-outs: 0\n• Pending: 0\n\n💰 PAYMENTS:\n• Revenue (30 days): $0.00\n• Pending: $120.67\n• Completed: 0\n\n🧾 INVOICES:\n• Total: 1\n• Overdue: 0\n\n💬 CHATS:\n• Unanswered: 0\n\n⚠️ ISSUES:\n• Rooms with problems: 3\n - Room 106: Room 106 is under maintenance\n - Room 130: Room 130 is under maintenance\n - Room 239: Room 239 is under maintenance\n','general_status','{\"room_summary\": {\"cleaning\": 2, \"occupied\": 5, \"available\": 40, \"maintenance\": 3, \"total_rooms\": 50, \"occupancy_rate\": 10.0, \"rooms_with_active_bookings\": 0}, \"room_problems\": [{\"status\": \"maintenance\", \"issue_type\": \"maintenance\", \"description\": \"Room 106 is under maintenance\", \"room_number\": \"106\"}, {\"status\": \"maintenance\", \"issue_type\": \"maintenance\", \"description\": \"Room 130 is under maintenance\", \"room_number\": \"130\"}, {\"status\": \"maintenance\", \"issue_type\": \"maintenance\", \"description\": \"Room 239 is under maintenance\", \"room_number\": \"239\"}], \"booking_summary\": {\"period_days\": 7, \"active_bookings\": 0, \"pending_bookings\": 0, \"upcoming_checkins\": 0, \"upcoming_checkouts\": 0}, \"invoice_summary\": {\"total_invoices\": 1, \"overdue_invoices\": 0, \"status_breakdown\": {\"draft\": 1}}, \"payment_summary\": {\"period_days\": 30, \"total_revenue\": 0.0, \"pending_amount\": 120.67, \"failed_payments\": 14, \"completed_payments\": 0}, \"unanswered_chats\": []}','admin',158,NULL,'2025-11-30 19:15:58'),(2,3,NULL,'what this platform is about','📊 Hotel Status Overview:\n\n🏨 ROOMS:\n• Total: 50\n• Available: 40\n• Occupied: 5\n• Cleaning: 2\n• Maintenance: 3\n• Occupancy Rate: 10.0%\n\n📅 BOOKINGS:\n• Active: 0\n• Upcoming Check-ins: 0\n• Upcoming Check-outs: 0\n• Pending: 0\n\n💰 PAYMENTS:\n• Revenue (30 days): $0.00\n• Pending: $120.67\n• Completed: 0\n\n🧾 INVOICES:\n• Total: 1\n• Overdue: 0\n\n💬 CHATS:\n• Unanswered: 0\n\n⚠️ ISSUES:\n• Rooms with problems: 3\n - Room 106: Room 106 is under maintenance\n - Room 130: Room 130 is under maintenance\n - Room 239: Room 239 is under maintenance\n','general_status','{\"room_summary\": {\"cleaning\": 2, \"occupied\": 5, \"available\": 40, \"maintenance\": 3, \"total_rooms\": 50, \"occupancy_rate\": 10.0, \"rooms_with_active_bookings\": 0}, \"room_problems\": [{\"status\": \"maintenance\", \"issue_type\": \"maintenance\", \"description\": \"Room 106 is under maintenance\", \"room_number\": \"106\"}, {\"status\": \"maintenance\", \"issue_type\": \"maintenance\", \"description\": \"Room 130 is under maintenance\", \"room_number\": \"130\"}, {\"status\": \"maintenance\", \"issue_type\": \"maintenance\", \"description\": \"Room 239 is under maintenance\", \"room_number\": \"239\"}], \"booking_summary\": {\"period_days\": 7, \"active_bookings\": 0, \"pending_bookings\": 0, \"upcoming_checkins\": 0, \"upcoming_checkouts\": 0}, \"invoice_summary\": {\"total_invoices\": 1, \"overdue_invoices\": 0, \"status_breakdown\": {\"draft\": 1}}, \"payment_summary\": {\"period_days\": 30, \"total_revenue\": 0.0, \"pending_amount\": 120.67, \"failed_payments\": 14, \"completed_payments\": 0}, \"unanswered_chats\": []}','admin',167,NULL,'2025-11-30 19:17:44'),(3,3,NULL,'clear','I can help you with information about:\n\n🏨 Rooms - availability, occupancy, status, problems\n📅 Bookings - active, upcoming, pending reservations\n💰 Payments - revenue, pending payments, transactions\n🧾 Invoices - status, overdue invoices\n💬 Chats - unanswered customer messages\n\nQuick Stats: 50 total rooms, 5 occupied, 40 available.\n\nTry asking:\n• \'How many rooms do we have?\'\n• \'Show me occupied rooms\'\n• \'What\'s our revenue?\'\n• \'Are there any unanswered chats?\'','general_query','{\"room_summary\": {\"cleaning\": 2, \"occupied\": 5, \"available\": 40, \"maintenance\": 3, \"total_rooms\": 50, \"occupancy_rate\": 10.0, \"rooms_with_active_bookings\": 0}, \"booking_summary\": {\"period_days\": 7, \"active_bookings\": 0, \"pending_bookings\": 0, \"upcoming_checkins\": 0, \"upcoming_checkouts\": 0}, \"invoice_summary\": {\"total_invoices\": 1, \"overdue_invoices\": 0, \"status_breakdown\": {\"draft\": 1}}, \"payment_summary\": {\"period_days\": 30, \"total_revenue\": 0.0, \"pending_amount\": 120.67, \"failed_payments\": 14, \"completed_payments\": 0}}','admin',189,NULL,'2025-11-30 19:20:31'),(4,3,NULL,'tell me what is about this platform','📊 Hotel Status Overview:\n\n🏨 ROOMS:\n• Total: 50\n• Available: 40\n• Occupied: 5\n• Cleaning: 2\n• Maintenance: 3\n• Occupancy Rate: 10.0%\n\n📅 BOOKINGS:\n• Active: 0\n• Upcoming Check-ins: 0\n• Upcoming Check-outs: 0\n• Pending: 0\n\n💰 PAYMENTS:\n• Revenue (30 days): $0.00\n• Pending: $120.67\n• Completed: 0\n\n🧾 INVOICES:\n• Total: 1\n• Overdue: 0\n\n💬 CHATS:\n• Unanswered: 0\n\n⚠️ ISSUES:\n• Rooms with problems: 3\n - Room 106: Room 106 is under maintenance\n - Room 130: Room 130 is under maintenance\n - Room 239: Room 239 is under maintenance\n','general_status','{\"room_summary\": {\"cleaning\": 2, \"occupied\": 5, \"available\": 40, \"maintenance\": 3, \"total_rooms\": 50, \"occupancy_rate\": 10.0, \"rooms_with_active_bookings\": 0}, \"room_problems\": [{\"status\": \"maintenance\", \"issue_type\": \"maintenance\", \"description\": \"Room 106 is under maintenance\", \"room_number\": \"106\"}, {\"status\": \"maintenance\", \"issue_type\": \"maintenance\", \"description\": \"Room 130 is under maintenance\", \"room_number\": \"130\"}, {\"status\": \"maintenance\", \"issue_type\": \"maintenance\", \"description\": \"Room 239 is under maintenance\", \"room_number\": \"239\"}], \"booking_summary\": {\"period_days\": 7, \"active_bookings\": 0, \"pending_bookings\": 0, \"upcoming_checkins\": 0, \"upcoming_checkouts\": 0}, \"invoice_summary\": {\"total_invoices\": 1, \"overdue_invoices\": 0, \"status_breakdown\": {\"draft\": 1}}, \"payment_summary\": {\"period_days\": 30, \"total_revenue\": 0.0, \"pending_amount\": 120.67, \"failed_payments\": 14, \"completed_payments\": 0}, \"unanswered_chats\": []}','admin',113,NULL,'2025-11-30 19:20:44'),(5,3,NULL,'list features','📱 Hotel Booking & Management System (HBMS) - Complete Overview\n\n============================================================\n\n📋 SYSTEM OVERVIEW:\n\n This is a comprehensive Hotel Booking and Management System (HBMS) - an enterprise-grade\n solution for managing hotel operations, reservations, payments, guest services, and business analytics.\n \n The system supports multiple user roles: Admin, Staff, Accountant, and Customer, each with\n different access levels and permissions.\n \n\n🔧 CORE FEATURES & MODULES:\n\n1. Booking Management\n Complete booking lifecycle management including creation, confirmation, check-in, check-out, and cancellation\n Models: Booking, BookingStatus\n Statuses: pending, confirmed, checked_in, checked_out, cancelled\n\n2. Room Management\n Room inventory, availability, status tracking, and maintenance\n Models: Room, RoomType, RoomStatus\n Statuses: available, occupied, maintenance, cleaning\n\n3. Payment Processing\n Payment handling for bookings with multiple payment methods and status tracking\n Models: Payment, PaymentMethod, PaymentStatus, PaymentType\n Statuses: pending, completed, failed, refunded\n\n4. Invoice Management\n Invoice generation, tracking, and payment reconciliation\n Models: Invoice, InvoiceItem, InvoiceStatus\n Statuses: draft, sent, paid, overdue, cancelled\n\n5. User Management\n User accounts, roles, authentication, and guest profiles\n Models: User, Role, RefreshToken, PasswordResetToken\n\n6. Loyalty Program\n Customer loyalty program with tiers, points, rewards, and referrals\n Models: LoyaltyTier, UserLoyalty, LoyaltyPointTransaction, LoyaltyReward, RewardRedemption (+1 more)\n\n7. Service Management\n Additional hotel services like spa, restaurant, room service\n Models: Service, ServiceUsage, ServiceBooking, ServiceBookingItem, ServicePayment\n\n8. Promotion System\n Discount codes, promotional campaigns, and special offers\n Models: Promotion\n\n9. Reviews And Ratings\n Guest reviews and ratings for rooms and services\n Models: Review\n\n10. Chat System\n Real-time chat support between guests and staff\n Models: Chat, ChatMessage, ChatStatus\n Statuses: open, closed\n\n11. Check In Check Out\n Check-in and check-out process management\n Models: CheckInCheckOut\n\n12. Maintenance Tracking\n Room maintenance scheduling and tracking\n Models: RoomMaintenance, RoomInspection\n\n13. Housekeeping\n Housekeeping task management and scheduling\n Models: HousekeepingTask\n\n14. Guest Management\n Comprehensive guest profile management and CRM features\n Models: GuestNote, GuestPreference, GuestTag, GuestSegment, GuestCommunication\n\n15. Group Bookings\n Group booking management for multiple rooms\n Models: GroupBooking\n\n16. Rate Plans\n Dynamic pricing and rate plan management\n Models: RatePlan\n\n17. Packages\n Pre-configured booking packages (room + services)\n Models: Package\n\n18. Blog And Content\n Content management for hotel blog and marketing\n Models: BlogPost, Banner, PageContent\n\n19. Analytics And Reporting\n Business intelligence, analytics, and financial reporting\n Models: AuditLog\n\n20. System Settings\n System-wide configuration and settings\n Models: SystemSettings\n\n21. Security And Compliance\n Security, audit logging, and GDPR compliance\n Models: SecurityEvent, AuditLog, GDPRCompliance\n\n22. Notifications\n System notifications and alerts\n Models: Notification\n\n23. Workflows\n Automated workflow management for business processes\n Models: Workflow\n\n24. Email Campaigns\n Marketing email campaigns and automation\n Models: EmailCampaign\n\n👥 USER ROLES & PERMISSIONS:\n\n• ADMIN\n Full system access with all administrative privileges\n Can Access: 19 features\n - All bookings (all customers)\n - All rooms and room management\n - All payments and financial data\n - All invoices\n - All users and user management\n ... and 14 more\n\n• ACCOUNTANT\n Financial data access for accounting and reporting\n Can Access: 10 features\n - All payments and payment history\n - All invoices and invoice management\n - Financial reports and analytics\n - Revenue summaries\n - Payment reconciliation\n ... and 5 more\n Restrictions: 5 items\n\n• STAFF\n Operational staff with access to daily hotel operations\n Can Access: 11 features\n - All bookings and booking management\n - Room status and availability\n - Check-in and check-out operations\n - Guest information (for operations)\n - Room maintenance and housekeeping tasks\n ... and 6 more\n Restrictions: 8 items\n\n• CUSTOMER\n Hotel guests with access to their own booking and account information\n Can Access: 13 features\n - Own bookings (view, cancel)\n - Own booking details\n - Own invoices (view only)\n - Own payment history\n - Own profile information\n ... and 8 more\n Restrictions: 8 items\n\n💻 TECHNOLOGY STACK:\n\n• Backend: FastAPI (Python)\n• Frontend: React/TypeScript\n• Database: SQLAlchemy ORM\n• AI: Self-learning assistant with pattern recognition\n• Authentication: JWT with MFA support\n• Security: Role-based access control, audit logging\n\n✨ KEY CAPABILITIES:\n\n• Complete booking lifecycle management\n• Multi-role access control (Admin, Staff, Accountant, Customer)\n• Payment processing with multiple methods\n• Invoice generation and tracking\n• Loyalty program with points and rewards\n• Real-time chat support system\n• Room maintenance and housekeeping management\n• Guest profile and CRM features\n• Analytics and reporting\n• Content management (blog, pages, banners)\n• Email campaigns and marketing automation\n• Group booking management\n• Dynamic pricing and rate plans\n• Package deals (room + services)\n• Review and rating system\n• Audit logging and security compliance\n\n💬 COMMON QUERY CATEGORIES:\n\n• Booking: booking status, check-in date, check-out date (+5 more)\n• Room: available rooms, room types, room amenities (+4 more)\n• Payment: payment status, payment history, payment methods (+4 more)\n• Invoice: invoice status, invoice number, invoice amount (+4 more)\n• Loyalty: loyalty points, loyalty tier, rewards (+3 more)\n• General: hotel information, contact, policies (+5 more)\n\n============================================================\n\n💡 TIP: Ask me about any specific feature, model, or capability for detailed information!','app_info','{\"app_knowledge\": {\"features\": {\"packages\": {\"models\": [\"Package\"], \"key_fields\": [\"name\", \"price\", \"includes\", \"valid_period\"], \"description\": \"Pre-configured booking packages (room + services)\", \"relationships\": [\"RoomType\", \"Service\"]}, \"workflows\": {\"models\": [\"Workflow\"], \"key_fields\": [\"name\", \"trigger\", \"actions\", \"conditions\"], \"description\": \"Automated workflow management for business processes\", \"relationships\": []}, \"rate_plans\": {\"models\": [\"RatePlan\"], \"key_fields\": [\"name\", \"base_price\", \"season_multiplier\", \"valid_from\", \"valid_to\"], \"description\": \"Dynamic pricing and rate plan management\", \"relationships\": [\"Booking\"]}, \"chat_system\": {\"models\": [\"Chat\", \"ChatMessage\", \"ChatStatus\"], \"statuses\": [\"open\", \"closed\"], \"key_fields\": [\"visitor_name\", \"visitor_email\", \"status\", \"message\", \"sender_type\", \"is_read\"], \"description\": \"Real-time chat support between guests and staff\", \"relationships\": [\"User\"]}, \"housekeeping\": {\"models\": [\"HousekeepingTask\"], \"key_fields\": [\"task_type\", \"status\", \"scheduled_time\", \"completed_at\"], \"description\": \"Housekeeping task management and scheduling\", \"relationships\": [\"Room\"]}, \"notifications\": {\"models\": [\"Notification\"], \"key_fields\": [\"type\", \"message\", \"is_read\", \"priority\"], \"description\": \"System notifications and alerts\", \"relationships\": [\"User\"]}, \"group_bookings\": {\"models\": [\"GroupBooking\"], \"key_fields\": [\"group_name\", \"contact_person\", \"total_rooms\", \"group_discount\"], \"description\": \"Group booking management for multiple rooms\", \"relationships\": [\"Booking\"]}, \"email_campaigns\": {\"models\": [\"EmailCampaign\"], \"key_fields\": [\"subject\", \"content\", \"recipient_segment\", \"scheduled_time\"], \"description\": \"Marketing email campaigns and automation\", \"relationships\": [\"GuestSegment\"]}, \"loyalty_program\": {\"models\": [\"LoyaltyTier\", \"UserLoyalty\", \"LoyaltyPointTransaction\", \"LoyaltyReward\", \"RewardRedemption\", \"Referral\"], \"key_fields\": [\"tier_level\", \"points_balance\", \"lifetime_points\", \"referral_code\"], \"description\": \"Customer loyalty program with tiers, points, rewards, and referrals\", \"relationships\": [\"User\", \"Booking\"]}, \"room_management\": {\"models\": [\"Room\", \"RoomType\", \"RoomStatus\"], \"statuses\": [\"available\", \"occupied\", \"maintenance\", \"cleaning\"], \"key_fields\": [\"room_number\", \"floor\", \"status\", \"price\", \"capacity\", \"amenities\", \"room_size\", \"view\"], \"description\": \"Room inventory, availability, status tracking, and maintenance\", \"relationships\": [\"RoomType\", \"Booking\", \"Review\", \"RoomMaintenance\", \"HousekeepingTask\"]}, \"system_settings\": {\"models\": [\"SystemSettings\"], \"categories\": [\"general\", \"payment\", \"email\", \"company_info\"], \"key_fields\": [\"key\", \"value\", \"category\"], \"description\": \"System-wide configuration and settings\"}, \"user_management\": {\"roles\": [\"admin\", \"staff\", \"customer\", \"accountant\"], \"models\": [\"User\", \"Role\", \"RefreshToken\", \"PasswordResetToken\"], \"key_fields\": [\"email\", \"full_name\", \"phone\", \"role_id\", \"is_active\", \"currency\"], \"description\": \"User accounts, roles, authentication, and guest profiles\", \"guest_fields\": [\"is_vip\", \"lifetime_value\", \"satisfaction_score\", \"total_visits\", \"last_visit_date\"], \"relationships\": [\"Role\", \"Booking\", \"Payment\", \"Invoice\", \"Review\", \"Favorite\"]}, \"blog_and_content\": {\"models\": [\"BlogPost\", \"Banner\", \"PageContent\"], \"key_fields\": [\"title\", \"content\", \"is_published\", \"published_at\"], \"description\": \"Content management for hotel blog and marketing\", \"relationships\": []}, \"guest_management\": {\"models\": [\"GuestNote\", \"GuestPreference\", \"GuestTag\", \"GuestSegment\", \"GuestCommunication\"], \"key_fields\": [\"notes\", \"preferences\", \"tags\", \"communication_history\"], \"description\": \"Comprehensive guest profile management and CRM features\", \"relationships\": [\"User\"]}, \"promotion_system\": {\"models\": [\"Promotion\"], \"key_fields\": [\"code\", \"discount_type\", \"discount_value\", \"start_date\", \"end_date\", \"is_active\"], \"description\": \"Discount codes, promotional campaigns, and special offers\", \"relationships\": [\"Booking\"]}, \"booking_management\": {\"models\": [\"Booking\", \"BookingStatus\"], \"statuses\": [\"pending\", \"confirmed\", \"checked_in\", \"checked_out\", \"cancelled\"], \"key_fields\": [\"booking_number\", \"user_id\", \"room_id\", \"check_in_date\", \"check_out_date\", \"num_guests\", \"total_price\", \"status\", \"special_requests\"], \"description\": \"Complete booking lifecycle management including creation, confirmation, check-in, check-out, and cancellation\", \"relationships\": [\"User\", \"Room\", \"Payment\", \"Invoice\", \"ServiceUsage\", \"CheckInCheckOut\"]}, \"check_in_check_out\": {\"models\": [\"CheckInCheckOut\"], \"key_fields\": [\"checked_in_at\", \"checked_out_at\", \"checked_in_by\", \"checked_out_by\", \"notes\"], \"description\": \"Check-in and check-out process management\", \"relationships\": [\"Booking\", \"User\"]}, \"invoice_management\": {\"models\": [\"Invoice\", \"InvoiceItem\", \"InvoiceStatus\"], \"statuses\": [\"draft\", \"sent\", \"paid\", \"overdue\", \"cancelled\"], \"key_fields\": [\"invoice_number\", \"total_amount\", \"subtotal\", \"tax_amount\", \"discount_amount\", \"balance_due\", \"status\", \"due_date\", \"paid_date\"], \"description\": \"Invoice generation, tracking, and payment reconciliation\", \"relationships\": [\"Booking\", \"User\", \"InvoiceItem\"]}, \"payment_processing\": {\"models\": [\"Payment\", \"PaymentMethod\", \"PaymentStatus\", \"PaymentType\"], \"statuses\": [\"pending\", \"completed\", \"failed\", \"refunded\"], \"key_fields\": [\"amount\", \"payment_method\", \"payment_type\", \"payment_status\", \"transaction_id\", \"payment_date\"], \"description\": \"Payment handling for bookings with multiple payment methods and status tracking\", \"payment_types\": [\"full\", \"deposit\", \"remaining\"], \"relationships\": [\"Booking\"], \"payment_methods\": [\"cash\", \"credit_card\", \"debit_card\", \"bank_transfer\", \"e_wallet\", \"stripe\", \"paypal\", \"borica\"]}, \"service_management\": {\"models\": [\"Service\", \"ServiceUsage\", \"ServiceBooking\", \"ServiceBookingItem\", \"ServicePayment\"], \"key_fields\": [\"service_name\", \"price\", \"category\", \"description\"], \"description\": \"Additional hotel services like spa, restaurant, room service\", \"relationships\": [\"Booking\"]}, \"reviews_and_ratings\": {\"models\": [\"Review\"], \"key_fields\": [\"rating\", \"comment\", \"is_verified\"], \"description\": \"Guest reviews and ratings for rooms and services\", \"relationships\": [\"User\", \"Room\"]}, \"maintenance_tracking\": {\"models\": [\"RoomMaintenance\", \"RoomInspection\"], \"key_fields\": [\"scheduled_start\", \"scheduled_end\", \"status\", \"description\", \"priority\"], \"description\": \"Room maintenance scheduling and tracking\", \"relationships\": [\"Room\"]}, \"analytics_and_reporting\": {\"models\": [\"AuditLog\"], \"features\": [\"Revenue reports\", \"Occupancy analytics\", \"Guest analytics\", \"Payment reports\", \"Invoice reports\", \"Booking trends\", \"Customer lifetime value\"], \"description\": \"Business intelligence, analytics, and financial reporting\"}, \"security_and_compliance\": {\"models\": [\"SecurityEvent\", \"AuditLog\", \"GDPRCompliance\"], \"features\": [\"Action audit trails\", \"Security event logging\", \"GDPR data requests\", \"Cookie consent management\"], \"description\": \"Security, audit logging, and GDPR compliance\"}}, \"overview\": \"\\n This is a comprehensive Hotel Booking and Management System (HBMS) - an enterprise-grade\\n solution for managing hotel operations, reservations, payments, guest services, and business analytics.\\n \\n The system supports multiple user roles: Admin, Staff, Accountant, and Customer, each with\\n different access levels and permissions.\\n \", \"common_queries\": {\"room\": [\"available rooms\", \"room types\", \"room amenities\", \"room prices\", \"room availability\", \"occupied rooms\", \"room status\"], \"booking\": [\"booking status\", \"check-in date\", \"check-out date\", \"booking number\", \"cancel booking\", \"modify booking\", \"upcoming bookings\", \"past bookings\"], \"general\": [\"hotel information\", \"contact\", \"policies\", \"services\", \"amenities\", \"location\", \"FAQ\", \"help\"], \"invoice\": [\"invoice status\", \"invoice number\", \"invoice amount\", \"due date\", \"paid invoice\", \"outstanding invoice\", \"invoice download\"], \"loyalty\": [\"loyalty points\", \"loyalty tier\", \"rewards\", \"referral code\", \"points balance\", \"points history\"], \"payment\": [\"payment status\", \"payment history\", \"payment methods\", \"refund\", \"outstanding balance\", \"payment due\", \"transaction\"]}, \"role_capabilities\": {\"admin\": {\"can_access\": [\"All bookings (all customers)\", \"All rooms and room management\", \"All payments and financial data\", \"All invoices\", \"All users and user management\", \"System settings and configuration\", \"Analytics and reports\", \"Audit logs and security events\", \"Content management (blog, banners, pages)\", \"Promotion management\", \"Loyalty program administration\", \"Service management\", \"Maintenance and housekeeping\", \"Check-in/check-out operations\", \"Chat management\", \"Email campaigns\", \"Workflow management\", \"Group bookings\", \"Rate plans and packages\"], \"description\": \"Full system access with all administrative privileges\", \"restrictions\": \"None - full access\", \"cannot_access\": []}, \"staff\": {\"can_access\": [\"All bookings and booking management\", \"Room status and availability\", \"Check-in and check-out operations\", \"Guest information (for operations)\", \"Room maintenance and housekeeping tasks\", \"Service bookings and service usage\", \"Chat system for customer support\", \"Basic booking reports\", \"Occupancy status\", \"Group bookings\", \"Guest preferences and notes (operational)\"], \"description\": \"Operational staff with access to daily hotel operations\", \"restrictions\": \"Operational data only, no financial or system administration\", \"cannot_access\": [\"Financial reports and analytics\", \"System settings\", \"User management (except guest profile updates)\", \"Content management\", \"Email campaigns\", \"Workflow management\", \"Full payment details (can view payment status only)\", \"Invoice editing (view only)\"]}, \"customer\": {\"can_access\": [\"Own bookings (view, cancel)\", \"Own booking details\", \"Own invoices (view only)\", \"Own payment history\", \"Own profile information\", \"Room browsing and availability (public)\", \"Service browsing\", \"Booking creation\", \"Review submission\", \"Favorite rooms\", \"Loyalty points and rewards\", \"Referral code usage\", \"Chat with support\"], \"description\": \"Hotel guests with access to their own booking and account information\", \"restrictions\": \"Only own data and customer-facing features\", \"cannot_access\": [\"Other customers\' bookings or information\", \"All bookings overview\", \"Financial reports\", \"System settings\", \"Room management\", \"Staff operations\", \"Admin features\", \"Other users\' data\"]}, \"accountant\": {\"can_access\": [\"All payments and payment history\", \"All invoices and invoice management\", \"Financial reports and analytics\", \"Revenue summaries\", \"Payment reconciliation\", \"Invoice generation and editing\", \"Booking financial details (for invoicing)\", \"Customer payment history\", \"Refund processing\", \"Financial dashboard statistics\"], \"description\": \"Financial data access for accounting and reporting\", \"restrictions\": \"Financial and payment data only\", \"cannot_access\": [\"User personal information (except payment-related)\", \"System settings\", \"Content management\", \"Room operational details (unless related to billing)\", \"Security and audit logs (financial audit access only)\"]}}}}','admin',63,NULL,'2025-11-30 19:21:00'),(6,3,NULL,'what does this app do','📱 Hotel Booking & Management System (HBMS) - Complete Overview\n\n============================================================\n\n📋 SYSTEM OVERVIEW:\n\n This is a comprehensive Hotel Booking and Management System (HBMS) - an enterprise-grade\n solution for managing hotel operations, reservations, payments, guest services, and business analytics.\n \n The system supports multiple user roles: Admin, Staff, Accountant, and Customer, each with\n different access levels and permissions.\n \n\n🔧 CORE FEATURES & MODULES:\n\n1. Booking Management\n Complete booking lifecycle management including creation, confirmation, check-in, check-out, and cancellation\n Models: Booking, BookingStatus\n Statuses: pending, confirmed, checked_in, checked_out, cancelled\n\n2. Room Management\n Room inventory, availability, status tracking, and maintenance\n Models: Room, RoomType, RoomStatus\n Statuses: available, occupied, maintenance, cleaning\n\n3. Payment Processing\n Payment handling for bookings with multiple payment methods and status tracking\n Models: Payment, PaymentMethod, PaymentStatus, PaymentType\n Statuses: pending, completed, failed, refunded\n\n4. Invoice Management\n Invoice generation, tracking, and payment reconciliation\n Models: Invoice, InvoiceItem, InvoiceStatus\n Statuses: draft, sent, paid, overdue, cancelled\n\n5. User Management\n User accounts, roles, authentication, and guest profiles\n Models: User, Role, RefreshToken, PasswordResetToken\n\n6. Loyalty Program\n Customer loyalty program with tiers, points, rewards, and referrals\n Models: LoyaltyTier, UserLoyalty, LoyaltyPointTransaction, LoyaltyReward, RewardRedemption (+1 more)\n\n7. Service Management\n Additional hotel services like spa, restaurant, room service\n Models: Service, ServiceUsage, ServiceBooking, ServiceBookingItem, ServicePayment\n\n8. Promotion System\n Discount codes, promotional campaigns, and special offers\n Models: Promotion\n\n9. Reviews And Ratings\n Guest reviews and ratings for rooms and services\n Models: Review\n\n10. Chat System\n Real-time chat support between guests and staff\n Models: Chat, ChatMessage, ChatStatus\n Statuses: open, closed\n\n11. Check In Check Out\n Check-in and check-out process management\n Models: CheckInCheckOut\n\n12. Maintenance Tracking\n Room maintenance scheduling and tracking\n Models: RoomMaintenance, RoomInspection\n\n13. Housekeeping\n Housekeeping task management and scheduling\n Models: HousekeepingTask\n\n14. Guest Management\n Comprehensive guest profile management and CRM features\n Models: GuestNote, GuestPreference, GuestTag, GuestSegment, GuestCommunication\n\n15. Group Bookings\n Group booking management for multiple rooms\n Models: GroupBooking\n\n16. Rate Plans\n Dynamic pricing and rate plan management\n Models: RatePlan\n\n17. Packages\n Pre-configured booking packages (room + services)\n Models: Package\n\n18. Blog And Content\n Content management for hotel blog and marketing\n Models: BlogPost, Banner, PageContent\n\n19. Analytics And Reporting\n Business intelligence, analytics, and financial reporting\n Models: AuditLog\n\n20. System Settings\n System-wide configuration and settings\n Models: SystemSettings\n\n21. Security And Compliance\n Security, audit logging, and GDPR compliance\n Models: SecurityEvent, AuditLog, GDPRCompliance\n\n22. Notifications\n System notifications and alerts\n Models: Notification\n\n23. Workflows\n Automated workflow management for business processes\n Models: Workflow\n\n24. Email Campaigns\n Marketing email campaigns and automation\n Models: EmailCampaign\n\n👥 USER ROLES & PERMISSIONS:\n\n• ADMIN\n Full system access with all administrative privileges\n Can Access: 19 features\n - All bookings (all customers)\n - All rooms and room management\n - All payments and financial data\n - All invoices\n - All users and user management\n ... and 14 more\n\n• ACCOUNTANT\n Financial data access for accounting and reporting\n Can Access: 10 features\n - All payments and payment history\n - All invoices and invoice management\n - Financial reports and analytics\n - Revenue summaries\n - Payment reconciliation\n ... and 5 more\n Restrictions: 5 items\n\n• STAFF\n Operational staff with access to daily hotel operations\n Can Access: 11 features\n - All bookings and booking management\n - Room status and availability\n - Check-in and check-out operations\n - Guest information (for operations)\n - Room maintenance and housekeeping tasks\n ... and 6 more\n Restrictions: 8 items\n\n• CUSTOMER\n Hotel guests with access to their own booking and account information\n Can Access: 13 features\n - Own bookings (view, cancel)\n - Own booking details\n - Own invoices (view only)\n - Own payment history\n - Own profile information\n ... and 8 more\n Restrictions: 8 items\n\n💻 TECHNOLOGY STACK:\n\n• Backend: FastAPI (Python)\n• Frontend: React/TypeScript\n• Database: SQLAlchemy ORM\n• AI: Self-learning assistant with pattern recognition\n• Authentication: JWT with MFA support\n• Security: Role-based access control, audit logging\n\n✨ KEY CAPABILITIES:\n\n• Complete booking lifecycle management\n• Multi-role access control (Admin, Staff, Accountant, Customer)\n• Payment processing with multiple methods\n• Invoice generation and tracking\n• Loyalty program with points and rewards\n• Real-time chat support system\n• Room maintenance and housekeeping management\n• Guest profile and CRM features\n• Analytics and reporting\n• Content management (blog, pages, banners)\n• Email campaigns and marketing automation\n• Group booking management\n• Dynamic pricing and rate plans\n• Package deals (room + services)\n• Review and rating system\n• Audit logging and security compliance\n\n💬 COMMON QUERY CATEGORIES:\n\n• Booking: booking status, check-in date, check-out date (+5 more)\n• Room: available rooms, room types, room amenities (+4 more)\n• Payment: payment status, payment history, payment methods (+4 more)\n• Invoice: invoice status, invoice number, invoice amount (+4 more)\n• Loyalty: loyalty points, loyalty tier, rewards (+3 more)\n• General: hotel information, contact, policies (+5 more)\n\n============================================================\n\n💡 TIP: Ask me about any specific feature, model, or capability for detailed information!','app_info','{\"app_knowledge\": {\"features\": {\"packages\": {\"models\": [\"Package\"], \"key_fields\": [\"name\", \"price\", \"includes\", \"valid_period\"], \"description\": \"Pre-configured booking packages (room + services)\", \"relationships\": [\"RoomType\", \"Service\"]}, \"workflows\": {\"models\": [\"Workflow\"], \"key_fields\": [\"name\", \"trigger\", \"actions\", \"conditions\"], \"description\": \"Automated workflow management for business processes\", \"relationships\": []}, \"rate_plans\": {\"models\": [\"RatePlan\"], \"key_fields\": [\"name\", \"base_price\", \"season_multiplier\", \"valid_from\", \"valid_to\"], \"description\": \"Dynamic pricing and rate plan management\", \"relationships\": [\"Booking\"]}, \"chat_system\": {\"models\": [\"Chat\", \"ChatMessage\", \"ChatStatus\"], \"statuses\": [\"open\", \"closed\"], \"key_fields\": [\"visitor_name\", \"visitor_email\", \"status\", \"message\", \"sender_type\", \"is_read\"], \"description\": \"Real-time chat support between guests and staff\", \"relationships\": [\"User\"]}, \"housekeeping\": {\"models\": [\"HousekeepingTask\"], \"key_fields\": [\"task_type\", \"status\", \"scheduled_time\", \"completed_at\"], \"description\": \"Housekeeping task management and scheduling\", \"relationships\": [\"Room\"]}, \"notifications\": {\"models\": [\"Notification\"], \"key_fields\": [\"type\", \"message\", \"is_read\", \"priority\"], \"description\": \"System notifications and alerts\", \"relationships\": [\"User\"]}, \"group_bookings\": {\"models\": [\"GroupBooking\"], \"key_fields\": [\"group_name\", \"contact_person\", \"total_rooms\", \"group_discount\"], \"description\": \"Group booking management for multiple rooms\", \"relationships\": [\"Booking\"]}, \"email_campaigns\": {\"models\": [\"EmailCampaign\"], \"key_fields\": [\"subject\", \"content\", \"recipient_segment\", \"scheduled_time\"], \"description\": \"Marketing email campaigns and automation\", \"relationships\": [\"GuestSegment\"]}, \"loyalty_program\": {\"models\": [\"LoyaltyTier\", \"UserLoyalty\", \"LoyaltyPointTransaction\", \"LoyaltyReward\", \"RewardRedemption\", \"Referral\"], \"key_fields\": [\"tier_level\", \"points_balance\", \"lifetime_points\", \"referral_code\"], \"description\": \"Customer loyalty program with tiers, points, rewards, and referrals\", \"relationships\": [\"User\", \"Booking\"]}, \"room_management\": {\"models\": [\"Room\", \"RoomType\", \"RoomStatus\"], \"statuses\": [\"available\", \"occupied\", \"maintenance\", \"cleaning\"], \"key_fields\": [\"room_number\", \"floor\", \"status\", \"price\", \"capacity\", \"amenities\", \"room_size\", \"view\"], \"description\": \"Room inventory, availability, status tracking, and maintenance\", \"relationships\": [\"RoomType\", \"Booking\", \"Review\", \"RoomMaintenance\", \"HousekeepingTask\"]}, \"system_settings\": {\"models\": [\"SystemSettings\"], \"categories\": [\"general\", \"payment\", \"email\", \"company_info\"], \"key_fields\": [\"key\", \"value\", \"category\"], \"description\": \"System-wide configuration and settings\"}, \"user_management\": {\"roles\": [\"admin\", \"staff\", \"customer\", \"accountant\"], \"models\": [\"User\", \"Role\", \"RefreshToken\", \"PasswordResetToken\"], \"key_fields\": [\"email\", \"full_name\", \"phone\", \"role_id\", \"is_active\", \"currency\"], \"description\": \"User accounts, roles, authentication, and guest profiles\", \"guest_fields\": [\"is_vip\", \"lifetime_value\", \"satisfaction_score\", \"total_visits\", \"last_visit_date\"], \"relationships\": [\"Role\", \"Booking\", \"Payment\", \"Invoice\", \"Review\", \"Favorite\"]}, \"blog_and_content\": {\"models\": [\"BlogPost\", \"Banner\", \"PageContent\"], \"key_fields\": [\"title\", \"content\", \"is_published\", \"published_at\"], \"description\": \"Content management for hotel blog and marketing\", \"relationships\": []}, \"guest_management\": {\"models\": [\"GuestNote\", \"GuestPreference\", \"GuestTag\", \"GuestSegment\", \"GuestCommunication\"], \"key_fields\": [\"notes\", \"preferences\", \"tags\", \"communication_history\"], \"description\": \"Comprehensive guest profile management and CRM features\", \"relationships\": [\"User\"]}, \"promotion_system\": {\"models\": [\"Promotion\"], \"key_fields\": [\"code\", \"discount_type\", \"discount_value\", \"start_date\", \"end_date\", \"is_active\"], \"description\": \"Discount codes, promotional campaigns, and special offers\", \"relationships\": [\"Booking\"]}, \"booking_management\": {\"models\": [\"Booking\", \"BookingStatus\"], \"statuses\": [\"pending\", \"confirmed\", \"checked_in\", \"checked_out\", \"cancelled\"], \"key_fields\": [\"booking_number\", \"user_id\", \"room_id\", \"check_in_date\", \"check_out_date\", \"num_guests\", \"total_price\", \"status\", \"special_requests\"], \"description\": \"Complete booking lifecycle management including creation, confirmation, check-in, check-out, and cancellation\", \"relationships\": [\"User\", \"Room\", \"Payment\", \"Invoice\", \"ServiceUsage\", \"CheckInCheckOut\"]}, \"check_in_check_out\": {\"models\": [\"CheckInCheckOut\"], \"key_fields\": [\"checked_in_at\", \"checked_out_at\", \"checked_in_by\", \"checked_out_by\", \"notes\"], \"description\": \"Check-in and check-out process management\", \"relationships\": [\"Booking\", \"User\"]}, \"invoice_management\": {\"models\": [\"Invoice\", \"InvoiceItem\", \"InvoiceStatus\"], \"statuses\": [\"draft\", \"sent\", \"paid\", \"overdue\", \"cancelled\"], \"key_fields\": [\"invoice_number\", \"total_amount\", \"subtotal\", \"tax_amount\", \"discount_amount\", \"balance_due\", \"status\", \"due_date\", \"paid_date\"], \"description\": \"Invoice generation, tracking, and payment reconciliation\", \"relationships\": [\"Booking\", \"User\", \"InvoiceItem\"]}, \"payment_processing\": {\"models\": [\"Payment\", \"PaymentMethod\", \"PaymentStatus\", \"PaymentType\"], \"statuses\": [\"pending\", \"completed\", \"failed\", \"refunded\"], \"key_fields\": [\"amount\", \"payment_method\", \"payment_type\", \"payment_status\", \"transaction_id\", \"payment_date\"], \"description\": \"Payment handling for bookings with multiple payment methods and status tracking\", \"payment_types\": [\"full\", \"deposit\", \"remaining\"], \"relationships\": [\"Booking\"], \"payment_methods\": [\"cash\", \"credit_card\", \"debit_card\", \"bank_transfer\", \"e_wallet\", \"stripe\", \"paypal\", \"borica\"]}, \"service_management\": {\"models\": [\"Service\", \"ServiceUsage\", \"ServiceBooking\", \"ServiceBookingItem\", \"ServicePayment\"], \"key_fields\": [\"service_name\", \"price\", \"category\", \"description\"], \"description\": \"Additional hotel services like spa, restaurant, room service\", \"relationships\": [\"Booking\"]}, \"reviews_and_ratings\": {\"models\": [\"Review\"], \"key_fields\": [\"rating\", \"comment\", \"is_verified\"], \"description\": \"Guest reviews and ratings for rooms and services\", \"relationships\": [\"User\", \"Room\"]}, \"maintenance_tracking\": {\"models\": [\"RoomMaintenance\", \"RoomInspection\"], \"key_fields\": [\"scheduled_start\", \"scheduled_end\", \"status\", \"description\", \"priority\"], \"description\": \"Room maintenance scheduling and tracking\", \"relationships\": [\"Room\"]}, \"analytics_and_reporting\": {\"models\": [\"AuditLog\"], \"features\": [\"Revenue reports\", \"Occupancy analytics\", \"Guest analytics\", \"Payment reports\", \"Invoice reports\", \"Booking trends\", \"Customer lifetime value\"], \"description\": \"Business intelligence, analytics, and financial reporting\"}, \"security_and_compliance\": {\"models\": [\"SecurityEvent\", \"AuditLog\", \"GDPRCompliance\"], \"features\": [\"Action audit trails\", \"Security event logging\", \"GDPR data requests\", \"Cookie consent management\"], \"description\": \"Security, audit logging, and GDPR compliance\"}}, \"overview\": \"\\n This is a comprehensive Hotel Booking and Management System (HBMS) - an enterprise-grade\\n solution for managing hotel operations, reservations, payments, guest services, and business analytics.\\n \\n The system supports multiple user roles: Admin, Staff, Accountant, and Customer, each with\\n different access levels and permissions.\\n \", \"common_queries\": {\"room\": [\"available rooms\", \"room types\", \"room amenities\", \"room prices\", \"room availability\", \"occupied rooms\", \"room status\"], \"booking\": [\"booking status\", \"check-in date\", \"check-out date\", \"booking number\", \"cancel booking\", \"modify booking\", \"upcoming bookings\", \"past bookings\"], \"general\": [\"hotel information\", \"contact\", \"policies\", \"services\", \"amenities\", \"location\", \"FAQ\", \"help\"], \"invoice\": [\"invoice status\", \"invoice number\", \"invoice amount\", \"due date\", \"paid invoice\", \"outstanding invoice\", \"invoice download\"], \"loyalty\": [\"loyalty points\", \"loyalty tier\", \"rewards\", \"referral code\", \"points balance\", \"points history\"], \"payment\": [\"payment status\", \"payment history\", \"payment methods\", \"refund\", \"outstanding balance\", \"payment due\", \"transaction\"]}, \"role_capabilities\": {\"admin\": {\"can_access\": [\"All bookings (all customers)\", \"All rooms and room management\", \"All payments and financial data\", \"All invoices\", \"All users and user management\", \"System settings and configuration\", \"Analytics and reports\", \"Audit logs and security events\", \"Content management (blog, banners, pages)\", \"Promotion management\", \"Loyalty program administration\", \"Service management\", \"Maintenance and housekeeping\", \"Check-in/check-out operations\", \"Chat management\", \"Email campaigns\", \"Workflow management\", \"Group bookings\", \"Rate plans and packages\"], \"description\": \"Full system access with all administrative privileges\", \"restrictions\": \"None - full access\", \"cannot_access\": []}, \"staff\": {\"can_access\": [\"All bookings and booking management\", \"Room status and availability\", \"Check-in and check-out operations\", \"Guest information (for operations)\", \"Room maintenance and housekeeping tasks\", \"Service bookings and service usage\", \"Chat system for customer support\", \"Basic booking reports\", \"Occupancy status\", \"Group bookings\", \"Guest preferences and notes (operational)\"], \"description\": \"Operational staff with access to daily hotel operations\", \"restrictions\": \"Operational data only, no financial or system administration\", \"cannot_access\": [\"Financial reports and analytics\", \"System settings\", \"User management (except guest profile updates)\", \"Content management\", \"Email campaigns\", \"Workflow management\", \"Full payment details (can view payment status only)\", \"Invoice editing (view only)\"]}, \"customer\": {\"can_access\": [\"Own bookings (view, cancel)\", \"Own booking details\", \"Own invoices (view only)\", \"Own payment history\", \"Own profile information\", \"Room browsing and availability (public)\", \"Service browsing\", \"Booking creation\", \"Review submission\", \"Favorite rooms\", \"Loyalty points and rewards\", \"Referral code usage\", \"Chat with support\"], \"description\": \"Hotel guests with access to their own booking and account information\", \"restrictions\": \"Only own data and customer-facing features\", \"cannot_access\": [\"Other customers\' bookings or information\", \"All bookings overview\", \"Financial reports\", \"System settings\", \"Room management\", \"Staff operations\", \"Admin features\", \"Other users\' data\"]}, \"accountant\": {\"can_access\": [\"All payments and payment history\", \"All invoices and invoice management\", \"Financial reports and analytics\", \"Revenue summaries\", \"Payment reconciliation\", \"Invoice generation and editing\", \"Booking financial details (for invoicing)\", \"Customer payment history\", \"Refund processing\", \"Financial dashboard statistics\"], \"description\": \"Financial data access for accounting and reporting\", \"restrictions\": \"Financial and payment data only\", \"cannot_access\": [\"User personal information (except payment-related)\", \"System settings\", \"Content management\", \"Room operational details (unless related to billing)\", \"Security and audit logs (financial audit access only)\"]}}}}','admin',59,NULL,'2025-11-30 19:21:25'),(7,3,NULL,'Which rooms are occupied?','Currently, 5 rooms are occupied out of 50 total rooms.','room_occupied','{\"room_summary\": {\"cleaning\": 2, \"occupied\": 5, \"available\": 40, \"maintenance\": 3, \"total_rooms\": 50, \"occupancy_rate\": 10.0, \"rooms_with_active_bookings\": 0}, \"occupied_rooms\": []}','admin',145,NULL,'2025-11-30 20:41:01'),(8,3,NULL,'tell me the payments','Payment Status Summary:\n• Total Revenue (last 30 days): $0.00\n• Pending Payments: $120.67\n• Completed Payments: 0','payment_status','{\"payment_summary\": {\"period_days\": 30, \"total_revenue\": 0.0, \"pending_amount\": 120.67, \"failed_payments\": 14, \"completed_payments\": 0}}','admin',127,NULL,'2025-11-30 23:06:47'); +/*!40000 ALTER TABLE `ai_conversations` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `ai_knowledge_entries` +-- + +DROP TABLE IF EXISTS `ai_knowledge_entries`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ai_knowledge_entries` ( + `id` int NOT NULL AUTO_INCREMENT, + `topic` varchar(200) NOT NULL, + `question` text NOT NULL, + `answer` text NOT NULL, + `keywords` json DEFAULT NULL, + `related_intent` varchar(100) DEFAULT NULL, + `source` varchar(100) DEFAULT NULL, + `confidence` decimal(5,2) NOT NULL, + `usage_count` int NOT NULL, + `success_count` int NOT NULL, + `user_role` varchar(50) DEFAULT NULL, + `is_verified` tinyint(1) NOT NULL, + `created_by_user_id` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `last_used_at` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `created_by_user_id` (`created_by_user_id`), + KEY `ix_ai_knowledge_entries_id` (`id`), + KEY `ix_ai_knowledge_entries_related_intent` (`related_intent`), + KEY `ix_ai_knowledge_entries_topic` (`topic`), + KEY `idx_ai_knowledge_topic_role` (`topic`,`user_role`), + KEY `idx_ai_knowledge_active` (`is_verified`,`confidence`), + KEY `ix_ai_knowledge_entries_user_role` (`user_role`), + CONSTRAINT `ai_knowledge_entries_ibfk_1` FOREIGN KEY (`created_by_user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `ai_knowledge_entries` +-- + +LOCK TABLES `ai_knowledge_entries` WRITE; +/*!40000 ALTER TABLE `ai_knowledge_entries` DISABLE KEYS */; +INSERT INTO `ai_knowledge_entries` VALUES (1,'Platform','what is this platform about','📊 Hotel Status Overview:\n\n🏨 ROOMS:\n• Total: 50\n• Available: 40\n• Occupied: 5\n• Cleaning: 2\n• Maintenance: 3\n• Occupancy Rate: 10.0%\n\n📅 BOOKINGS:\n• Active: 0\n• Upcoming Check-ins: 0\n• Upcoming Check-outs: 0\n• Pending: 0\n\n💰 PAYMENTS:\n• Revenue (30 days): $0.00\n• Pending: $120.67\n• Completed: 0\n\n🧾 INVOICES:\n• Total: 1\n• Overdue: 0\n\n💬 CHATS:\n• Unanswered: 0\n\n⚠️ ISSUES:\n• Rooms with problems: 3\n - Room 106: Room 106 is under maintenance\n - Room 130: Room 130 is under maintenance\n - Room 239: Room 239 is under maintenance\n','[\"platform\", \"about\"]','general_status','auto_learned',50.00,66,0,'admin',0,NULL,'2025-11-30 19:15:58','2025-12-02 23:23:54',NULL),(2,'Platform','what this platform is about','📊 Hotel Status Overview:\n\n🏨 ROOMS:\n• Total: 50\n• Available: 40\n• Occupied: 5\n• Cleaning: 2\n• Maintenance: 3\n• Occupancy Rate: 10.0%\n\n📅 BOOKINGS:\n• Active: 0\n• Upcoming Check-ins: 0\n• Upcoming Check-outs: 0\n• Pending: 0\n\n💰 PAYMENTS:\n• Revenue (30 days): $0.00\n• Pending: $120.67\n• Completed: 0\n\n🧾 INVOICES:\n• Total: 1\n• Overdue: 0\n\n💬 CHATS:\n• Unanswered: 0\n\n⚠️ ISSUES:\n• Rooms with problems: 3\n - Room 106: Room 106 is under maintenance\n - Room 130: Room 130 is under maintenance\n - Room 239: Room 239 is under maintenance\n','[\"platform\", \"about\"]','general_status','auto_learned',50.00,64,0,'admin',0,NULL,'2025-11-30 19:18:25','2025-12-02 23:23:54',NULL),(3,'Clear','clear','I can help you with information about:\n\n🏨 Rooms - availability, occupancy, status, problems\n📅 Bookings - active, upcoming, pending reservations\n💰 Payments - revenue, pending payments, transactions\n🧾 Invoices - status, overdue invoices\n💬 Chats - unanswered customer messages\n\nQuick Stats: 50 total rooms, 5 occupied, 40 available.\n\nTry asking:\n• \'How many rooms do we have?\'\n• \'Show me occupied rooms\'\n• \'What\'s our revenue?\'\n• \'Are there any unanswered chats?\'','[\"clear\"]','general_query','auto_learned',50.00,64,0,'admin',0,NULL,'2025-11-30 19:20:31','2025-12-02 23:23:54',NULL),(4,'Features','list features','📱 Hotel Booking & Management System (HBMS) - Complete Overview\n\n============================================================\n\n📋 SYSTEM OVERVIEW:\n\n This is a comprehensive Hotel Booking and Management System (HBMS) - an enterprise-grade\n solution for managing hotel operations, reservations, payments, guest services, and business analytics.\n \n The system supports multiple user roles: Admin, Staff, Accountant, and Customer, each with\n different access levels and permissions.\n \n\n🔧 CORE FEATURES & MODULES:\n\n1. Booking Management\n Complete booking lifecycle management including creation, confirmation, check-in, check-out, and cancellation\n Models: Booking, BookingStatus\n Statuses: pending, confirmed, checked_in, checked_out, cancelled\n\n2. Room Management\n Room inventory, availability, status tracking, and maintenance\n Models: Room, RoomType, RoomStatus\n Statuses: available, occupied, maintenance, cleaning\n\n3. Payment Processing\n Payment handling for bookings with multiple payment methods and status tracking\n Models: Payment, PaymentMethod, PaymentStatus, PaymentType\n Statuses: pending, completed, failed, refunded\n\n4. Invoice Management\n Invoice generation, tracking, and payment reconciliation\n Models: Invoice, InvoiceItem, InvoiceStatus\n Statuses: draft, sent, paid, overdue, cancelled\n\n5. User Management\n User accounts, roles, authentication, and guest profiles\n Models: User, Role, RefreshToken, PasswordResetToken\n\n6. Loyalty Program\n Customer loyalty program with tiers, points, rewards, and referrals\n Models: LoyaltyTier, UserLoyalty, LoyaltyPointTransaction, LoyaltyReward, RewardRedemption (+1 more)\n\n7. Service Management\n Additional hotel services like spa, restaurant, room service\n Models: Service, ServiceUsage, ServiceBooking, ServiceBookingItem, ServicePayment\n\n8. Promotion System\n Discount codes, promotional campaigns, and special offers\n Models: Promotion\n\n9. Reviews And Ratings\n Guest reviews and ratings for rooms and services\n Models: Review\n\n10. Chat System\n Real-time chat support between guests and staff\n Models: Chat, ChatMessage, ChatStatus\n Statuses: open, closed\n\n11. Check In Check Out\n Check-in and check-out process management\n Models: CheckInCheckOut\n\n12. Maintenance Tracking\n Room maintenance scheduling and tracking\n Models: RoomMaintenance, RoomInspection\n\n13. Housekeeping\n Housekeeping task management and scheduling\n Models: HousekeepingTask\n\n14. Guest Management\n Comprehensive guest profile management and CRM features\n Models: GuestNote, GuestPreference, GuestTag, GuestSegment, GuestCommunication\n\n15. Group Bookings\n Group booking management for multiple rooms\n Models: GroupBooking\n\n16. Rate Plans\n Dynamic pricing and rate plan management\n Models: RatePlan\n\n17. Packages\n Pre-configured booking packages (room + services)\n Models: Package\n\n18. Blog And Content\n Content management for hotel blog and marketing\n Models: BlogPost, Banner, PageContent\n\n19. Analytics And Reporting\n Business intelligence, analytics, and financial reporting\n Models: AuditLog\n\n20. System Settings\n System-wide configuration and settings\n Models: SystemSettings\n\n21. Security And Compliance\n Security, audit logging, and GDPR compliance\n Models: SecurityEvent, AuditLog, GDPRCompliance\n\n22. Notifications\n System notifications and alerts\n Models: Notification\n\n23. Workflows\n Automated workflow management for business processes\n Models: Workflow\n\n24. Email Campaigns\n Marketing email campaigns and automation\n Models: EmailCampaign\n\n👥 USER ROLES & PERMISSIONS:\n\n• ADMIN\n Full system access with all administrative privileges\n Can Access: 19 features\n - All bookings (all customers)\n - All rooms and room management\n - All payments and financial data\n - All invoices\n - All users and user management\n ... and 14 more\n\n• ACCOUNTANT\n Financial data access for accounting and reporting\n Can Access: 10 features\n - All payments and payment history\n - All invoices and invoice management\n - Financial reports and analytics\n - Revenue summaries\n - Payment reconciliation\n ... and 5 more\n Restrictions: 5 items\n\n• STAFF\n Operational staff with access to daily hotel operations\n Can Access: 11 features\n - All bookings and booking management\n - Room status and availability\n - Check-in and check-out operations\n - Guest information (for operations)\n - Room maintenance and housekeeping tasks\n ... and 6 more\n Restrictions: 8 items\n\n• CUSTOMER\n Hotel guests with access to their own booking and account information\n Can Access: 13 features\n - Own bookings (view, cancel)\n - Own booking details\n - Own invoices (view only)\n - Own payment history\n - Own profile information\n ... and 8 more\n Restrictions: 8 items\n\n💻 TECHNOLOGY STACK:\n\n• Backend: FastAPI (Python)\n• Frontend: React/TypeScript\n• Database: SQLAlchemy ORM\n• AI: Self-learning assistant with pattern recognition\n• Authentication: JWT with MFA support\n• Security: Role-based access control, audit logging\n\n✨ KEY CAPABILITIES:\n\n• Complete booking lifecycle management\n• Multi-role access control (Admin, Staff, Accountant, Customer)\n• Payment processing with multiple methods\n• Invoice generation and tracking\n• Loyalty program with points and rewards\n• Real-time chat support system\n• Room maintenance and housekeeping management\n• Guest profile and CRM features\n• Analytics and reporting\n• Content management (blog, pages, banners)\n• Email campaigns and marketing automation\n• Group booking management\n• Dynamic pricing and rate plans\n• Package deals (room + services)\n• Review and rating system\n• Audit logging and security compliance\n\n💬 COMMON QUERY CATEGORIES:\n\n• Booking: booking status, check-in date, check-out date (+5 more)\n• Room: available rooms, room types, room amenities (+4 more)\n• Payment: payment status, payment history, payment methods (+4 more)\n• Invoice: invoice status, invoice number, invoice amount (+4 more)\n• Loyalty: loyalty points, loyalty tier, rewards (+3 more)\n• General: hotel information, contact, policies (+5 more)\n\n============================================================\n\n💡 TIP: Ask me about any specific feature, model, or capability for detailed information!','[\"features\"]','app_info','auto_learned',50.00,64,0,'admin',0,NULL,'2025-11-30 19:21:00','2025-12-02 23:23:54',NULL),(5,'About','tell me what is about this platform','📊 Hotel Status Overview:\n\n🏨 ROOMS:\n• Total: 50\n• Available: 40\n• Occupied: 5\n• Cleaning: 2\n• Maintenance: 3\n• Occupancy Rate: 10.0%\n\n📅 BOOKINGS:\n• Active: 0\n• Upcoming Check-ins: 0\n• Upcoming Check-outs: 0\n• Pending: 0\n\n💰 PAYMENTS:\n• Revenue (30 days): $0.00\n• Pending: $120.67\n• Completed: 0\n\n🧾 INVOICES:\n• Total: 1\n• Overdue: 0\n\n💬 CHATS:\n• Unanswered: 0\n\n⚠️ ISSUES:\n• Rooms with problems: 3\n - Room 106: Room 106 is under maintenance\n - Room 130: Room 130 is under maintenance\n - Room 239: Room 239 is under maintenance\n','[\"about\", \"platform\"]','general_status','auto_learned',50.00,63,0,'admin',0,NULL,'2025-11-30 19:21:24','2025-12-02 23:23:54',NULL),(6,'App','what does this app do','📱 Hotel Booking & Management System (HBMS) - Complete Overview\n\n============================================================\n\n📋 SYSTEM OVERVIEW:\n\n This is a comprehensive Hotel Booking and Management System (HBMS) - an enterprise-grade\n solution for managing hotel operations, reservations, payments, guest services, and business analytics.\n \n The system supports multiple user roles: Admin, Staff, Accountant, and Customer, each with\n different access levels and permissions.\n \n\n🔧 CORE FEATURES & MODULES:\n\n1. Booking Management\n Complete booking lifecycle management including creation, confirmation, check-in, check-out, and cancellation\n Models: Booking, BookingStatus\n Statuses: pending, confirmed, checked_in, checked_out, cancelled\n\n2. Room Management\n Room inventory, availability, status tracking, and maintenance\n Models: Room, RoomType, RoomStatus\n Statuses: available, occupied, maintenance, cleaning\n\n3. Payment Processing\n Payment handling for bookings with multiple payment methods and status tracking\n Models: Payment, PaymentMethod, PaymentStatus, PaymentType\n Statuses: pending, completed, failed, refunded\n\n4. Invoice Management\n Invoice generation, tracking, and payment reconciliation\n Models: Invoice, InvoiceItem, InvoiceStatus\n Statuses: draft, sent, paid, overdue, cancelled\n\n5. User Management\n User accounts, roles, authentication, and guest profiles\n Models: User, Role, RefreshToken, PasswordResetToken\n\n6. Loyalty Program\n Customer loyalty program with tiers, points, rewards, and referrals\n Models: LoyaltyTier, UserLoyalty, LoyaltyPointTransaction, LoyaltyReward, RewardRedemption (+1 more)\n\n7. Service Management\n Additional hotel services like spa, restaurant, room service\n Models: Service, ServiceUsage, ServiceBooking, ServiceBookingItem, ServicePayment\n\n8. Promotion System\n Discount codes, promotional campaigns, and special offers\n Models: Promotion\n\n9. Reviews And Ratings\n Guest reviews and ratings for rooms and services\n Models: Review\n\n10. Chat System\n Real-time chat support between guests and staff\n Models: Chat, ChatMessage, ChatStatus\n Statuses: open, closed\n\n11. Check In Check Out\n Check-in and check-out process management\n Models: CheckInCheckOut\n\n12. Maintenance Tracking\n Room maintenance scheduling and tracking\n Models: RoomMaintenance, RoomInspection\n\n13. Housekeeping\n Housekeeping task management and scheduling\n Models: HousekeepingTask\n\n14. Guest Management\n Comprehensive guest profile management and CRM features\n Models: GuestNote, GuestPreference, GuestTag, GuestSegment, GuestCommunication\n\n15. Group Bookings\n Group booking management for multiple rooms\n Models: GroupBooking\n\n16. Rate Plans\n Dynamic pricing and rate plan management\n Models: RatePlan\n\n17. Packages\n Pre-configured booking packages (room + services)\n Models: Package\n\n18. Blog And Content\n Content management for hotel blog and marketing\n Models: BlogPost, Banner, PageContent\n\n19. Analytics And Reporting\n Business intelligence, analytics, and financial reporting\n Models: AuditLog\n\n20. System Settings\n System-wide configuration and settings\n Models: SystemSettings\n\n21. Security And Compliance\n Security, audit logging, and GDPR compliance\n Models: SecurityEvent, AuditLog, GDPRCompliance\n\n22. Notifications\n System notifications and alerts\n Models: Notification\n\n23. Workflows\n Automated workflow management for business processes\n Models: Workflow\n\n24. Email Campaigns\n Marketing email campaigns and automation\n Models: EmailCampaign\n\n👥 USER ROLES & PERMISSIONS:\n\n• ADMIN\n Full system access with all administrative privileges\n Can Access: 19 features\n - All bookings (all customers)\n - All rooms and room management\n - All payments and financial data\n - All invoices\n - All users and user management\n ... and 14 more\n\n• ACCOUNTANT\n Financial data access for accounting and reporting\n Can Access: 10 features\n - All payments and payment history\n - All invoices and invoice management\n - Financial reports and analytics\n - Revenue summaries\n - Payment reconciliation\n ... and 5 more\n Restrictions: 5 items\n\n• STAFF\n Operational staff with access to daily hotel operations\n Can Access: 11 features\n - All bookings and booking management\n - Room status and availability\n - Check-in and check-out operations\n - Guest information (for operations)\n - Room maintenance and housekeeping tasks\n ... and 6 more\n Restrictions: 8 items\n\n• CUSTOMER\n Hotel guests with access to their own booking and account information\n Can Access: 13 features\n - Own bookings (view, cancel)\n - Own booking details\n - Own invoices (view only)\n - Own payment history\n - Own profile information\n ... and 8 more\n Restrictions: 8 items\n\n💻 TECHNOLOGY STACK:\n\n• Backend: FastAPI (Python)\n• Frontend: React/TypeScript\n• Database: SQLAlchemy ORM\n• AI: Self-learning assistant with pattern recognition\n• Authentication: JWT with MFA support\n• Security: Role-based access control, audit logging\n\n✨ KEY CAPABILITIES:\n\n• Complete booking lifecycle management\n• Multi-role access control (Admin, Staff, Accountant, Customer)\n• Payment processing with multiple methods\n• Invoice generation and tracking\n• Loyalty program with points and rewards\n• Real-time chat support system\n• Room maintenance and housekeeping management\n• Guest profile and CRM features\n• Analytics and reporting\n• Content management (blog, pages, banners)\n• Email campaigns and marketing automation\n• Group booking management\n• Dynamic pricing and rate plans\n• Package deals (room + services)\n• Review and rating system\n• Audit logging and security compliance\n\n💬 COMMON QUERY CATEGORIES:\n\n• Booking: booking status, check-in date, check-out date (+5 more)\n• Room: available rooms, room types, room amenities (+4 more)\n• Payment: payment status, payment history, payment methods (+4 more)\n• Invoice: invoice status, invoice number, invoice amount (+4 more)\n• Loyalty: loyalty points, loyalty tier, rewards (+3 more)\n• General: hotel information, contact, policies (+5 more)\n\n============================================================\n\n💡 TIP: Ask me about any specific feature, model, or capability for detailed information!','[\"app\"]','app_info','auto_learned',50.00,63,0,'admin',0,NULL,'2025-11-30 19:21:25','2025-12-02 23:23:54',NULL),(7,'Rooms','Which rooms are occupied?','Currently, 5 rooms are occupied out of 50 total rooms.','[\"rooms\", \"occupied\"]','room_occupied','auto_learned',50.00,61,0,'admin',0,NULL,'2025-11-30 20:41:01','2025-12-02 23:23:54',NULL),(8,'Payments','tell me the payments','Payment Status Summary:\n• Total Revenue (last 30 days): $0.00\n• Pending Payments: $120.67\n• Completed Payments: 0','[\"payments\"]','payment_status','auto_learned',50.00,51,0,'admin',0,NULL,'2025-11-30 23:06:47','2025-12-02 23:23:54',NULL); +/*!40000 ALTER TABLE `ai_knowledge_entries` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `ai_learned_patterns` +-- + +DROP TABLE IF EXISTS `ai_learned_patterns`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ai_learned_patterns` ( + `id` int NOT NULL AUTO_INCREMENT, + `pattern_keywords` text NOT NULL, + `query_pattern` text NOT NULL, + `intent` varchar(100) NOT NULL, + `response_template` text, + `context_keys` json DEFAULT NULL, + `confidence_score` decimal(5,2) NOT NULL, + `usage_count` int NOT NULL, + `success_count` int NOT NULL, + `source_conversation_id` int DEFAULT NULL, + `user_role` varchar(50) DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `last_used_at` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `source_conversation_id` (`source_conversation_id`), + KEY `idx_ai_pattern_active` (`is_active`,`confidence_score`), + KEY `ix_ai_learned_patterns_intent` (`intent`), + KEY `ix_ai_learned_patterns_user_role` (`user_role`), + KEY `ix_ai_learned_patterns_id` (`id`), + KEY `idx_ai_pattern_intent_role` (`intent`,`user_role`), + CONSTRAINT `ai_learned_patterns_ibfk_1` FOREIGN KEY (`source_conversation_id`) REFERENCES `ai_conversations` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `ai_learned_patterns` +-- + +LOCK TABLES `ai_learned_patterns` WRITE; +/*!40000 ALTER TABLE `ai_learned_patterns` DISABLE KEYS */; +INSERT INTO `ai_learned_patterns` VALUES (1,'[\"platform\", \"about\"]','what is this platform about','general_status','📊 Hotel Status Overview:\n\n🏨 ROOMS:\n• Total: 50\n• Available: 40\n• Occupied: 5\n• Cleaning: 2\n• Maintenance: 3\n• Occupancy Rate: 10.0%\n\n📅 BOOKINGS:\n• Active: 0\n• Upcoming Check-ins: 0\n• Upcoming Check-outs: 0\n• Pending: 0\n\n💰 PAYMENTS:\n• Revenue (30 days): $0.00\n• Pending: $120.67\n• Completed: 0\n\n🧾 INVOICES:\n• Total: 1\n• Overdue: 0\n\n💬 CHATS:\n• Unanswered: 0\n\n⚠️ ISSUES:\n• Rooms with problems: 3\n - Room 106: Room 106 is under maintenance\n - Room 130: Room 130 is under maintenance\n - Room 239: Room ','{\"room_summary\": {\"cleaning\": 2, \"occupied\": 5, \"available\": 40, \"maintenance\": 3, \"total_rooms\": 50, \"occupancy_rate\": 10.0, \"rooms_with_active_bookings\": 0}, \"room_problems\": [{\"status\": \"maintenance\", \"issue_type\": \"maintenance\", \"description\": \"Room 106 is under maintenance\", \"room_number\": \"106\"}, {\"status\": \"maintenance\", \"issue_type\": \"maintenance\", \"description\": \"Room 130 is under maintenance\", \"room_number\": \"130\"}, {\"status\": \"maintenance\", \"issue_type\": \"maintenance\", \"description\": \"Room 239 is under maintenance\", \"room_number\": \"239\"}], \"booking_summary\": {\"period_days\": 7, \"active_bookings\": 0, \"pending_bookings\": 0, \"upcoming_checkins\": 0, \"upcoming_checkouts\": 0}, \"invoice_summary\": {\"total_invoices\": 1, \"overdue_invoices\": 0, \"status_breakdown\": {\"draft\": 1}}, \"payment_summary\": {\"period_days\": 30, \"total_revenue\": 0.0, \"pending_amount\": 120.67, \"failed_payments\": 14, \"completed_payments\": 0}, \"unanswered_chats\": []}',50.00,200,1,1,'admin',1,'2025-11-30 19:15:58','2025-12-02 23:23:54','2025-12-02 23:23:54'),(2,'[\"clear\"]','clear','general_query','I can help you with information about:\n\n🏨 Rooms - availability, occupancy, status, problems\n📅 Bookings - active, upcoming, pending reservations\n💰 Payments - revenue, pending payments, transactions\n🧾 Invoices - status, overdue invoices\n💬 Chats - unanswered customer messages\n\nQuick Stats: 50 total rooms, 5 occupied, 40 available.\n\nTry asking:\n• \'How many rooms do we have?\'\n• \'Show me occupied rooms\'\n• \'What\'s our revenue?\'\n• \'Are there any unanswered chats?\'','{\"room_summary\": {\"cleaning\": 2, \"occupied\": 5, \"available\": 40, \"maintenance\": 3, \"total_rooms\": 50, \"occupancy_rate\": 10.0, \"rooms_with_active_bookings\": 0}, \"booking_summary\": {\"period_days\": 7, \"active_bookings\": 0, \"pending_bookings\": 0, \"upcoming_checkins\": 0, \"upcoming_checkouts\": 0}, \"invoice_summary\": {\"total_invoices\": 1, \"overdue_invoices\": 0, \"status_breakdown\": {\"draft\": 1}}, \"payment_summary\": {\"period_days\": 30, \"total_revenue\": 0.0, \"pending_amount\": 120.67, \"failed_payments\": 14, \"completed_payments\": 0}}',50.00,65,1,3,'admin',1,'2025-11-30 19:20:31','2025-12-02 23:23:54','2025-12-02 23:23:54'),(3,'[\"features\"]','list features','app_info','📱 Hotel Booking & Management System (HBMS) - Complete Overview\n\n============================================================\n\n📋 SYSTEM OVERVIEW:\n\n This is a comprehensive Hotel Booking and Management System (HBMS) - an enterprise-grade\n solution for managing hotel operations, reservations, payments, guest services, and business analytics.\n \n The system supports multiple user roles: Admin, Staff, Accountant, and Customer, each with\n different access levels and permissions.\n \n\n🔧 ','{\"app_knowledge\": {\"features\": {\"packages\": {\"models\": [\"Package\"], \"key_fields\": [\"name\", \"price\", \"includes\", \"valid_period\"], \"description\": \"Pre-configured booking packages (room + services)\", \"relationships\": [\"RoomType\", \"Service\"]}, \"workflows\": {\"models\": [\"Workflow\"], \"key_fields\": [\"name\", \"trigger\", \"actions\", \"conditions\"], \"description\": \"Automated workflow management for business processes\", \"relationships\": []}, \"rate_plans\": {\"models\": [\"RatePlan\"], \"key_fields\": [\"name\", \"base_price\", \"season_multiplier\", \"valid_from\", \"valid_to\"], \"description\": \"Dynamic pricing and rate plan management\", \"relationships\": [\"Booking\"]}, \"chat_system\": {\"models\": [\"Chat\", \"ChatMessage\", \"ChatStatus\"], \"statuses\": [\"open\", \"closed\"], \"key_fields\": [\"visitor_name\", \"visitor_email\", \"status\", \"message\", \"sender_type\", \"is_read\"], \"description\": \"Real-time chat support between guests and staff\", \"relationships\": [\"User\"]}, \"housekeeping\": {\"models\": [\"HousekeepingTask\"], \"key_fields\": [\"task_type\", \"status\", \"scheduled_time\", \"completed_at\"], \"description\": \"Housekeeping task management and scheduling\", \"relationships\": [\"Room\"]}, \"notifications\": {\"models\": [\"Notification\"], \"key_fields\": [\"type\", \"message\", \"is_read\", \"priority\"], \"description\": \"System notifications and alerts\", \"relationships\": [\"User\"]}, \"group_bookings\": {\"models\": [\"GroupBooking\"], \"key_fields\": [\"group_name\", \"contact_person\", \"total_rooms\", \"group_discount\"], \"description\": \"Group booking management for multiple rooms\", \"relationships\": [\"Booking\"]}, \"email_campaigns\": {\"models\": [\"EmailCampaign\"], \"key_fields\": [\"subject\", \"content\", \"recipient_segment\", \"scheduled_time\"], \"description\": \"Marketing email campaigns and automation\", \"relationships\": [\"GuestSegment\"]}, \"loyalty_program\": {\"models\": [\"LoyaltyTier\", \"UserLoyalty\", \"LoyaltyPointTransaction\", \"LoyaltyReward\", \"RewardRedemption\", \"Referral\"], \"key_fields\": [\"tier_level\", \"points_balance\", \"lifetime_points\", \"referral_code\"], \"description\": \"Customer loyalty program with tiers, points, rewards, and referrals\", \"relationships\": [\"User\", \"Booking\"]}, \"room_management\": {\"models\": [\"Room\", \"RoomType\", \"RoomStatus\"], \"statuses\": [\"available\", \"occupied\", \"maintenance\", \"cleaning\"], \"key_fields\": [\"room_number\", \"floor\", \"status\", \"price\", \"capacity\", \"amenities\", \"room_size\", \"view\"], \"description\": \"Room inventory, availability, status tracking, and maintenance\", \"relationships\": [\"RoomType\", \"Booking\", \"Review\", \"RoomMaintenance\", \"HousekeepingTask\"]}, \"system_settings\": {\"models\": [\"SystemSettings\"], \"categories\": [\"general\", \"payment\", \"email\", \"company_info\"], \"key_fields\": [\"key\", \"value\", \"category\"], \"description\": \"System-wide configuration and settings\"}, \"user_management\": {\"roles\": [\"admin\", \"staff\", \"customer\", \"accountant\"], \"models\": [\"User\", \"Role\", \"RefreshToken\", \"PasswordResetToken\"], \"key_fields\": [\"email\", \"full_name\", \"phone\", \"role_id\", \"is_active\", \"currency\"], \"description\": \"User accounts, roles, authentication, and guest profiles\", \"guest_fields\": [\"is_vip\", \"lifetime_value\", \"satisfaction_score\", \"total_visits\", \"last_visit_date\"], \"relationships\": [\"Role\", \"Booking\", \"Payment\", \"Invoice\", \"Review\", \"Favorite\"]}, \"blog_and_content\": {\"models\": [\"BlogPost\", \"Banner\", \"PageContent\"], \"key_fields\": [\"title\", \"content\", \"is_published\", \"published_at\"], \"description\": \"Content management for hotel blog and marketing\", \"relationships\": []}, \"guest_management\": {\"models\": [\"GuestNote\", \"GuestPreference\", \"GuestTag\", \"GuestSegment\", \"GuestCommunication\"], \"key_fields\": [\"notes\", \"preferences\", \"tags\", \"communication_history\"], \"description\": \"Comprehensive guest profile management and CRM features\", \"relationships\": [\"User\"]}, \"promotion_system\": {\"models\": [\"Promotion\"], \"key_fields\": [\"code\", \"discount_type\", \"discount_value\", \"start_date\", \"end_date\", \"is_active\"], \"description\": \"Discount codes, promotional campaigns, and special offers\", \"relationships\": [\"Booking\"]}, \"booking_management\": {\"models\": [\"Booking\", \"BookingStatus\"], \"statuses\": [\"pending\", \"confirmed\", \"checked_in\", \"checked_out\", \"cancelled\"], \"key_fields\": [\"booking_number\", \"user_id\", \"room_id\", \"check_in_date\", \"check_out_date\", \"num_guests\", \"total_price\", \"status\", \"special_requests\"], \"description\": \"Complete booking lifecycle management including creation, confirmation, check-in, check-out, and cancellation\", \"relationships\": [\"User\", \"Room\", \"Payment\", \"Invoice\", \"ServiceUsage\", \"CheckInCheckOut\"]}, \"check_in_check_out\": {\"models\": [\"CheckInCheckOut\"], \"key_fields\": [\"checked_in_at\", \"checked_out_at\", \"checked_in_by\", \"checked_out_by\", \"notes\"], \"description\": \"Check-in and check-out process management\", \"relationships\": [\"Booking\", \"User\"]}, \"invoice_management\": {\"models\": [\"Invoice\", \"InvoiceItem\", \"InvoiceStatus\"], \"statuses\": [\"draft\", \"sent\", \"paid\", \"overdue\", \"cancelled\"], \"key_fields\": [\"invoice_number\", \"total_amount\", \"subtotal\", \"tax_amount\", \"discount_amount\", \"balance_due\", \"status\", \"due_date\", \"paid_date\"], \"description\": \"Invoice generation, tracking, and payment reconciliation\", \"relationships\": [\"Booking\", \"User\", \"InvoiceItem\"]}, \"payment_processing\": {\"models\": [\"Payment\", \"PaymentMethod\", \"PaymentStatus\", \"PaymentType\"], \"statuses\": [\"pending\", \"completed\", \"failed\", \"refunded\"], \"key_fields\": [\"amount\", \"payment_method\", \"payment_type\", \"payment_status\", \"transaction_id\", \"payment_date\"], \"description\": \"Payment handling for bookings with multiple payment methods and status tracking\", \"payment_types\": [\"full\", \"deposit\", \"remaining\"], \"relationships\": [\"Booking\"], \"payment_methods\": [\"cash\", \"credit_card\", \"debit_card\", \"bank_transfer\", \"e_wallet\", \"stripe\", \"paypal\", \"borica\"]}, \"service_management\": {\"models\": [\"Service\", \"ServiceUsage\", \"ServiceBooking\", \"ServiceBookingItem\", \"ServicePayment\"], \"key_fields\": [\"service_name\", \"price\", \"category\", \"description\"], \"description\": \"Additional hotel services like spa, restaurant, room service\", \"relationships\": [\"Booking\"]}, \"reviews_and_ratings\": {\"models\": [\"Review\"], \"key_fields\": [\"rating\", \"comment\", \"is_verified\"], \"description\": \"Guest reviews and ratings for rooms and services\", \"relationships\": [\"User\", \"Room\"]}, \"maintenance_tracking\": {\"models\": [\"RoomMaintenance\", \"RoomInspection\"], \"key_fields\": [\"scheduled_start\", \"scheduled_end\", \"status\", \"description\", \"priority\"], \"description\": \"Room maintenance scheduling and tracking\", \"relationships\": [\"Room\"]}, \"analytics_and_reporting\": {\"models\": [\"AuditLog\"], \"features\": [\"Revenue reports\", \"Occupancy analytics\", \"Guest analytics\", \"Payment reports\", \"Invoice reports\", \"Booking trends\", \"Customer lifetime value\"], \"description\": \"Business intelligence, analytics, and financial reporting\"}, \"security_and_compliance\": {\"models\": [\"SecurityEvent\", \"AuditLog\", \"GDPRCompliance\"], \"features\": [\"Action audit trails\", \"Security event logging\", \"GDPR data requests\", \"Cookie consent management\"], \"description\": \"Security, audit logging, and GDPR compliance\"}}, \"overview\": \"\\n This is a comprehensive Hotel Booking and Management System (HBMS) - an enterprise-grade\\n solution for managing hotel operations, reservations, payments, guest services, and business analytics.\\n \\n The system supports multiple user roles: Admin, Staff, Accountant, and Customer, each with\\n different access levels and permissions.\\n \", \"common_queries\": {\"room\": [\"available rooms\", \"room types\", \"room amenities\", \"room prices\", \"room availability\", \"occupied rooms\", \"room status\"], \"booking\": [\"booking status\", \"check-in date\", \"check-out date\", \"booking number\", \"cancel booking\", \"modify booking\", \"upcoming bookings\", \"past bookings\"], \"general\": [\"hotel information\", \"contact\", \"policies\", \"services\", \"amenities\", \"location\", \"FAQ\", \"help\"], \"invoice\": [\"invoice status\", \"invoice number\", \"invoice amount\", \"due date\", \"paid invoice\", \"outstanding invoice\", \"invoice download\"], \"loyalty\": [\"loyalty points\", \"loyalty tier\", \"rewards\", \"referral code\", \"points balance\", \"points history\"], \"payment\": [\"payment status\", \"payment history\", \"payment methods\", \"refund\", \"outstanding balance\", \"payment due\", \"transaction\"]}, \"role_capabilities\": {\"admin\": {\"can_access\": [\"All bookings (all customers)\", \"All rooms and room management\", \"All payments and financial data\", \"All invoices\", \"All users and user management\", \"System settings and configuration\", \"Analytics and reports\", \"Audit logs and security events\", \"Content management (blog, banners, pages)\", \"Promotion management\", \"Loyalty program administration\", \"Service management\", \"Maintenance and housekeeping\", \"Check-in/check-out operations\", \"Chat management\", \"Email campaigns\", \"Workflow management\", \"Group bookings\", \"Rate plans and packages\"], \"description\": \"Full system access with all administrative privileges\", \"restrictions\": \"None - full access\", \"cannot_access\": []}, \"staff\": {\"can_access\": [\"All bookings and booking management\", \"Room status and availability\", \"Check-in and check-out operations\", \"Guest information (for operations)\", \"Room maintenance and housekeeping tasks\", \"Service bookings and service usage\", \"Chat system for customer support\", \"Basic booking reports\", \"Occupancy status\", \"Group bookings\", \"Guest preferences and notes (operational)\"], \"description\": \"Operational staff with access to daily hotel operations\", \"restrictions\": \"Operational data only, no financial or system administration\", \"cannot_access\": [\"Financial reports and analytics\", \"System settings\", \"User management (except guest profile updates)\", \"Content management\", \"Email campaigns\", \"Workflow management\", \"Full payment details (can view payment status only)\", \"Invoice editing (view only)\"]}, \"customer\": {\"can_access\": [\"Own bookings (view, cancel)\", \"Own booking details\", \"Own invoices (view only)\", \"Own payment history\", \"Own profile information\", \"Room browsing and availability (public)\", \"Service browsing\", \"Booking creation\", \"Review submission\", \"Favorite rooms\", \"Loyalty points and rewards\", \"Referral code usage\", \"Chat with support\"], \"description\": \"Hotel guests with access to their own booking and account information\", \"restrictions\": \"Only own data and customer-facing features\", \"cannot_access\": [\"Other customers\' bookings or information\", \"All bookings overview\", \"Financial reports\", \"System settings\", \"Room management\", \"Staff operations\", \"Admin features\", \"Other users\' data\"]}, \"accountant\": {\"can_access\": [\"All payments and payment history\", \"All invoices and invoice management\", \"Financial reports and analytics\", \"Revenue summaries\", \"Payment reconciliation\", \"Invoice generation and editing\", \"Booking financial details (for invoicing)\", \"Customer payment history\", \"Refund processing\", \"Financial dashboard statistics\"], \"description\": \"Financial data access for accounting and reporting\", \"restrictions\": \"Financial and payment data only\", \"cannot_access\": [\"User personal information (except payment-related)\", \"System settings\", \"Content management\", \"Room operational details (unless related to billing)\", \"Security and audit logs (financial audit access only)\"]}}}}',50.00,65,1,5,'admin',1,'2025-11-30 19:21:00','2025-12-02 23:23:54','2025-12-02 23:23:54'),(4,'[\"app\"]','what does this app do','app_info','📱 Hotel Booking & Management System (HBMS) - Complete Overview\n\n============================================================\n\n📋 SYSTEM OVERVIEW:\n\n This is a comprehensive Hotel Booking and Management System (HBMS) - an enterprise-grade\n solution for managing hotel operations, reservations, payments, guest services, and business analytics.\n \n The system supports multiple user roles: Admin, Staff, Accountant, and Customer, each with\n different access levels and permissions.\n \n\n🔧 ','{\"app_knowledge\": {\"features\": {\"packages\": {\"models\": [\"Package\"], \"key_fields\": [\"name\", \"price\", \"includes\", \"valid_period\"], \"description\": \"Pre-configured booking packages (room + services)\", \"relationships\": [\"RoomType\", \"Service\"]}, \"workflows\": {\"models\": [\"Workflow\"], \"key_fields\": [\"name\", \"trigger\", \"actions\", \"conditions\"], \"description\": \"Automated workflow management for business processes\", \"relationships\": []}, \"rate_plans\": {\"models\": [\"RatePlan\"], \"key_fields\": [\"name\", \"base_price\", \"season_multiplier\", \"valid_from\", \"valid_to\"], \"description\": \"Dynamic pricing and rate plan management\", \"relationships\": [\"Booking\"]}, \"chat_system\": {\"models\": [\"Chat\", \"ChatMessage\", \"ChatStatus\"], \"statuses\": [\"open\", \"closed\"], \"key_fields\": [\"visitor_name\", \"visitor_email\", \"status\", \"message\", \"sender_type\", \"is_read\"], \"description\": \"Real-time chat support between guests and staff\", \"relationships\": [\"User\"]}, \"housekeeping\": {\"models\": [\"HousekeepingTask\"], \"key_fields\": [\"task_type\", \"status\", \"scheduled_time\", \"completed_at\"], \"description\": \"Housekeeping task management and scheduling\", \"relationships\": [\"Room\"]}, \"notifications\": {\"models\": [\"Notification\"], \"key_fields\": [\"type\", \"message\", \"is_read\", \"priority\"], \"description\": \"System notifications and alerts\", \"relationships\": [\"User\"]}, \"group_bookings\": {\"models\": [\"GroupBooking\"], \"key_fields\": [\"group_name\", \"contact_person\", \"total_rooms\", \"group_discount\"], \"description\": \"Group booking management for multiple rooms\", \"relationships\": [\"Booking\"]}, \"email_campaigns\": {\"models\": [\"EmailCampaign\"], \"key_fields\": [\"subject\", \"content\", \"recipient_segment\", \"scheduled_time\"], \"description\": \"Marketing email campaigns and automation\", \"relationships\": [\"GuestSegment\"]}, \"loyalty_program\": {\"models\": [\"LoyaltyTier\", \"UserLoyalty\", \"LoyaltyPointTransaction\", \"LoyaltyReward\", \"RewardRedemption\", \"Referral\"], \"key_fields\": [\"tier_level\", \"points_balance\", \"lifetime_points\", \"referral_code\"], \"description\": \"Customer loyalty program with tiers, points, rewards, and referrals\", \"relationships\": [\"User\", \"Booking\"]}, \"room_management\": {\"models\": [\"Room\", \"RoomType\", \"RoomStatus\"], \"statuses\": [\"available\", \"occupied\", \"maintenance\", \"cleaning\"], \"key_fields\": [\"room_number\", \"floor\", \"status\", \"price\", \"capacity\", \"amenities\", \"room_size\", \"view\"], \"description\": \"Room inventory, availability, status tracking, and maintenance\", \"relationships\": [\"RoomType\", \"Booking\", \"Review\", \"RoomMaintenance\", \"HousekeepingTask\"]}, \"system_settings\": {\"models\": [\"SystemSettings\"], \"categories\": [\"general\", \"payment\", \"email\", \"company_info\"], \"key_fields\": [\"key\", \"value\", \"category\"], \"description\": \"System-wide configuration and settings\"}, \"user_management\": {\"roles\": [\"admin\", \"staff\", \"customer\", \"accountant\"], \"models\": [\"User\", \"Role\", \"RefreshToken\", \"PasswordResetToken\"], \"key_fields\": [\"email\", \"full_name\", \"phone\", \"role_id\", \"is_active\", \"currency\"], \"description\": \"User accounts, roles, authentication, and guest profiles\", \"guest_fields\": [\"is_vip\", \"lifetime_value\", \"satisfaction_score\", \"total_visits\", \"last_visit_date\"], \"relationships\": [\"Role\", \"Booking\", \"Payment\", \"Invoice\", \"Review\", \"Favorite\"]}, \"blog_and_content\": {\"models\": [\"BlogPost\", \"Banner\", \"PageContent\"], \"key_fields\": [\"title\", \"content\", \"is_published\", \"published_at\"], \"description\": \"Content management for hotel blog and marketing\", \"relationships\": []}, \"guest_management\": {\"models\": [\"GuestNote\", \"GuestPreference\", \"GuestTag\", \"GuestSegment\", \"GuestCommunication\"], \"key_fields\": [\"notes\", \"preferences\", \"tags\", \"communication_history\"], \"description\": \"Comprehensive guest profile management and CRM features\", \"relationships\": [\"User\"]}, \"promotion_system\": {\"models\": [\"Promotion\"], \"key_fields\": [\"code\", \"discount_type\", \"discount_value\", \"start_date\", \"end_date\", \"is_active\"], \"description\": \"Discount codes, promotional campaigns, and special offers\", \"relationships\": [\"Booking\"]}, \"booking_management\": {\"models\": [\"Booking\", \"BookingStatus\"], \"statuses\": [\"pending\", \"confirmed\", \"checked_in\", \"checked_out\", \"cancelled\"], \"key_fields\": [\"booking_number\", \"user_id\", \"room_id\", \"check_in_date\", \"check_out_date\", \"num_guests\", \"total_price\", \"status\", \"special_requests\"], \"description\": \"Complete booking lifecycle management including creation, confirmation, check-in, check-out, and cancellation\", \"relationships\": [\"User\", \"Room\", \"Payment\", \"Invoice\", \"ServiceUsage\", \"CheckInCheckOut\"]}, \"check_in_check_out\": {\"models\": [\"CheckInCheckOut\"], \"key_fields\": [\"checked_in_at\", \"checked_out_at\", \"checked_in_by\", \"checked_out_by\", \"notes\"], \"description\": \"Check-in and check-out process management\", \"relationships\": [\"Booking\", \"User\"]}, \"invoice_management\": {\"models\": [\"Invoice\", \"InvoiceItem\", \"InvoiceStatus\"], \"statuses\": [\"draft\", \"sent\", \"paid\", \"overdue\", \"cancelled\"], \"key_fields\": [\"invoice_number\", \"total_amount\", \"subtotal\", \"tax_amount\", \"discount_amount\", \"balance_due\", \"status\", \"due_date\", \"paid_date\"], \"description\": \"Invoice generation, tracking, and payment reconciliation\", \"relationships\": [\"Booking\", \"User\", \"InvoiceItem\"]}, \"payment_processing\": {\"models\": [\"Payment\", \"PaymentMethod\", \"PaymentStatus\", \"PaymentType\"], \"statuses\": [\"pending\", \"completed\", \"failed\", \"refunded\"], \"key_fields\": [\"amount\", \"payment_method\", \"payment_type\", \"payment_status\", \"transaction_id\", \"payment_date\"], \"description\": \"Payment handling for bookings with multiple payment methods and status tracking\", \"payment_types\": [\"full\", \"deposit\", \"remaining\"], \"relationships\": [\"Booking\"], \"payment_methods\": [\"cash\", \"credit_card\", \"debit_card\", \"bank_transfer\", \"e_wallet\", \"stripe\", \"paypal\", \"borica\"]}, \"service_management\": {\"models\": [\"Service\", \"ServiceUsage\", \"ServiceBooking\", \"ServiceBookingItem\", \"ServicePayment\"], \"key_fields\": [\"service_name\", \"price\", \"category\", \"description\"], \"description\": \"Additional hotel services like spa, restaurant, room service\", \"relationships\": [\"Booking\"]}, \"reviews_and_ratings\": {\"models\": [\"Review\"], \"key_fields\": [\"rating\", \"comment\", \"is_verified\"], \"description\": \"Guest reviews and ratings for rooms and services\", \"relationships\": [\"User\", \"Room\"]}, \"maintenance_tracking\": {\"models\": [\"RoomMaintenance\", \"RoomInspection\"], \"key_fields\": [\"scheduled_start\", \"scheduled_end\", \"status\", \"description\", \"priority\"], \"description\": \"Room maintenance scheduling and tracking\", \"relationships\": [\"Room\"]}, \"analytics_and_reporting\": {\"models\": [\"AuditLog\"], \"features\": [\"Revenue reports\", \"Occupancy analytics\", \"Guest analytics\", \"Payment reports\", \"Invoice reports\", \"Booking trends\", \"Customer lifetime value\"], \"description\": \"Business intelligence, analytics, and financial reporting\"}, \"security_and_compliance\": {\"models\": [\"SecurityEvent\", \"AuditLog\", \"GDPRCompliance\"], \"features\": [\"Action audit trails\", \"Security event logging\", \"GDPR data requests\", \"Cookie consent management\"], \"description\": \"Security, audit logging, and GDPR compliance\"}}, \"overview\": \"\\n This is a comprehensive Hotel Booking and Management System (HBMS) - an enterprise-grade\\n solution for managing hotel operations, reservations, payments, guest services, and business analytics.\\n \\n The system supports multiple user roles: Admin, Staff, Accountant, and Customer, each with\\n different access levels and permissions.\\n \", \"common_queries\": {\"room\": [\"available rooms\", \"room types\", \"room amenities\", \"room prices\", \"room availability\", \"occupied rooms\", \"room status\"], \"booking\": [\"booking status\", \"check-in date\", \"check-out date\", \"booking number\", \"cancel booking\", \"modify booking\", \"upcoming bookings\", \"past bookings\"], \"general\": [\"hotel information\", \"contact\", \"policies\", \"services\", \"amenities\", \"location\", \"FAQ\", \"help\"], \"invoice\": [\"invoice status\", \"invoice number\", \"invoice amount\", \"due date\", \"paid invoice\", \"outstanding invoice\", \"invoice download\"], \"loyalty\": [\"loyalty points\", \"loyalty tier\", \"rewards\", \"referral code\", \"points balance\", \"points history\"], \"payment\": [\"payment status\", \"payment history\", \"payment methods\", \"refund\", \"outstanding balance\", \"payment due\", \"transaction\"]}, \"role_capabilities\": {\"admin\": {\"can_access\": [\"All bookings (all customers)\", \"All rooms and room management\", \"All payments and financial data\", \"All invoices\", \"All users and user management\", \"System settings and configuration\", \"Analytics and reports\", \"Audit logs and security events\", \"Content management (blog, banners, pages)\", \"Promotion management\", \"Loyalty program administration\", \"Service management\", \"Maintenance and housekeeping\", \"Check-in/check-out operations\", \"Chat management\", \"Email campaigns\", \"Workflow management\", \"Group bookings\", \"Rate plans and packages\"], \"description\": \"Full system access with all administrative privileges\", \"restrictions\": \"None - full access\", \"cannot_access\": []}, \"staff\": {\"can_access\": [\"All bookings and booking management\", \"Room status and availability\", \"Check-in and check-out operations\", \"Guest information (for operations)\", \"Room maintenance and housekeeping tasks\", \"Service bookings and service usage\", \"Chat system for customer support\", \"Basic booking reports\", \"Occupancy status\", \"Group bookings\", \"Guest preferences and notes (operational)\"], \"description\": \"Operational staff with access to daily hotel operations\", \"restrictions\": \"Operational data only, no financial or system administration\", \"cannot_access\": [\"Financial reports and analytics\", \"System settings\", \"User management (except guest profile updates)\", \"Content management\", \"Email campaigns\", \"Workflow management\", \"Full payment details (can view payment status only)\", \"Invoice editing (view only)\"]}, \"customer\": {\"can_access\": [\"Own bookings (view, cancel)\", \"Own booking details\", \"Own invoices (view only)\", \"Own payment history\", \"Own profile information\", \"Room browsing and availability (public)\", \"Service browsing\", \"Booking creation\", \"Review submission\", \"Favorite rooms\", \"Loyalty points and rewards\", \"Referral code usage\", \"Chat with support\"], \"description\": \"Hotel guests with access to their own booking and account information\", \"restrictions\": \"Only own data and customer-facing features\", \"cannot_access\": [\"Other customers\' bookings or information\", \"All bookings overview\", \"Financial reports\", \"System settings\", \"Room management\", \"Staff operations\", \"Admin features\", \"Other users\' data\"]}, \"accountant\": {\"can_access\": [\"All payments and payment history\", \"All invoices and invoice management\", \"Financial reports and analytics\", \"Revenue summaries\", \"Payment reconciliation\", \"Invoice generation and editing\", \"Booking financial details (for invoicing)\", \"Customer payment history\", \"Refund processing\", \"Financial dashboard statistics\"], \"description\": \"Financial data access for accounting and reporting\", \"restrictions\": \"Financial and payment data only\", \"cannot_access\": [\"User personal information (except payment-related)\", \"System settings\", \"Content management\", \"Room operational details (unless related to billing)\", \"Security and audit logs (financial audit access only)\"]}}}}',50.00,64,1,6,'admin',1,'2025-11-30 19:21:25','2025-12-02 23:23:54','2025-12-02 23:23:54'),(5,'[\"rooms\", \"occupied\"]','Which rooms are occupied?','room_occupied','Currently, 5 rooms are occupied out of 50 total rooms.','{\"room_summary\": {\"cleaning\": 2, \"occupied\": 5, \"available\": 40, \"maintenance\": 3, \"total_rooms\": 50, \"occupancy_rate\": 10.0, \"rooms_with_active_bookings\": 0}, \"occupied_rooms\": []}',50.00,62,1,7,'admin',1,'2025-11-30 20:41:01','2025-12-02 23:23:54','2025-12-02 23:23:54'),(6,'[\"payments\"]','tell me the payments','payment_status','Payment Status Summary:\n• Total Revenue (last 30 days): $0.00\n• Pending Payments: $120.67\n• Completed Payments: 0','{\"payment_summary\": {\"period_days\": 30, \"total_revenue\": 0.0, \"pending_amount\": 120.67, \"failed_payments\": 14, \"completed_payments\": 0}}',50.00,52,1,8,'admin',1,'2025-11-30 23:06:47','2025-12-02 23:23:54','2025-12-02 23:23:54'); +/*!40000 ALTER TABLE `ai_learned_patterns` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `ai_training_metrics` +-- + +DROP TABLE IF EXISTS `ai_training_metrics`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ai_training_metrics` ( + `id` int NOT NULL AUTO_INCREMENT, + `metric_date` datetime NOT NULL, + `total_conversations` int NOT NULL, + `total_patterns_learned` int NOT NULL, + `total_knowledge_entries` int NOT NULL, + `average_response_time_ms` int DEFAULT NULL, + `average_rating` decimal(3,2) DEFAULT NULL, + `helpful_rate` decimal(5,2) DEFAULT NULL, + `correct_rate` decimal(5,2) DEFAULT NULL, + `pattern_match_success_rate` decimal(5,2) DEFAULT NULL, + `knowledge_usage_rate` decimal(5,2) DEFAULT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_ai_training_metrics_metric_date` (`metric_date`), + KEY `idx_ai_metrics_date` (`metric_date`), + KEY `ix_ai_training_metrics_id` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `ai_training_metrics` +-- + +LOCK TABLES `ai_training_metrics` WRITE; +/*!40000 ALTER TABLE `ai_training_metrics` DISABLE KEYS */; +INSERT INTO `ai_training_metrics` VALUES (1,'2025-11-30 19:16:39',7,5,0,127,NULL,NULL,NULL,NULL,NULL,'2025-11-30 19:16:39'),(2,'2025-12-01 01:56:29',8,6,0,127,NULL,NULL,NULL,NULL,NULL,'2025-12-01 01:56:29'),(3,'2025-12-02 05:50:35',8,6,0,127,NULL,NULL,NULL,NULL,NULL,'2025-12-02 05:50:35'); +/*!40000 ALTER TABLE `ai_training_metrics` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `alembic_version` +-- + +DROP TABLE IF EXISTS `alembic_version`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `alembic_version` ( + `version_num` varchar(32) NOT NULL, + PRIMARY KEY (`version_num`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `alembic_version` +-- + +LOCK TABLES `alembic_version` WRITE; +/*!40000 ALTER TABLE `alembic_version` DISABLE KEYS */; +INSERT INTO `alembic_version` VALUES ('6f7f8689fc98'); +/*!40000 ALTER TABLE `alembic_version` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `api_keys` +-- + +DROP TABLE IF EXISTS `api_keys`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `api_keys` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `key_hash` varchar(255) NOT NULL, + `key_prefix` varchar(20) NOT NULL, + `scopes` json NOT NULL, + `rate_limit` int NOT NULL, + `is_active` tinyint(1) NOT NULL, + `expires_at` datetime DEFAULT NULL, + `description` text, + `last_used_at` datetime DEFAULT NULL, + `created_by` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_api_keys_key_hash` (`key_hash`), + KEY `created_by` (`created_by`), + KEY `ix_api_keys_id` (`id`), + KEY `ix_api_keys_key_prefix` (`key_prefix`), + KEY `ix_api_keys_is_active` (`is_active`), + KEY `ix_api_keys_expires_at` (`expires_at`), + CONSTRAINT `api_keys_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `api_keys` +-- + +LOCK TABLES `api_keys` WRITE; +/*!40000 ALTER TABLE `api_keys` DISABLE KEYS */; +INSERT INTO `api_keys` VALUES (1,'test','a58b6f350f7ca9c9369f105fb04170664ca8e16924086c5e8e2f462faaf0c4c2','hb_lvbamOBa','[\"read:bookings\", \"read:payments\", \"read:invoices\", \"write:payments\"]',100,0,NULL,'tesy',NULL,3,'2025-11-30 22:58:20','2025-11-30 22:58:37'),(2,'test','f94ed753f5c255803e91261c98b11606386abef2a9b17513fbf5ac673ac52787','hb_KCZ1z8pa','[\"read:bookings\", \"read:payments\"]',100,0,NULL,'test',NULL,3,'2025-11-30 23:01:43','2025-12-01 01:56:56'); +/*!40000 ALTER TABLE `api_keys` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `approval_requests` +-- + +DROP TABLE IF EXISTS `approval_requests`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `approval_requests` ( + `id` int NOT NULL AUTO_INCREMENT, + `approval_type` enum('invoice_update','payment_refund','invoice_mark_paid','financial_adjustment','user_role_change','large_transaction') NOT NULL, + `status` enum('pending','approved','rejected','cancelled') NOT NULL, + `requested_by` int NOT NULL, + `requested_at` datetime NOT NULL, + `approved_by` int DEFAULT NULL, + `approved_at` datetime DEFAULT NULL, + `rejection_reason` text, + `resource_type` varchar(50) NOT NULL, + `resource_id` int NOT NULL, + `request_data` json DEFAULT NULL, + `current_data` json DEFAULT NULL, + `priority` varchar(20) DEFAULT NULL, + `notes` text, + `extra_metadata` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_approval_requests_id` (`id`), + KEY `ix_approval_requests_approval_type` (`approval_type`), + KEY `ix_approval_requests_status` (`status`), + KEY `ix_approval_requests_requested_by` (`requested_by`), + KEY `ix_approval_requests_approved_by` (`approved_by`), + KEY `ix_approval_requests_resource_type` (`resource_type`), + KEY `ix_approval_requests_resource_id` (`resource_id`), + CONSTRAINT `approval_requests_ibfk_1` FOREIGN KEY (`approved_by`) REFERENCES `users` (`id`), + CONSTRAINT `approval_requests_ibfk_2` FOREIGN KEY (`requested_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `approval_requests` +-- + +LOCK TABLES `approval_requests` WRITE; +/*!40000 ALTER TABLE `approval_requests` DISABLE KEYS */; +/*!40000 ALTER TABLE `approval_requests` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `audit_logs` +-- + +DROP TABLE IF EXISTS `audit_logs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `audit_logs` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int DEFAULT NULL, + `action` varchar(100) NOT NULL, + `resource_type` varchar(50) NOT NULL, + `resource_id` int DEFAULT NULL, + `ip_address` varchar(45) DEFAULT NULL, + `user_agent` varchar(255) DEFAULT NULL, + `request_id` varchar(36) DEFAULT NULL, + `details` json DEFAULT NULL, + `status` varchar(20) NOT NULL, + `error_message` text, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_audit_logs_id` (`id`), + KEY `ix_audit_logs_action` (`action`), + KEY `ix_audit_logs_request_id` (`request_id`), + KEY `ix_audit_logs_resource_type` (`resource_type`), + KEY `ix_audit_logs_user_id` (`user_id`), + KEY `ix_audit_logs_resource_id` (`resource_id`), + KEY `ix_audit_logs_created_at` (`created_at`), + CONSTRAINT `audit_logs_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=216 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `audit_logs` +-- + +LOCK TABLES `audit_logs` WRITE; +/*!40000 ALTER TABLE `audit_logs` DISABLE KEYS */; +INSERT INTO `audit_logs` VALUES (1,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','60446f23-d9d1-4dae-98d1-9869e08dca20','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 00:29:40'),(2,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','810794fa-0fab-4888-8707-9a7632bff1b8','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-28 10:35:43'),(3,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','a9aec281-d143-4081-a358-101db86eba48','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 10:36:05'),(4,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','707a3479-9a06-4d8a-a726-d80b0e43a759','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-11-28 10:43:19'),(5,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e52ea797-d749-4341-819e-fa556af5c09a','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 10:43:23'),(6,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','372d6505-7fbd-49d0-af88-4858626f3b57','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-28 10:49:50'),(7,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ae178583-a54f-4eed-9f29-9ab8822c88d9','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 10:53:28'),(8,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','0766faed-7e32-4d2f-baf9-69b4d9875af4','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-28 10:54:59'),(9,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','f4cbc32b-f2cb-4aca-bc67-85844f2b3792','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 15:33:27'),(10,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','30be2865-65d4-48e6-a54b-6f86ac61520a','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-28 16:16:43'),(11,NULL,'login_failed','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','17fdac96-e71f-4a4e-b9cb-e3007125dde3','{\"email\": \"admin@gnxsoft.com\"}','failed','Invalid email or password. 4 attempt(s) remaining before account lockout.','2025-11-28 17:47:03'),(12,NULL,'login_failed','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','dc8fb82c-2e56-4b09-9d6b-879c2aa3912b','{\"email\": \"admin@gnxsoft.com\"}','failed','Invalid email or password. 3 attempt(s) remaining before account lockout.','2025-11-28 17:47:11'),(13,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','5a2f9255-4fab-45f9-9dbc-7b910fb38966','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 17:47:53'),(14,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','42d0086e-0b44-40cf-b9d7-7d4fb2d07476','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-28 17:56:13'),(15,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','1d2798fb-e343-49ac-bbed-d04aa39efc50','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 21:16:46'),(16,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e2f03185-961b-4b1d-a87d-b3db23d21bed','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-28 21:22:21'),(17,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','5e0e3d5c-d7bf-44c9-bce7-dada7a0826c8','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 21:34:04'),(18,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','197830f5-cf07-4344-9eaf-533de0f2bbb3','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 21:36:25'),(19,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','3dba6466-802d-4a2f-a326-3963dfbc4171','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 21:39:42'),(20,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ebfbc608-6b77-4f24-b209-67b7fa0477bc','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 21:41:27'),(21,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','3d8672c3-d648-44ed-81a9-23d8c3260cfd','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-28 21:47:17'),(22,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','2b3139ea-7d8e-4441-8e8f-f7adf7f11b51','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 21:47:21'),(23,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','51c23a30-adc0-4b36-97d5-40db32cc31a7','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 21:48:13'),(24,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','6b27ba1e-911a-47db-a2b4-e316fad5aa1e','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-11-28 21:48:33'),(25,12,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','6f775c4f-8edb-42dd-bc19-b995a49e5c8d','{\"email\": \"anna@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 21:48:40'),(26,12,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','1b880eca-90ed-4ea6-acbe-43f47cd993ff','{\"email\": \"anna@gnxsoft.com\"}','success',NULL,'2025-11-28 21:48:56'),(27,4,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','aed1e481-fc7e-4dec-a7d7-8ecffa83ada4','{\"email\": \"staff@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 21:49:04'),(28,4,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','86243b9c-abb1-4282-ae60-65379483247b','{\"email\": \"staff@gnxsoft.com\"}','success',NULL,'2025-11-28 21:50:44'),(29,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','35fe5c3c-f55c-4e90-8b3c-08d5b6abde3c','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 22:02:52'),(30,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','20f6cf9f-8974-4042-b0cf-a07ce8ddca25','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-28 22:17:56'),(31,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e662b313-2ccb-446d-8988-4649de436295','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 22:22:27'),(32,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','8fb9d7e1-f640-42ef-9ebb-517ffe8b15ed','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-28 23:02:01'),(33,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','3e60c58f-19a1-4e2e-bc83-20d9c5db5242','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-29 12:56:33'),(34,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','4980ea46-410c-4e3e-96a5-66ff076cba08','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-29 13:31:58'),(35,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','87769d70-6197-4b8e-a68f-e61374d264c9','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-29 13:37:23'),(36,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','d317fd8a-b7ef-44de-9dc2-01e52bdb99b6','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-29 13:42:31'),(37,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','9100b973-30f1-4260-b5f3-97d3521da6b3','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-29 13:44:37'),(38,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','dc9df44b-86a0-4bf9-839a-4a03ff17bba6','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-29 14:12:27'),(39,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','5b43b908-f327-4cc4-827d-778e7db84828','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-29 14:15:03'),(40,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','51b9839f-9573-4d34-8e32-000e3d40e190','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 16:56:49'),(41,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','f35deeab-e5fb-4b08-9067-365b41173cfb','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-30 17:06:44'),(42,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e08710ec-b9bf-46ba-91c1-a66c8dbdb2d8','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 17:12:35'),(43,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','86807d10-f045-4809-9200-70d790eca315','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-30 18:53:55'),(44,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','a6031493-3917-4776-b29f-6409c98c758e','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 18:54:03'),(45,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','b033c4a4-9f1c-4790-a8d9-e3c8ffea334d','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-11-30 18:54:58'),(46,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','b644e8f0-5f48-4892-87b4-8ac4e317dcec','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 18:55:06'),(47,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','6a99d6ac-5bea-4253-817a-eda02a8b2f9f','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-30 19:21:51'),(48,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','1b87da33-a1ad-499b-8bf8-20ce7a64c03d','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 19:21:59'),(49,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ed7544b0-7b6b-493a-9332-901b309aabcd','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-11-30 19:22:08'),(50,12,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','a6348c97-976b-4744-956b-64e4dad34d20','{\"email\": \"anna@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 19:22:12'),(51,12,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','f9d2013c-18a7-41d5-9b9b-93fb44a12ef5','{\"email\": \"anna@gnxsoft.com\"}','success',NULL,'2025-11-30 19:22:24'),(52,4,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','f0ef2f7e-6a61-4977-aba3-0a970bf3db8d','{\"email\": \"staff@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 19:22:28'),(53,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','aa5e1bf2-92cf-4fa3-9574-d530a336a6e5','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 19:29:45'),(54,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','b04ee80e-70a4-488c-b753-1439606638f2','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-30 20:18:51'),(55,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','c27716a9-df23-4e85-948d-022b07b6d7bc','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 20:18:58'),(56,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','f84f6942-4e3f-4b8e-ba2b-cdbaf3dd0602','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-30 20:29:28'),(57,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','81a1a592-4345-4fdc-9e51-9f84c91a53c5','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 20:40:22'),(58,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ef3292d4-fe69-49cc-8b0b-e936e09c61c8','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 20:40:27'),(59,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','69922c59-d0f3-4471-9074-48c8815beb90','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-30 20:48:20'),(60,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','9c4d6a6c-d3ef-4afa-833f-938503651b36','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 20:48:26'),(61,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','84432dd1-1533-421e-a0a6-13cfccb03b17','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-30 20:54:58'),(62,12,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','27c2568e-7df7-4e8e-a0a2-ac7d156ecfac','{\"email\": \"anna@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 20:55:10'),(63,12,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','75ae7972-0bfd-430b-9642-914352c6995e','{\"email\": \"anna@gnxsoft.com\"}','success',NULL,'2025-11-30 20:57:04'),(64,4,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','077d06c3-c89c-4c9c-916a-9b60d23cd068','{\"email\": \"staff@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 20:57:11'),(65,4,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','4d97bea9-d5b2-4004-84ee-10e826c480ca','{\"email\": \"staff@gnxsoft.com\"}','success',NULL,'2025-11-30 21:04:59'),(66,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','dd1a3301-5e1e-4bb4-811e-ea8d3d614ab2','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 21:11:45'),(67,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ae4ba52d-19b1-493b-b370-b3d3cc0eb7bf','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-30 21:12:19'),(68,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','edf27a58-af38-41b0-b838-111d2d124389','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 21:12:25'),(69,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','36fa33cd-9eae-461a-9a01-00ee7f9a297d','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-11-30 21:17:23'),(70,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','94ff2f05-3db6-4445-b6e6-3f4fb05598b1','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 21:17:28'),(71,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','0cc2d946-70ed-43e7-8c1c-0aa9c6efb141','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-30 21:21:16'),(72,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','988209f8-2b70-4f6b-9706-1f5ffb5e6425','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 21:21:23'),(73,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ab9add27-51b8-4807-9782-d1612d17f077','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-11-30 21:25:35'),(74,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','21ab7857-c88c-471f-95a0-e81789fbf51d','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 21:25:39'),(75,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','389a08d1-9484-4f17-89dd-adc21bf7f87f','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-30 21:26:14'),(76,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','7fb5c5c1-8f08-437c-866c-0a42f843dd78','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 21:26:51'),(77,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','fb942eb1-d197-481c-aab9-1dff001056d6','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-11-30 21:27:09'),(78,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e8acc0db-f515-4e9e-8531-2c341bb6c5da','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 21:28:12'),(79,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','2a426ad9-8d0c-4b15-934c-d308cd8a8336','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-11-30 21:28:33'),(80,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','1353d684-ac77-4199-81e8-630f5ad656a7','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 22:22:31'),(81,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','acd8db7c-96ac-4e7d-a8d6-b3e3aa72af31','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 22:38:45'),(82,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','6fb319f6-0ab9-4733-8d63-10551021260c','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 22:40:44'),(83,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','2daa3b4c-dcbf-4191-8d27-343530f3618a','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-30 22:44:12'),(84,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','84534b99-5327-4339-bfa3-29e9ed99c072','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 22:44:18'),(85,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','cb76f019-6a69-4da7-9f39-e96654b42f58','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-11-30 22:45:04'),(86,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','5e3fa678-3656-48c0-b047-80dd64529dd1','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 22:45:08'),(87,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','6c5c8051-6cf8-4cb2-bea1-4dda669bddcd','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-11-30 22:46:26'),(88,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e667b938-cdba-4ebf-bb43-b27285f40b6e','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 22:46:31'),(89,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','30381dd7-696a-4eee-8bf2-fff720a77a30','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-11-30 22:47:21'),(90,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','1c9b0545-853e-4890-888c-1a8d45b3b047','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-11-30 22:50:13'),(91,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','21c22c92-b758-4bc4-bbb5-389f8d722bcb','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 02:00:42'),(92,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','92cde05a-6fa6-4fd4-8966-2d2b8588f225','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:01:04'),(93,5,'gdpr_deletion_requested','gdpr_request',1,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0',NULL,'{\"request_type\": \"data_deletion\"}','success',NULL,'2025-12-01 02:01:41'),(94,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','559d80e0-1b15-4711-bf1e-03bcaf1c725c','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-12-01 02:02:44'),(95,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','d1dab7fc-f961-46d4-8289-0eaba9d71158','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:02:49'),(96,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','67f86a5d-2d68-4e82-a88e-882ad1c35f67','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 02:07:18'),(97,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','39eee30f-ed17-40c9-a800-d7f0353765d0','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:07:53'),(98,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','59fabd2e-9a8b-46b0-ab5c-080fc50032c5','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 02:08:06'),(99,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','b93e3cd9-69f9-441a-92eb-b5080711c0a0','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:08:10'),(100,5,'gdpr_deletion_requested','gdpr_request',2,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0',NULL,'{\"request_type\": \"data_deletion\"}','success',NULL,'2025-12-01 02:08:42'),(101,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','a7c072ed-9c8f-4eba-9f97-3a1b4ba8e3ba','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:14:38'),(102,5,'gdpr_deletion_requested','gdpr_request',3,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0',NULL,'{\"request_type\": \"data_deletion\"}','success',NULL,'2025-12-01 02:14:42'),(103,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','1ea85911-2fc4-4a53-91ca-1a7b2317cc64','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-12-01 02:15:35'),(104,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','2c2b555a-9835-416d-9634-e6ae2bc59371','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:24:15'),(105,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e155c1ec-5525-42e2-a5dd-85655b69b749','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-12-01 02:34:04'),(106,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','dc0dcc3c-14de-4d8e-a96b-441e3eb22bc9','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:34:09'),(107,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','4b5712f3-d7ef-4095-99ec-98a48f73862e','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 02:35:33'),(108,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','6dc7ba8c-8e35-4cb9-ba27-56104d8f5542','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:35:38'),(109,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','7e961e73-6d3a-4501-b8d5-ea3aee8614ef','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:36:56'),(110,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','edb67207-3dab-4511-a950-b4afffc00e29','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-12-01 02:37:18'),(111,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','88da33da-27fd-40f1-9cfa-3bda1003c7bd','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:39:17'),(112,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','cf2413cd-367e-401a-80cf-f0e96b892965','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-12-01 02:41:50'),(113,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e96248ae-c24a-4771-9d87-a8006373520c','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:42:51'),(114,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','f3d3a4e3-7698-4769-8310-b392ce62f207','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:44:02'),(115,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','989447b5-b452-4079-ab44-48d925b81fcd','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:44:34'),(116,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','711fd18e-8963-464e-bc20-179a9d0bb716','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:45:06'),(117,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','8641ed28-1ec8-437d-84be-3d632400f151','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:47:00'),(118,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','fbf93a87-cdc2-434f-b369-458965d0804d','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:47:27'),(119,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','3abd05e4-0e80-4c2b-852f-c50b9047a373','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-12-01 02:57:51'),(120,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','880fc65e-eab3-40d1-8885-181f0184a496','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 02:57:56'),(121,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','88d593e4-6065-47db-8c84-8e37268ddad4','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 03:06:55'),(122,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','9f1a40ce-5576-4073-98f9-70cfd5bf6b59','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 03:07:02'),(123,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','a7eefdb2-91bf-476c-8524-31dd1be4c80a','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-12-01 03:17:54'),(124,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','9e6b8821-20f8-4735-9db6-9b50aa7b9be9','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 03:17:59'),(125,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','6142e8ee-ff75-448d-893d-f8b54a7a3a7d','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 03:30:33'),(126,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','001074bc-f1de-401b-be19-b58fa9730445','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 03:38:10'),(127,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','d5223e51-ff64-44b0-a266-e832c5515744','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-12-01 03:53:09'),(128,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','cbe10e22-9db0-49c5-ab98-edc5e92ab756','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 04:19:29'),(129,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','28682781-890b-4712-ab9b-fc305a49d14c','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 04:54:06'),(130,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e865bd2f-cc13-41cc-a9bc-35e49f61497f','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 05:16:26'),(131,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','dc9c1803-df4c-43b1-871d-fcf77fbeb346','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 05:18:54'),(132,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','dde5538e-560f-4741-8fdb-3d76eb6cc2ea','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 05:22:34'),(133,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','cafc4633-897e-493a-a210-2fd955e9c3c7','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 11:43:48'),(134,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','41314497-a576-418c-b8d4-284704d2e8f3','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 11:47:44'),(135,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ef96ab07-73bd-4b73-a67a-46ffee31f6d0','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 11:48:43'),(136,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','647f046a-2c9b-4752-83ff-c67e35240eba','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 11:49:46'),(137,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','5d8046b6-8563-4e9b-8857-c03fb1ac0f35','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 11:52:31'),(138,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','2933245d-e7b0-4435-8d06-71ea104ab4d4','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 12:31:59'),(139,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','9348de2e-6ae8-43c3-a341-c1da034ec2c6','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 12:37:22'),(140,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','bcf6b2f8-9342-44a2-9059-5aa345fc37e8','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 12:39:18'),(141,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ccf89be7-e467-4a2a-ad6c-89cf4b22fba1','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 13:10:50'),(142,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','72f4ed65-b264-4e7f-b734-866e7d13d6d0','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 13:12:24'),(143,NULL,'login_failed','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','1ae3d3d3-a17f-42e6-a6a2-116b6f32ff4d','{\"email\": \"housekeeping@gnxsoft.com\"}','failed','Invalid email or password. 4 attempt(s) remaining before account lockout.','2025-12-01 13:12:31'),(144,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','94f126d0-cded-46ed-92b3-ccddc8f1167e','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 13:12:44'),(145,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','8e53d3e1-bba6-4b03-b6ac-b39642bab8ce','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-01 13:14:59'),(146,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','bd0e11ea-f319-4c0d-85b5-5a9814203a58','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 13:15:04'),(147,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','76830a63-61b2-465c-a836-8485c3160deb','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-01 13:16:44'),(148,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','35509f94-2ef5-4a29-9c86-8803a1e008c6','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 13:16:48'),(149,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','5323cc78-1d83-4f30-b134-9be60508c338','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-01 13:17:46'),(150,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','1076b30f-42d9-4ee7-9124-84b9aac3b955','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 13:18:01'),(151,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e23023ec-dc83-4b74-89dc-5707e7836a34','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 13:22:08'),(152,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','499ce4ad-cb79-46cc-9e3e-32fd1821883d','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 13:22:18'),(153,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','7a7da5e5-11c7-4341-ae4b-d70f40e4939f','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-01 13:27:24'),(154,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','06cbb9b4-ff22-4578-b75b-6ce9077d2529','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 13:27:29'),(155,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','7715e653-8a66-489d-bbd2-b94dd2bf3d50','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 18:16:04'),(156,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','3cd5c171-9858-45ea-9a35-8e12ea15a3fe','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 18:47:56'),(157,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','fc03096a-ae06-4ecb-8ddf-7a8216c7b564','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-01 18:48:44'),(158,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','9c52654d-f668-4275-85c9-9055fbff8357','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 18:56:20'),(159,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','fd4c5d48-7ce0-471e-bfea-ff7506530158','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 18:56:20'),(160,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','356953ca-a0d4-470f-b17d-616cf2d6470e','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 18:56:53'),(161,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','a4bbdde5-a17e-4ccc-9690-7079d9e441dd','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 18:57:02'),(162,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','35e11e72-5070-4d65-9d62-5543f022d4a7','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 20:18:42'),(163,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','b17f3eee-fc9a-43d4-a186-e81e78d1c808','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 20:18:42'),(164,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ac819748-be9f-4c67-99a5-7f18cc55df55','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 20:21:22'),(165,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','df34a6c8-765c-426d-96fa-f758081ac084','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-01 20:21:31'),(166,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','b0755b90-f96b-4b59-ba13-2cac1f711cad','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 20:21:56'),(167,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','074ce39b-8038-4238-afec-653c4b9eecfd','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 20:21:56'),(168,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','2e9dab73-4e3c-45df-bff7-c53414f37e62','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 20:23:24'),(169,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e730f283-07b1-471c-b79d-918851d3381d','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 20:23:24'),(170,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','a0c7e7e4-7749-416e-8ff1-1a7a660f9026','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 20:25:08'),(171,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','b9ca0b68-9bd2-4184-86d1-ed40570a0333','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-01 20:25:08'),(172,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','2bf50636-4e82-429f-b348-c080c65652c8','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 20:25:28'),(173,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','3cebdde4-eb83-4cf2-a80e-79219f72ee2b','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-01 20:25:28'),(174,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','98e3701e-0568-4243-8db5-71133de56cfa','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 20:25:39'),(175,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','daa3f59c-046f-4e23-8ee9-ba447bae7930','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-01 20:25:39'),(176,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','67aa8e9b-71fa-40bf-a69d-d5d6f8312fae','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 20:25:50'),(177,5,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','7e60c218-2445-4283-a987-cfbcffe5e1cd','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-01 21:24:21'),(178,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','fe96c995-386b-4ede-af86-81fc831d3ab9','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-12-01 21:27:49'),(179,NULL,'login_failed','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','3623d24a-bf0e-427a-902d-45d2bcc8c755','{\"email\": \"admin@gnxsoft.com\"}','failed','This login endpoint is only for customer users','2025-12-01 21:29:25'),(180,NULL,'login_failed','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','83ea97a6-cac3-44af-8c8e-973ad024c518','{\"email\": \"anna@gnxsoft.com\"}','failed','This login endpoint is only for admin users','2025-12-01 21:29:43'),(181,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','df0e5077-b4fd-46da-ae33-96565fea80c3','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 05:54:57'),(182,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','96a38cef-72d0-4654-a64b-7e21fc249914','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 06:06:31'),(183,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','2316385e-19df-4271-90f3-a644546d3434','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 06:37:07'),(184,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e1059776-e4a6-43c3-9430-1479a7fac7be','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 06:38:07'),(185,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','8f1d0eab-ff33-464e-88b8-3edea77d09fa','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 06:52:28'),(186,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','973cc30c-fe7f-4704-a11c-6b1dd911938d','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 07:22:50'),(187,NULL,'login_failed','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','6574c117-e57a-43e1-b72d-5081085589d5','{\"email\": \"admin@gnxsoft.com\"}','failed','This login endpoint is only for customer users','2025-12-02 07:35:42'),(188,NULL,'login_failed','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','4363a9c3-3c82-47ec-a8ad-1f8379135586','{\"email\": \"admin@gnxsoft.com\"}','failed','This login endpoint is only for customer users','2025-12-02 07:35:48'),(189,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','652067c6-3ef0-4d5d-b4ba-237f9cbe07a7','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 07:35:56'),(190,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ba8353a8-2e49-464f-b04b-95cf56ef2a85','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 07:48:45'),(191,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e6345479-18cb-4ce4-b57f-e468c29e5ab6','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 08:13:14'),(192,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','de05098e-9fbd-4526-bc53-06f8efce6d59','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 08:33:06'),(193,NULL,'login_failed','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','cfe75798-e26b-4b70-b3a5-e56d81a4ef4f','{\"email\": \"admin@gnxsoft.com\"}','failed','This login endpoint is only for customer users','2025-12-02 15:34:53'),(194,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','f86dcdcc-8bce-4a2e-898d-6d64bdb32dba','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 15:35:03'),(195,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','86893199-0437-446c-9264-5bf137d0492f','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 15:38:06'),(196,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','7001c1b6-ae6b-4180-b185-6023d3df5e2c','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 15:42:38'),(197,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','15c698c2-ce8d-4970-b09f-1aaf9fa9f37c','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 15:47:34'),(198,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','39cf8057-f7b5-49df-8b43-fb81559a23a7','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 22:48:51'),(199,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','caaa9d25-2c04-4f39-a7ce-9ad77ec3f691','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 22:49:32'),(200,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','fecf5571-7e16-4554-92b0-e9c1515a3377','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-02 22:56:41'),(201,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','135479ea-8d9e-4d49-accd-8923ad3f6504','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 22:56:50'),(202,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','b6fbd50f-e6fb-4ee3-a45a-aed5d650a3f3','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 22:59:14'),(203,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','cafba4dc-564a-4033-bfdd-d2b2e363aef7','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 23:07:37'),(204,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','6ac8970e-334c-43e3-828f-e0221146310c','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 23:10:07'),(205,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','2d34b828-1d25-4fc3-bf72-492e6027fc5a','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-02 23:10:18'),(206,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','af7fd373-95ce-44ed-8257-1f09ce4d0af2','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 23:10:33'),(207,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','d25bc9ec-726b-40ae-abbd-b098d6a66b0d','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 23:18:44'),(208,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','584e4994-d352-4c24-b8a1-d776689a3689','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-02 23:19:05'),(209,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','8b862103-d2fd-4be0-a1c3-6f6ce568ea92','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 23:19:14'),(210,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','103c0338-08cc-445f-b2b3-79fa9ff44e73','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-02 23:20:01'),(211,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','bfd726ab-744f-45d4-bff6-838225febc2f','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 23:20:44'),(212,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','4be58972-9a91-4ff5-bb12-7b06bac31b7d','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-02 23:21:03'),(213,13,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ac64f62d-ab1c-4b52-9117-6fd70d6eb599','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 23:21:18'),(214,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','b893baaf-ad15-4193-9b11-a44343a38699','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-02 23:23:35'),(215,3,'login_success','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','8bd6ab98-8313-4654-ac0a-7fd28f79c0ac','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-02 23:23:46'); +/*!40000 ALTER TABLE `audit_logs` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `banners` +-- + +DROP TABLE IF EXISTS `banners`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `banners` ( + `id` int NOT NULL AUTO_INCREMENT, + `title` varchar(100) NOT NULL, + `description` text, + `image_url` varchar(255) NOT NULL, + `link_url` varchar(255) DEFAULT NULL, + `position` varchar(50) NOT NULL, + `display_order` int NOT NULL, + `is_active` tinyint(1) NOT NULL, + `start_date` datetime DEFAULT NULL, + `end_date` datetime DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_banners_id` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `banners` +-- + +LOCK TABLES `banners` WRITE; +/*!40000 ALTER TABLE `banners` DISABLE KEYS */; +INSERT INTO `banners` VALUES (1,'Welcome to Unparalleled Luxury','Where timeless elegance meets modern sophistication. Experience the pinnacle of hospitality in our award-winning luxury hotel.','https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1920','/rooms','home',1,1,'2025-10-22 12:24:07','2026-11-21 12:24:07','2025-11-21 12:24:07','2025-11-21 12:24:07'),(2,'Exclusive Presidential Suites','Indulge in our most opulent accommodations. Spacious suites with panoramic views, private terraces, and personalized butler service.','https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1920','/rooms','home',2,1,'2025-11-14 12:24:07','2026-11-21 12:24:07','2025-11-21 12:24:07','2025-11-21 12:24:07'),(3,'World-Class Spa & Wellness','Rejuvenate your mind, body, and soul. Our award-winning spa offers bespoke treatments using the finest luxury products.','https://images.unsplash.com/photo-1544161515-4ab6ce6db874?w=1920','/services','home',3,1,'2025-11-20 12:24:07','2026-11-21 12:24:07','2025-11-21 12:24:07','2025-11-21 12:24:07'),(4,'Michelin-Starred Culinary Excellence','Savor extraordinary flavors crafted by world-renowned chefs. Our fine dining restaurants offer an unforgettable gastronomic journey.','https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?w=1920','/services','home',4,1,'2025-11-21 12:24:07','2026-11-21 12:24:07','2025-11-21 12:24:07','2025-11-21 12:24:07'),(5,'Private Yacht & Exclusive Experiences','Create unforgettable memories with our curated luxury experiences. From private yacht charters to exclusive cultural tours.','https://images.unsplash.com/photo-1544551763-46a013bb70d5?w=1920','/services','home',5,1,'2025-11-06 12:24:07','2026-11-21 12:24:07','2025-11-21 12:24:07','2025-11-21 12:24:07'); +/*!40000 ALTER TABLE `banners` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `blog_posts` +-- + +DROP TABLE IF EXISTS `blog_posts`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `blog_posts` ( + `id` int NOT NULL AUTO_INCREMENT, + `title` varchar(500) NOT NULL, + `slug` varchar(500) NOT NULL, + `excerpt` text, + `content` text NOT NULL, + `featured_image` varchar(1000) DEFAULT NULL, + `author_id` int NOT NULL, + `published_at` datetime DEFAULT NULL, + `is_published` tinyint(1) NOT NULL, + `tags` text, + `meta_title` varchar(500) DEFAULT NULL, + `meta_description` text, + `meta_keywords` varchar(1000) DEFAULT NULL, + `views_count` int NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `sections` json DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_blog_posts_slug` (`slug`), + KEY `ix_blog_posts_id` (`id`), + KEY `ix_blog_posts_published_at` (`published_at`), + KEY `ix_blog_posts_is_published` (`is_published`), + KEY `ix_blog_posts_title` (`title`), + KEY `ix_blog_posts_author_id` (`author_id`), + CONSTRAINT `blog_posts_ibfk_1` FOREIGN KEY (`author_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `blog_posts` +-- + +LOCK TABLES `blog_posts` WRITE; +/*!40000 ALTER TABLE `blog_posts` DISABLE KEYS */; +INSERT INTO `blog_posts` VALUES (1,'10 Essential Tips for a Perfect Hotel Stay','10-essential-tips-perfect-hotel-stay','Discover insider secrets to make your hotel experience unforgettable. From booking strategies to room selection, we share expert tips.','\n
Planning a hotel stay? Whether you\'re traveling for business or pleasure, these essential tips will help you make the most of your experience.
\n \nBooking directly with the hotel often provides better rates, room upgrades, and exclusive perks. Plus, you\'ll have direct communication with the property.
\n \nMost hotels offer loyalty programs that provide points, discounts, and special benefits. Sign up before your stay to start earning rewards.
\n \nWhether you need a late checkout, extra pillows, or have dietary restrictions, communicate your needs when booking or at least 24 hours before arrival.
\n \nMany hotels now offer online check-in, saving you time at the front desk. You can often select your room and receive your key digitally.
\n \nTake advantage of hotel amenities like the spa, fitness center, pool, and restaurants. These are often included in your stay or available at discounted rates.
\n \nA friendly attitude goes a long way. Hotel staff are more likely to help with special requests or upgrades if you\'re courteous and respectful.
\n \nThe concierge can provide local recommendations, make reservations, and help with transportation. They\'re a valuable resource for making your stay memorable.
\n \nBefore checking out, review your bill carefully. Check for any unexpected charges and ensure all services match what you received.
\n \nShare your experience by leaving a review. This helps future guests and provides valuable feedback to the hotel.
\n \nFollow the hotel on social media for special offers, events, and updates. You might discover exclusive deals or experiences.
\n \nBy following these tips, you\'ll enhance your hotel stay and create lasting memories. Remember, a great hotel experience is about more than just a comfortable bed—it\'s about the entire journey.
\n ','https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200&h=800&fit=crop',1,'2025-09-19 22:50:03',1,'[\"Travel Tips\", \"Hotel Guide\", \"Hospitality\"]','10 Essential Tips for a Perfect Hotel Stay | Luxury Hotel Blog','Discover expert tips for making your hotel stay unforgettable. From booking strategies to maximizing amenities, learn how to get the most from your hotel experience.','hotel tips, travel guide, hotel stay, hospitality, travel advice',0,'2025-11-28 22:28:27','2025-11-28 22:50:03',NULL),(2,'The Art of Luxury Hospitality: What Sets Premium Hotels Apart','art-of-luxury-hospitality-premium-hotels','Explore the defining characteristics of luxury hotels and what makes them stand out in the hospitality industry.','\nLuxury hospitality is an art form that goes beyond beautiful decor and premium amenities. It\'s about creating unforgettable experiences that touch every aspect of a guest\'s journey.
\n \nTrue luxury hotels excel at personalization. From remembering guest preferences to anticipating needs, personalized service creates a sense of being truly valued.
\n \nEvery element matters in luxury hospitality. From the thread count of sheets to the temperature of the pool, attention to detail ensures perfection at every turn.
\n \nLuxury hotels are architectural and design masterpieces. They blend local culture with contemporary elegance, creating spaces that inspire and delight.
\n \nFine dining is a cornerstone of luxury hospitality. Award-winning restaurants, celebrity chefs, and exceptional culinary experiences define premium hotels.
\n \nFrom private butlers to exclusive spa treatments, luxury hotels offer amenities that go beyond the ordinary, creating unique and memorable experiences.
\n \nLuxury hospitality is about creating moments that guests will remember forever. It\'s the combination of exceptional service, attention to detail, and genuine care that sets premium hotels apart.
\n ','https://images.unsplash.com/photo-1551882547-ff40c63fe5fa?w=1200&h=800&fit=crop',1,'2025-09-29 22:50:03',1,'[\"Luxury\", \"Hospitality\", \"Premium\"]','The Art of Luxury Hospitality | Premium Hotel Features','Discover what makes luxury hotels exceptional. Learn about personalized service, attention to detail, and the elements that define premium hospitality.','luxury hotels, premium hospitality, luxury travel, hotel design, fine dining',1,'2025-11-28 22:28:27','2025-11-28 23:11:22',NULL),(3,'Sustainable Tourism: How Hotels Are Going Green','sustainable-tourism-hotels-going-green','Learn how modern hotels are implementing sustainable practices to protect the environment while providing exceptional guest experiences.','\nSustainable tourism is no longer a trend—it\'s a necessity. Hotels worldwide are implementing eco-friendly practices to reduce their environmental impact while maintaining luxury standards.
\n \nModern hotels are investing in renewable energy, LED lighting, and smart systems that reduce energy consumption without compromising guest comfort.
\n \nFrom low-flow fixtures to water recycling systems, hotels are finding innovative ways to conserve water while maintaining the luxury experience guests expect.
\n \nComprehensive recycling programs, composting, and reducing single-use plastics are becoming standard practices in environmentally conscious hotels.
\n \nSupporting local communities through sourcing local products, hiring local staff, and preserving local culture benefits both the environment and the community.
\n \nMany hotels are pursuing green certifications like LEED and Green Key, demonstrating their commitment to sustainability and environmental responsibility.
\n \nHotels are educating guests about sustainable practices, encouraging participation in conservation efforts, and making it easy to make eco-friendly choices.
\n \nSustainable tourism is the future of hospitality. By choosing eco-friendly hotels, guests can enjoy luxury experiences while supporting environmental conservation.
\n ','https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?w=1200&h=800&fit=crop',1,'2025-09-27 22:50:03',1,'[\"Sustainability\", \"Eco-Friendly\", \"Green Travel\"]','Sustainable Tourism: How Hotels Are Going Green','Discover how hotels are implementing sustainable practices to protect the environment while providing exceptional guest experiences.','sustainable tourism, eco-friendly hotels, green travel, environmental conservation, sustainable hospitality',7,'2025-11-28 22:28:27','2025-11-29 12:56:47',NULL),(4,'The Ultimate Guide to Hotel Room Types','ultimate-guide-hotel-room-types','Navigate the world of hotel accommodations with our comprehensive guide to different room types and what to expect from each.','\nUnderstanding hotel room types can help you choose the perfect accommodation for your needs and budget. Here\'s your guide to navigating hotel room categories.
\n \nStandard rooms are the most basic accommodation, typically featuring a bed, bathroom, and essential amenities. Perfect for short stays or budget-conscious travelers.
\n \nDeluxe rooms offer more space and upgraded amenities. They often feature better views, larger bathrooms, and additional seating areas.
\n \nSuites provide separate living and sleeping areas, making them ideal for longer stays or guests who need extra space for work or relaxation.
\n \nThe pinnacle of hotel accommodations, presidential suites offer multiple rooms, premium amenities, and often include butler service and exclusive access.
\n \nMany hotels offer specialty rooms like honeymoon suites, family rooms, or themed accommodations designed for specific guest needs or occasions.
\n \nConsider your needs: space requirements, view preferences, length of stay, and budget. Don\'t hesitate to contact the hotel directly for recommendations.
\n \nUnderstanding room types helps you make informed decisions and ensures you get the accommodation that best suits your travel needs and preferences.
\n ','https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop',1,'2025-09-25 22:50:03',1,'[\"Hotel Guide\", \"Accommodation\", \"Travel Tips\"]','The Ultimate Guide to Hotel Room Types | Choose Your Perfect Room','Learn about different hotel room types and find the perfect accommodation for your needs. From standard rooms to presidential suites, we cover it all.','hotel rooms, room types, hotel accommodation, suites, travel guide',0,'2025-11-28 22:28:27','2025-11-28 22:50:03',NULL),(5,'Wellness Tourism: Hotels as Health and Wellness Destinations','wellness-tourism-hotels-health-destinations','Discover how hotels are transforming into wellness destinations, offering comprehensive health and wellness programs for modern travelers.','\nWellness tourism is one of the fastest-growing segments in travel. Hotels are responding by creating comprehensive wellness programs that address physical, mental, and spiritual well-being.
\n \nModern hotel spas offer more than massages. They provide holistic treatments, thermal experiences, and wellness consultations tailored to individual needs.
\n \nFrom fully equipped gyms to yoga studios and personal training, hotels are making it easy for guests to maintain their fitness routines while traveling.
\n \nWellness-focused hotels offer nutritious menus, dietary accommodations, and nutritionist consultations, making healthy eating effortless during your stay.
\n \nMany hotels now offer meditation spaces, mindfulness programs, and stress-reduction activities to help guests find balance and peace.
\n \nWellness hotels often provide access to nature, outdoor activities, and adventure experiences that promote physical activity and connection with the environment.
\n \nRecognizing the importance of rest, wellness hotels focus on sleep quality with premium bedding, blackout curtains, and sleep enhancement programs.
\n \nWellness tourism represents a shift toward holistic travel experiences. Hotels that embrace this trend are creating spaces where guests can truly rejuvenate and restore.
\n ','https://images.unsplash.com/photo-1544161515-4ab6ce6db874?w=1200&h=800&fit=crop',1,'2025-09-23 22:50:03',1,'[\"Wellness\", \"Health\", \"Spa\", \"Fitness\"]','Wellness Tourism: Hotels as Health and Wellness Destinations','Explore how hotels are becoming wellness destinations, offering comprehensive health and wellness programs for modern travelers seeking balance and rejuvenation.','wellness tourism, health travel, spa hotels, wellness retreats, fitness travel',2,'2025-11-28 22:28:27','2025-11-28 22:50:03',NULL),(6,'Technology in Modern Hotels: Enhancing the Guest Experience','technology-modern-hotels-enhancing-guest-experience','Explore how cutting-edge technology is revolutionizing the hotel industry and creating seamless, personalized guest experiences.','\nTechnology is transforming the hotel industry, making stays more convenient, personalized, and enjoyable. From mobile check-in to smart room controls, innovation is everywhere.
\n \nGuests can now check in via mobile apps and use their smartphones as room keys, eliminating wait times and providing instant access to their rooms.
\n \nVoice-activated assistants and smart controls allow guests to adjust lighting, temperature, and entertainment systems with simple commands or mobile apps.
\n \nAI-powered systems analyze guest preferences to provide personalized recommendations for dining, activities, and services, enhancing the overall experience.
\n \nFrom contactless payments to digital menus and virtual concierge services, hotels are reducing physical contact while maintaining high service standards.
\n \nSome hotels are using VR and AR to provide virtual tours, immersive experiences, and enhanced wayfinding, helping guests explore and navigate properties.
\n \nHotels use data analytics to understand guest behavior, optimize operations, and predict needs, ensuring every stay is better than the last.
\n \nTechnology in hotels is about enhancing human connection, not replacing it. The best hotels use technology to free up staff to provide more personalized, meaningful service.
\n ','https://images.unsplash.com/photo-1517245386807-bb43f82c33c4?w=1200&h=800&fit=crop',1,'2025-09-21 22:50:03',1,'[\"Technology\", \"Innovation\", \"Smart Hotels\"]','Technology in Modern Hotels: Enhancing Guest Experience','Discover how cutting-edge technology is revolutionizing hotels, from mobile check-in to smart room controls and AI-powered personalization.','hotel technology, smart hotels, mobile check-in, hotel innovation, tech travel',0,'2025-11-28 22:28:27','2025-11-28 22:50:03',NULL),(7,'The Ultimate Guide to Hotel Amenities: What to Expect','ultimate-guide-hotel-amenities-what-to-expect','From spas to fitness centers, discover the essential amenities that make a hotel stay memorable and how to make the most of them.','\nModern hotels offer an impressive array of amenities designed to enhance your stay. Understanding what\'s available can help you choose the perfect hotel and maximize your experience.
\n \nLuxury hotels often feature world-class spas offering massages, facials, and holistic treatments. These facilities provide relaxation and rejuvenation during your stay.
\n \nState-of-the-art fitness centers with modern equipment allow you to maintain your workout routine while traveling. Many hotels also offer personal training and group classes.
\n \nFrom rooftop infinity pools to heated indoor pools, swimming facilities provide relaxation and recreation. Some hotels offer poolside service and cabanas for ultimate comfort.
\n \nFine dining restaurants, casual cafes, room service, and bars create diverse culinary experiences. Many hotels feature award-winning chefs and unique dining concepts.
\n \nBusiness centers, meeting rooms, and conference facilities cater to corporate travelers. High-speed internet and printing services ensure productivity.
\n \nProfessional concierge teams can arrange restaurant reservations, transportation, tickets, and local experiences, making your stay seamless and memorable.
\n \nHotel amenities significantly enhance your stay. Research available amenities when booking to ensure your hotel meets all your needs and preferences.
\n ','https://images.unsplash.com/photo-1540541338287-41700207dee6?w=1200&h=800&fit=crop',1,'2025-07-27 22:50:03',1,'[\"Amenities\", \"Hotel Guide\", \"Luxury\"]','The Ultimate Guide to Hotel Amenities | What to Expect','Discover essential hotel amenities from spas to fitness centers. Learn what to expect and how to make the most of your hotel stay.','hotel amenities, spa, fitness center, hotel facilities, luxury amenities',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(8,'Business Travel Tips: Making the Most of Your Hotel Stay','business-travel-tips-making-most-hotel-stay','Essential strategies for business travelers to maximize productivity, comfort, and efficiency during hotel stays.','\nBusiness travel requires efficiency and comfort. These tips will help you make the most of your hotel stay while maintaining productivity and well-being.
\n \nSelect hotels close to your meetings or with excellent transportation links. This saves time and reduces stress during your business trip.
\n \nTake advantage of business centers, meeting rooms, and high-speed internet. Many hotels offer complimentary business services for corporate guests.
\n \nUse hotel fitness centers to maintain your exercise routine. Regular workouts help manage stress and maintain energy levels during business trips.
\n \nRequest a quiet room away from elevators and high-traffic areas. Ensure your room has adequate workspace and lighting for productivity.
\n \nHotel concierges can handle restaurant reservations, transportation, and local recommendations, freeing your time for business matters.
\n \nBusiness travelers benefit significantly from hotel loyalty programs, earning points, upgrades, and exclusive perks that enhance every stay.
\n \nStrategic planning and utilizing hotel services can transform business travel from stressful to seamless, allowing you to focus on your work.
\n ','https://images.unsplash.com/photo-1497366216548-37526070297c?w=1200&h=800&fit=crop',1,'2025-07-29 22:50:03',1,'[\"Business Travel\", \"Travel Tips\", \"Productivity\"]','Business Travel Tips: Making the Most of Your Hotel Stay','Essential strategies for business travelers to maximize productivity and comfort during hotel stays. Tips for efficient business travel.','business travel, corporate travel, hotel business services, travel productivity, business tips',2,'2025-11-28 22:47:08','2025-11-28 22:53:05',NULL),(9,'Family-Friendly Hotels: What to Look For','family-friendly-hotels-what-to-look-for','Discover the essential features and amenities that make hotels perfect for families traveling with children.','\nTraveling with family requires special considerations. Family-friendly hotels offer amenities and services designed to make stays comfortable and enjoyable for all ages.
\n \nLook for hotels offering family rooms, suites, or connecting rooms. These provide space for everyone and often include extra beds or pull-out sofas.
\n \nChildren\'s programs, kids\' clubs, playgrounds, and game rooms keep young guests entertained. Some hotels offer babysitting services for parents\' peace of mind.
\n \nFamily-friendly hotels provide children\'s menus, flexible dining times, and room service options. Buffet breakfasts are particularly convenient for families.
\n \nSafety is paramount. Look for hotels with pool safety measures, childproofing options, and secure room access. Ground-floor rooms or rooms near elevators can be safer for families.
\n \nPools, game rooms, and outdoor spaces provide entertainment for children while allowing parents to relax. Some hotels offer family activities and events.
\n \nChoose hotels near family attractions, parks, or beaches. Easy access to activities reduces travel time and keeps children engaged.
\n \nFamily-friendly hotels create memorable experiences for all family members. Research and choose hotels that cater specifically to families for the best experience.
\n ','https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200&h=800&fit=crop',1,'2025-07-31 22:50:03',1,'[\"Family Travel\", \"Family Hotels\", \"Travel Tips\"]','Family-Friendly Hotels: What to Look For | Family Travel Guide','Discover essential features that make hotels perfect for families. Learn what to look for when booking family-friendly accommodations.','family hotels, family travel, kid-friendly hotels, family accommodations, travel with children',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(10,'Romantic Getaways: Choosing the Perfect Hotel','romantic-getaways-choosing-perfect-hotel','Create unforgettable romantic experiences with our guide to selecting hotels perfect for couples and special occasions.','\nRomantic getaways require special attention to detail. The right hotel can transform a trip into an unforgettable romantic experience.
\n \nLook for hotels with intimate atmospheres, private balconies, and romantic room designs. Boutique hotels often excel at creating romantic environments.
\n \nMany hotels offer romantic packages including champagne, flowers, couples\' spa treatments, and special dining experiences. These packages add magic to your stay.
\n \nHotels with stunning views, beachfront locations, or mountain settings create romantic backdrops. Sunsets and scenic vistas enhance the romantic atmosphere.
\n \nRomantic restaurants with candlelit dinners, private dining options, and exceptional cuisine create memorable experiences. Room service can also be romantic.
\n \nCouples\' spa treatments, private hot tubs, and wellness facilities provide relaxation and connection. Many hotels offer romantic spa packages.
\n \nPrivate villas, secluded rooms, and adults-only areas ensure privacy and intimacy. These features are essential for romantic getaways.
\n \nThe perfect romantic hotel combines beautiful settings, intimate atmosphere, and thoughtful amenities to create unforgettable moments for couples.
\n ','https://images.unsplash.com/photo-1520250497591-112f2f40a3f4?w=1200&h=800&fit=crop',1,'2025-08-02 22:50:03',1,'[\"Romantic\", \"Couples\", \"Getaways\"]','Romantic Getaways: Choosing the Perfect Hotel for Couples','Create unforgettable romantic experiences with our guide to selecting hotels perfect for couples and special occasions.','romantic hotels, couples travel, romantic getaways, honeymoon hotels, romantic destinations',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(11,'Hotel Booking Strategies: Getting the Best Deals','hotel-booking-strategies-getting-best-deals','Master the art of hotel booking with insider tips and strategies to secure the best rates and exclusive deals.','\nSmart booking strategies can save significant money while securing better rooms and amenities. Learn the secrets to getting the best hotel deals.
\n \nBooking directly with hotels often provides better rates, room upgrades, and exclusive perks not available through third-party sites.
\n \nFlexibility with travel dates can result in substantial savings. Mid-week stays and off-peak seasons typically offer better rates.
\n \nHotel loyalty programs provide points, discounts, and member-exclusive rates. Frequent travelers benefit significantly from these programs.
\n \nHotels often offer last-minute deals to fill empty rooms. If you\'re flexible, these can provide excellent value.
\n \nBundling hotel stays with flights or activities can result in savings. Compare package prices with individual bookings.
\n \nDon\'t hesitate to call hotels directly and negotiate rates, especially for longer stays or group bookings. Hotels often have flexibility.
\n \nStrategic booking approaches can significantly reduce costs while enhancing your hotel experience. Combine multiple strategies for maximum savings.
\n ','https://images.unsplash.com/photo-1559526324-4b87b5e36e44?w=1200&h=800&fit=crop',1,'2025-08-04 22:50:03',1,'[\"Booking Tips\", \"Travel Deals\", \"Savings\"]','Hotel Booking Strategies: Getting the Best Deals and Rates','Master hotel booking with insider tips to secure the best rates, exclusive deals, and room upgrades.','hotel deals, booking tips, hotel discounts, travel savings, best hotel rates',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(12,'The History of Luxury Hospitality','history-luxury-hospitality','Explore the evolution of luxury hospitality from ancient inns to modern five-star hotels and what defines true luxury.','\nLuxury hospitality has evolved dramatically over centuries, from simple inns to today\'s sophisticated five-star establishments. Understanding this history enriches our appreciation of modern luxury.
\n \nHospitality dates back to ancient civilizations where travelers found shelter in inns and guesthouses. These early establishments laid the foundation for modern hospitality.
\n \nThe 19th century saw the rise of grand hotels in Europe and America. These magnificent establishments set new standards for luxury, service, and architecture.
\n \nToday\'s luxury hotels combine traditional elegance with modern amenities, technology, and personalized service. The definition of luxury continues to evolve.
\n \nLegendary hotels like The Ritz, The Savoy, and The Plaza have become symbols of luxury hospitality, setting benchmarks for excellence worldwide.
\n \nModern luxury emphasizes experiences, sustainability, wellness, and personalization. Hotels adapt to changing guest expectations while maintaining timeless elegance.
\n \nThe history of luxury hospitality reflects our evolving understanding of comfort, service, and elegance. Today\'s luxury hotels honor tradition while embracing innovation.
\n ','https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200&h=800&fit=crop',1,'2025-08-06 22:50:03',1,'[\"History\", \"Luxury\", \"Hospitality\"]','The History of Luxury Hospitality: From Ancient Inns to Modern Hotels','Explore the evolution of luxury hospitality from ancient inns to modern five-star hotels and what defines true luxury.','hotel history, luxury hospitality history, grand hotels, hospitality evolution, luxury travel history',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(13,'Hotel Etiquette: Do\'s and Don\'ts for Guests','hotel-etiquette-dos-donts-guests','Master proper hotel etiquette to ensure a pleasant stay for yourself and other guests while respecting hotel staff and property.','\nProper hotel etiquette ensures pleasant experiences for everyone. Understanding expected behavior helps create positive interactions with staff and fellow guests.
\n \nArrive on time for check-in and respect check-out times. Be patient and courteous with front desk staff, especially during busy periods.
\n \nKeep noise levels reasonable, especially during quiet hours. Respect room capacity limits and treat hotel property with care.
\n \nTreat all hotel staff with respect and kindness. A friendly attitude often results in better service and assistance with special requests.
\n \nRespect shared spaces like lobbies, pools, and restaurants. Follow dress codes, keep areas clean, and be mindful of other guests.
\n \nTip housekeeping, bellhops, and concierge staff appropriately. Tipping shows appreciation for good service and is standard practice.
\n \nMake special requests in advance when possible. Be reasonable and understanding if requests cannot be accommodated.
\n \nGood hotel etiquette creates positive experiences for everyone. Simple courtesy and respect go a long way in ensuring pleasant stays.
\n ','https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=1200&h=800&fit=crop',1,'2025-08-08 22:50:03',1,'[\"Etiquette\", \"Travel Tips\", \"Guest Guide\"]','Hotel Etiquette: Do\'s and Don\'ts for Hotel Guests','Master proper hotel etiquette to ensure pleasant stays. Learn do\'s and don\'ts for interacting with staff and other guests.','hotel etiquette, guest etiquette, travel etiquette, hotel manners, guest behavior',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(14,'Boutique Hotels vs. Chain Hotels: Which is Right for You?','boutique-hotels-vs-chain-hotels-which-right-for-you','Compare boutique and chain hotels to determine which type best suits your travel style, preferences, and needs.','\nChoosing between boutique and chain hotels depends on your preferences, travel style, and priorities. Each offers distinct advantages.
\n \nBoutique hotels offer unique character, personalized service, and distinctive design. They provide intimate experiences and local flavor, perfect for travelers seeking authenticity.
\n \nChain hotels provide consistency, loyalty programs, and predictable experiences. They\'re ideal for business travelers and those who value reliability and familiarity.
\n \nBoutique hotels excel in personalized, attentive service, while chains offer standardized, efficient service. Choose based on your preference for customization vs. consistency.
\n \nChain hotels typically offer extensive amenities and facilities, while boutiques focus on curated, high-quality experiences. Consider what matters most to you.
\n \nBoutique hotels often feature unique, locally-inspired designs in interesting neighborhoods. Chains provide familiar layouts in convenient, predictable locations.
\n \nBoth can offer excellent value. Boutiques provide unique experiences, while chains offer loyalty rewards and package deals. Compare based on total value, not just price.
\n \nThe best choice depends on your priorities. Boutiques offer uniqueness and character, while chains provide consistency and rewards. Consider your travel style and needs.
\n ','https://images.unsplash.com/photo-1551882547-ff40c63fe5fa?w=1200&h=800&fit=crop',1,'2025-08-10 22:50:03',1,'[\"Hotel Types\", \"Travel Guide\", \"Comparison\"]','Boutique Hotels vs. Chain Hotels: Which is Right for You?','Compare boutique and chain hotels to determine which type best suits your travel style, preferences, and needs.','boutique hotels, chain hotels, hotel comparison, hotel types, travel guide',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(15,'Accessibility in Hotels: Ensuring Comfortable Stays for All','accessibility-hotels-ensuring-comfortable-stays-all','Learn about hotel accessibility features and how to ensure comfortable, accessible stays for guests with disabilities.','\nAccessible hotels ensure comfortable stays for all guests. Understanding accessibility features helps travelers with disabilities find suitable accommodations.
\n \nAccessible rooms feature wider doorways, roll-in showers, grab bars, and lower fixtures. These rooms meet ADA standards and provide comfort and safety.
\n \nAccessible hotels provide ramps, elevators, and accessible paths throughout. Restaurants, pools, and facilities should be accessible to all guests.
\n \nHotels should offer visual alarms, TTY devices, and staff trained in sign language or communication assistance for guests with hearing impairments.
\n \nHotels must accommodate service animals. Understanding policies and communicating needs ensures smooth stays for guests with service animals.
\n \nWhen booking, specify accessibility needs clearly. Contact hotels directly to confirm specific features and ensure your requirements are met.
\n \nWell-trained staff understand accessibility needs and can assist effectively. Choose hotels known for excellent accessibility service.
\n \nAccessible hotels create inclusive experiences for all guests. Research and communicate needs to ensure comfortable, accessible stays.
\n ','https://images.unsplash.com/photo-1522771739844-6a9f6d5f14af?w=1200&h=800&fit=crop',1,'2025-08-12 22:50:03',1,'[\"Accessibility\", \"Inclusive Travel\", \"Guest Services\"]','Accessibility in Hotels: Ensuring Comfortable Stays for All Guests','Learn about hotel accessibility features and how to ensure comfortable, accessible stays for guests with disabilities.','accessible hotels, hotel accessibility, disability travel, accessible accommodations, inclusive travel',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(16,'Hotel Security: Staying Safe During Your Stay','hotel-security-staying-safe-during-stay','Essential security tips and practices to ensure your safety and protect your belongings during hotel stays.','\nHotel security is a shared responsibility between guests and hotels. Following security best practices ensures safe, worry-free stays.
\n \nAlways lock your room door and use deadbolts. Never leave doors propped open, and verify room numbers before entering. Use room safes for valuables.
\n \nUse in-room safes for passports, jewelry, and electronics. Don\'t leave valuables unattended in public areas. Consider hotel safety deposit boxes for important items.
\n \nProtect personal information. Be cautious with Wi-Fi networks, and avoid sharing room numbers publicly. Use secure payment methods.
\n \nBe aware of your surroundings in common areas. Use well-lit paths, and don\'t hesitate to ask hotel staff for assistance or security escorts.
\n \nFamiliarize yourself with emergency exits and procedures. Know the location of fire exits and emergency contact information.
\n \nIf something feels wrong, trust your instincts. Report suspicious activity to hotel security immediately. Your safety is the priority.
\n \nFollowing security best practices ensures safe hotel stays. Stay vigilant, use available security features, and communicate concerns to hotel staff.
\n ','https://images.unsplash.com/photo-1557804506-669a67965ba0?w=1200&h=800&fit=crop',1,'2025-08-14 22:50:03',1,'[\"Security\", \"Safety\", \"Travel Tips\"]','Hotel Security: Staying Safe During Your Stay | Safety Tips','Essential security tips and practices to ensure your safety and protect your belongings during hotel stays.','hotel security, travel safety, hotel safety tips, guest security, travel security',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(17,'Pet-Friendly Hotels: Traveling with Your Furry Friends','pet-friendly-hotels-traveling-furry-friends','Discover how to find and enjoy pet-friendly hotels that welcome your four-legged companions with open arms.','\nTraveling with pets requires special planning. Pet-friendly hotels make it possible to bring your furry friends along, ensuring everyone enjoys the trip.
\n \nResearch hotels that explicitly welcome pets. Check policies regarding size limits, breed restrictions, and number of pets allowed per room.
\n \nMany pet-friendly hotels offer special amenities like pet beds, bowls, treats, and walking services. Some even have pet spas and play areas.
\n \nUnderstand pet fees, which can vary significantly. Some hotels charge per night, while others have flat fees. Review cancellation policies for pet-related issues.
\n \nKeep pets leashed in common areas, clean up after them, and respect other guests. Don\'t leave pets unattended in rooms for extended periods.
\n \nBring familiar items like beds and toys. Ensure pets are well-behaved and up-to-date on vaccinations. Bring necessary documentation.
\n \nResearch nearby veterinarians, pet stores, and dog parks. Hotels in pet-friendly areas often provide recommendations and assistance.
\n \nPet-friendly hotels make traveling with pets enjoyable. Research thoroughly, follow policies, and be considerate to ensure positive experiences for all.
\n ','https://images.unsplash.com/photo-1601758228041-f3b2795255f1?w=1200&h=800&fit=crop',1,'2025-08-16 22:50:03',1,'[\"Pet Travel\", \"Pet-Friendly\", \"Travel Tips\"]','Pet-Friendly Hotels: Traveling with Your Furry Friends','Discover how to find and enjoy pet-friendly hotels that welcome your four-legged companions with open arms.','pet-friendly hotels, traveling with pets, pet travel, dog-friendly hotels, pet accommodations',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(18,'Hotel Concierge Services: Maximizing Your Experience','hotel-concierge-services-maximizing-experience','Learn how to leverage hotel concierge services to enhance your stay with local insights, reservations, and personalized assistance.','\nHotel concierges are valuable resources for enhancing your stay. Understanding how to work with them unlocks local expertise and exclusive access.
\n \nConcierges provide restaurant reservations, event tickets, transportation, local recommendations, and assistance with special requests. They\'re your local experts.
\n \nConcierges often have relationships with popular restaurants, securing tables at hard-to-book establishments. They know the best local dining options.
\n \nTap into concierges\' local knowledge for hidden gems, cultural experiences, and authentic recommendations beyond tourist guides.
\n \nConcierges excel at arranging special occasions—anniversaries, proposals, birthdays. They coordinate flowers, cakes, decorations, and surprises.
\n \nFrom airport transfers to car rentals and private drivers, concierges handle transportation needs efficiently and reliably.
\n \nBuilding rapport with concierges through courtesy and clear communication often results in better service and special considerations.
\n \nConcierge services transform hotel stays into exceptional experiences. Don\'t hesitate to utilize their expertise and connections.
\n ','https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1200&h=800&fit=crop',1,'2025-08-18 22:50:03',1,'[\"Concierge\", \"Guest Services\", \"Travel Tips\"]','Hotel Concierge Services: Maximizing Your Experience','Learn how to leverage hotel concierge services to enhance your stay with local insights, reservations, and personalized assistance.','hotel concierge, concierge services, guest services, travel assistance, hotel services',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(19,'Seasonal Hotel Stays: Best Times to Visit','seasonal-hotel-stays-best-times-visit','Discover the advantages of different seasons for hotel stays and how timing affects rates, crowds, and experiences.','\nTiming your hotel stay can significantly impact your experience, costs, and enjoyment. Understanding seasonal patterns helps you choose the perfect time to visit.
\n \nPeak seasons offer ideal weather and full amenities but come with higher prices and crowds. Book well in advance and expect premium rates.
\n \nShoulder seasons provide a balance of good weather, reasonable prices, and fewer crowds. These periods often offer the best value and experience.
\n \nOff-season travel offers significant savings, fewer crowds, and more personalized service. Some amenities may be limited, but value is exceptional.
\n \nResearch destination weather patterns. Some locations are beautiful year-round, while others have distinct seasons affecting activities and experiences.
\n \nConsider local festivals, holidays, and events. These can enhance experiences but also increase prices and require early booking.
\n \nBusiness travelers may prefer off-peak times for better rates and availability. Leisure travelers can choose based on weather and activities.
\n \nChoosing the right season balances your priorities—weather, budget, crowds, and experiences. Research thoroughly to find your ideal timing.
\n ','https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200&h=800&fit=crop',1,'2025-08-20 22:50:03',1,'[\"Travel Planning\", \"Seasonal Travel\", \"Travel Tips\"]','Seasonal Hotel Stays: Best Times to Visit | Travel Planning','Discover the advantages of different seasons for hotel stays and how timing affects rates, crowds, and experiences.','seasonal travel, best time to travel, travel seasons, hotel booking seasons, travel planning',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(20,'Hotel Loyalty Programs: Maximizing Rewards','hotel-loyalty-programs-maximizing-rewards','Unlock the full potential of hotel loyalty programs with strategies to earn points, achieve elite status, and redeem rewards effectively.','\nHotel loyalty programs offer significant value for frequent travelers. Understanding how to maximize these programs enhances every stay with rewards and perks.
\n \nSelect programs aligned with your travel patterns. Consider hotel locations, frequency of travel, and program benefits that matter most to you.
\n \nMaximize point earning through direct bookings, credit card partnerships, and promotional offers. Some programs offer bonus points for specific activities.
\n \nElite status provides room upgrades, late checkout, breakfast, and lounge access. Focus on one program to achieve status faster.
\n \nRedeem points strategically for maximum value. Award nights, upgrades, and experiences offer different redemption values—choose wisely.
\n \nHotel-branded credit cards accelerate point earning and provide automatic elite status. Evaluate annual fees against benefits received.
\n \nTake advantage of promotions, bonus point offers, and special events. Sign up for program emails to stay informed about opportunities.
\n \nStrategic participation in loyalty programs provides substantial value. Focus, be consistent, and leverage all available benefits for maximum rewards.
\n ','https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?w=1200&h=800&fit=crop',1,'2025-08-22 22:50:03',1,'[\"Loyalty Programs\", \"Travel Rewards\", \"Travel Tips\"]','Hotel Loyalty Programs: Maximizing Rewards and Benefits','Unlock the full potential of hotel loyalty programs with strategies to earn points, achieve elite status, and redeem rewards effectively.','hotel loyalty programs, travel rewards, points programs, hotel rewards, loyalty benefits',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(21,'Hotel Room Service: A Complete Guide','hotel-room-service-complete-guide','Navigate hotel room service menus, etiquette, and tips to enjoy convenient dining in the comfort of your room.','\nRoom service offers convenience and privacy, allowing guests to dine in their rooms. Understanding how to use this service enhances your hotel experience.
\n \nRoom service menus range from simple snacks to full meals. Many hotels offer 24-hour service with diverse options to suit different tastes and times.
\n \nOrder through phone, in-room tablets, or hotel apps. Specify delivery time, special requests, and dietary requirements when ordering.
\n \nRoom service typically includes service charges and delivery fees. Prices are often higher than restaurant dining, but convenience may justify the cost.
\n \nOrder during off-peak hours for faster service. Breakfast orders placed the night before ensure timely morning delivery.
\n \nHotels accommodate dietary restrictions, allergies, and special requests. Communicate needs clearly when ordering for best results.
\n \nTip room service staff appropriately, typically 15-20% of the bill. Some hotels include service charges, but additional tips are appreciated.
\n \nRoom service provides convenient dining options. Understanding menus, ordering processes, and etiquette ensures enjoyable experiences.
\n ','https://images.unsplash.com/photo-1555396273-367ea4eb4db5?w=1200&h=800&fit=crop',1,'2025-09-17 22:50:03',1,'[\"Room Service\", \"Dining\", \"Hotel Services\"]','Hotel Room Service: A Complete Guide to In-Room Dining','Navigate hotel room service menus, etiquette, and tips to enjoy convenient dining in the comfort of your room.','room service, hotel dining, in-room dining, hotel food service, room service guide',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(22,'Extended Stay Hotels: Living in Comfort','extended-stay-hotels-living-comfort','Discover the benefits of extended stay hotels for long-term travel, relocations, and temporary housing needs.','\nExtended stay hotels provide comfortable, convenient accommodations for longer visits. These properties are designed specifically for guests staying weeks or months.
\n \nExtended stay hotels offer apartment-like rooms with kitchens, living areas, and separate bedrooms. These features make long stays comfortable and practical.
\n \nExtended stay rates are typically lower than traditional hotels for longer periods. Weekly and monthly rates provide significant savings.
\n \nFull kitchens, laundry facilities, and larger spaces create home-like environments. These amenities are essential for comfortable extended stays.
\n \nExtended stay hotels are often located near business districts, hospitals, or universities, providing convenient access for work or study.
\n \nFlexible booking options accommodate changing schedules. Many properties offer month-to-month arrangements without long-term commitments.
\n \nHousekeeping, maintenance, and front desk services provide support while maintaining independence. Balance of service and privacy is key.
\n \nExtended stay hotels bridge the gap between hotels and apartments, offering comfort and convenience for longer visits.
\n ','https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?w=1200&h=800&fit=crop',1,'2025-09-13 22:50:03',1,'[\"Extended Stay\", \"Long-Term Travel\", \"Accommodation\"]','Extended Stay Hotels: Living in Comfort for Long-Term Travel','Discover the benefits of extended stay hotels for long-term travel, relocations, and temporary housing needs.','extended stay hotels, long-term hotels, temporary housing, relocation hotels, monthly hotels',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(23,'Hotel Photography: Capturing Your Stay','hotel-photography-capturing-your-stay','Tips and techniques for taking stunning photos of your hotel stay to preserve memories and share experiences.','\nHotel photography preserves memories and shares experiences. Whether for personal keepsakes or social media, great photos enhance your travel documentation.
\n \nCapture rooms in natural light, showing key features and ambiance. Include details like views, amenities, and design elements that make the room special.
\n \nPhotograph lobbies, restaurants, and facilities to document the full hotel experience. These spaces often showcase the hotel\'s character and style.
\n \nFood photography requires good lighting and composition. Capture presentation, ambiance, and memorable meals to preserve dining experiences.
\n \nHotel views are often highlights. Capture sunrises, sunsets, and scenic vistas from rooms, balconies, and hotel terraces.
\n \nRespect other guests\' privacy when photographing. Avoid photographing staff without permission and follow hotel photography policies.
\n \nEdit photos to enhance colors and composition while maintaining authenticity. Share thoughtfully, respecting the hotel and other guests.
\n \nHotel photography creates lasting memories. With respect and good technique, you can capture beautiful images that preserve your travel experiences.
\n ','https://images.unsplash.com/photo-1516035069371-29a1b244cc32?w=1200&h=800&fit=crop',1,'2025-09-11 22:50:03',1,'[\"Photography\", \"Travel Tips\", \"Social Media\"]','Hotel Photography: Capturing Your Stay | Travel Photography Tips','Tips and techniques for taking stunning photos of your hotel stay to preserve memories and share experiences.','hotel photography, travel photography, hotel photos, travel tips, photography tips',6,'2025-11-28 22:47:08','2025-11-29 12:56:58',NULL),(24,'Eco-Friendly Hotels: Sustainable Travel Choices','eco-friendly-hotels-sustainable-travel-choices','Learn how to identify and choose eco-friendly hotels that prioritize sustainability and environmental responsibility.','\nEco-friendly hotels combine luxury with environmental responsibility. Choosing sustainable accommodations supports conservation while enjoying comfortable stays.
\n \nLook for hotels with recognized certifications like LEED, Green Key, or EarthCheck. These certifications verify genuine environmental commitments.
\n \nEco-friendly hotels use renewable energy, efficient systems, and smart technology to reduce energy consumption without compromising comfort.
\n \nSustainable hotels implement water-saving measures, recycling systems, and responsible water management practices throughout their operations.
\n \nComprehensive recycling, composting, and waste reduction programs minimize environmental impact. Some hotels eliminate single-use plastics entirely.
\n \nSustainable hotels source locally, supporting communities and reducing transportation impacts. Local food, materials, and services benefit everyone.
\n \nEco-friendly hotels encourage guest participation through towel reuse programs, energy conservation, and educational initiatives about sustainability.
\n \nChoosing eco-friendly hotels supports environmental conservation while enjoying luxury experiences. Sustainable travel benefits destinations and future generations.
\n ','https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?w=1200&h=800&fit=crop',1,'2025-09-09 22:50:03',1,'[\"Sustainability\", \"Eco-Friendly\", \"Green Travel\"]','Eco-Friendly Hotels: Sustainable Travel Choices | Green Hotels','Learn how to identify and choose eco-friendly hotels that prioritize sustainability and environmental responsibility.','eco-friendly hotels, sustainable hotels, green hotels, eco travel, sustainable travel',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(25,'Hotel Reviews: How to Write Helpful Reviews','hotel-reviews-how-write-helpful-reviews','Master the art of writing hotel reviews that help other travelers make informed decisions while providing valuable feedback to hotels.','\nWell-written hotel reviews help travelers make informed decisions and provide valuable feedback to hotels. Learning to write effective reviews benefits everyone.
\n \nProvide specific details about your experience—room features, service interactions, amenities used. Specific information is more helpful than general statements.
\n \nHonest reviews include both positive aspects and areas for improvement. Balanced perspectives help readers understand the full experience.
\n \nStick to factual observations about your stay. Avoid speculation or assumptions about things you didn\'t directly experience.
\n \nMention relevant context—travel purpose, time of year, special occasions. This helps readers understand if your experience applies to their situation.
\n \nWrite respectfully, even when reporting negative experiences. Constructive criticism is more valuable than harsh complaints.
\n \nPhotos enhance reviews significantly, showing actual conditions and experiences. Include images of rooms, amenities, and notable features.
\n \nHelpful reviews require thoughtfulness, honesty, and respect. Well-written reviews create value for travelers and hotels alike.
\n ','https://images.unsplash.com/photo-1450101499163-c8848c66ca85?w=1200&h=800&fit=crop',1,'2025-09-07 22:50:03',1,'[\"Reviews\", \"Travel Tips\", \"Guest Feedback\"]','Hotel Reviews: How to Write Helpful Reviews for Travelers','Master the art of writing hotel reviews that help other travelers make informed decisions while providing valuable feedback to hotels.','hotel reviews, writing reviews, travel reviews, review tips, guest feedback',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(26,'Hotel Cancellation Policies: Understanding Your Options','hotel-cancellation-policies-understanding-options','Navigate hotel cancellation policies to understand your rights, options, and how to handle changes to your travel plans.','jghgjggjgjgjjg','https://images.unsplash.com/photo-1559526324-4b87b5e36e44?w=1200&h=800&fit=crop',1,'2025-09-05 22:50:03',1,'[\"Booking\", \"Travel Tips\", \"Policies\"]','','','',12,'2025-11-28 22:47:08','2025-11-28 23:20:25','[{\"type\": \"image\", \"image\": \"http://localhost:8000/uploads/blog/blog-b97e9a9b-501f-4445-9366-4d5ea4d90939.jpg\", \"alignment\": \"center\", \"is_visible\": true}]'),(27,'Hotel Wi-Fi: Staying Connected on the Go','hotel-wifi-staying-connected-go','Navigate hotel Wi-Fi services, understand connection options, and ensure reliable internet access during your stay.','\nReliable hotel Wi-Fi is essential for modern travelers. Understanding Wi-Fi options and how to optimize connections ensures productivity and connectivity.
\n \nMany hotels offer multiple Wi-Fi tiers—basic free service and premium high-speed options. Choose based on your needs and usage.
\n \nPosition devices near routers, avoid peak usage times, and disconnect unused devices. These simple steps improve connection quality.
\n \nUse hotel Wi-Fi cautiously. Avoid sensitive transactions on public networks. Consider VPN services for enhanced security when traveling.
\n \nBusiness travelers may need premium Wi-Fi for video calls and large file transfers. Verify speeds and reliability before booking.
\n \nHotel IT support can assist with connection issues. Don\'t hesitate to contact them for help with Wi-Fi problems.
\n \nMobile hotspots and data plans provide alternatives to hotel Wi-Fi. Consider these options for critical connectivity needs.
\n \nUnderstanding hotel Wi-Fi options and optimizing connections ensures reliable internet access during your stay.
\n ','https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1200&h=800&fit=crop',1,'2025-09-03 22:50:03',1,'[\"Technology\", \"Wi-Fi\", \"Business Travel\"]','Hotel Wi-Fi: Staying Connected on the Go | Internet Access','Navigate hotel Wi-Fi services, understand connection options, and ensure reliable internet access during your stay.','hotel wifi, hotel internet, wifi tips, travel technology, hotel connectivity',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(28,'Hotel Breakfast: Starting Your Day Right','hotel-breakfast-starting-day-right','Explore hotel breakfast options from continental to full breakfast buffets and how to make the most of morning dining.','\nHotel breakfasts set the tone for your day. Understanding options and making the most of breakfast services enhances your stay experience.
\n \nHotels offer various breakfast options—continental, buffet, à la carte, and room service. Each provides different experiences and value.
\n \nBreakfast buffets offer variety and value, allowing you to sample different items and eat as much as you like. They\'re perfect for families.
\n \nBreakfast service hours vary. Early risers and late sleepers should check times. Some hotels offer extended or 24-hour breakfast options.
\n \nHotels accommodate dietary restrictions, allergies, and preferences. Communicate needs in advance for best results.
\n \nSome hotels include breakfast in rates, while others charge separately. Compare total costs when evaluating hotel options.
\n \nHotel breakfasts often feature local specialties, providing cultural experiences and authentic flavors of the destination.
\n \nHotel breakfasts offer convenience and variety. Understanding options helps you start each day of your stay on the right note.
\n ','https://images.unsplash.com/photo-1525351484163-7529414344d8?w=1200&h=800&fit=crop',1,'2025-09-01 22:50:03',1,'[\"Dining\", \"Breakfast\", \"Hotel Services\"]','Hotel Breakfast: Starting Your Day Right | Breakfast Guide','Explore hotel breakfast options from continental to full breakfast buffets and how to make the most of morning dining.','hotel breakfast, breakfast buffet, hotel dining, morning meals, hotel food',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(29,'Hotel Pools: Making the Most of Pool Facilities','hotel-pools-making-most-pool-facilities','Discover how to enjoy hotel pool facilities, from infinity pools to rooftop pools, and poolside service experiences.','\nHotel pools provide relaxation and recreation. Understanding pool facilities and etiquette ensures enjoyable experiences for all guests.
\n \nHotels offer various pool types—outdoor, indoor, rooftop, infinity, and heated pools. Each provides unique experiences and benefits.
\n \nMany hotels offer poolside service for food and beverages. Enjoy meals and drinks without leaving the pool area.
\n \nRespect other guests, follow pool rules, and maintain cleanliness. Proper etiquette ensures pleasant experiences for everyone.
\n \nFamily-friendly pools often have shallow areas, lifeguards, and children\'s activities. Some hotels offer separate adult pools for quiet relaxation.
\n \nCheck pool operating hours, which may vary by season or day. Some pools offer extended hours or 24-hour access.
\n \nHotels may offer pool amenities like cabanas, loungers, towels, and changing facilities. Inquire about available services.
\n \nHotel pools enhance stays with relaxation and recreation. Understanding facilities and following etiquette ensures enjoyable pool experiences.
\n ','https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=1200&h=800&fit=crop',1,'2025-08-30 22:50:03',1,'[\"Amenities\", \"Pools\", \"Recreation\"]','Hotel Pools: Making the Most of Pool Facilities','Discover how to enjoy hotel pool facilities, from infinity pools to rooftop pools, and poolside service experiences.','hotel pools, pool facilities, poolside service, hotel amenities, pool guide',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(30,'Hotel Spas: Ultimate Relaxation Experiences','hotel-spas-ultimate-relaxation-experiences','Explore hotel spa facilities and treatments, from massages to holistic wellness programs, for complete relaxation and rejuvenation.','\nHotel spas provide sanctuary for relaxation and rejuvenation. Understanding spa offerings helps you choose treatments and maximize your experience.
\n \nHotel spas offer diverse treatments—massages, facials, body wraps, and holistic therapies. Each addresses different wellness needs.
\n \nBook spa appointments in advance, especially for popular treatments and peak times. Early booking ensures preferred times and availability.
\n \nMany spas offer packages combining multiple treatments at discounted rates. Packages provide comprehensive wellness experiences.
\n \nHotel spas often include saunas, steam rooms, hot tubs, and relaxation areas. Arrive early to enjoy these facilities before treatments.
\n \nSome hotel spas offer comprehensive wellness programs including fitness, nutrition, and mindfulness components for holistic health.
\n \nCouples\' treatments and private spa suites create romantic, intimate experiences perfect for special occasions or getaways.
\n \nHotel spas provide essential relaxation and wellness experiences. Understanding offerings and booking strategically maximizes your spa visit.
\n ','https://images.unsplash.com/photo-1544161515-4ab6ce6db874?w=1200&h=800&fit=crop',1,'2025-08-28 22:50:03',1,'[\"Spa\", \"Wellness\", \"Relaxation\"]','Hotel Spas: Ultimate Relaxation Experiences | Spa Guide','Explore hotel spa facilities and treatments, from massages to holistic wellness programs, for complete relaxation and rejuvenation.','hotel spas, spa treatments, wellness, relaxation, spa guide',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(31,'Hotel Bars and Lounges: Evening Entertainment','hotel-bars-lounges-evening-entertainment','Discover hotel bars and lounges offering craft cocktails, live music, and sophisticated atmospheres for evening relaxation and socializing.','\nHotel bars and lounges provide sophisticated settings for evening entertainment, socializing, and enjoying craft beverages in elegant atmospheres.
\n \nHotel bars often feature expert mixologists creating craft cocktails with premium ingredients. These establishments showcase beverage artistry.
\n \nHotel bars create distinct atmospheres through design, lighting, and music. From rooftop bars to speakeasies, each offers unique experiences.
\n \nMany hotel bars feature live music, DJs, or entertainment. These elements enhance evening experiences and create memorable nights.
\n \nHotel bars often serve excellent bar food, from small plates to full meals. Quality food complements beverage experiences.
\n \nBars and lounges serve as social hubs, perfect for meeting other travelers, business networking, or simply relaxing after a day of activities.
\n \nRooftop bars offer stunning views and unique atmospheres. These elevated spaces provide exceptional evening experiences.
\n \nHotel bars and lounges enhance stays with sophisticated evening entertainment. These spaces provide perfect settings for relaxation and socializing.
\n ','https://images.unsplash.com/photo-1517245386807-bb43f82c33c4?w=1200&h=800&fit=crop',1,'2025-08-26 22:50:03',1,'[\"Entertainment\", \"Bars\", \"Nightlife\"]','Hotel Bars and Lounges: Evening Entertainment | Nightlife','Discover hotel bars and lounges offering craft cocktails, live music, and sophisticated atmospheres for evening relaxation and socializing.','hotel bars, hotel lounges, nightlife, cocktails, evening entertainment',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(32,'Hotel Fitness Centers: Staying Active While Traveling','hotel-fitness-centers-staying-active-traveling','Maintain your fitness routine with hotel fitness centers featuring modern equipment, classes, and wellness facilities.','\nHotel fitness centers allow travelers to maintain exercise routines while away from home. Modern facilities provide comprehensive workout options.
\n \nHotel fitness centers vary in equipment quality and variety. Premium hotels offer state-of-the-art equipment matching commercial gyms.
\n \nMany hotel fitness centers offer 24-hour access, accommodating early risers and late-night exercisers. Check hours when booking.
\n \nSome hotels offer fitness classes like yoga, Pilates, or spinning. These classes provide structured workouts and social interaction.
\n \nPremium hotels may offer personal training services. These sessions provide personalized guidance and motivation during your stay.
\n \nHotels in scenic locations may offer outdoor fitness options like running trails, tennis courts, or water sports facilities.
\n \nFitness centers often integrate with hotel spas and wellness programs, providing comprehensive health and fitness experiences.
\n \nHotel fitness centers enable travelers to maintain active lifestyles. Understanding facilities and options helps you stay fit while traveling.
\n ','https://images.unsplash.com/photo-1534438327276-14e5300c3a48?w=1200&h=800&fit=crop',1,'2025-08-24 22:50:03',1,'[\"Fitness\", \"Wellness\", \"Health\"]','Hotel Fitness Centers: Staying Active While Traveling','Maintain your fitness routine with hotel fitness centers featuring modern equipment, classes, and wellness facilities.','hotel fitness, gym, fitness centers, travel fitness, hotel gym',0,'2025-11-28 22:47:08','2025-11-28 22:50:03',NULL),(33,'Hotel Meeting Spaces: Hosting Successful Events','hotel-meeting-spaces-hosting-successful-events','Plan and execute successful meetings, conferences, and events using hotel meeting spaces and professional event services.','\nHotel meeting spaces provide professional settings for business events, conferences, and social gatherings. Understanding options ensures successful events.
\n \nHotels offer various meeting spaces—boardrooms, ballrooms, conference halls, and breakout rooms. Each serves different event types and sizes.
\n \nModern meeting spaces include AV equipment, high-speed internet, video conferencing, and presentation technology. Verify available equipment when booking.
\n \nHotel catering provides meals, breaks, and beverages for events. Professional catering ensures quality food service throughout your event.
\n \nHotel event coordinators assist with planning, setup, and execution. Their expertise ensures smooth, professional events.
\n \nMeeting spaces can be configured for various setups—theater, classroom, banquet, or boardroom styles. Choose configurations matching your needs.
\n \nHotels often offer packages combining meeting spaces with guest rooms, providing convenience and value for event attendees.
\n \nHotel meeting spaces provide professional environments for successful events. Leveraging hotel services and expertise ensures memorable gatherings.
\n ','https://images.unsplash.com/photo-1497366216548-37526070297c?w=1200&h=800&fit=crop',1,'2025-09-15 22:50:03',1,'[\"Business\", \"Meetings\", \"Events\"]','Hotel Meeting Spaces: Hosting Successful Events | Business','Plan and execute successful meetings, conferences, and events using hotel meeting spaces and professional event services.','hotel meetings, conference rooms, event spaces, business meetings, hotel events',2,'2025-11-28 22:47:08','2025-11-29 13:31:24',NULL); +/*!40000 ALTER TABLE `blog_posts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `bookings` +-- + +DROP TABLE IF EXISTS `bookings`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bookings` ( + `id` int NOT NULL AUTO_INCREMENT, + `booking_number` varchar(50) NOT NULL, + `user_id` int NOT NULL, + `room_id` int NOT NULL, + `check_in_date` datetime NOT NULL, + `check_out_date` datetime NOT NULL, + `num_guests` int NOT NULL, + `total_price` decimal(10,2) NOT NULL, + `original_price` decimal(10,2) DEFAULT NULL, + `discount_amount` decimal(10,2) DEFAULT NULL, + `promotion_code` varchar(50) DEFAULT NULL, + `status` enum('pending','confirmed','checked_in','checked_out','cancelled') NOT NULL, + `deposit_paid` tinyint(1) NOT NULL, + `requires_deposit` tinyint(1) NOT NULL, + `special_requests` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `group_booking_id` int DEFAULT NULL, + `rate_plan_id` int DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_bookings_booking_number` (`booking_number`), + KEY `user_id` (`user_id`), + KEY `room_id` (`room_id`), + KEY `ix_bookings_id` (`id`), + KEY `ix_bookings_group_booking_id` (`group_booking_id`), + KEY `ix_bookings_rate_plan_id` (`rate_plan_id`), + CONSTRAINT `bookings_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `bookings_ibfk_2` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`id`), + CONSTRAINT `fk_bookings_group_booking` FOREIGN KEY (`group_booking_id`) REFERENCES `group_bookings` (`id`) ON DELETE SET NULL, + CONSTRAINT `fk_bookings_rate_plan` FOREIGN KEY (`rate_plan_id`) REFERENCES `rate_plans` (`id`) ON DELETE SET NULL +) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `bookings` +-- + +LOCK TABLES `bookings` WRITE; +/*!40000 ALTER TABLE `bookings` DISABLE KEYS */; +INSERT INTO `bookings` VALUES (51,'BK-1764710565937-1153',7,37,'2025-11-28 23:22:46','2025-12-01 23:22:46',1,703.17,NULL,0.00,NULL,'checked_out',1,0,'Sample booking for testing - Checked out 1 day(s) ago','2025-12-02 23:22:46','2025-12-02 23:22:46',NULL,NULL),(52,'BK-1764710565950-8846',7,48,'2025-11-27 23:22:46','2025-12-01 23:22:46',1,713.52,NULL,0.00,NULL,'checked_out',1,0,'Sample booking for testing - Checked out 1 day(s) ago','2025-12-02 23:22:46','2025-12-02 23:22:46',NULL,NULL),(53,'BK-1764710565957-5525',7,43,'2025-11-26 23:22:46','2025-11-30 23:22:46',2,946.68,NULL,0.00,NULL,'checked_out',1,0,'Sample booking for testing - Checked out 2 day(s) ago','2025-12-02 23:22:46','2025-12-02 23:22:46',NULL,NULL),(54,'BK-1764710565964-7267',6,27,'2025-11-29 23:22:46','2025-12-04 23:22:46',2,844.85,NULL,0.00,NULL,'checked_in',1,0,'Sample booking for testing - Currently checked in','2025-12-02 23:22:46','2025-12-02 23:22:46',NULL,NULL),(55,'BK-1764710565970-3341',9,34,'2025-12-01 23:22:46','2025-12-03 23:22:46',1,367.28,NULL,0.00,NULL,'checked_in',1,0,'Sample booking for testing - Currently checked in','2025-12-02 23:22:46','2025-12-02 23:22:46',NULL,NULL),(56,'BK-1764710565975-7780',5,12,'2025-12-06 23:22:46','2025-12-09 23:22:46',1,537.72,NULL,0.00,NULL,'confirmed',1,1,'Sample booking for testing - Future reservation','2025-12-02 23:22:46','2025-12-02 23:22:46',NULL,NULL),(57,'BK-1764710565977-8062',9,44,'2025-12-05 23:22:46','2025-12-09 23:22:46',2,980.64,NULL,0.00,NULL,'confirmed',1,1,'Sample booking for testing - Future reservation','2025-12-02 23:22:46','2025-12-02 23:22:46',NULL,NULL),(58,'BK-1764710565978-9043',9,19,'2025-12-09 23:22:46','2025-12-13 23:22:46',1,924.04,NULL,0.00,NULL,'confirmed',1,1,'Sample booking for testing - Future reservation','2025-12-02 23:22:46','2025-12-02 23:22:46',NULL,NULL); +/*!40000 ALTER TABLE `bookings` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `campaign_emails` +-- + +DROP TABLE IF EXISTS `campaign_emails`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `campaign_emails` ( + `id` int NOT NULL AUTO_INCREMENT, + `campaign_id` int NOT NULL, + `user_id` int DEFAULT NULL, + `email` varchar(255) NOT NULL, + `status` enum('pending','sent','delivered','opened','clicked','bounced','failed','unsubscribed') NOT NULL, + `sent_at` datetime DEFAULT NULL, + `delivered_at` datetime DEFAULT NULL, + `opened_at` datetime DEFAULT NULL, + `clicked_at` datetime DEFAULT NULL, + `bounced_at` datetime DEFAULT NULL, + `unsubscribed_at` datetime DEFAULT NULL, + `open_count` int NOT NULL, + `click_count` int NOT NULL, + `last_opened_at` datetime DEFAULT NULL, + `last_clicked_at` datetime DEFAULT NULL, + `ab_test_variant` varchar(1) DEFAULT NULL, + `error_message` text, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_campaign_emails_status` (`status`), + KEY `ix_campaign_emails_user_id` (`user_id`), + KEY `ix_campaign_emails_campaign_id` (`campaign_id`), + KEY `ix_campaign_emails_created_at` (`created_at`), + KEY `ix_campaign_emails_email` (`email`), + KEY `ix_campaign_emails_id` (`id`), + CONSTRAINT `campaign_emails_ibfk_1` FOREIGN KEY (`campaign_id`) REFERENCES `email_campaigns` (`id`), + CONSTRAINT `campaign_emails_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `campaign_emails` +-- + +LOCK TABLES `campaign_emails` WRITE; +/*!40000 ALTER TABLE `campaign_emails` DISABLE KEYS */; +/*!40000 ALTER TABLE `campaign_emails` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `campaign_segments` +-- + +DROP TABLE IF EXISTS `campaign_segments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `campaign_segments` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(200) NOT NULL, + `description` text, + `criteria` json NOT NULL, + `estimated_count` int DEFAULT NULL, + `last_calculated_at` datetime DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `created_by` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `created_by` (`created_by`), + KEY `ix_campaign_segments_id` (`id`), + KEY `ix_campaign_segments_name` (`name`), + CONSTRAINT `campaign_segments_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `campaign_segments` +-- + +LOCK TABLES `campaign_segments` WRITE; +/*!40000 ALTER TABLE `campaign_segments` DISABLE KEYS */; +/*!40000 ALTER TABLE `campaign_segments` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `chat_messages` +-- + +DROP TABLE IF EXISTS `chat_messages`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `chat_messages` ( + `id` int NOT NULL AUTO_INCREMENT, + `chat_id` int NOT NULL, + `sender_id` int DEFAULT NULL, + `sender_type` varchar(20) NOT NULL, + `message` text NOT NULL, + `is_read` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `chat_id` (`chat_id`), + KEY `sender_id` (`sender_id`), + KEY `ix_chat_messages_id` (`id`), + CONSTRAINT `chat_messages_ibfk_1` FOREIGN KEY (`chat_id`) REFERENCES `chats` (`id`), + CONSTRAINT `chat_messages_ibfk_2` FOREIGN KEY (`sender_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `chat_messages` +-- + +LOCK TABLES `chat_messages` WRITE; +/*!40000 ALTER TABLE `chat_messages` DISABLE KEYS */; +/*!40000 ALTER TABLE `chat_messages` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `chats` +-- + +DROP TABLE IF EXISTS `chats`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `chats` ( + `id` int NOT NULL AUTO_INCREMENT, + `visitor_id` int DEFAULT NULL, + `visitor_name` varchar(100) DEFAULT NULL, + `visitor_email` varchar(100) DEFAULT NULL, + `staff_id` int DEFAULT NULL, + `status` enum('pending','active','closed') NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `closed_at` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `visitor_id` (`visitor_id`), + KEY `staff_id` (`staff_id`), + KEY `ix_chats_id` (`id`), + CONSTRAINT `chats_ibfk_1` FOREIGN KEY (`visitor_id`) REFERENCES `users` (`id`), + CONSTRAINT `chats_ibfk_2` FOREIGN KEY (`staff_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `chats` +-- + +LOCK TABLES `chats` WRITE; +/*!40000 ALTER TABLE `chats` DISABLE KEYS */; +INSERT INTO `chats` VALUES (1,3,'Administrator','admin@gnxsoft.com',NULL,'closed','2025-11-23 12:53:37','2025-11-23 12:53:43','2025-11-23 12:53:43'); +/*!40000 ALTER TABLE `chats` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `checkin_checkout` +-- + +DROP TABLE IF EXISTS `checkin_checkout`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `checkin_checkout` ( + `id` int NOT NULL AUTO_INCREMENT, + `booking_id` int NOT NULL, + `checkin_time` datetime DEFAULT NULL, + `checkout_time` datetime DEFAULT NULL, + `checkin_by` int DEFAULT NULL, + `checkout_by` int DEFAULT NULL, + `room_condition_checkin` text, + `room_condition_checkout` text, + `additional_charges` decimal(10,2) NOT NULL, + `notes` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `booking_id` (`booking_id`), + KEY `checkin_by` (`checkin_by`), + KEY `checkout_by` (`checkout_by`), + KEY `ix_checkin_checkout_id` (`id`), + CONSTRAINT `checkin_checkout_ibfk_1` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `checkin_checkout_ibfk_2` FOREIGN KEY (`checkin_by`) REFERENCES `users` (`id`), + CONSTRAINT `checkin_checkout_ibfk_3` FOREIGN KEY (`checkout_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `checkin_checkout` +-- + +LOCK TABLES `checkin_checkout` WRITE; +/*!40000 ALTER TABLE `checkin_checkout` DISABLE KEYS */; +/*!40000 ALTER TABLE `checkin_checkout` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `complaint_updates` +-- + +DROP TABLE IF EXISTS `complaint_updates`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `complaint_updates` ( + `id` int NOT NULL AUTO_INCREMENT, + `complaint_id` int NOT NULL, + `update_type` varchar(50) NOT NULL, + `description` text NOT NULL, + `updated_by` int NOT NULL, + `created_at` datetime NOT NULL, + `update_metadata` json DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `updated_by` (`updated_by`), + KEY `ix_complaint_updates_id` (`id`), + KEY `ix_complaint_updates_complaint_id` (`complaint_id`), + KEY `ix_complaint_updates_created_at` (`created_at`), + CONSTRAINT `complaint_updates_ibfk_1` FOREIGN KEY (`complaint_id`) REFERENCES `guest_complaints` (`id`), + CONSTRAINT `complaint_updates_ibfk_2` FOREIGN KEY (`updated_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `complaint_updates` +-- + +LOCK TABLES `complaint_updates` WRITE; +/*!40000 ALTER TABLE `complaint_updates` DISABLE KEYS */; +/*!40000 ALTER TABLE `complaint_updates` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `consent_records` +-- + +DROP TABLE IF EXISTS `consent_records`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `consent_records` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `consent_type` varchar(100) NOT NULL, + `granted` tinyint(1) NOT NULL, + `granted_at` datetime DEFAULT NULL, + `revoked_at` datetime DEFAULT NULL, + `ip_address` varchar(45) DEFAULT NULL, + `user_agent` varchar(500) DEFAULT NULL, + `version` varchar(50) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_consent_records_id` (`id`), + KEY `ix_consent_records_consent_type` (`consent_type`), + KEY `ix_consent_records_user_id` (`user_id`), + CONSTRAINT `consent_records_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `consent_records` +-- + +LOCK TABLES `consent_records` WRITE; +/*!40000 ALTER TABLE `consent_records` DISABLE KEYS */; +/*!40000 ALTER TABLE `consent_records` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `consents` +-- + +DROP TABLE IF EXISTS `consents`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `consents` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int DEFAULT NULL, + `consent_type` enum('marketing','analytics','necessary','preferences','third_party_sharing','profiling','automated_decision_making') NOT NULL, + `status` enum('granted','withdrawn','pending','expired') NOT NULL, + `granted_at` datetime DEFAULT NULL, + `withdrawn_at` datetime DEFAULT NULL, + `expires_at` datetime DEFAULT NULL, + `legal_basis` varchar(100) DEFAULT NULL, + `consent_method` varchar(50) DEFAULT NULL, + `consent_version` varchar(20) DEFAULT NULL, + `ip_address` varchar(45) DEFAULT NULL, + `user_agent` varchar(255) DEFAULT NULL, + `source` varchar(100) DEFAULT NULL, + `extra_metadata` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `user_email` varchar(255) DEFAULT NULL, + `is_anonymous` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + KEY `ix_consents_id` (`id`), + KEY `ix_consents_user_id` (`user_id`), + KEY `ix_consents_consent_type` (`consent_type`), + KEY `ix_consents_status` (`status`), + KEY `ix_consents_created_at` (`created_at`), + KEY `ix_consents_user_email` (`user_email`), + KEY `ix_consents_is_anonymous` (`is_anonymous`), + CONSTRAINT `consents_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `consents` +-- + +LOCK TABLES `consents` WRITE; +/*!40000 ALTER TABLE `consents` DISABLE KEYS */; +/*!40000 ALTER TABLE `consents` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `cookie_integration_configs` +-- + +DROP TABLE IF EXISTS `cookie_integration_configs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `cookie_integration_configs` ( + `id` int NOT NULL AUTO_INCREMENT, + `ga_measurement_id` varchar(64) DEFAULT NULL, + `fb_pixel_id` varchar(64) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `updated_by_id` int DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `updated_by_id` (`updated_by_id`), + KEY `ix_cookie_integration_configs_id` (`id`), + CONSTRAINT `cookie_integration_configs_ibfk_1` FOREIGN KEY (`updated_by_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `cookie_integration_configs` +-- + +LOCK TABLES `cookie_integration_configs` WRITE; +/*!40000 ALTER TABLE `cookie_integration_configs` DISABLE KEYS */; +INSERT INTO `cookie_integration_configs` VALUES (1,NULL,NULL,'2025-11-21 12:23:06','2025-11-21 12:23:06',NULL); +/*!40000 ALTER TABLE `cookie_integration_configs` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `cookie_policies` +-- + +DROP TABLE IF EXISTS `cookie_policies`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `cookie_policies` ( + `id` int NOT NULL AUTO_INCREMENT, + `analytics_enabled` tinyint(1) NOT NULL, + `marketing_enabled` tinyint(1) NOT NULL, + `preferences_enabled` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `updated_by_id` int DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `updated_by_id` (`updated_by_id`), + KEY `ix_cookie_policies_id` (`id`), + CONSTRAINT `cookie_policies_ibfk_1` FOREIGN KEY (`updated_by_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `cookie_policies` +-- + +LOCK TABLES `cookie_policies` WRITE; +/*!40000 ALTER TABLE `cookie_policies` DISABLE KEYS */; +INSERT INTO `cookie_policies` VALUES (1,1,1,1,'2025-11-21 12:23:06','2025-11-21 12:23:06',NULL); +/*!40000 ALTER TABLE `cookie_policies` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `data_breaches` +-- + +DROP TABLE IF EXISTS `data_breaches`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `data_breaches` ( + `id` int NOT NULL AUTO_INCREMENT, + `breach_type` enum('confidentiality','integrity','availability') NOT NULL, + `status` enum('detected','investigating','contained','reported_to_authority','notified_data_subjects','resolved') NOT NULL, + `description` text NOT NULL, + `affected_data_categories` json DEFAULT NULL, + `affected_data_subjects` json DEFAULT NULL, + `detected_at` datetime NOT NULL, + `occurred_at` datetime DEFAULT NULL, + `contained_at` datetime DEFAULT NULL, + `reported_to_authority_at` datetime DEFAULT NULL, + `authority_reference` varchar(255) DEFAULT NULL, + `notified_data_subjects_at` datetime DEFAULT NULL, + `notification_method` varchar(100) DEFAULT NULL, + `likely_consequences` text, + `measures_proposed` text, + `risk_level` varchar(20) DEFAULT NULL, + `reported_by` int NOT NULL, + `investigated_by` int DEFAULT NULL, + `extra_metadata` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `investigated_by` (`investigated_by`), + KEY `reported_by` (`reported_by`), + KEY `ix_data_breaches_id` (`id`), + KEY `ix_data_breaches_breach_type` (`breach_type`), + KEY `ix_data_breaches_status` (`status`), + KEY `ix_data_breaches_detected_at` (`detected_at`), + CONSTRAINT `data_breaches_ibfk_1` FOREIGN KEY (`investigated_by`) REFERENCES `users` (`id`), + CONSTRAINT `data_breaches_ibfk_2` FOREIGN KEY (`reported_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `data_breaches` +-- + +LOCK TABLES `data_breaches` WRITE; +/*!40000 ALTER TABLE `data_breaches` DISABLE KEYS */; +/*!40000 ALTER TABLE `data_breaches` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `data_processing_records` +-- + +DROP TABLE IF EXISTS `data_processing_records`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `data_processing_records` ( + `id` int NOT NULL AUTO_INCREMENT, + `processing_category` enum('collection','storage','usage','sharing','deletion','anonymization','transfer') NOT NULL, + `legal_basis` enum('consent','contract','legal_obligation','vital_interests','public_task','legitimate_interests') NOT NULL, + `purpose` text NOT NULL, + `data_categories` json DEFAULT NULL, + `data_subjects` json DEFAULT NULL, + `recipients` json DEFAULT NULL, + `third_parties` json DEFAULT NULL, + `transfers_to_third_countries` tinyint(1) NOT NULL, + `transfer_countries` json DEFAULT NULL, + `safeguards` text, + `retention_period` varchar(100) DEFAULT NULL, + `retention_criteria` text, + `security_measures` text, + `user_id` int DEFAULT NULL, + `related_booking_id` int DEFAULT NULL, + `related_payment_id` int DEFAULT NULL, + `processed_by` int DEFAULT NULL, + `processing_timestamp` datetime NOT NULL, + `extra_metadata` json DEFAULT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `processed_by` (`processed_by`), + KEY `ix_data_processing_records_id` (`id`), + KEY `ix_data_processing_records_processing_category` (`processing_category`), + KEY `ix_data_processing_records_legal_basis` (`legal_basis`), + KEY `ix_data_processing_records_user_id` (`user_id`), + KEY `ix_data_processing_records_processing_timestamp` (`processing_timestamp`), + KEY `ix_data_processing_records_created_at` (`created_at`), + CONSTRAINT `data_processing_records_ibfk_1` FOREIGN KEY (`processed_by`) REFERENCES `users` (`id`), + CONSTRAINT `data_processing_records_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `data_processing_records` +-- + +LOCK TABLES `data_processing_records` WRITE; +/*!40000 ALTER TABLE `data_processing_records` DISABLE KEYS */; +/*!40000 ALTER TABLE `data_processing_records` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `data_retention_logs` +-- + +DROP TABLE IF EXISTS `data_retention_logs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `data_retention_logs` ( + `id` int NOT NULL AUTO_INCREMENT, + `retention_rule_id` int NOT NULL, + `data_category` varchar(100) NOT NULL, + `action_taken` varchar(50) NOT NULL, + `records_affected` int NOT NULL, + `affected_ids` json DEFAULT NULL, + `executed_by` int DEFAULT NULL, + `executed_at` datetime NOT NULL, + `success` tinyint(1) NOT NULL, + `error_message` text, + `extra_metadata` json DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `executed_by` (`executed_by`), + KEY `ix_data_retention_logs_id` (`id`), + KEY `ix_data_retention_logs_retention_rule_id` (`retention_rule_id`), + KEY `ix_data_retention_logs_data_category` (`data_category`), + KEY `ix_data_retention_logs_executed_at` (`executed_at`), + CONSTRAINT `data_retention_logs_ibfk_1` FOREIGN KEY (`executed_by`) REFERENCES `users` (`id`), + CONSTRAINT `data_retention_logs_ibfk_2` FOREIGN KEY (`retention_rule_id`) REFERENCES `retention_rules` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `data_retention_logs` +-- + +LOCK TABLES `data_retention_logs` WRITE; +/*!40000 ALTER TABLE `data_retention_logs` DISABLE KEYS */; +/*!40000 ALTER TABLE `data_retention_logs` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `data_retention_policies` +-- + +DROP TABLE IF EXISTS `data_retention_policies`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `data_retention_policies` ( + `id` int NOT NULL AUTO_INCREMENT, + `data_type` varchar(100) NOT NULL, + `retention_days` int NOT NULL, + `auto_delete` tinyint(1) NOT NULL, + `description` text, + `is_active` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `data_type` (`data_type`), + KEY `ix_data_retention_policies_id` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `data_retention_policies` +-- + +LOCK TABLES `data_retention_policies` WRITE; +/*!40000 ALTER TABLE `data_retention_policies` DISABLE KEYS */; +/*!40000 ALTER TABLE `data_retention_policies` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `data_subject_requests` +-- + +DROP TABLE IF EXISTS `data_subject_requests`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `data_subject_requests` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int DEFAULT NULL, + `email` varchar(255) NOT NULL, + `request_type` enum('access','rectification','erasure','portability','restriction','objection') NOT NULL, + `status` enum('pending','in_progress','completed','rejected','cancelled') NOT NULL, + `description` text, + `verification_token` varchar(100) DEFAULT NULL, + `verified` tinyint(1) NOT NULL, + `verified_at` datetime DEFAULT NULL, + `assigned_to` int DEFAULT NULL, + `notes` text, + `response_data` json DEFAULT NULL, + `completed_at` datetime DEFAULT NULL, + `completed_by` int DEFAULT NULL, + `ip_address` varchar(45) DEFAULT NULL, + `user_agent` varchar(500) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `user` int DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_data_subject_requests_verification_token` (`verification_token`), + KEY `assigned_to` (`assigned_to`), + KEY `completed_by` (`completed_by`), + KEY `user` (`user`), + KEY `ix_data_subject_requests_request_type` (`request_type`), + KEY `ix_data_subject_requests_user_id` (`user_id`), + KEY `ix_data_subject_requests_created_at` (`created_at`), + KEY `ix_data_subject_requests_status` (`status`), + KEY `ix_data_subject_requests_id` (`id`), + KEY `ix_data_subject_requests_email` (`email`), + CONSTRAINT `data_subject_requests_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `data_subject_requests_ibfk_2` FOREIGN KEY (`assigned_to`) REFERENCES `users` (`id`), + CONSTRAINT `data_subject_requests_ibfk_3` FOREIGN KEY (`completed_by`) REFERENCES `users` (`id`), + CONSTRAINT `data_subject_requests_ibfk_4` FOREIGN KEY (`user`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `data_subject_requests` +-- + +LOCK TABLES `data_subject_requests` WRITE; +/*!40000 ALTER TABLE `data_subject_requests` DISABLE KEYS */; +/*!40000 ALTER TABLE `data_subject_requests` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `drip_sequence_enrollments` +-- + +DROP TABLE IF EXISTS `drip_sequence_enrollments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `drip_sequence_enrollments` ( + `id` int NOT NULL AUTO_INCREMENT, + `sequence_id` int NOT NULL, + `user_id` int NOT NULL, + `current_step` int NOT NULL, + `next_send_at` datetime DEFAULT NULL, + `completed` tinyint(1) NOT NULL, + `completed_at` datetime DEFAULT NULL, + `trigger_data` json DEFAULT NULL, + `enrolled_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_drip_sequence_enrollments_enrolled_at` (`enrolled_at`), + KEY `ix_drip_sequence_enrollments_id` (`id`), + KEY `ix_drip_sequence_enrollments_next_send_at` (`next_send_at`), + KEY `ix_drip_sequence_enrollments_user_id` (`user_id`), + KEY `ix_drip_sequence_enrollments_sequence_id` (`sequence_id`), + CONSTRAINT `drip_sequence_enrollments_ibfk_1` FOREIGN KEY (`sequence_id`) REFERENCES `drip_sequences` (`id`), + CONSTRAINT `drip_sequence_enrollments_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `drip_sequence_enrollments` +-- + +LOCK TABLES `drip_sequence_enrollments` WRITE; +/*!40000 ALTER TABLE `drip_sequence_enrollments` DISABLE KEYS */; +/*!40000 ALTER TABLE `drip_sequence_enrollments` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `drip_sequence_steps` +-- + +DROP TABLE IF EXISTS `drip_sequence_steps`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `drip_sequence_steps` ( + `id` int NOT NULL AUTO_INCREMENT, + `sequence_id` int NOT NULL, + `step_order` int NOT NULL, + `subject` varchar(500) NOT NULL, + `html_content` text NOT NULL, + `text_content` text, + `template_id` int DEFAULT NULL, + `delay_days` int NOT NULL, + `delay_hours` int NOT NULL, + `conditions` json DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `template_id` (`template_id`), + KEY `ix_drip_sequence_steps_sequence_id` (`sequence_id`), + KEY `ix_drip_sequence_steps_id` (`id`), + CONSTRAINT `drip_sequence_steps_ibfk_1` FOREIGN KEY (`sequence_id`) REFERENCES `drip_sequences` (`id`), + CONSTRAINT `drip_sequence_steps_ibfk_2` FOREIGN KEY (`template_id`) REFERENCES `email_templates` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `drip_sequence_steps` +-- + +LOCK TABLES `drip_sequence_steps` WRITE; +/*!40000 ALTER TABLE `drip_sequence_steps` DISABLE KEYS */; +/*!40000 ALTER TABLE `drip_sequence_steps` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `drip_sequences` +-- + +DROP TABLE IF EXISTS `drip_sequences`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `drip_sequences` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(200) NOT NULL, + `description` text, + `trigger_event` varchar(100) DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `created_by` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `created_by` (`created_by`), + KEY `ix_drip_sequences_id` (`id`), + KEY `ix_drip_sequences_name` (`name`), + CONSTRAINT `drip_sequences_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `drip_sequences` +-- + +LOCK TABLES `drip_sequences` WRITE; +/*!40000 ALTER TABLE `drip_sequences` DISABLE KEYS */; +/*!40000 ALTER TABLE `drip_sequences` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `email_campaigns` +-- + +DROP TABLE IF EXISTS `email_campaigns`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `email_campaigns` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(200) NOT NULL, + `subject` varchar(500) NOT NULL, + `campaign_type` enum('newsletter','promotional','transactional','abandoned_booking','welcome','drip','custom') NOT NULL, + `status` enum('draft','scheduled','sending','sent','paused','cancelled') NOT NULL, + `html_content` text, + `text_content` text, + `template_id` int DEFAULT NULL, + `scheduled_at` datetime DEFAULT NULL, + `sent_at` datetime DEFAULT NULL, + `segment_id` int DEFAULT NULL, + `segment_criteria` json DEFAULT NULL, + `is_ab_test` tinyint(1) NOT NULL, + `ab_test_variant_a_id` int DEFAULT NULL, + `ab_test_variant_b_id` int DEFAULT NULL, + `ab_test_split_percentage` int DEFAULT NULL, + `ab_test_winner` varchar(1) DEFAULT NULL, + `is_drip` tinyint(1) NOT NULL, + `drip_sequence_id` int DEFAULT NULL, + `drip_delay_days` int DEFAULT NULL, + `total_recipients` int NOT NULL, + `total_sent` int NOT NULL, + `total_delivered` int NOT NULL, + `total_opened` int NOT NULL, + `total_clicked` int NOT NULL, + `total_bounced` int NOT NULL, + `total_unsubscribed` int NOT NULL, + `open_rate` decimal(5,2) DEFAULT NULL, + `click_rate` decimal(5,2) DEFAULT NULL, + `bounce_rate` decimal(5,2) DEFAULT NULL, + `from_name` varchar(200) DEFAULT NULL, + `from_email` varchar(255) DEFAULT NULL, + `reply_to_email` varchar(255) DEFAULT NULL, + `track_opens` tinyint(1) NOT NULL, + `track_clicks` tinyint(1) NOT NULL, + `created_by` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `template_id` (`template_id`), + KEY `segment_id` (`segment_id`), + KEY `ab_test_variant_a_id` (`ab_test_variant_a_id`), + KEY `ab_test_variant_b_id` (`ab_test_variant_b_id`), + KEY `drip_sequence_id` (`drip_sequence_id`), + KEY `created_by` (`created_by`), + KEY `ix_email_campaigns_name` (`name`), + KEY `ix_email_campaigns_scheduled_at` (`scheduled_at`), + KEY `ix_email_campaigns_status` (`status`), + KEY `ix_email_campaigns_id` (`id`), + KEY `ix_email_campaigns_created_at` (`created_at`), + CONSTRAINT `email_campaigns_ibfk_1` FOREIGN KEY (`template_id`) REFERENCES `email_templates` (`id`), + CONSTRAINT `email_campaigns_ibfk_2` FOREIGN KEY (`segment_id`) REFERENCES `campaign_segments` (`id`), + CONSTRAINT `email_campaigns_ibfk_3` FOREIGN KEY (`ab_test_variant_a_id`) REFERENCES `email_campaigns` (`id`), + CONSTRAINT `email_campaigns_ibfk_4` FOREIGN KEY (`ab_test_variant_b_id`) REFERENCES `email_campaigns` (`id`), + CONSTRAINT `email_campaigns_ibfk_5` FOREIGN KEY (`drip_sequence_id`) REFERENCES `drip_sequences` (`id`), + CONSTRAINT `email_campaigns_ibfk_6` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `email_campaigns` +-- + +LOCK TABLES `email_campaigns` WRITE; +/*!40000 ALTER TABLE `email_campaigns` DISABLE KEYS */; +/*!40000 ALTER TABLE `email_campaigns` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `email_clicks` +-- + +DROP TABLE IF EXISTS `email_clicks`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `email_clicks` ( + `id` int NOT NULL AUTO_INCREMENT, + `campaign_email_id` int NOT NULL, + `url` varchar(1000) NOT NULL, + `clicked_at` datetime NOT NULL, + `ip_address` varchar(45) DEFAULT NULL, + `user_agent` varchar(500) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `ix_email_clicks_id` (`id`), + KEY `ix_email_clicks_campaign_email_id` (`campaign_email_id`), + KEY `ix_email_clicks_clicked_at` (`clicked_at`), + CONSTRAINT `email_clicks_ibfk_1` FOREIGN KEY (`campaign_email_id`) REFERENCES `campaign_emails` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `email_clicks` +-- + +LOCK TABLES `email_clicks` WRITE; +/*!40000 ALTER TABLE `email_clicks` DISABLE KEYS */; +/*!40000 ALTER TABLE `email_clicks` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `email_templates` +-- + +DROP TABLE IF EXISTS `email_templates`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `email_templates` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(200) NOT NULL, + `subject` varchar(500) NOT NULL, + `html_content` text NOT NULL, + `text_content` text, + `variables` json DEFAULT NULL, + `category` varchar(100) DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `is_system` tinyint(1) NOT NULL, + `created_by` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `created_by` (`created_by`), + KEY `ix_email_templates_name` (`name`), + KEY `ix_email_templates_id` (`id`), + KEY `ix_email_templates_category` (`category`), + CONSTRAINT `email_templates_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `email_templates` +-- + +LOCK TABLES `email_templates` WRITE; +/*!40000 ALTER TABLE `email_templates` DISABLE KEYS */; +/*!40000 ALTER TABLE `email_templates` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `email_unsubscribes` +-- + +DROP TABLE IF EXISTS `email_unsubscribes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `email_unsubscribes` ( + `id` int NOT NULL AUTO_INCREMENT, + `email` varchar(255) NOT NULL, + `user_id` int DEFAULT NULL, + `campaign_id` int DEFAULT NULL, + `unsubscribe_all` tinyint(1) NOT NULL, + `unsubscribe_type` varchar(50) DEFAULT NULL, + `reason` text, + `unsubscribed_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `campaign_id` (`campaign_id`), + KEY `ix_email_unsubscribes_email` (`email`), + KEY `ix_email_unsubscribes_unsubscribed_at` (`unsubscribed_at`), + KEY `ix_email_unsubscribes_id` (`id`), + KEY `ix_email_unsubscribes_user_id` (`user_id`), + CONSTRAINT `email_unsubscribes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `email_unsubscribes_ibfk_2` FOREIGN KEY (`campaign_id`) REFERENCES `email_campaigns` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `email_unsubscribes` +-- + +LOCK TABLES `email_unsubscribes` WRITE; +/*!40000 ALTER TABLE `email_unsubscribes` DISABLE KEYS */; +/*!40000 ALTER TABLE `email_unsubscribes` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `favorites` +-- + +DROP TABLE IF EXISTS `favorites`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `favorites` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `room_id` int NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `user_id` (`user_id`), + KEY `room_id` (`room_id`), + KEY `ix_favorites_id` (`id`), + CONSTRAINT `favorites_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `favorites_ibfk_2` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `favorites` +-- + +LOCK TABLES `favorites` WRITE; +/*!40000 ALTER TABLE `favorites` DISABLE KEYS */; +/*!40000 ALTER TABLE `favorites` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `gdpr_requests` +-- + +DROP TABLE IF EXISTS `gdpr_requests`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `gdpr_requests` ( + `id` int NOT NULL AUTO_INCREMENT, + `request_type` enum('data_export','data_deletion','data_rectification','consent_withdrawal') NOT NULL, + `status` enum('pending','processing','completed','rejected','cancelled') NOT NULL, + `user_id` int DEFAULT NULL, + `user_email` varchar(255) NOT NULL, + `request_data` json DEFAULT NULL, + `verification_token` varchar(255) DEFAULT NULL, + `verified_at` datetime DEFAULT NULL, + `processed_by` int DEFAULT NULL, + `processed_at` datetime DEFAULT NULL, + `processing_notes` text, + `export_file_path` varchar(500) DEFAULT NULL, + `deletion_log` json DEFAULT NULL, + `ip_address` varchar(45) DEFAULT NULL, + `user_agent` varchar(255) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `expires_at` datetime DEFAULT NULL, + `is_anonymous` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `ix_gdpr_requests_verification_token` (`verification_token`), + KEY `processed_by` (`processed_by`), + KEY `ix_gdpr_requests_id` (`id`), + KEY `ix_gdpr_requests_request_type` (`request_type`), + KEY `ix_gdpr_requests_status` (`status`), + KEY `ix_gdpr_requests_user_id` (`user_id`), + KEY `ix_gdpr_requests_is_anonymous` (`is_anonymous`), + CONSTRAINT `gdpr_requests_ibfk_1` FOREIGN KEY (`processed_by`) REFERENCES `users` (`id`), + CONSTRAINT `gdpr_requests_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `gdpr_requests` +-- + +LOCK TABLES `gdpr_requests` WRITE; +/*!40000 ALTER TABLE `gdpr_requests` DISABLE KEYS */; +/*!40000 ALTER TABLE `gdpr_requests` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `group_booking_members` +-- + +DROP TABLE IF EXISTS `group_booking_members`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `group_booking_members` ( + `id` int NOT NULL AUTO_INCREMENT, + `group_booking_id` int NOT NULL, + `full_name` varchar(100) NOT NULL, + `email` varchar(100) DEFAULT NULL, + `phone` varchar(20) DEFAULT NULL, + `user_id` int DEFAULT NULL, + `room_block_id` int DEFAULT NULL, + `assigned_room_id` int DEFAULT NULL, + `individual_booking_id` int DEFAULT NULL, + `special_requests` text, + `preferences` json DEFAULT NULL, + `individual_amount` decimal(10,2) DEFAULT NULL, + `individual_paid` decimal(10,2) DEFAULT NULL, + `individual_balance` decimal(10,2) DEFAULT NULL, + `is_checked_in` tinyint(1) NOT NULL, + `checked_in_at` datetime DEFAULT NULL, + `is_checked_out` tinyint(1) NOT NULL, + `checked_out_at` datetime DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `group_booking_id` (`group_booking_id`), + KEY `user_id` (`user_id`), + KEY `room_block_id` (`room_block_id`), + KEY `assigned_room_id` (`assigned_room_id`), + KEY `individual_booking_id` (`individual_booking_id`), + KEY `ix_group_booking_members_id` (`id`), + CONSTRAINT `group_booking_members_ibfk_1` FOREIGN KEY (`group_booking_id`) REFERENCES `group_bookings` (`id`), + CONSTRAINT `group_booking_members_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `group_booking_members_ibfk_3` FOREIGN KEY (`room_block_id`) REFERENCES `group_room_blocks` (`id`), + CONSTRAINT `group_booking_members_ibfk_4` FOREIGN KEY (`assigned_room_id`) REFERENCES `rooms` (`id`), + CONSTRAINT `group_booking_members_ibfk_5` FOREIGN KEY (`individual_booking_id`) REFERENCES `bookings` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `group_booking_members` +-- + +LOCK TABLES `group_booking_members` WRITE; +/*!40000 ALTER TABLE `group_booking_members` DISABLE KEYS */; +/*!40000 ALTER TABLE `group_booking_members` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `group_bookings` +-- + +DROP TABLE IF EXISTS `group_bookings`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `group_bookings` ( + `id` int NOT NULL AUTO_INCREMENT, + `group_booking_number` varchar(50) NOT NULL, + `coordinator_id` int NOT NULL, + `coordinator_name` varchar(100) NOT NULL, + `coordinator_email` varchar(100) NOT NULL, + `coordinator_phone` varchar(20) DEFAULT NULL, + `group_name` varchar(200) DEFAULT NULL, + `group_type` varchar(50) DEFAULT NULL, + `total_rooms` int NOT NULL, + `total_guests` int NOT NULL, + `check_in_date` datetime NOT NULL, + `check_out_date` datetime NOT NULL, + `base_rate_per_room` decimal(10,2) NOT NULL, + `group_discount_percentage` decimal(5,2) DEFAULT NULL, + `group_discount_amount` decimal(10,2) DEFAULT NULL, + `original_total_price` decimal(10,2) NOT NULL, + `discount_amount` decimal(10,2) DEFAULT NULL, + `total_price` decimal(10,2) NOT NULL, + `payment_option` enum('coordinator_pays_all','individual_payments','split_payment') NOT NULL, + `deposit_required` tinyint(1) NOT NULL, + `deposit_percentage` int DEFAULT NULL, + `deposit_amount` decimal(10,2) DEFAULT NULL, + `amount_paid` decimal(10,2) NOT NULL, + `balance_due` decimal(10,2) NOT NULL, + `status` enum('draft','pending','confirmed','partially_confirmed','checked_in','checked_out','cancelled') NOT NULL, + `cancellation_policy` text, + `cancellation_deadline` datetime DEFAULT NULL, + `cancellation_penalty_percentage` decimal(5,2) DEFAULT NULL, + `special_requests` text, + `notes` text, + `contract_terms` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `confirmed_at` datetime DEFAULT NULL, + `cancelled_at` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_group_bookings_group_booking_number` (`group_booking_number`), + KEY `coordinator_id` (`coordinator_id`), + KEY `ix_group_bookings_id` (`id`), + CONSTRAINT `group_bookings_ibfk_1` FOREIGN KEY (`coordinator_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `group_bookings` +-- + +LOCK TABLES `group_bookings` WRITE; +/*!40000 ALTER TABLE `group_bookings` DISABLE KEYS */; +/*!40000 ALTER TABLE `group_bookings` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `group_payments` +-- + +DROP TABLE IF EXISTS `group_payments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `group_payments` ( + `id` int NOT NULL AUTO_INCREMENT, + `group_booking_id` int NOT NULL, + `amount` decimal(10,2) NOT NULL, + `payment_method` varchar(50) NOT NULL, + `payment_type` varchar(50) NOT NULL, + `payment_status` varchar(50) NOT NULL, + `transaction_id` varchar(100) DEFAULT NULL, + `payment_date` datetime DEFAULT NULL, + `notes` text, + `paid_by_member_id` int DEFAULT NULL, + `paid_by_user_id` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `group_booking_id` (`group_booking_id`), + KEY `paid_by_member_id` (`paid_by_member_id`), + KEY `paid_by_user_id` (`paid_by_user_id`), + KEY `ix_group_payments_id` (`id`), + CONSTRAINT `group_payments_ibfk_1` FOREIGN KEY (`group_booking_id`) REFERENCES `group_bookings` (`id`), + CONSTRAINT `group_payments_ibfk_2` FOREIGN KEY (`paid_by_member_id`) REFERENCES `group_booking_members` (`id`), + CONSTRAINT `group_payments_ibfk_3` FOREIGN KEY (`paid_by_user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `group_payments` +-- + +LOCK TABLES `group_payments` WRITE; +/*!40000 ALTER TABLE `group_payments` DISABLE KEYS */; +/*!40000 ALTER TABLE `group_payments` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `group_room_blocks` +-- + +DROP TABLE IF EXISTS `group_room_blocks`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `group_room_blocks` ( + `id` int NOT NULL AUTO_INCREMENT, + `group_booking_id` int NOT NULL, + `room_type_id` int NOT NULL, + `rooms_blocked` int NOT NULL, + `rooms_confirmed` int NOT NULL, + `rooms_available` int NOT NULL, + `rate_per_room` decimal(10,2) NOT NULL, + `total_block_price` decimal(10,2) NOT NULL, + `is_active` tinyint(1) NOT NULL, + `block_released_at` datetime DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `group_booking_id` (`group_booking_id`), + KEY `room_type_id` (`room_type_id`), + KEY `ix_group_room_blocks_id` (`id`), + CONSTRAINT `group_room_blocks_ibfk_1` FOREIGN KEY (`group_booking_id`) REFERENCES `group_bookings` (`id`), + CONSTRAINT `group_room_blocks_ibfk_2` FOREIGN KEY (`room_type_id`) REFERENCES `room_types` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `group_room_blocks` +-- + +LOCK TABLES `group_room_blocks` WRITE; +/*!40000 ALTER TABLE `group_room_blocks` DISABLE KEYS */; +/*!40000 ALTER TABLE `group_room_blocks` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guest_communications` +-- + +DROP TABLE IF EXISTS `guest_communications`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `guest_communications` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `staff_id` int DEFAULT NULL, + `communication_type` enum('email','phone','sms','chat','in_person','other') NOT NULL, + `direction` enum('inbound','outbound') NOT NULL, + `subject` varchar(255) DEFAULT NULL, + `content` text NOT NULL, + `booking_id` int DEFAULT NULL, + `is_automated` tinyint(1) NOT NULL, + `communication_metadata` text, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `staff_id` (`staff_id`), + KEY `booking_id` (`booking_id`), + KEY `ix_guest_communications_user_id` (`user_id`), + KEY `ix_guest_communications_id` (`id`), + CONSTRAINT `guest_communications_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `guest_communications_ibfk_2` FOREIGN KEY (`staff_id`) REFERENCES `users` (`id`), + CONSTRAINT `guest_communications_ibfk_3` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `guest_communications` +-- + +LOCK TABLES `guest_communications` WRITE; +/*!40000 ALTER TABLE `guest_communications` DISABLE KEYS */; +INSERT INTO `guest_communications` VALUES (1,5,3,'in_person','outbound','late','late hours',NULL,0,NULL,'2025-11-22 17:04:28'); +/*!40000 ALTER TABLE `guest_communications` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guest_complaints` +-- + +DROP TABLE IF EXISTS `guest_complaints`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `guest_complaints` ( + `id` int NOT NULL AUTO_INCREMENT, + `guest_id` int NOT NULL, + `booking_id` int DEFAULT NULL, + `room_id` int DEFAULT NULL, + `category` enum('room_quality','service','cleanliness','noise','billing','staff_behavior','amenities','other') NOT NULL, + `priority` enum('low','medium','high','urgent') NOT NULL, + `status` enum('open','in_progress','resolved','closed','escalated') NOT NULL, + `title` varchar(255) NOT NULL, + `description` text NOT NULL, + `resolution` text, + `resolved_at` datetime DEFAULT NULL, + `resolved_by` int DEFAULT NULL, + `assigned_to` int DEFAULT NULL, + `escalated_to` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `closed_at` datetime DEFAULT NULL, + `guest_satisfaction_rating` int DEFAULT NULL, + `guest_feedback` text, + `internal_notes` text, + `attachments` json DEFAULT NULL, + `requires_follow_up` tinyint(1) NOT NULL, + `follow_up_date` datetime DEFAULT NULL, + `follow_up_completed` tinyint(1) NOT NULL, + PRIMARY KEY (`id`), + KEY `resolved_by` (`resolved_by`), + KEY `escalated_to` (`escalated_to`), + KEY `ix_guest_complaints_id` (`id`), + KEY `ix_guest_complaints_assigned_to` (`assigned_to`), + KEY `ix_guest_complaints_booking_id` (`booking_id`), + KEY `ix_guest_complaints_created_at` (`created_at`), + KEY `ix_guest_complaints_category` (`category`), + KEY `ix_guest_complaints_guest_id` (`guest_id`), + KEY `ix_guest_complaints_priority` (`priority`), + KEY `ix_guest_complaints_room_id` (`room_id`), + KEY `ix_guest_complaints_status` (`status`), + CONSTRAINT `guest_complaints_ibfk_1` FOREIGN KEY (`guest_id`) REFERENCES `users` (`id`), + CONSTRAINT `guest_complaints_ibfk_2` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `guest_complaints_ibfk_3` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`id`), + CONSTRAINT `guest_complaints_ibfk_4` FOREIGN KEY (`resolved_by`) REFERENCES `users` (`id`), + CONSTRAINT `guest_complaints_ibfk_5` FOREIGN KEY (`assigned_to`) REFERENCES `users` (`id`), + CONSTRAINT `guest_complaints_ibfk_6` FOREIGN KEY (`escalated_to`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `guest_complaints` +-- + +LOCK TABLES `guest_complaints` WRITE; +/*!40000 ALTER TABLE `guest_complaints` DISABLE KEYS */; +/*!40000 ALTER TABLE `guest_complaints` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guest_notes` +-- + +DROP TABLE IF EXISTS `guest_notes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `guest_notes` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `created_by` int NOT NULL, + `note` text NOT NULL, + `is_important` tinyint(1) NOT NULL, + `is_private` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `created_by` (`created_by`), + KEY `ix_guest_notes_user_id` (`user_id`), + KEY `ix_guest_notes_id` (`id`), + CONSTRAINT `guest_notes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `guest_notes_ibfk_2` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `guest_notes` +-- + +LOCK TABLES `guest_notes` WRITE; +/*!40000 ALTER TABLE `guest_notes` DISABLE KEYS */; +INSERT INTO `guest_notes` VALUES (1,5,3,'he wants more beer',1,0,'2025-11-22 17:04:01','2025-11-22 17:04:01'); +/*!40000 ALTER TABLE `guest_notes` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guest_preferences` +-- + +DROP TABLE IF EXISTS `guest_preferences`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `guest_preferences` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `preferred_room_location` varchar(100) DEFAULT NULL, + `preferred_floor` int DEFAULT NULL, + `preferred_room_type_id` int DEFAULT NULL, + `preferred_amenities` json DEFAULT NULL, + `special_requests` text, + `preferred_services` json DEFAULT NULL, + `preferred_contact_method` varchar(50) DEFAULT NULL, + `preferred_language` varchar(10) DEFAULT NULL, + `dietary_restrictions` json DEFAULT NULL, + `additional_preferences` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `preferred_room_type_id` (`preferred_room_type_id`), + KEY `ix_guest_preferences_user_id` (`user_id`), + KEY `ix_guest_preferences_id` (`id`), + CONSTRAINT `guest_preferences_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `guest_preferences_ibfk_2` FOREIGN KEY (`preferred_room_type_id`) REFERENCES `room_types` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `guest_preferences` +-- + +LOCK TABLES `guest_preferences` WRITE; +/*!40000 ALTER TABLE `guest_preferences` DISABLE KEYS */; +/*!40000 ALTER TABLE `guest_preferences` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guest_segment_associations` +-- + +DROP TABLE IF EXISTS `guest_segment_associations`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `guest_segment_associations` ( + `user_id` int NOT NULL, + `segment_id` int NOT NULL, + `assigned_at` datetime NOT NULL, + PRIMARY KEY (`user_id`,`segment_id`), + KEY `segment_id` (`segment_id`), + CONSTRAINT `guest_segment_associations_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `guest_segment_associations_ibfk_2` FOREIGN KEY (`segment_id`) REFERENCES `guest_segments` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `guest_segment_associations` +-- + +LOCK TABLES `guest_segment_associations` WRITE; +/*!40000 ALTER TABLE `guest_segment_associations` DISABLE KEYS */; +/*!40000 ALTER TABLE `guest_segment_associations` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guest_segments` +-- + +DROP TABLE IF EXISTS `guest_segments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `guest_segments` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL, + `description` text, + `criteria` json DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_guest_segments_name` (`name`), + KEY `ix_guest_segments_id` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `guest_segments` +-- + +LOCK TABLES `guest_segments` WRITE; +/*!40000 ALTER TABLE `guest_segments` DISABLE KEYS */; +/*!40000 ALTER TABLE `guest_segments` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guest_tag_associations` +-- + +DROP TABLE IF EXISTS `guest_tag_associations`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `guest_tag_associations` ( + `user_id` int NOT NULL, + `tag_id` int NOT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`user_id`,`tag_id`), + KEY `tag_id` (`tag_id`), + CONSTRAINT `guest_tag_associations_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `guest_tag_associations_ibfk_2` FOREIGN KEY (`tag_id`) REFERENCES `guest_tags` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `guest_tag_associations` +-- + +LOCK TABLES `guest_tag_associations` WRITE; +/*!40000 ALTER TABLE `guest_tag_associations` DISABLE KEYS */; +/*!40000 ALTER TABLE `guest_tag_associations` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `guest_tags` +-- + +DROP TABLE IF EXISTS `guest_tags`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `guest_tags` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `color` varchar(7) DEFAULT NULL, + `description` varchar(255) DEFAULT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_guest_tags_name` (`name`), + KEY `ix_guest_tags_id` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `guest_tags` +-- + +LOCK TABLES `guest_tags` WRITE; +/*!40000 ALTER TABLE `guest_tags` DISABLE KEYS */; +/*!40000 ALTER TABLE `guest_tags` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `housekeeping_tasks` +-- + +DROP TABLE IF EXISTS `housekeeping_tasks`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `housekeeping_tasks` ( + `id` int NOT NULL AUTO_INCREMENT, + `room_id` int NOT NULL, + `booking_id` int DEFAULT NULL, + `task_type` enum('checkout','stayover','vacant','inspection','turndown') NOT NULL, + `status` enum('pending','in_progress','completed','skipped','cancelled') NOT NULL, + `scheduled_time` datetime NOT NULL, + `started_at` datetime DEFAULT NULL, + `completed_at` datetime DEFAULT NULL, + `assigned_to` int DEFAULT NULL, + `created_by` int DEFAULT NULL, + `checklist_items` json DEFAULT NULL, + `notes` text, + `issues_found` text, + `inspected_by` int DEFAULT NULL, + `inspected_at` datetime DEFAULT NULL, + `inspection_notes` text, + `quality_score` int DEFAULT NULL, + `estimated_duration_minutes` int DEFAULT NULL, + `actual_duration_minutes` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `assigned_to` (`assigned_to`), + KEY `created_by` (`created_by`), + KEY `inspected_by` (`inspected_by`), + KEY `ix_housekeeping_tasks_room_id` (`room_id`), + KEY `ix_housekeeping_tasks_id` (`id`), + KEY `ix_housekeeping_tasks_booking_id` (`booking_id`), + KEY `ix_housekeeping_tasks_scheduled_time` (`scheduled_time`), + CONSTRAINT `housekeeping_tasks_ibfk_1` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`id`), + CONSTRAINT `housekeeping_tasks_ibfk_2` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `housekeeping_tasks_ibfk_3` FOREIGN KEY (`assigned_to`) REFERENCES `users` (`id`), + CONSTRAINT `housekeeping_tasks_ibfk_4` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`), + CONSTRAINT `housekeeping_tasks_ibfk_5` FOREIGN KEY (`inspected_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `housekeeping_tasks` +-- + +LOCK TABLES `housekeeping_tasks` WRITE; +/*!40000 ALTER TABLE `housekeeping_tasks` DISABLE KEYS */; +INSERT INTO `housekeeping_tasks` VALUES (1,39,NULL,'vacant','completed','2025-11-20 23:58:37',NULL,'2025-11-23 00:12:54',4,3,'[{\"item\": \"Deep clean bathroom\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Change linens\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Vacuum and mop\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Dust surfaces\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Check amenities\", \"notes\": \"\", \"completed\": true}]','test3',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2025-11-22 23:59:01','2025-11-23 00:12:54'),(2,1,NULL,'checkout','completed','2025-12-01 09:00:00','2025-12-01 13:24:03','2025-12-01 13:24:08',13,1,'[{\"item\": \"Bathroom cleaned\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Beds made with fresh linens\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Trash emptied\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Towels replaced\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Amenities restocked\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Floor vacuumed and mopped\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Surfaces dusted\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Windows and mirrors cleaned\", \"notes\": \"\", \"completed\": true}]','Test task for Room 101 - checkout cleaning',NULL,NULL,NULL,NULL,NULL,45,0,'2025-12-01 13:21:37','2025-12-01 13:24:08'),(3,2,NULL,'stayover','completed','2025-12-01 10:00:00','2025-12-01 13:24:21','2025-12-01 18:16:22',13,1,'[{\"item\": \"Beds made\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Trash emptied\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Towels replaced\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Bathroom cleaned\", \"notes\": \"\", \"completed\": true}]','Test task for Room 102 - stayover cleaning',NULL,NULL,NULL,NULL,NULL,30,292,'2025-12-01 13:21:37','2025-12-01 18:16:22'),(4,3,NULL,'vacant','completed','2025-12-01 11:00:00','2025-12-01 13:25:58','2025-12-01 13:26:06',13,1,'[{\"item\": \"Deep clean bathroom\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Change linens\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Vacuum and mop\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Dust surfaces\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Check amenities\", \"notes\": \"\", \"completed\": true}]','Test task for Room 103 - vacant cleaning',NULL,NULL,NULL,NULL,NULL,30,0,'2025-12-01 13:21:37','2025-12-01 13:26:06'),(5,4,NULL,'inspection','completed','2025-12-01 12:00:00','2025-12-01 18:16:25','2025-12-01 18:16:37',13,1,'[{\"item\": \"Check all amenities\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Test electronics\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Check for damages\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Verify cleanliness\", \"notes\": \"\", \"completed\": true}]','Test task for Room 104 - inspection cleaning',NULL,NULL,NULL,NULL,NULL,30,0,'2025-12-01 13:21:37','2025-12-01 18:16:37'),(6,5,NULL,'checkout','pending','2025-12-01 13:00:00',NULL,NULL,13,1,'[{\"item\": \"Bathroom cleaned\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Beds made with fresh linens\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Trash emptied\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Towels replaced\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Amenities restocked\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Floor vacuumed and mopped\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Surfaces dusted\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Windows and mirrors cleaned\", \"notes\": \"\", \"completed\": true}]','Test task for Room 105 - checkout cleaning',NULL,NULL,NULL,NULL,NULL,45,NULL,'2025-12-01 13:21:37','2025-12-01 18:25:02'),(7,22,NULL,'vacant','completed','2025-12-02 23:07:54','2025-12-02 23:07:55','2025-12-02 23:08:09',13,13,'[{\"item\": \"Deep clean bathroom\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Change linens\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Vacuum and mop\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Dust surfaces\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Check amenities\", \"notes\": \"\", \"completed\": true}]','Task created by housekeeping staff',NULL,NULL,NULL,NULL,NULL,45,0,'2025-12-02 23:07:54','2025-12-02 23:08:09'),(8,43,NULL,'vacant','completed','2025-12-02 23:08:29','2025-12-02 23:08:35','2025-12-02 23:08:40',13,13,'[{\"item\": \"Deep clean bathroom\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Change linens\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Vacuum and mop\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Dust surfaces\", \"notes\": \"\", \"completed\": true}, {\"item\": \"Check amenities\", \"notes\": \"\", \"completed\": true}]','Task created by housekeeping staff',NULL,NULL,NULL,NULL,NULL,45,0,'2025-12-02 23:08:35','2025-12-02 23:08:40'),(9,37,51,'checkout','pending','2025-12-02 23:22:46',NULL,NULL,NULL,1,'[{\"item\": \"Bathroom cleaned\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Beds made with fresh linens\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Trash emptied\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Towels replaced\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Amenities restocked\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Floor vacuumed and mopped\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Surfaces dusted\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Windows and mirrors cleaned\", \"notes\": \"\", \"completed\": false}]','Auto-created on checkout for booking BK-1764710565937-1153',NULL,NULL,NULL,NULL,NULL,45,NULL,'2025-12-02 23:22:46','2025-12-02 23:22:46'),(10,48,52,'checkout','pending','2025-12-02 23:22:46',NULL,NULL,NULL,1,'[{\"item\": \"Bathroom cleaned\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Beds made with fresh linens\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Trash emptied\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Towels replaced\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Amenities restocked\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Floor vacuumed and mopped\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Surfaces dusted\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Windows and mirrors cleaned\", \"notes\": \"\", \"completed\": false}]','Auto-created on checkout for booking BK-1764710565950-8846',NULL,NULL,NULL,NULL,NULL,45,NULL,'2025-12-02 23:22:46','2025-12-02 23:22:46'),(11,43,53,'checkout','pending','2025-12-02 23:22:46',NULL,NULL,NULL,1,'[{\"item\": \"Bathroom cleaned\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Beds made with fresh linens\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Trash emptied\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Towels replaced\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Amenities restocked\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Floor vacuumed and mopped\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Surfaces dusted\", \"notes\": \"\", \"completed\": false}, {\"item\": \"Windows and mirrors cleaned\", \"notes\": \"\", \"completed\": false}]','Auto-created on checkout for booking BK-1764710565957-5525',NULL,NULL,NULL,NULL,NULL,45,NULL,'2025-12-02 23:22:46','2025-12-02 23:22:46'); +/*!40000 ALTER TABLE `housekeeping_tasks` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `invoice_items` +-- + +DROP TABLE IF EXISTS `invoice_items`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `invoice_items` ( + `id` int NOT NULL AUTO_INCREMENT, + `invoice_id` int NOT NULL, + `description` varchar(500) NOT NULL, + `quantity` decimal(10,2) NOT NULL, + `unit_price` decimal(10,2) NOT NULL, + `tax_rate` decimal(5,2) NOT NULL, + `discount_amount` decimal(10,2) NOT NULL, + `line_total` decimal(10,2) NOT NULL, + `room_id` int DEFAULT NULL, + `service_id` int DEFAULT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `invoice_id` (`invoice_id`), + KEY `room_id` (`room_id`), + KEY `service_id` (`service_id`), + KEY `ix_invoice_items_id` (`id`), + CONSTRAINT `invoice_items_ibfk_1` FOREIGN KEY (`invoice_id`) REFERENCES `invoices` (`id`), + CONSTRAINT `invoice_items_ibfk_2` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`id`), + CONSTRAINT `invoice_items_ibfk_3` FOREIGN KEY (`service_id`) REFERENCES `services` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `invoice_items` +-- + +LOCK TABLES `invoice_items` WRITE; +/*!40000 ALTER TABLE `invoice_items` DISABLE KEYS */; +/*!40000 ALTER TABLE `invoice_items` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `invoices` +-- + +DROP TABLE IF EXISTS `invoices`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `invoices` ( + `id` int NOT NULL AUTO_INCREMENT, + `invoice_number` varchar(50) NOT NULL, + `booking_id` int NOT NULL, + `user_id` int NOT NULL, + `issue_date` datetime NOT NULL, + `due_date` datetime NOT NULL, + `paid_date` datetime DEFAULT NULL, + `subtotal` decimal(10,2) NOT NULL, + `tax_rate` decimal(5,2) NOT NULL, + `tax_amount` decimal(10,2) NOT NULL, + `discount_amount` decimal(10,2) NOT NULL, + `total_amount` decimal(10,2) NOT NULL, + `amount_paid` decimal(10,2) NOT NULL, + `balance_due` decimal(10,2) NOT NULL, + `status` enum('draft','sent','paid','overdue','cancelled') NOT NULL, + `is_proforma` tinyint(1) NOT NULL, + `company_name` varchar(200) DEFAULT NULL, + `company_address` text, + `company_phone` varchar(50) DEFAULT NULL, + `company_email` varchar(100) DEFAULT NULL, + `company_tax_id` varchar(100) DEFAULT NULL, + `company_logo_url` varchar(500) DEFAULT NULL, + `customer_name` varchar(200) NOT NULL, + `customer_email` varchar(100) NOT NULL, + `customer_address` text, + `customer_phone` varchar(50) DEFAULT NULL, + `customer_tax_id` varchar(100) DEFAULT NULL, + `notes` text, + `terms_and_conditions` text, + `payment_instructions` text, + `created_by_id` int DEFAULT NULL, + `updated_by_id` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_invoices_invoice_number` (`invoice_number`), + KEY `booking_id` (`booking_id`), + KEY `user_id` (`user_id`), + KEY `created_by_id` (`created_by_id`), + KEY `updated_by_id` (`updated_by_id`), + KEY `ix_invoices_id` (`id`), + CONSTRAINT `invoices_ibfk_1` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `invoices_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `invoices_ibfk_3` FOREIGN KEY (`created_by_id`) REFERENCES `users` (`id`), + CONSTRAINT `invoices_ibfk_4` FOREIGN KEY (`updated_by_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `invoices` +-- + +LOCK TABLES `invoices` WRITE; +/*!40000 ALTER TABLE `invoices` DISABLE KEYS */; +/*!40000 ALTER TABLE `invoices` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `ip_blacklist` +-- + +DROP TABLE IF EXISTS `ip_blacklist`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ip_blacklist` ( + `id` int NOT NULL AUTO_INCREMENT, + `ip_address` varchar(45) NOT NULL, + `reason` text, + `is_active` tinyint(1) NOT NULL, + `blocked_until` datetime DEFAULT NULL, + `created_by` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_ip_blacklist_ip_address` (`ip_address`), + KEY `created_by` (`created_by`), + KEY `ix_ip_blacklist_id` (`id`), + CONSTRAINT `ip_blacklist_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `ip_blacklist` +-- + +LOCK TABLES `ip_blacklist` WRITE; +/*!40000 ALTER TABLE `ip_blacklist` DISABLE KEYS */; +INSERT INTO `ip_blacklist` VALUES (1,'192.168.1.10','ban',0,NULL,3,'2025-11-23 12:15:02','2025-11-23 12:15:25'); +/*!40000 ALTER TABLE `ip_blacklist` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `ip_whitelist` +-- + +DROP TABLE IF EXISTS `ip_whitelist`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `ip_whitelist` ( + `id` int NOT NULL AUTO_INCREMENT, + `ip_address` varchar(45) NOT NULL, + `description` varchar(255) DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `created_by` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_ip_whitelist_ip_address` (`ip_address`), + KEY `created_by` (`created_by`), + KEY `ix_ip_whitelist_id` (`id`), + CONSTRAINT `ip_whitelist_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `ip_whitelist` +-- + +LOCK TABLES `ip_whitelist` WRITE; +/*!40000 ALTER TABLE `ip_whitelist` DISABLE KEYS */; +/*!40000 ALTER TABLE `ip_whitelist` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `loyalty_point_transactions` +-- + +DROP TABLE IF EXISTS `loyalty_point_transactions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `loyalty_point_transactions` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_loyalty_id` int NOT NULL, + `booking_id` int DEFAULT NULL, + `transaction_type` enum('earned','redeemed','expired','bonus','adjustment') NOT NULL, + `source` enum('booking','referral','birthday','anniversary','redemption','promotion','manual') NOT NULL, + `points` int NOT NULL, + `description` text, + `expires_at` datetime DEFAULT NULL, + `reference_number` varchar(100) DEFAULT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_loyalty_point_transactions_created_at` (`created_at`), + KEY `ix_loyalty_point_transactions_transaction_type` (`transaction_type`), + KEY `ix_loyalty_point_transactions_booking_id` (`booking_id`), + KEY `ix_loyalty_point_transactions_id` (`id`), + KEY `ix_loyalty_point_transactions_user_loyalty_id` (`user_loyalty_id`), + CONSTRAINT `loyalty_point_transactions_ibfk_1` FOREIGN KEY (`user_loyalty_id`) REFERENCES `user_loyalty` (`id`), + CONSTRAINT `loyalty_point_transactions_ibfk_2` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=243 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `loyalty_point_transactions` +-- + +LOCK TABLES `loyalty_point_transactions` WRITE; +/*!40000 ALTER TABLE `loyalty_point_transactions` DISABLE KEYS */; +INSERT INTO `loyalty_point_transactions` VALUES (1,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:39:56',NULL,'2025-11-21 19:39:56'),(2,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:39:56',NULL,'2025-11-21 19:39:56'),(3,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:36',NULL,'2025-11-21 19:40:36'),(4,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:36',NULL,'2025-11-21 19:40:36'),(5,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:40',NULL,'2025-11-21 19:40:40'),(6,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:40',NULL,'2025-11-21 19:40:40'),(7,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:46',NULL,'2025-11-21 19:40:46'),(8,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:46',NULL,'2025-11-21 19:40:46'),(9,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:49',NULL,'2025-11-21 19:40:49'),(10,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:49',NULL,'2025-11-21 19:40:49'),(11,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:50',NULL,'2025-11-21 19:40:50'),(12,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:50',NULL,'2025-11-21 19:40:50'),(13,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:50',NULL,'2025-11-21 19:40:50'),(14,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:50',NULL,'2025-11-21 19:40:50'),(15,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:50',NULL,'2025-11-21 19:40:50'),(16,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:50',NULL,'2025-11-21 19:40:50'),(17,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:51',NULL,'2025-11-21 19:40:51'),(18,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:51',NULL,'2025-11-21 19:40:51'),(19,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:51',NULL,'2025-11-21 19:40:51'),(20,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:51',NULL,'2025-11-21 19:40:51'),(21,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:51',NULL,'2025-11-21 19:40:51'),(22,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:51',NULL,'2025-11-21 19:40:51'),(23,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:51',NULL,'2025-11-21 19:40:51'),(24,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:51',NULL,'2025-11-21 19:40:51'),(25,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:51',NULL,'2025-11-21 19:40:51'),(26,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:52',NULL,'2025-11-21 19:40:52'),(27,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:52',NULL,'2025-11-21 19:40:52'),(28,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:52',NULL,'2025-11-21 19:40:52'),(29,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:52',NULL,'2025-11-21 19:40:52'),(30,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:52',NULL,'2025-11-21 19:40:52'),(31,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:52',NULL,'2025-11-21 19:40:52'),(32,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:52',NULL,'2025-11-21 19:40:52'),(33,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:52',NULL,'2025-11-21 19:40:52'),(34,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:52',NULL,'2025-11-21 19:40:52'),(35,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:52',NULL,'2025-11-21 19:40:52'),(36,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:52',NULL,'2025-11-21 19:40:52'),(37,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:40:53',NULL,'2025-11-21 19:40:53'),(38,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:40:53',NULL,'2025-11-21 19:40:53'),(39,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:05',NULL,'2025-11-21 19:41:05'),(40,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:05',NULL,'2025-11-21 19:41:05'),(41,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:05',NULL,'2025-11-21 19:41:05'),(42,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:05',NULL,'2025-11-21 19:41:05'),(43,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:05',NULL,'2025-11-21 19:41:05'),(44,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:05',NULL,'2025-11-21 19:41:05'),(45,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:05',NULL,'2025-11-21 19:41:05'),(46,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:05',NULL,'2025-11-21 19:41:05'),(47,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:06',NULL,'2025-11-21 19:41:06'),(48,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:06',NULL,'2025-11-21 19:41:06'),(49,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:06',NULL,'2025-11-21 19:41:06'),(50,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:06',NULL,'2025-11-21 19:41:06'),(51,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:06',NULL,'2025-11-21 19:41:06'),(52,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:06',NULL,'2025-11-21 19:41:06'),(53,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:06',NULL,'2025-11-21 19:41:06'),(54,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:06',NULL,'2025-11-21 19:41:06'),(55,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:06',NULL,'2025-11-21 19:41:06'),(56,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:06',NULL,'2025-11-21 19:41:06'),(57,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:07',NULL,'2025-11-21 19:41:07'),(58,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:07',NULL,'2025-11-21 19:41:07'),(59,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:07',NULL,'2025-11-21 19:41:07'),(60,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:07',NULL,'2025-11-21 19:41:07'),(61,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:07',NULL,'2025-11-21 19:41:07'),(62,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:07',NULL,'2025-11-21 19:41:07'),(63,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:07',NULL,'2025-11-21 19:41:07'),(64,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:07',NULL,'2025-11-21 19:41:07'),(65,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:07',NULL,'2025-11-21 19:41:07'),(66,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:07',NULL,'2025-11-21 19:41:07'),(67,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:08',NULL,'2025-11-21 19:41:08'),(68,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:08',NULL,'2025-11-21 19:41:08'),(69,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:08',NULL,'2025-11-21 19:41:08'),(70,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:08',NULL,'2025-11-21 19:41:08'),(71,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:08',NULL,'2025-11-21 19:41:08'),(72,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:08',NULL,'2025-11-21 19:41:08'),(73,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:08',NULL,'2025-11-21 19:41:08'),(74,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:08',NULL,'2025-11-21 19:41:08'),(75,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:08',NULL,'2025-11-21 19:41:08'),(76,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:08',NULL,'2025-11-21 19:41:08'),(77,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:09',NULL,'2025-11-21 19:41:09'),(78,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:09',NULL,'2025-11-21 19:41:09'),(79,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:09',NULL,'2025-11-21 19:41:09'),(80,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:09',NULL,'2025-11-21 19:41:09'),(81,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:09',NULL,'2025-11-21 19:41:09'),(82,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:09',NULL,'2025-11-21 19:41:09'),(83,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:09',NULL,'2025-11-21 19:41:09'),(84,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:09',NULL,'2025-11-21 19:41:09'),(85,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:09',NULL,'2025-11-21 19:41:09'),(86,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:10',NULL,'2025-11-21 19:41:10'),(87,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:10',NULL,'2025-11-21 19:41:10'),(88,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:10',NULL,'2025-11-21 19:41:10'),(89,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:10',NULL,'2025-11-21 19:41:10'),(90,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:10',NULL,'2025-11-21 19:41:10'),(91,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:10',NULL,'2025-11-21 19:41:10'),(92,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:10',NULL,'2025-11-21 19:41:10'),(93,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:10',NULL,'2025-11-21 19:41:10'),(94,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:10',NULL,'2025-11-21 19:41:10'),(95,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:11',NULL,'2025-11-21 19:41:11'),(96,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:11',NULL,'2025-11-21 19:41:11'),(97,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:11',NULL,'2025-11-21 19:41:11'),(98,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:11',NULL,'2025-11-21 19:41:11'),(99,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:11',NULL,'2025-11-21 19:41:11'),(100,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:11',NULL,'2025-11-21 19:41:11'),(101,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:11',NULL,'2025-11-21 19:41:11'),(102,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:11',NULL,'2025-11-21 19:41:11'),(103,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:11',NULL,'2025-11-21 19:41:11'),(104,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:11',NULL,'2025-11-21 19:41:11'),(105,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:12',NULL,'2025-11-21 19:41:12'),(106,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:12',NULL,'2025-11-21 19:41:12'),(107,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:12',NULL,'2025-11-21 19:41:12'),(108,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:12',NULL,'2025-11-21 19:41:12'),(109,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:55',NULL,'2025-11-21 19:41:55'),(110,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:55',NULL,'2025-11-21 19:41:55'),(111,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:56',NULL,'2025-11-21 19:41:56'),(112,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:56',NULL,'2025-11-21 19:41:56'),(113,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:56',NULL,'2025-11-21 19:41:56'),(114,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:56',NULL,'2025-11-21 19:41:56'),(115,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:56',NULL,'2025-11-21 19:41:56'),(116,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:56',NULL,'2025-11-21 19:41:56'),(117,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:56',NULL,'2025-11-21 19:41:56'),(118,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:56',NULL,'2025-11-21 19:41:56'),(119,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:56',NULL,'2025-11-21 19:41:56'),(120,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:56',NULL,'2025-11-21 19:41:56'),(121,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:56',NULL,'2025-11-21 19:41:56'),(122,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:56',NULL,'2025-11-21 19:41:56'),(123,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:57',NULL,'2025-11-21 19:41:57'),(124,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:57',NULL,'2025-11-21 19:41:57'),(125,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:57',NULL,'2025-11-21 19:41:57'),(126,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:57',NULL,'2025-11-21 19:41:57'),(127,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:57',NULL,'2025-11-21 19:41:57'),(128,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:57',NULL,'2025-11-21 19:41:57'),(129,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:57',NULL,'2025-11-21 19:41:57'),(130,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:57',NULL,'2025-11-21 19:41:57'),(131,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:57',NULL,'2025-11-21 19:41:57'),(132,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:57',NULL,'2025-11-21 19:41:57'),(133,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:57',NULL,'2025-11-21 19:41:57'),(134,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:57',NULL,'2025-11-21 19:41:57'),(135,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:58',NULL,'2025-11-21 19:41:58'),(136,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:58',NULL,'2025-11-21 19:41:58'),(137,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:58',NULL,'2025-11-21 19:41:58'),(138,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:58',NULL,'2025-11-21 19:41:58'),(139,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:58',NULL,'2025-11-21 19:41:58'),(140,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:58',NULL,'2025-11-21 19:41:58'),(141,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:58',NULL,'2025-11-21 19:41:58'),(142,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:58',NULL,'2025-11-21 19:41:58'),(143,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:58',NULL,'2025-11-21 19:41:58'),(144,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:58',NULL,'2025-11-21 19:41:58'),(145,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:58',NULL,'2025-11-21 19:41:58'),(146,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:58',NULL,'2025-11-21 19:41:58'),(147,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:59',NULL,'2025-11-21 19:41:59'),(148,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:59',NULL,'2025-11-21 19:41:59'),(149,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:59',NULL,'2025-11-21 19:41:59'),(150,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:59',NULL,'2025-11-21 19:41:59'),(151,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:59',NULL,'2025-11-21 19:41:59'),(152,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:59',NULL,'2025-11-21 19:41:59'),(153,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:59',NULL,'2025-11-21 19:41:59'),(154,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:59',NULL,'2025-11-21 19:41:59'),(155,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:59',NULL,'2025-11-21 19:41:59'),(156,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:59',NULL,'2025-11-21 19:41:59'),(157,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:41:59',NULL,'2025-11-21 19:41:59'),(158,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:41:59',NULL,'2025-11-21 19:41:59'),(159,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:00',NULL,'2025-11-21 19:42:00'),(160,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:00',NULL,'2025-11-21 19:42:00'),(161,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:00',NULL,'2025-11-21 19:42:00'),(162,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:00',NULL,'2025-11-21 19:42:00'),(163,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:00',NULL,'2025-11-21 19:42:00'),(164,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:00',NULL,'2025-11-21 19:42:00'),(165,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:00',NULL,'2025-11-21 19:42:00'),(166,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:00',NULL,'2025-11-21 19:42:00'),(167,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:00',NULL,'2025-11-21 19:42:00'),(168,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:00',NULL,'2025-11-21 19:42:00'),(169,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:01',NULL,'2025-11-21 19:42:01'),(170,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:01',NULL,'2025-11-21 19:42:01'),(171,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:01',NULL,'2025-11-21 19:42:01'),(172,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:01',NULL,'2025-11-21 19:42:01'),(173,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:01',NULL,'2025-11-21 19:42:01'),(174,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:01',NULL,'2025-11-21 19:42:01'),(175,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:01',NULL,'2025-11-21 19:42:01'),(176,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:01',NULL,'2025-11-21 19:42:01'),(177,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:08',NULL,'2025-11-21 19:42:08'),(178,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:08',NULL,'2025-11-21 19:42:08'),(179,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:08',NULL,'2025-11-21 19:42:08'),(180,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:08',NULL,'2025-11-21 19:42:08'),(181,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:09',NULL,'2025-11-21 19:42:09'),(182,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:09',NULL,'2025-11-21 19:42:09'),(183,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:09',NULL,'2025-11-21 19:42:09'),(184,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:09',NULL,'2025-11-21 19:42:09'),(185,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:09',NULL,'2025-11-21 19:42:09'),(186,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:09',NULL,'2025-11-21 19:42:09'),(187,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:09',NULL,'2025-11-21 19:42:09'),(188,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:09',NULL,'2025-11-21 19:42:09'),(189,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:09',NULL,'2025-11-21 19:42:09'),(190,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:09',NULL,'2025-11-21 19:42:09'),(191,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:09',NULL,'2025-11-21 19:42:09'),(192,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:09',NULL,'2025-11-21 19:42:09'),(193,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:10',NULL,'2025-11-21 19:42:10'),(194,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:10',NULL,'2025-11-21 19:42:10'),(195,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:10',NULL,'2025-11-21 19:42:10'),(196,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:10',NULL,'2025-11-21 19:42:10'),(197,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:10',NULL,'2025-11-21 19:42:10'),(198,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:10',NULL,'2025-11-21 19:42:10'),(199,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:10',NULL,'2025-11-21 19:42:10'),(200,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:10',NULL,'2025-11-21 19:42:10'),(201,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:10',NULL,'2025-11-21 19:42:10'),(202,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:10',NULL,'2025-11-21 19:42:10'),(203,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:11',NULL,'2025-11-21 19:42:11'),(204,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:11',NULL,'2025-11-21 19:42:11'),(205,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:11',NULL,'2025-11-21 19:42:11'),(206,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:11',NULL,'2025-11-21 19:42:11'),(207,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:11',NULL,'2025-11-21 19:42:11'),(208,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:11',NULL,'2025-11-21 19:42:11'),(209,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:11',NULL,'2025-11-21 19:42:11'),(210,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:11',NULL,'2025-11-21 19:42:11'),(211,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:12',NULL,'2025-11-21 19:42:12'),(212,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:12',NULL,'2025-11-21 19:42:12'),(213,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:12',NULL,'2025-11-21 19:42:12'),(214,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:12',NULL,'2025-11-21 19:42:12'),(215,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:12',NULL,'2025-11-21 19:42:12'),(216,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:12',NULL,'2025-11-21 19:42:12'),(217,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:12',NULL,'2025-11-21 19:42:12'),(218,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:12',NULL,'2025-11-21 19:42:12'),(219,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:12',NULL,'2025-11-21 19:42:12'),(220,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:12',NULL,'2025-11-21 19:42:12'),(221,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:12',NULL,'2025-11-21 19:42:12'),(222,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:12',NULL,'2025-11-21 19:42:12'),(223,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:13',NULL,'2025-11-21 19:42:13'),(224,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:13',NULL,'2025-11-21 19:42:13'),(225,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:13',NULL,'2025-11-21 19:42:13'),(226,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:13',NULL,'2025-11-21 19:42:13'),(227,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:13',NULL,'2025-11-21 19:42:13'),(228,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:13',NULL,'2025-11-21 19:42:13'),(229,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:13',NULL,'2025-11-21 19:42:13'),(230,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:13',NULL,'2025-11-21 19:42:13'),(231,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:13',NULL,'2025-11-21 19:42:13'),(232,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:13',NULL,'2025-11-21 19:42:13'),(233,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:14',NULL,'2025-11-21 19:42:14'),(234,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:14',NULL,'2025-11-21 19:42:14'),(235,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:14',NULL,'2025-11-21 19:42:14'),(236,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:14',NULL,'2025-11-21 19:42:14'),(237,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:14',NULL,'2025-11-21 19:42:14'),(238,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:14',NULL,'2025-11-21 19:42:14'),(239,1,NULL,'bonus','birthday',500,'Birthday bonus - Happy Birthday!','2026-11-21 19:42:14',NULL,'2025-11-21 19:42:14'),(240,1,NULL,'bonus','anniversary',1000,'Anniversary bonus - Thank you for your loyalty!','2026-11-21 19:42:14',NULL,'2025-11-21 19:42:14'),(241,1,NULL,'redeemed','redemption',-5000,'Points redeemed for 5% Booking Discount',NULL,'YK5NKXNEMIM8','2025-11-21 19:59:40'),(242,1,NULL,'redeemed','redemption',-8000,'Points redeemed for Breakfast for Two',NULL,'0F4U1XO9TW8D','2025-11-21 20:01:36'); +/*!40000 ALTER TABLE `loyalty_point_transactions` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `loyalty_rewards` +-- + +DROP TABLE IF EXISTS `loyalty_rewards`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `loyalty_rewards` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(200) NOT NULL, + `description` text, + `reward_type` enum('discount','room_upgrade','amenity','cashback','voucher') NOT NULL, + `points_cost` int NOT NULL, + `discount_percentage` decimal(5,2) DEFAULT NULL, + `discount_amount` decimal(10,2) DEFAULT NULL, + `max_discount_amount` decimal(10,2) DEFAULT NULL, + `applicable_tier_id` int DEFAULT NULL, + `min_booking_amount` decimal(10,2) DEFAULT NULL, + `icon` varchar(255) DEFAULT NULL, + `image` varchar(255) DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `stock_quantity` int DEFAULT NULL, + `redeemed_count` int NOT NULL, + `valid_from` datetime DEFAULT NULL, + `valid_until` datetime DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `applicable_tier_id` (`applicable_tier_id`), + KEY `ix_loyalty_rewards_id` (`id`), + KEY `ix_loyalty_rewards_reward_type` (`reward_type`), + CONSTRAINT `loyalty_rewards_ibfk_1` FOREIGN KEY (`applicable_tier_id`) REFERENCES `loyalty_tiers` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `loyalty_rewards` +-- + +LOCK TABLES `loyalty_rewards` WRITE; +/*!40000 ALTER TABLE `loyalty_rewards` DISABLE KEYS */; +INSERT INTO `loyalty_rewards` VALUES (1,'5% Booking Discount','Get 5% off your next booking. Valid for bookings over $100.','discount',5000,5.00,NULL,50.00,NULL,100.00,'🎫',NULL,1,NULL,1,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:40'),(2,'10% Booking Discount','Get 10% off your next booking. Valid for bookings over $200.','discount',10000,10.00,NULL,100.00,2,200.00,'🎫',NULL,1,NULL,0,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:29'),(3,'15% Premium Discount','Get 15% off your next booking. Maximum discount $150. Valid for bookings over $300.','discount',15000,15.00,NULL,150.00,3,300.00,'💎',NULL,1,NULL,0,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:29'),(4,'20% VIP Discount','Exclusive 20% discount for Platinum members. Maximum discount $200. Valid for bookings over $500.','discount',25000,20.00,NULL,200.00,4,500.00,'👑',NULL,1,NULL,0,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:29'),(5,'Complimentary Room Upgrade','Upgrade to the next room category at no extra cost. Subject to availability at check-in.','room_upgrade',20000,NULL,NULL,NULL,2,NULL,'🛏️',NULL,1,50,0,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:29'),(6,'Premium Suite Upgrade','Upgrade to a premium suite or executive room. Subject to availability.','room_upgrade',35000,NULL,NULL,NULL,3,NULL,'🏨',NULL,1,30,0,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:29'),(7,'Luxury Suite Upgrade','Upgrade to our most luxurious suite category. Ultimate comfort guaranteed. Subject to availability.','room_upgrade',50000,NULL,NULL,NULL,4,NULL,'✨',NULL,1,20,0,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:29'),(8,'Welcome Amenity Package','Complimentary welcome basket with fruits, chocolates, and wine upon arrival.','amenity',3000,NULL,NULL,NULL,NULL,NULL,'🍾',NULL,1,NULL,0,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:29'),(9,'Breakfast for Two','Complimentary breakfast buffet for two guests during your stay.','amenity',8000,NULL,NULL,NULL,NULL,NULL,'🍳',NULL,1,NULL,1,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 20:01:36'),(10,'Spa Treatment Voucher','One complimentary spa treatment of your choice (60 minutes). Valid for 90 days.','amenity',12000,NULL,NULL,NULL,2,NULL,'💆',NULL,1,40,0,NULL,'2026-02-19 19:59:29','2025-11-21 19:59:29','2025-11-21 19:59:29'),(11,'Romantic Dinner Package','Private romantic dinner for two with wine pairing at our fine dining restaurant.','amenity',18000,NULL,NULL,NULL,3,NULL,'🍽️',NULL,1,25,0,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:29'),(12,'VIP Airport Transfer','Complimentary luxury airport transfer (one-way) in premium vehicle.','amenity',15000,NULL,NULL,NULL,4,NULL,'🚗',NULL,1,20,0,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:29'),(13,'$50 Hotel Credit','Redeem for $50 credit towards room service, spa, or dining at the hotel. Valid for 6 months.','voucher',10000,NULL,50.00,NULL,NULL,NULL,'💳',NULL,1,NULL,0,NULL,'2026-05-20 19:59:29','2025-11-21 19:59:29','2025-11-21 19:59:29'),(14,'$100 Hotel Credit','Redeem for $100 credit towards any hotel service. Valid for 6 months.','voucher',20000,NULL,100.00,NULL,2,NULL,'💵',NULL,1,NULL,0,NULL,'2026-05-20 19:59:29','2025-11-21 19:59:29','2025-11-21 19:59:29'),(15,'$200 Premium Credit','Redeem for $200 credit towards premium services. Perfect for special occasions. Valid for 1 year.','voucher',40000,NULL,200.00,NULL,3,NULL,'💰',NULL,1,NULL,0,NULL,'2026-11-21 19:59:29','2025-11-21 19:59:29','2025-11-21 19:59:29'),(16,'Early Check-in Benefit','Guaranteed early check-in (12:00 PM) at no extra charge. Subject to availability.','amenity',2000,NULL,NULL,NULL,NULL,NULL,'⏰',NULL,1,NULL,0,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:29'),(17,'Late Check-out Benefit','Extended check-out until 2:00 PM at no extra charge. Subject to availability.','amenity',2000,NULL,NULL,NULL,NULL,NULL,'🕐',NULL,1,NULL,0,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:29'),(18,'Free Night Stay','One complimentary night stay in a standard room. Valid for bookings of 2+ nights.','voucher',30000,NULL,NULL,NULL,3,NULL,'🌙',NULL,1,15,0,NULL,'2026-05-20 19:59:29','2025-11-21 19:59:29','2025-11-21 19:59:29'),(19,'Complimentary Room Service','$75 credit for room service orders. Valid for one stay.','amenity',6000,NULL,75.00,NULL,NULL,NULL,'🍽️',NULL,1,NULL,0,NULL,NULL,'2025-11-21 19:59:29','2025-11-21 19:59:29'); +/*!40000 ALTER TABLE `loyalty_rewards` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `loyalty_tiers` +-- + +DROP TABLE IF EXISTS `loyalty_tiers`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `loyalty_tiers` ( + `id` int NOT NULL AUTO_INCREMENT, + `level` enum('bronze','silver','gold','platinum') NOT NULL, + `name` varchar(100) NOT NULL, + `description` text, + `min_points` int NOT NULL, + `points_earn_rate` decimal(5,2) NOT NULL, + `discount_percentage` decimal(5,2) DEFAULT NULL, + `benefits` text, + `icon` varchar(255) DEFAULT NULL, + `color` varchar(50) DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_loyalty_tiers_level` (`level`), + KEY `ix_loyalty_tiers_id` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `loyalty_tiers` +-- + +LOCK TABLES `loyalty_tiers` WRITE; +/*!40000 ALTER TABLE `loyalty_tiers` DISABLE KEYS */; +INSERT INTO `loyalty_tiers` VALUES (1,'bronze','Bronze','Starting tier - Earn points on every booking',0,1.00,0.00,'Welcome bonus points, Access to basic rewards',NULL,'#CD7F32',1,'2025-11-21 19:37:22','2025-11-21 19:37:22'),(2,'silver','Silver','Earn points faster with 1.25x multiplier',5000,1.25,2.00,'25% faster point earning, 2% member discount, Priority customer support',NULL,'#C0C0C0',1,'2025-11-21 19:37:22','2025-11-21 19:37:22'),(3,'gold','Gold','Premium tier with exclusive benefits',15000,1.50,5.00,'50% faster point earning, 5% member discount, Room upgrade priority, Exclusive rewards',NULL,'#FFD700',1,'2025-11-21 19:37:22','2025-11-21 19:37:22'),(4,'platinum','Platinum','Elite tier with maximum benefits',50000,2.00,10.00,'100% faster point earning, 10% member discount, Guaranteed room upgrades, Concierge service, Birthday & anniversary bonuses',NULL,'#E5E4E2',1,'2025-11-21 19:37:22','2025-11-21 19:37:22'); +/*!40000 ALTER TABLE `loyalty_tiers` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `notification_delivery_logs` +-- + +DROP TABLE IF EXISTS `notification_delivery_logs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `notification_delivery_logs` ( + `id` int NOT NULL AUTO_INCREMENT, + `notification_id` int NOT NULL, + `channel` enum('email','sms','push','whatsapp','in_app') NOT NULL, + `status` enum('pending','sent','delivered','failed','read') NOT NULL, + `external_id` varchar(255) DEFAULT NULL, + `error_message` text, + `response_data` json DEFAULT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `notification_id` (`notification_id`), + KEY `ix_notification_delivery_logs_id` (`id`), + CONSTRAINT `notification_delivery_logs_ibfk_1` FOREIGN KEY (`notification_id`) REFERENCES `notifications` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `notification_delivery_logs` +-- + +LOCK TABLES `notification_delivery_logs` WRITE; +/*!40000 ALTER TABLE `notification_delivery_logs` DISABLE KEYS */; +/*!40000 ALTER TABLE `notification_delivery_logs` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `notification_preferences` +-- + +DROP TABLE IF EXISTS `notification_preferences`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `notification_preferences` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `email_enabled` tinyint(1) NOT NULL, + `sms_enabled` tinyint(1) NOT NULL, + `push_enabled` tinyint(1) NOT NULL, + `whatsapp_enabled` tinyint(1) NOT NULL, + `in_app_enabled` tinyint(1) NOT NULL, + `booking_confirmation_email` tinyint(1) NOT NULL, + `booking_confirmation_sms` tinyint(1) NOT NULL, + `payment_receipt_email` tinyint(1) NOT NULL, + `payment_receipt_sms` tinyint(1) NOT NULL, + `pre_arrival_reminder_email` tinyint(1) NOT NULL, + `pre_arrival_reminder_sms` tinyint(1) NOT NULL, + `check_in_reminder_email` tinyint(1) NOT NULL, + `check_in_reminder_sms` tinyint(1) NOT NULL, + `check_out_reminder_email` tinyint(1) NOT NULL, + `check_out_reminder_sms` tinyint(1) NOT NULL, + `marketing_campaign_email` tinyint(1) NOT NULL, + `marketing_campaign_sms` tinyint(1) NOT NULL, + `loyalty_update_email` tinyint(1) NOT NULL, + `loyalty_update_sms` tinyint(1) NOT NULL, + `system_alert_email` tinyint(1) NOT NULL, + `system_alert_push` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `user_id` (`user_id`), + KEY `ix_notification_preferences_id` (`id`), + CONSTRAINT `notification_preferences_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `notification_preferences` +-- + +LOCK TABLES `notification_preferences` WRITE; +/*!40000 ALTER TABLE `notification_preferences` DISABLE KEYS */; +/*!40000 ALTER TABLE `notification_preferences` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `notification_templates` +-- + +DROP TABLE IF EXISTS `notification_templates`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `notification_templates` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `notification_type` enum('booking_confirmation','payment_receipt','pre_arrival_reminder','check_in_reminder','check_out_reminder','marketing_campaign','loyalty_update','system_alert','custom') NOT NULL, + `channel` enum('email','sms','push','whatsapp','in_app') NOT NULL, + `subject` varchar(255) DEFAULT NULL, + `content` text NOT NULL, + `variables` json DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `created_by` int NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `created_by` (`created_by`), + KEY `ix_notification_templates_id` (`id`), + CONSTRAINT `notification_templates_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `notification_templates` +-- + +LOCK TABLES `notification_templates` WRITE; +/*!40000 ALTER TABLE `notification_templates` DISABLE KEYS */; +/*!40000 ALTER TABLE `notification_templates` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `notifications` +-- + +DROP TABLE IF EXISTS `notifications`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `notifications` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int DEFAULT NULL, + `notification_type` enum('booking_confirmation','payment_receipt','pre_arrival_reminder','check_in_reminder','check_out_reminder','marketing_campaign','loyalty_update','system_alert','custom') NOT NULL, + `channel` enum('email','sms','push','whatsapp','in_app') NOT NULL, + `subject` varchar(255) DEFAULT NULL, + `content` text NOT NULL, + `template_id` int DEFAULT NULL, + `status` enum('pending','sent','delivered','failed','read') NOT NULL, + `priority` varchar(20) NOT NULL, + `scheduled_at` datetime DEFAULT NULL, + `sent_at` datetime DEFAULT NULL, + `delivered_at` datetime DEFAULT NULL, + `read_at` datetime DEFAULT NULL, + `error_message` text, + `external_id` varchar(255) DEFAULT NULL, + `meta_data` json DEFAULT NULL, + `booking_id` int DEFAULT NULL, + `payment_id` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `user_id` (`user_id`), + KEY `template_id` (`template_id`), + KEY `booking_id` (`booking_id`), + KEY `payment_id` (`payment_id`), + KEY `ix_notifications_id` (`id`), + CONSTRAINT `notifications_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `notifications_ibfk_2` FOREIGN KEY (`template_id`) REFERENCES `notification_templates` (`id`), + CONSTRAINT `notifications_ibfk_3` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `notifications_ibfk_4` FOREIGN KEY (`payment_id`) REFERENCES `payments` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `notifications` +-- + +LOCK TABLES `notifications` WRITE; +/*!40000 ALTER TABLE `notifications` DISABLE KEYS */; +/*!40000 ALTER TABLE `notifications` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `oauth_providers` +-- + +DROP TABLE IF EXISTS `oauth_providers`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `oauth_providers` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `display_name` varchar(100) NOT NULL, + `client_id` varchar(500) NOT NULL, + `client_secret` varchar(500) NOT NULL, + `authorization_url` varchar(500) NOT NULL, + `token_url` varchar(500) NOT NULL, + `userinfo_url` varchar(500) NOT NULL, + `scopes` varchar(500) DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `is_sso_enabled` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`), + KEY `ix_oauth_providers_id` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `oauth_providers` +-- + +LOCK TABLES `oauth_providers` WRITE; +/*!40000 ALTER TABLE `oauth_providers` DISABLE KEYS */; +/*!40000 ALTER TABLE `oauth_providers` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `oauth_tokens` +-- + +DROP TABLE IF EXISTS `oauth_tokens`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `oauth_tokens` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `provider_id` int NOT NULL, + `provider_user_id` varchar(255) NOT NULL, + `access_token` text NOT NULL, + `refresh_token` text, + `token_type` varchar(50) DEFAULT NULL, + `expires_at` datetime DEFAULT NULL, + `scopes` varchar(500) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `provider_id` (`provider_id`), + KEY `ix_oauth_tokens_user_id` (`user_id`), + KEY `ix_oauth_tokens_id` (`id`), + CONSTRAINT `oauth_tokens_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `oauth_tokens_ibfk_2` FOREIGN KEY (`provider_id`) REFERENCES `oauth_providers` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `oauth_tokens` +-- + +LOCK TABLES `oauth_tokens` WRITE; +/*!40000 ALTER TABLE `oauth_tokens` DISABLE KEYS */; +/*!40000 ALTER TABLE `oauth_tokens` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `package_items` +-- + +DROP TABLE IF EXISTS `package_items`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `package_items` ( + `id` int NOT NULL AUTO_INCREMENT, + `package_id` int NOT NULL, + `item_type` enum('room','service','breakfast','activity','amenity','discount') NOT NULL, + `item_id` int DEFAULT NULL, + `item_name` varchar(200) NOT NULL, + `item_description` text, + `quantity` int NOT NULL, + `unit` varchar(50) DEFAULT NULL, + `price` decimal(10,2) DEFAULT NULL, + `included` tinyint(1) NOT NULL, + `price_modifier` decimal(5,2) DEFAULT NULL, + `display_order` int NOT NULL, + `extra_data` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_package_items_id` (`id`), + KEY `ix_package_items_package_id` (`package_id`), + CONSTRAINT `package_items_ibfk_1` FOREIGN KEY (`package_id`) REFERENCES `packages` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `package_items` +-- + +LOCK TABLES `package_items` WRITE; +/*!40000 ALTER TABLE `package_items` DISABLE KEYS */; +/*!40000 ALTER TABLE `package_items` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `packages` +-- + +DROP TABLE IF EXISTS `packages`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `packages` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL, + `code` varchar(50) NOT NULL, + `description` text, + `status` enum('active','inactive','scheduled','expired') NOT NULL, + `base_price` decimal(10,2) DEFAULT NULL, + `price_modifier` decimal(5,2) NOT NULL, + `discount_percentage` decimal(5,2) DEFAULT NULL, + `room_type_id` int DEFAULT NULL, + `min_nights` int DEFAULT NULL, + `max_nights` int DEFAULT NULL, + `valid_from` date DEFAULT NULL, + `valid_to` date DEFAULT NULL, + `image_url` varchar(500) DEFAULT NULL, + `highlights` json DEFAULT NULL, + `terms_conditions` text, + `extra_data` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_packages_code` (`code`), + KEY `room_type_id` (`room_type_id`), + KEY `ix_packages_id` (`id`), + KEY `ix_packages_name` (`name`), + CONSTRAINT `packages_ibfk_1` FOREIGN KEY (`room_type_id`) REFERENCES `room_types` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `packages` +-- + +LOCK TABLES `packages` WRITE; +/*!40000 ALTER TABLE `packages` DISABLE KEYS */; +/*!40000 ALTER TABLE `packages` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `page_contents` +-- + +DROP TABLE IF EXISTS `page_contents`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `page_contents` ( + `id` int NOT NULL AUTO_INCREMENT, + `page_type` varchar(50) NOT NULL, + `title` varchar(500) DEFAULT NULL, + `subtitle` varchar(1000) DEFAULT NULL, + `description` text, + `content` text, + `meta_title` varchar(500) DEFAULT NULL, + `meta_description` text, + `meta_keywords` varchar(1000) DEFAULT NULL, + `og_title` varchar(500) DEFAULT NULL, + `og_description` text, + `og_image` varchar(1000) DEFAULT NULL, + `canonical_url` varchar(1000) DEFAULT NULL, + `contact_info` text, + `map_url` varchar(1000) DEFAULT NULL, + `social_links` text, + `footer_links` text, + `badges` text, + `copyright_text` text, + `hero_title` varchar(500) DEFAULT NULL, + `hero_subtitle` varchar(1000) DEFAULT NULL, + `hero_image` varchar(1000) DEFAULT NULL, + `story_content` text, + `values` text, + `features` text, + `about_hero_image` text, + `mission` text, + `vision` text, + `team` text, + `timeline` text, + `achievements` text, + `luxury_section_title` text, + `luxury_section_subtitle` text, + `luxury_section_image` text, + `luxury_features` text, + `luxury_gallery_section_title` text, + `luxury_gallery_section_subtitle` text, + `luxury_gallery` text, + `luxury_testimonials_section_title` text, + `luxury_testimonials_section_subtitle` text, + `luxury_testimonials` text, + `amenities_section_title` varchar(500) DEFAULT NULL, + `amenities_section_subtitle` varchar(1000) DEFAULT NULL, + `amenities` text, + `testimonials_section_title` varchar(500) DEFAULT NULL, + `testimonials_section_subtitle` varchar(1000) DEFAULT NULL, + `testimonials` text, + `gallery_section_title` varchar(500) DEFAULT NULL, + `gallery_section_subtitle` varchar(1000) DEFAULT NULL, + `gallery_images` text, + `about_preview_title` varchar(500) DEFAULT NULL, + `about_preview_subtitle` varchar(1000) DEFAULT NULL, + `about_preview_content` text, + `about_preview_image` varchar(1000) DEFAULT NULL, + `stats` text, + `luxury_services_section_title` text, + `luxury_services_section_subtitle` text, + `luxury_services` text, + `luxury_experiences_section_title` text, + `luxury_experiences_section_subtitle` text, + `luxury_experiences` text, + `awards_section_title` text, + `awards_section_subtitle` text, + `awards` text, + `cta_title` text, + `cta_subtitle` text, + `cta_button_text` text, + `cta_button_link` text, + `cta_image` text, + `partners_section_title` text, + `partners_section_subtitle` text, + `partners` text, + `is_active` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_page_contents_page_type` (`page_type`), + KEY `ix_page_contents_id` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `page_contents` +-- + +LOCK TABLES `page_contents` WRITE; +/*!40000 ALTER TABLE `page_contents` DISABLE KEYS */; +INSERT INTO `page_contents` VALUES (1,'about','About Luxury Hotel','Where Excellence Meets Unforgettable Experiences','Discover the story behind our commitment to luxury hospitality and exceptional service.',NULL,'About Us - Luxury Hotel | Our Story, Mission & Vision','Learn about Luxury Hotel\'s commitment to excellence, our story, values, and the dedicated team that makes every stay unforgettable.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'For over three decades, Luxury Hotel has been a beacon of excellence in the hospitality industry. Founded with a vision to redefine luxury travel, we have grown from a single property to a collection of world-renowned destinations, each offering a unique blend of timeless elegance and modern sophistication. Our journey has been marked by countless awards, memorable moments, and the unwavering trust of our guests who return year after year.','[{\"icon\": \"Heart\", \"title\": \"Passion\", \"description\": \"We are passionate about hospitality and dedicated to creating exceptional experiences for every guest.\"}, {\"icon\": \"Award\", \"title\": \"Excellence\", \"description\": \"We strive for excellence in every aspect of our service, from the smallest detail to the grandest gesture.\"}, {\"icon\": \"Shield\", \"title\": \"Integrity\", \"description\": \"We conduct our business with honesty, transparency, and respect for our guests and community.\"}, {\"icon\": \"Users\", \"title\": \"Service\", \"description\": \"Our guests are at the heart of everything we do. Your comfort and satisfaction are our top priorities.\"}]','[{\"icon\": \"Star\", \"title\": \"Premium Accommodations\", \"description\": \"Luxuriously appointed rooms and suites designed for ultimate comfort and relaxation.\"}, {\"icon\": \"Clock\", \"title\": \"24/7 Service\", \"description\": \"Round-the-clock concierge and room service to attend to your needs at any time.\"}, {\"icon\": \"Award\", \"title\": \"Award-Winning\", \"description\": \"Recognized for excellence in hospitality and guest satisfaction.\"}]','https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1920&h=1080&fit=crop','To provide unparalleled luxury hospitality experiences that exceed expectations, creating lasting memories for our guests through exceptional service, attention to detail, and genuine care.','To be recognized as the world\'s premier luxury hotel brand, setting the standard for excellence in hospitality while maintaining our commitment to sustainability and community engagement.','[{\"name\": \"Sarah Johnson\", \"role\": \"General Manager\", \"image\": \"https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=400&h=400&fit=crop\", \"bio\": \"With over 15 years of experience in luxury hospitality, Sarah leads our team with passion and dedication.\", \"social_links\": {\"linkedin\": \"https://linkedin.com/in/sarahjohnson\", \"twitter\": \"https://twitter.com/sarahjohnson\"}}, {\"name\": \"Michael Chen\", \"role\": \"Head Chef\", \"image\": \"https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&h=400&fit=crop\", \"bio\": \"Award-winning chef with expertise in international cuisine, bringing world-class dining experiences to our guests.\", \"social_links\": {\"linkedin\": \"https://linkedin.com/in/michaelchen\", \"twitter\": \"https://twitter.com/michaelchen\"}}, {\"name\": \"Emily Rodriguez\", \"role\": \"Guest Relations Manager\", \"image\": \"https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=400&h=400&fit=crop\", \"bio\": \"Ensuring every guest feels valued and receives personalized attention throughout their stay.\", \"social_links\": {\"linkedin\": \"https://linkedin.com/in/emilyrodriguez\"}}]','[{\"year\": \"2010\", \"title\": \"Grand Opening\", \"description\": \"Luxury Hotel opened its doors, welcoming guests to a new standard of luxury hospitality.\", \"image\": \"https://images.unsplash.com/photo-1566073771259-6a8506099945?w=800&h=600&fit=crop\"}, {\"year\": \"2015\", \"title\": \"First Award\", \"description\": \"Received our first \'Best Luxury Hotel\' award, recognizing our commitment to excellence.\", \"image\": \"https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=800&h=600&fit=crop\"}, {\"year\": \"2018\", \"title\": \"Major Renovation\", \"description\": \"Completed a comprehensive renovation, adding state-of-the-art facilities and expanding our capacity.\", \"image\": \"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=800&h=600&fit=crop\"}, {\"year\": \"2020\", \"title\": \"Sustainability Initiative\", \"description\": \"Launched our sustainability program, committing to eco-friendly practices and community engagement.\", \"image\": \"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=800&h=600&fit=crop\"}, {\"year\": \"2023\", \"title\": \"International Recognition\", \"description\": \"Achieved international recognition as one of the world\'s top luxury hotels.\", \"image\": \"https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=800&h=600&fit=crop\"}]','[{\"icon\": \"Award\", \"title\": \"Best Luxury Hotel 2023\", \"description\": \"Recognized as the best luxury hotel in the region for exceptional service and amenities.\", \"year\": \"2023\", \"image\": \"https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=400&h=300&fit=crop\"}, {\"icon\": \"Star\", \"title\": \"5-Star Rating\", \"description\": \"Maintained our prestigious 5-star rating for over a decade, a testament to our consistent excellence.\", \"year\": \"2022\", \"image\": \"https://images.unsplash.com/photo-1566073771259-6a8506099945?w=400&h=300&fit=crop\"}, {\"icon\": \"Award\", \"title\": \"Sustainable Hotel of the Year\", \"description\": \"Awarded for our commitment to environmental sustainability and green practices.\", \"year\": \"2021\", \"image\": \"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=400&h=300&fit=crop\"}, {\"icon\": \"Users\", \"title\": \"Guest Satisfaction Excellence\", \"description\": \"Achieved 98% guest satisfaction rate, the highest in our category.\", \"year\": \"2023\", \"image\": \"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=400&h=300&fit=crop\"}]',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,'2025-11-21 12:24:20','2025-11-21 12:24:20'),(2,'home','Luxury Hotel - Experience Unparalleled Elegance','Where timeless luxury meets modern sophistication','Discover a world of refined elegance and exceptional service','','','','','','','',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'Welcome to Luxury','Experience the pinnacle of hospitality','https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200',NULL,NULL,'[{\"icon\": \"Shield\", \"title\": \"Secure & Safe\", \"description\": \"24/7 security and state-of-the-art safety systems\"}, {\"icon\": \"Wifi\", \"title\": \"Free WiFi\", \"description\": \"High-speed internet access throughout the property\"}, {\"icon\": \"Coffee\", \"title\": \"Room Service\", \"description\": \"24/7 room service available for your convenience\"}, {\"icon\": \"Car\", \"title\": \"Parking\", \"description\": \"Complimentary valet parking for all guests\"}, {\"icon\": \"UtensilsCrossed\", \"title\": \"Fine Dining\", \"description\": \"World-class restaurants and dining experiences\"}, {\"icon\": \"Dumbbell\", \"title\": \"Fitness Center\", \"description\": \"State-of-the-art fitness facilities\"}]',NULL,NULL,NULL,NULL,NULL,NULL,'Experience Unparalleled Luxury','Where elegance meets comfort in every detail','https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=1200','[{\"icon\": \"Sparkles\", \"title\": \"Premium Amenities\", \"description\": \"World-class facilities designed for your comfort and relaxation\"}, {\"icon\": \"Crown\", \"title\": \"Royal Service\", \"description\": \"Dedicated concierge service available 24/7 for all your needs\"}, {\"icon\": \"Award\", \"title\": \"Award-Winning\", \"description\": \"Recognized for excellence in hospitality and guest satisfaction\"}, {\"icon\": \"Shield\", \"title\": \"Secure & Private\", \"description\": \"Your privacy and security are our top priorities\"}, {\"icon\": \"Heart\", \"title\": \"Personalized Care\", \"description\": \"Tailored experiences crafted just for you\"}, {\"icon\": \"Gem\", \"title\": \"Luxury Design\", \"description\": \"Elegantly designed spaces with attention to every detail\"}]','Our Luxury Gallery','A glimpse into our world of elegance','[\"https://images.unsplash.com/photo-1566073771259-6a8506099945?w=800\", \"https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=800\", \"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=800\", \"https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=800\", \"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=800\", \"https://images.unsplash.com/photo-1551882547-ff40c63fe5fa?w=800\"]','What Our Guests Say','Testimonials from our valued guests','[{\"name\": \"Sarah Johnson\", \"title\": \"Business Executive\", \"quote\": \"An absolutely stunning experience. The attention to detail and level of service exceeded all expectations.\", \"image\": \"https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=200\"}, {\"name\": \"Michael Chen\", \"title\": \"Travel Enthusiast\", \"quote\": \"The epitome of luxury. Every moment was perfect, from check-in to check-out.\", \"image\": \"https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=200\"}, {\"name\": \"Emma Williams\", \"title\": \"Luxury Traveler\", \"quote\": \"This hotel redefines what luxury means. I will definitely return.\", \"image\": \"https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=200\"}]','Premium Amenities','Everything you need for a perfect stay','[{\"icon\": \"Wifi\", \"title\": \"High-Speed WiFi\", \"description\": \"Complimentary high-speed internet throughout the property\", \"image\": \"\"}, {\"icon\": \"Coffee\", \"title\": \"24/7 Room Service\", \"description\": \"Round-the-clock dining and beverage service\", \"image\": \"\"}, {\"icon\": \"Car\", \"title\": \"Valet Parking\", \"description\": \"Complimentary valet parking for all guests\", \"image\": \"\"}, {\"icon\": \"Plane\", \"title\": \"Airport Transfer\", \"description\": \"Luxury airport transfer service available\", \"image\": \"\"}]','Guest Reviews','Hear from our satisfied guests','[{\"name\": \"Robert Martinez\", \"role\": \"CEO, Tech Corp\", \"image\": \"https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=200\", \"rating\": 5, \"comment\": \"Exceptional service and attention to detail. The staff went above and beyond to make our stay memorable.\"}, {\"name\": \"Lisa Anderson\", \"role\": \"Travel Blogger\", \"image\": \"https://images.unsplash.com/photo-1487412720507-e7ab37603c6f?w=200\", \"rating\": 5, \"comment\": \"The most luxurious hotel experience I\'ve ever had. Every detail was perfect.\"}, {\"name\": \"David Thompson\", \"role\": \"Investment Banker\", \"image\": \"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=200\", \"rating\": 5, \"comment\": \"Outstanding facilities and impeccable service. Highly recommend for business travelers.\"}]','Photo Gallery','Explore our beautiful spaces','[\"https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=800\", \"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=800\", \"https://images.unsplash.com/photo-1551882547-ff40c63fe5fa?w=800\", \"https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=800\", \"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=800\", \"https://images.unsplash.com/photo-1566073771259-6a8506099945?w=800\"]','About Our Luxury Hotel','A legacy of excellence','Discover a world of refined elegance and exceptional service. Our hotel combines timeless luxury with modern amenities to create an unforgettable experience. With over 50,000 satisfied guests and numerous awards, we continue to set the standard for luxury hospitality.','https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=800','[{\"icon\": \"Users\", \"number\": \"50,000+\", \"label\": \"Happy Guests\"}, {\"icon\": \"Award\", \"number\": \"25+\", \"label\": \"Awards Won\"}, {\"icon\": \"Star\", \"number\": \"4.9\", \"label\": \"Average Rating\"}, {\"icon\": \"Globe\", \"number\": \"100+\", \"label\": \"Countries Served\"}]','Premium Services','Indulge in our world-class amenities','[{\"icon\": \"UtensilsCrossed\", \"title\": \"Fine Dining\", \"description\": \"Michelin-starred restaurants offering world-class cuisine\", \"image\": \"https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?w=600\"}, {\"icon\": \"Wine\", \"title\": \"Premium Bar\", \"description\": \"Extensive wine collection and craft cocktails in elegant settings\", \"image\": \"https://images.unsplash.com/photo-1514362545857-3bc16c4c7d1b?w=600\"}, {\"icon\": \"Dumbbell\", \"title\": \"Spa & Wellness\", \"description\": \"Rejuvenating spa treatments and state-of-the-art fitness center\", \"image\": \"https://images.unsplash.com/photo-1544161515-4ab6ce6db874?w=600\"}, {\"icon\": \"Car\", \"title\": \"Concierge Services\", \"description\": \"Personalized assistance for all your travel and entertainment needs\", \"image\": \"https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=600\"}]','Exclusive Experiences','Create unforgettable memories','[{\"icon\": \"Sunset\", \"title\": \"Sunset Rooftop\", \"description\": \"Breathtaking views and exclusive rooftop experiences\", \"image\": \"https://images.unsplash.com/photo-1514933651103-005eec06c04b?w=600\"}, {\"icon\": \"Ship\", \"title\": \"Yacht Excursions\", \"description\": \"Private yacht charters for unforgettable sea adventures\", \"image\": \"https://images.unsplash.com/photo-1544551763-46a013bb70d5?w=600\"}, {\"icon\": \"Music\", \"title\": \"Live Entertainment\", \"description\": \"World-class performances and exclusive events\", \"image\": \"https://images.unsplash.com/photo-1470229722913-7c0e2dbbafd3?w=600\"}, {\"icon\": \"Palette\", \"title\": \"Art & Culture\", \"description\": \"Curated art collections and cultural experiences\", \"image\": \"https://images.unsplash.com/photo-1578301978018-3005759f48f7?w=600\"}]','Awards & Recognition','Recognized for excellence worldwide','[{\"icon\": \"Trophy\", \"title\": \"Best Luxury Hotel 2024\", \"description\": \"Awarded by International Luxury Travel Association\", \"image\": \"https://images.unsplash.com/photo-1579783902614-a3fb3927b6a5?w=400\", \"year\": \"2024\"}, {\"icon\": \"Star\", \"title\": \"5-Star Excellence\", \"description\": \"Consistently rated 5 stars by leading travel publications\", \"image\": \"https://images.unsplash.com/photo-1606761568499-6d2451b23c66?w=400\", \"year\": \"2023\"}, {\"icon\": \"Award\", \"title\": \"Sustainable Luxury\", \"description\": \"Recognized for environmental responsibility and sustainability\", \"image\": \"https://images.unsplash.com/photo-1473341304170-971dccb5ac1e?w=400\", \"year\": \"2024\"}]','Ready to Experience Luxury?','Book your stay today and discover the difference','Book Now','/rooms','https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200','Our Partners','Trusted by leading brands','[{\"name\": \"Luxury Travel Group\", \"logo\": \"https://images.unsplash.com/photo-1599305445671-ac291c95aaa9?w=200\", \"link\": \"#\"}, {\"name\": \"Premium Airlines\", \"logo\": \"https://images.unsplash.com/photo-1436491865332-7a61a109cc05?w=200\", \"link\": \"#\"}, {\"name\": \"Exclusive Events\", \"logo\": \"https://images.unsplash.com/photo-1511578314322-379afb476865?w=200\", \"link\": \"#\"}, {\"name\": \"Fine Dining Network\", \"logo\": \"https://images.unsplash.com/photo-1555396273-367ea4eb4db5?w=200\", \"link\": \"#\"}]',1,'2025-11-21 12:24:21','2025-12-02 06:04:24'),(3,'footer','Luxury Hotel','Experience Unparalleled Elegance','Your gateway to luxury hospitality and exceptional service',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'{\"phone\": \"+1 (555) 123-4567\", \"email\": \"info@luxuryhotel.com\", \"address\": \"123 Luxury Avenue, Premium District, City 12345\"}',NULL,'{\"facebook\": \"https://facebook.com/luxuryhotel\", \"twitter\": \"https://twitter.com/luxuryhotel\", \"instagram\": \"https://instagram.com/luxuryhotel\", \"linkedin\": \"https://linkedin.com/company/luxuryhotel\", \"youtube\": \"https://youtube.com/luxuryhotel\"}','{\"quick_links\": [{\"label\": \"Home\", \"url\": \"/\"}, {\"label\": \"Rooms & Suites\", \"url\": \"/rooms\"}, {\"label\": \"About Us\", \"url\": \"/about\"}, {\"label\": \"Contact\", \"url\": \"/contact\"}, {\"label\": \"Gallery\", \"url\": \"/gallery\"}], \"support_links\": [{\"label\": \"FAQ\", \"url\": \"/faq\"}, {\"label\": \"Privacy Policy\", \"url\": \"/privacy\"}, {\"label\": \"Terms of Service\", \"url\": \"/terms\"}, {\"label\": \"Cancellation Policy\", \"url\": \"/cancellation\"}, {\"label\": \"Accessibility\", \"url\": \"/accessibility\"}]}','[{\"text\": \"5-Star Rated\", \"icon\": \"Star\"}, {\"text\": \"Award Winning\", \"icon\": \"Award\"}, {\"text\": \"Eco Certified\", \"icon\": \"Leaf\"}, {\"text\": \"Luxury Collection\", \"icon\": \"Crown\"}]','© {YEAR} Luxury Hotel. All rights reserved.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,'2025-11-21 12:24:21','2025-11-21 12:24:21'),(4,'privacy','Privacy Policy','Your privacy is important to us','Learn how we collect, use, and protect your personal information.','\nAt our hotel, we are committed to protecting your privacy and ensuring the security of your personal information. This Privacy Policy explains how we collect, use, disclose, and safeguard your information when you visit our website or use our services.
\n \nWe collect information that you provide directly to us, including:
\nWe use the information we collect to:
\nWe implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, disclosure, or destruction.
\n \nYou have the right to:
\nIf you have any questions about this Privacy Policy, please contact us at privacy@hotel.com.
\n \nLast updated: November 21, 2025
\n ','Privacy Policy - Luxury Hotel | Data Protection & Privacy','Read our privacy policy to understand how we collect, use, and protect your personal information when you use our hotel booking services.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,'2025-11-21 12:24:23','2025-11-21 12:24:23'),(5,'terms','Terms & Conditions','Please read these terms carefully','Terms and conditions governing your use of our hotel booking services.','\nBy accessing and using our hotel\'s website and services, you accept and agree to be bound by the terms and provision of this agreement.
\n \nWhen making a reservation with us, you agree to:
\nPayment terms include:
\nOur cancellation policy is as follows:
\nStandard check-in time is 3:00 PM and check-out time is 11:00 AM. Early check-in and late check-out may be available upon request and subject to availability.
\n \nGuests are responsible for:
\nThe hotel shall not be liable for any loss, damage, or injury to persons or property during your stay, except where such loss, damage, or injury is caused by our negligence.
\n \nWe reserve the right to modify these terms at any time. Changes will be effective immediately upon posting on our website.
\n \nFor questions about these terms, please contact us at legal@hotel.com.
\n \nLast updated: November 21, 2025
\n ','Terms & Conditions - Luxury Hotel | Booking Terms & Policies','Read our terms and conditions to understand the rules and policies governing your bookings and stay at our luxury hotel.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,'2025-11-21 12:24:23','2025-11-21 12:24:23'),(6,'refunds','Refunds Policy','Our commitment to fair refunds','Learn about our refund policies and procedures for bookings and cancellations.','\nAt our hotel, we understand that plans can change. This policy outlines our refund procedures and timelines for various scenarios.
\n \nRefunds for cancelled bookings are processed as follows:
\nIf you check out earlier than your reserved departure date:
\nIf you experience service issues during your stay:
\nRefunds are typically processed within:
\nRefunds will be issued to the original payment method used for the booking. If the original payment method is no longer available, please contact us to arrange an alternative refund method.
\n \nSome special offers or promotional rates may be non-refundable. This will be clearly stated at the time of booking.
\n \nIn cases of force majeure (natural disasters, pandemics, government restrictions, etc.), we will work with you to reschedule your booking or provide appropriate refunds based on the circumstances.
\n \nIf you have concerns about a refund decision, please contact our customer service team. We are committed to resolving all disputes fairly and promptly.
\n \nFor refund inquiries, please contact us at refunds@hotel.com or call our customer service line.
\n \nLast updated: November 21, 2025
\n ','Refunds Policy - Luxury Hotel | Cancellation & Refund Terms','Understand our refund policy, including cancellation terms, processing times, and how to request refunds for your hotel bookings.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,'2025-11-21 12:24:23','2025-11-21 12:24:23'),(7,'cancellation','Cancellation Policy','Flexible cancellation options for your peace of mind','Learn about our cancellation policy, fees, and refund procedures.','\nWe understand that plans can change. This policy outlines our cancellation procedures and fees.
\n \nFor standard bookings, the following cancellation terms apply:
\nSome special rates or promotional offers may have different cancellation terms. Please review your booking confirmation for specific details.
\n \nTo cancel your booking:
\nRefunds will be processed to the original payment method within 5-10 business days after cancellation confirmation.
\n \nLast updated: November 21, 2025
\n ','Cancellation Policy - Luxury Hotel | Booking Cancellation Terms','Review our cancellation policy to understand cancellation fees, refund procedures, and terms for modifying or canceling your hotel booking.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,'2025-11-21 12:24:23','2025-11-21 12:24:23'),(8,'accessibility','Accessibility','Committed to providing an inclusive experience for all guests','Learn about our accessibility features and accommodations.','\nWe are committed to ensuring that our hotel and website are accessible to all guests, regardless of ability. We strive to provide an inclusive experience for everyone.
\n \nOur hotel offers the following accessibility features:
\nWe are continuously working to improve the accessibility of our website. Our website includes:
\nIf you require specific accommodations during your stay, please contact us at least 48 hours before your arrival. We will do our best to accommodate your needs.
\n \nWe welcome feedback on how we can improve accessibility. Please contact us with your suggestions or concerns.
\n \nLast updated: November 21, 2025
\n ','Accessibility - Luxury Hotel | Accessible Accommodations','Discover our commitment to accessibility, including accessible rooms, facilities, and website features for guests with disabilities.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,'2025-11-21 12:24:23','2025-11-21 12:24:23'),(9,'faq','Frequently Asked Questions','Find answers to common questions','Get answers to frequently asked questions about bookings, services, and policies.','\nFind answers to common questions about our hotel, bookings, and services.
\n \nYou can make a reservation online through our website, by phone, or by email. Simply select your dates, choose your room, and complete the booking process.
\n \nA 20% deposit is required to secure your booking. The remaining balance is due upon arrival at the hotel.
\n \nYes, you can modify your booking by logging into your account and visiting \"My Bookings\", or by contacting us directly. Changes are subject to availability and may incur fees.
\n \nCheck-in is from 3:00 PM, and check-out is by 11:00 AM. Early check-in and late check-out may be available upon request, subject to availability.
\n \nEarly check-in and late check-out are available upon request, subject to availability. Additional fees may apply.
\n \nWe accept major credit cards, debit cards, and bank transfers. Payment can be made online or at the hotel.
\n \nFor cancellations made more than 48 hours before check-in, the deposit is fully refundable. Cancellations made 48 hours or less before check-in are non-refundable. Please see our Cancellation Policy page for full details.
\n \nOur hotel offers complimentary Wi-Fi, parking, fitness center access, and more. Please check the room details for specific amenities.
\n \nYes, we offer complimentary parking for all guests. Valet parking is also available for an additional fee.
\n \nYes, complimentary high-speed Wi-Fi is available throughout the hotel.
\n \nYes, you can make special requests when booking. We will do our best to accommodate your preferences, subject to availability.
\n \nYes, please inform us of any dietary restrictions or allergies when making your reservation, and we will do our best to accommodate your needs.
\n \nYou can contact us by phone, email, or through our website\'s contact form. Our team is available 24/7 to assist you.
\n \nLast updated: November 21, 2025
\n ','FAQ - Luxury Hotel | Frequently Asked Questions','Find answers to common questions about hotel bookings, check-in, payment, cancellation, amenities, and more.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,'2025-11-21 12:24:23','2025-11-21 12:24:23'); +/*!40000 ALTER TABLE `page_contents` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `password_reset_tokens` +-- + +DROP TABLE IF EXISTS `password_reset_tokens`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `password_reset_tokens` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `token` varchar(255) NOT NULL, + `expires_at` datetime NOT NULL, + `used` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_password_reset_tokens_token` (`token`), + KEY `user_id` (`user_id`), + KEY `ix_password_reset_tokens_id` (`id`), + CONSTRAINT `password_reset_tokens_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `password_reset_tokens` +-- + +LOCK TABLES `password_reset_tokens` WRITE; +/*!40000 ALTER TABLE `password_reset_tokens` DISABLE KEYS */; +/*!40000 ALTER TABLE `password_reset_tokens` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `payments` +-- + +DROP TABLE IF EXISTS `payments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `payments` ( + `id` int NOT NULL AUTO_INCREMENT, + `booking_id` int NOT NULL, + `amount` decimal(10,2) NOT NULL, + `payment_method` enum('cash','credit_card','debit_card','bank_transfer','e_wallet','stripe','paypal','borica') NOT NULL, + `payment_type` enum('full','deposit','remaining') NOT NULL, + `deposit_percentage` int DEFAULT NULL, + `related_payment_id` int DEFAULT NULL, + `payment_status` enum('pending','completed','failed','refunded') NOT NULL, + `transaction_id` varchar(100) DEFAULT NULL, + `payment_date` datetime DEFAULT NULL, + `notes` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `booking_id` (`booking_id`), + KEY `related_payment_id` (`related_payment_id`), + KEY `ix_payments_id` (`id`), + CONSTRAINT `payments_ibfk_1` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `payments_ibfk_2` FOREIGN KEY (`related_payment_id`) REFERENCES `payments` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `payments` +-- + +LOCK TABLES `payments` WRITE; +/*!40000 ALTER TABLE `payments` DISABLE KEYS */; +/*!40000 ALTER TABLE `payments` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `promotions` +-- + +DROP TABLE IF EXISTS `promotions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `promotions` ( + `id` int NOT NULL AUTO_INCREMENT, + `code` varchar(50) NOT NULL, + `name` varchar(100) NOT NULL, + `description` text, + `discount_type` enum('percentage','fixed_amount') NOT NULL, + `discount_value` decimal(10,2) NOT NULL, + `min_booking_amount` decimal(10,2) DEFAULT NULL, + `max_discount_amount` decimal(10,2) DEFAULT NULL, + `start_date` datetime NOT NULL, + `end_date` datetime NOT NULL, + `usage_limit` int DEFAULT NULL, + `used_count` int NOT NULL, + `is_active` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_promotions_code` (`code`), + KEY `ix_promotions_id` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `promotions` +-- + +LOCK TABLES `promotions` WRITE; +/*!40000 ALTER TABLE `promotions` DISABLE KEYS */; +/*!40000 ALTER TABLE `promotions` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `rate_plan_rules` +-- + +DROP TABLE IF EXISTS `rate_plan_rules`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `rate_plan_rules` ( + `id` int NOT NULL AUTO_INCREMENT, + `rate_plan_id` int NOT NULL, + `rule_type` varchar(50) NOT NULL, + `rule_key` varchar(100) NOT NULL, + `rule_value` json DEFAULT NULL, + `price_modifier` decimal(5,2) DEFAULT NULL, + `discount_percentage` decimal(5,2) DEFAULT NULL, + `fixed_adjustment` decimal(10,2) DEFAULT NULL, + `priority` int NOT NULL, + `extra_data` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_rate_plan_rules_rate_plan_id` (`rate_plan_id`), + KEY `ix_rate_plan_rules_id` (`id`), + CONSTRAINT `rate_plan_rules_ibfk_1` FOREIGN KEY (`rate_plan_id`) REFERENCES `rate_plans` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `rate_plan_rules` +-- + +LOCK TABLES `rate_plan_rules` WRITE; +/*!40000 ALTER TABLE `rate_plan_rules` DISABLE KEYS */; +/*!40000 ALTER TABLE `rate_plan_rules` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `rate_plans` +-- + +DROP TABLE IF EXISTS `rate_plans`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `rate_plans` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL, + `code` varchar(50) NOT NULL, + `description` text, + `plan_type` enum('BAR','non_refundable','advance_purchase','corporate','government','military','long_stay','package') NOT NULL, + `status` enum('active','inactive','scheduled','expired') NOT NULL, + `base_price_modifier` decimal(5,2) NOT NULL, + `discount_percentage` decimal(5,2) DEFAULT NULL, + `fixed_discount` decimal(10,2) DEFAULT NULL, + `room_type_id` int DEFAULT NULL, + `min_nights` int DEFAULT NULL, + `max_nights` int DEFAULT NULL, + `advance_days_required` int DEFAULT NULL, + `valid_from` date DEFAULT NULL, + `valid_to` date DEFAULT NULL, + `is_refundable` tinyint(1) NOT NULL, + `requires_deposit` tinyint(1) NOT NULL, + `deposit_percentage` decimal(5,2) DEFAULT NULL, + `cancellation_hours` int DEFAULT NULL, + `corporate_code` varchar(50) DEFAULT NULL, + `requires_verification` tinyint(1) NOT NULL, + `verification_type` varchar(50) DEFAULT NULL, + `long_stay_nights` int DEFAULT NULL, + `is_package` tinyint(1) NOT NULL, + `package_id` int DEFAULT NULL, + `priority` int NOT NULL, + `extra_data` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_rate_plans_code` (`code`), + KEY `room_type_id` (`room_type_id`), + KEY `package_id` (`package_id`), + KEY `ix_rate_plans_corporate_code` (`corporate_code`), + KEY `ix_rate_plans_name` (`name`), + KEY `ix_rate_plans_id` (`id`), + CONSTRAINT `rate_plans_ibfk_1` FOREIGN KEY (`room_type_id`) REFERENCES `room_types` (`id`), + CONSTRAINT `rate_plans_ibfk_2` FOREIGN KEY (`package_id`) REFERENCES `packages` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `rate_plans` +-- + +LOCK TABLES `rate_plans` WRITE; +/*!40000 ALTER TABLE `rate_plans` DISABLE KEYS */; +/*!40000 ALTER TABLE `rate_plans` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `referrals` +-- + +DROP TABLE IF EXISTS `referrals`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `referrals` ( + `id` int NOT NULL AUTO_INCREMENT, + `referrer_id` int NOT NULL, + `referred_user_id` int NOT NULL, + `referral_code` varchar(50) NOT NULL, + `booking_id` int DEFAULT NULL, + `status` enum('pending','completed','rewarded') NOT NULL, + `referrer_points_earned` int NOT NULL, + `referred_points_earned` int NOT NULL, + `completed_at` datetime DEFAULT NULL, + `rewarded_at` datetime DEFAULT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_referrals_referrer_id` (`referrer_id`), + KEY `ix_referrals_status` (`status`), + KEY `ix_referrals_referral_code` (`referral_code`), + KEY `ix_referrals_booking_id` (`booking_id`), + KEY `ix_referrals_referred_user_id` (`referred_user_id`), + KEY `ix_referrals_id` (`id`), + KEY `ix_referrals_created_at` (`created_at`), + CONSTRAINT `referrals_ibfk_1` FOREIGN KEY (`referrer_id`) REFERENCES `user_loyalty` (`id`), + CONSTRAINT `referrals_ibfk_2` FOREIGN KEY (`referred_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `referrals_ibfk_3` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `referrals` +-- + +LOCK TABLES `referrals` WRITE; +/*!40000 ALTER TABLE `referrals` DISABLE KEYS */; +/*!40000 ALTER TABLE `referrals` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `refresh_tokens` +-- + +DROP TABLE IF EXISTS `refresh_tokens`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `refresh_tokens` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `token` varchar(500) NOT NULL, + `expires_at` datetime NOT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_refresh_tokens_token` (`token`), + KEY `user_id` (`user_id`), + KEY `ix_refresh_tokens_id` (`id`), + CONSTRAINT `refresh_tokens_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=197 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `refresh_tokens` +-- + +LOCK TABLES `refresh_tokens` WRITE; +/*!40000 ALTER TABLE `refresh_tokens` DISABLE KEYS */; +INSERT INTO `refresh_tokens` VALUES (196,3,'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjMsImV4cCI6MTc2NTMyMjYyNiwiaWF0IjoxNzY0NzE3ODI2LCJpc3MiOiJIb3RlbCBCb29raW5nIEFQSSIsInR5cGUiOiJyZWZyZXNoIn0.edzNBh_7JOuiB1K0eD0Iy75AMwKHoKjThKI6Rlhh-94','2025-12-03 23:23:46','2025-12-02 23:23:46'); +/*!40000 ALTER TABLE `refresh_tokens` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `retention_rules` +-- + +DROP TABLE IF EXISTS `retention_rules`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `retention_rules` ( + `id` int NOT NULL AUTO_INCREMENT, + `data_category` varchar(100) NOT NULL, + `retention_period_days` int NOT NULL, + `retention_period_months` int DEFAULT NULL, + `retention_period_years` int DEFAULT NULL, + `legal_basis` text, + `legal_requirement` text, + `action_after_retention` varchar(50) NOT NULL, + `conditions` json DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `description` text, + `created_by` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `data_category` (`data_category`), + UNIQUE KEY `ix_retention_rules_data_category` (`data_category`), + KEY `created_by` (`created_by`), + KEY `ix_retention_rules_id` (`id`), + KEY `ix_retention_rules_is_active` (`is_active`), + CONSTRAINT `retention_rules_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `retention_rules` +-- + +LOCK TABLES `retention_rules` WRITE; +/*!40000 ALTER TABLE `retention_rules` DISABLE KEYS */; +/*!40000 ALTER TABLE `retention_rules` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `reviews` +-- + +DROP TABLE IF EXISTS `reviews`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `reviews` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `room_id` int NOT NULL, + `rating` int NOT NULL, + `comment` text NOT NULL, + `status` enum('pending','approved','rejected') NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `user_id` (`user_id`), + KEY `room_id` (`room_id`), + KEY `ix_reviews_id` (`id`), + CONSTRAINT `reviews_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `reviews_ibfk_2` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `reviews` +-- + +LOCK TABLES `reviews` WRITE; +/*!40000 ALTER TABLE `reviews` DISABLE KEYS */; +INSERT INTO `reviews` VALUES (1,5,39,5,'very good!!!','approved','2025-11-28 10:36:22','2025-11-28 10:49:41'),(2,5,27,5,'ddwqddwdwqdwq','rejected','2025-11-28 10:43:06','2025-11-28 10:49:44'); +/*!40000 ALTER TABLE `reviews` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `reward_redemptions` +-- + +DROP TABLE IF EXISTS `reward_redemptions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `reward_redemptions` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_loyalty_id` int NOT NULL, + `reward_id` int NOT NULL, + `booking_id` int DEFAULT NULL, + `points_used` int NOT NULL, + `status` enum('pending','active','used','expired','cancelled') NOT NULL, + `code` varchar(50) DEFAULT NULL, + `expires_at` datetime DEFAULT NULL, + `used_at` datetime DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_reward_redemptions_code` (`code`), + KEY `ix_reward_redemptions_id` (`id`), + KEY `ix_reward_redemptions_reward_id` (`reward_id`), + KEY `ix_reward_redemptions_user_loyalty_id` (`user_loyalty_id`), + KEY `ix_reward_redemptions_status` (`status`), + KEY `ix_reward_redemptions_booking_id` (`booking_id`), + CONSTRAINT `reward_redemptions_ibfk_1` FOREIGN KEY (`user_loyalty_id`) REFERENCES `user_loyalty` (`id`), + CONSTRAINT `reward_redemptions_ibfk_2` FOREIGN KEY (`reward_id`) REFERENCES `loyalty_rewards` (`id`), + CONSTRAINT `reward_redemptions_ibfk_3` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `reward_redemptions` +-- + +LOCK TABLES `reward_redemptions` WRITE; +/*!40000 ALTER TABLE `reward_redemptions` DISABLE KEYS */; +INSERT INTO `reward_redemptions` VALUES (1,1,1,NULL,5000,'active','YK5NKXNEMIM8',NULL,NULL,'2025-11-21 19:59:40','2025-11-21 19:59:40'),(2,1,9,NULL,8000,'active','0F4U1XO9TW8D',NULL,NULL,'2025-11-21 20:01:36','2025-11-21 20:01:36'); +/*!40000 ALTER TABLE `reward_redemptions` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `roles` +-- + +DROP TABLE IF EXISTS `roles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `roles` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `description` varchar(255) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_roles_name` (`name`), + KEY `ix_roles_id` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `roles` +-- + +LOCK TABLES `roles` WRITE; +/*!40000 ALTER TABLE `roles` DISABLE KEYS */; +INSERT INTO `roles` VALUES (1,'admin','Administrator with full access','2025-11-21 12:23:51','2025-11-21 12:23:51'),(2,'staff','Staff member with limited admin access','2025-11-21 12:23:51','2025-11-21 12:23:51'),(3,'customer','Regular customer','2025-11-21 12:23:51','2025-11-21 12:23:51'),(4,'accountant','Accountant role with access to financial data, payments, and invoices','2025-11-21 12:38:40','2025-11-21 12:38:40'),(5,'housekeeping','Housekeeping staff role with access to room cleaning tasks and status updates','2025-12-01 13:07:08','2025-12-01 13:07:08'); +/*!40000 ALTER TABLE `roles` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `room_attributes` +-- + +DROP TABLE IF EXISTS `room_attributes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `room_attributes` ( + `id` int NOT NULL AUTO_INCREMENT, + `room_id` int NOT NULL, + `attribute_name` varchar(100) NOT NULL, + `attribute_value` varchar(255) DEFAULT NULL, + `attribute_data` json DEFAULT NULL, + `last_updated` datetime NOT NULL, + `updated_by` int DEFAULT NULL, + `notes` text, + `is_active` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `updated_by` (`updated_by`), + KEY `ix_room_attributes_id` (`id`), + KEY `ix_room_attributes_room_id` (`room_id`), + CONSTRAINT `room_attributes_ibfk_1` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`id`), + CONSTRAINT `room_attributes_ibfk_2` FOREIGN KEY (`updated_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `room_attributes` +-- + +LOCK TABLES `room_attributes` WRITE; +/*!40000 ALTER TABLE `room_attributes` DISABLE KEYS */; +/*!40000 ALTER TABLE `room_attributes` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `room_inspections` +-- + +DROP TABLE IF EXISTS `room_inspections`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `room_inspections` ( + `id` int NOT NULL AUTO_INCREMENT, + `room_id` int NOT NULL, + `booking_id` int DEFAULT NULL, + `inspection_type` enum('pre_checkin','post_checkout','routine','maintenance','damage') NOT NULL, + `status` enum('pending','in_progress','completed','failed','cancelled') NOT NULL, + `scheduled_at` datetime NOT NULL, + `started_at` datetime DEFAULT NULL, + `completed_at` datetime DEFAULT NULL, + `inspected_by` int DEFAULT NULL, + `created_by` int DEFAULT NULL, + `checklist_template_id` int DEFAULT NULL, + `checklist_items` json NOT NULL, + `overall_score` decimal(3,2) DEFAULT NULL, + `overall_notes` text, + `issues_found` json DEFAULT NULL, + `photos` json DEFAULT NULL, + `requires_followup` tinyint(1) NOT NULL, + `followup_notes` text, + `maintenance_request_id` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `inspected_by` (`inspected_by`), + KEY `created_by` (`created_by`), + KEY `maintenance_request_id` (`maintenance_request_id`), + KEY `ix_room_inspections_scheduled_at` (`scheduled_at`), + KEY `ix_room_inspections_booking_id` (`booking_id`), + KEY `ix_room_inspections_room_id` (`room_id`), + KEY `ix_room_inspections_id` (`id`), + CONSTRAINT `room_inspections_ibfk_1` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`id`), + CONSTRAINT `room_inspections_ibfk_2` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `room_inspections_ibfk_3` FOREIGN KEY (`inspected_by`) REFERENCES `users` (`id`), + CONSTRAINT `room_inspections_ibfk_4` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`), + CONSTRAINT `room_inspections_ibfk_5` FOREIGN KEY (`maintenance_request_id`) REFERENCES `room_maintenance` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `room_inspections` +-- + +LOCK TABLES `room_inspections` WRITE; +/*!40000 ALTER TABLE `room_inspections` DISABLE KEYS */; +/*!40000 ALTER TABLE `room_inspections` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `room_maintenance` +-- + +DROP TABLE IF EXISTS `room_maintenance`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `room_maintenance` ( + `id` int NOT NULL AUTO_INCREMENT, + `room_id` int NOT NULL, + `maintenance_type` enum('preventive','corrective','emergency','upgrade','inspection') NOT NULL, + `status` enum('scheduled','in_progress','completed','cancelled','on_hold') NOT NULL, + `title` varchar(255) NOT NULL, + `description` text, + `scheduled_start` datetime NOT NULL, + `scheduled_end` datetime DEFAULT NULL, + `actual_start` datetime DEFAULT NULL, + `actual_end` datetime DEFAULT NULL, + `assigned_to` int DEFAULT NULL, + `reported_by` int DEFAULT NULL, + `estimated_cost` decimal(10,2) DEFAULT NULL, + `actual_cost` decimal(10,2) DEFAULT NULL, + `blocks_room` tinyint(1) NOT NULL, + `block_start` datetime DEFAULT NULL, + `block_end` datetime DEFAULT NULL, + `priority` varchar(20) NOT NULL, + `notes` text, + `completion_notes` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `assigned_to` (`assigned_to`), + KEY `reported_by` (`reported_by`), + KEY `ix_room_maintenance_id` (`id`), + KEY `ix_room_maintenance_room_id` (`room_id`), + CONSTRAINT `room_maintenance_ibfk_1` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`id`), + CONSTRAINT `room_maintenance_ibfk_2` FOREIGN KEY (`assigned_to`) REFERENCES `users` (`id`), + CONSTRAINT `room_maintenance_ibfk_3` FOREIGN KEY (`reported_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `room_maintenance` +-- + +LOCK TABLES `room_maintenance` WRITE; +/*!40000 ALTER TABLE `room_maintenance` DISABLE KEYS */; +/*!40000 ALTER TABLE `room_maintenance` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `room_types` +-- + +DROP TABLE IF EXISTS `room_types`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `room_types` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL, + `description` text, + `base_price` decimal(10,2) NOT NULL, + `capacity` int NOT NULL, + `amenities` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`), + KEY `ix_room_types_id` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `room_types` +-- + +LOCK TABLES `room_types` WRITE; +/*!40000 ALTER TABLE `room_types` DISABLE KEYS */; +INSERT INTO `room_types` VALUES (1,'Standard Room','Comfortable and well-appointed standard accommodation',150.00,2,'\"[\\\"Free WiFi\\\", \\\"Air Conditioning\\\", \\\"TV\\\", \\\"Minibar\\\", \\\"Safe\\\"]\"','2025-11-21 12:23:51','2025-11-21 12:23:51'),(2,'Superior Room','Spacious room with enhanced amenities and better views',200.00,2,'\"[\\\"Free WiFi\\\", \\\"Air Conditioning\\\", \\\"Smart TV\\\", \\\"Minibar\\\", \\\"Safe\\\", \\\"Coffee Maker\\\"]\"','2025-11-21 12:23:51','2025-11-21 12:23:51'),(3,'Deluxe Room','Luxurious room with premium furnishings and amenities',280.00,3,'\"[\\\"Free WiFi\\\", \\\"Air Conditioning\\\", \\\"Smart TV\\\", \\\"Netflix\\\", \\\"Minibar\\\", \\\"Safe\\\", \\\"Coffee Maker\\\", \\\"Premium Toiletries\\\"]\"','2025-11-21 12:23:51','2025-11-21 12:23:51'),(4,'Executive Suite','Elegant suite with separate living area and premium amenities',400.00,4,'\"[\\\"Free WiFi\\\", \\\"Air Conditioning\\\", \\\"Smart TV\\\", \\\"Netflix\\\", \\\"Minibar\\\", \\\"Safe\\\", \\\"Espresso Machine\\\", \\\"Premium Toiletries\\\", \\\"Bathrobes\\\", \\\"Work Desk\\\"]\"','2025-11-21 12:23:51','2025-11-21 12:23:51'),(5,'Presidential Suite','The ultimate in luxury with expansive space and exclusive amenities',800.00,6,'\"[\\\"Free WiFi\\\", \\\"Air Conditioning\\\", \\\"Smart TV\\\", \\\"Netflix\\\", \\\"Private Bar\\\", \\\"Jacuzzi\\\", \\\"Butler Service\\\", \\\"Premium Toiletries\\\", \\\"Bathrobes\\\", \\\"Private Terrace\\\"]\"','2025-11-21 12:23:51','2025-11-21 12:23:51'); +/*!40000 ALTER TABLE `room_types` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `rooms` +-- + +DROP TABLE IF EXISTS `rooms`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `rooms` ( + `id` int NOT NULL AUTO_INCREMENT, + `room_type_id` int NOT NULL, + `room_number` varchar(20) NOT NULL, + `floor` int NOT NULL, + `status` enum('available','occupied','maintenance','cleaning') NOT NULL, + `price` decimal(10,2) NOT NULL, + `featured` tinyint(1) NOT NULL, + `capacity` int DEFAULT NULL, + `room_size` varchar(50) DEFAULT NULL, + `view` varchar(100) DEFAULT NULL, + `images` json DEFAULT NULL, + `amenities` json DEFAULT NULL, + `description` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_rooms_room_number` (`room_number`), + KEY `room_type_id` (`room_type_id`), + KEY `ix_rooms_id` (`id`), + CONSTRAINT `rooms_ibfk_1` FOREIGN KEY (`room_type_id`) REFERENCES `room_types` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `rooms` +-- + +LOCK TABLES `rooms` WRITE; +/*!40000 ALTER TABLE `rooms` DISABLE KEYS */; +INSERT INTO `rooms` VALUES (1,1,'101',1,'available',177.80,0,2,'36 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Iron & Ironing Board\\\", \\\"Premium Toiletries\\\", \\\"Pillow Menu\\\", \\\"Room Service\\\", \\\"Safe\\\", \\\"City View\\\", \\\"High-Speed Internet\\\", \\\"Work Desk\\\"]\"','Elegantly designed garden view room with modern luxury amenities and breathtaking views.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(2,2,'102',1,'cleaning',234.13,0,2,'43 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Espresso Machine\\\", \\\"High-Speed Internet\\\", \\\"Hair Dryer\\\", \\\"Safe\\\", \\\"City View\\\", \\\"Sound System\\\", \\\"Air Conditioning\\\", \\\"Private Balcony\\\"]\"','Spacious garden view accommodation featuring premium furnishings and world-class comfort.','2025-11-21 12:24:00','2025-12-02 23:22:22'),(3,2,'103',1,'available',231.16,0,2,'43 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Turndown Service\\\", \\\"Room Service\\\", \\\"Ocean View\\\", \\\"Refrigerator\\\", \\\"Blackout Curtains\\\", \\\"USB Charging Ports\\\", \\\"24/7 Concierge\\\", \\\"Bluetooth Speaker\\\"]\"','Spacious garden view accommodation featuring premium furnishings and world-class comfort.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(4,2,'104',1,'cleaning',227.04,0,2,'38 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Slippers\\\", \\\"Bluetooth Speaker\\\", \\\"Minibar\\\", \\\"Climate Control\\\", \\\"24/7 Concierge\\\", \\\"Ocean View\\\", \\\"Hair Dryer\\\", \\\"Iron & Ironing Board\\\"]\"','Luxurious garden view room with sophisticated decor and exceptional attention to detail.','2025-11-21 12:24:00','2025-12-02 23:22:22'),(5,2,'105',1,'available',230.69,0,2,'39 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Slippers\\\", \\\"City View\\\", \\\"Premium Toiletries\\\", \\\"Iron & Ironing Board\\\", \\\"Turndown Service\\\", \\\"Climate Control\\\", \\\"USB Charging Ports\\\", \\\"Private Balcony\\\"]\"','Luxurious garden view room with sophisticated decor and exceptional attention to detail.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(6,2,'106',1,'occupied',233.52,0,2,'37 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1566665797739-1674de7a421a?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Safe\\\", \\\"Slippers\\\", \\\"Pillow Menu\\\", \\\"Refrigerator\\\", \\\"Smart TV\\\", \\\"Coffee Maker\\\", \\\"Climate Control\\\", \\\"Ocean View\\\"]\"','Elegantly designed garden view room with modern luxury amenities and breathtaking views.','2025-11-21 12:24:00','2025-12-02 23:22:22'),(7,1,'107',1,'available',179.62,0,1,'40 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1566665797739-1674de7a421a?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Bathrobes\\\", \\\"Smart TV\\\", \\\"Work Desk\\\", \\\"Bluetooth Speaker\\\", \\\"Free WiFi\\\", \\\"Sound System\\\", \\\"Premium Toiletries\\\", \\\"High-Speed Internet\\\"]\"','Opulent garden view accommodation with bespoke interiors and premium amenities.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(8,1,'108',1,'occupied',166.40,0,2,'35 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"24/7 Concierge\\\", \\\"Refrigerator\\\", \\\"Work Desk\\\", \\\"Minibar\\\", \\\"Espresso Machine\\\", \\\"Air Conditioning\\\", \\\"Hair Dryer\\\", \\\"City View\\\"]\"','Spacious garden view accommodation featuring premium furnishings and world-class comfort.','2025-11-21 12:24:00','2025-12-02 23:22:22'),(9,1,'209',2,'available',185.74,0,1,'41 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1618221195710-dd6b41faaea8?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"24/7 Concierge\\\", \\\"Private Balcony\\\", \\\"Bluetooth Speaker\\\", \\\"Hair Dryer\\\", \\\"Safe\\\", \\\"USB Charging Ports\\\", \\\"Climate Control\\\", \\\"Ergonomic Chair\\\"]\"','Elegantly designed garden view room with modern luxury amenities and breathtaking views.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(10,2,'210',2,'available',217.54,0,2,'45 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Hair Dryer\\\", \\\"Turndown Service\\\", \\\"Espresso Machine\\\", \\\"Ergonomic Chair\\\", \\\"24/7 Concierge\\\", \\\"Slippers\\\", \\\"Coffee Maker\\\", \\\"Iron & Ironing Board\\\"]\"','Luxurious garden view room with sophisticated decor and exceptional attention to detail.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(11,1,'211',2,'available',172.09,0,2,'43 sqm','Garden View','[\"[\", \"\\\"\", \"h\", \"t\", \"t\", \"p\", \"s\", \":\", \"/\", \"/\", \"i\", \"m\", \"a\", \"g\", \"e\", \"s\", \".\", \"u\", \"n\", \"s\", \"p\", \"l\", \"a\", \"s\", \"h\", \".\", \"c\", \"o\", \"m\", \"/\", \"p\", \"h\", \"o\", \"t\", \"o\", \"-\", \"1\", \"6\", \"3\", \"1\", \"0\", \"4\", \"9\", \"3\", \"0\", \"7\", \"2\", \"6\", \"4\", \"-\", \"d\", \"a\", \"0\", \"e\", \"c\", \"9\", \"d\", \"7\", \"0\", \"3\", \"0\", \"4\", \"?\", \"w\", \"=\", \"1\", \"2\", \"0\", \"0\", \"&\", \"h\", \"=\", \"8\", \"0\", \"0\", \"&\", \"f\", \"i\", \"t\", \"=\", \"c\", \"r\", \"o\", \"p\", \"\\\"\", \",\", \" \", \"\\\"\", \"h\", \"t\", \"t\", \"p\", \"s\", \":\", \"/\", \"/\", \"i\", \"m\", \"a\", \"g\", \"e\", \"s\", \".\", \"u\", \"n\", \"s\", \"p\", \"l\", \"a\", \"s\", \"h\", \".\", \"c\", \"o\", \"m\", \"/\", \"p\", \"h\", \"o\", \"t\", \"o\", \"-\", \"1\", \"6\", \"1\", \"8\", \"7\", \"7\", \"3\", \"9\", \"2\", \"8\", \"1\", \"2\", \"1\", \"-\", \"c\", \"3\", \"2\", \"2\", \"4\", \"2\", \"e\", \"6\", \"3\", \"f\", \"3\", \"9\", \"?\", \"w\", \"=\", \"1\", \"2\", \"0\", \"0\", \"&\", \"h\", \"=\", \"8\", \"0\", \"0\", \"&\", \"f\", \"i\", \"t\", \"=\", \"c\", \"r\", \"o\", \"p\", \"\\\"\", \",\", \" \", \"\\\"\", \"h\", \"t\", \"t\", \"p\", \"s\", \":\", \"/\", \"/\", \"i\", \"m\", \"a\", \"g\", \"e\", \"s\", \".\", \"u\", \"n\", \"s\", \"p\", \"l\", \"a\", \"s\", \"h\", \".\", \"c\", \"o\", \"m\", \"/\", \"p\", \"h\", \"o\", \"t\", \"o\", \"-\", \"1\", \"5\", \"6\", \"6\", \"6\", \"6\", \"5\", \"7\", \"9\", \"7\", \"7\", \"3\", \"9\", \"-\", \"1\", \"6\", \"7\", \"4\", \"d\", \"e\", \"7\", \"a\", \"4\", \"2\", \"1\", \"a\", \"?\", \"w\", \"=\", \"1\", \"2\", \"0\", \"0\", \"&\", \"h\", \"=\", \"8\", \"0\", \"0\", \"&\", \"f\", \"i\", \"t\", \"=\", \"c\", \"r\", \"o\", \"p\", \"\\\"\", \"]\"]','\"[\\\"Climate Control\\\", \\\"Room Service\\\", \\\"Coffee Maker\\\", \\\"Free WiFi\\\", \\\"Slippers\\\", \\\"Safe\\\", \\\"Iron & Ironing Board\\\", \\\"City View\\\"]\"','Exquisite garden view suite offering unparalleled elegance and personalized service.','2025-11-21 12:24:00','2025-12-02 08:18:49'),(12,1,'212',2,'available',179.24,0,2,'43 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Bluetooth Speaker\\\", \\\"Netflix\\\", \\\"Coffee Maker\\\", \\\"Safe\\\", \\\"Slippers\\\", \\\"High-Speed Internet\\\", \\\"Climate Control\\\", \\\"Air Conditioning\\\"]\"','Elegantly designed garden view room with modern luxury amenities and breathtaking views.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(13,1,'213',2,'available',172.26,0,2,'43 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Blackout Curtains\\\", \\\"Bathrobes\\\", \\\"Safe\\\", \\\"Minibar\\\", \\\"Turndown Service\\\", \\\"Slippers\\\", \\\"Room Service\\\", \\\"Smart TV\\\"]\"','Luxurious garden view room with sophisticated decor and exceptional attention to detail.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(14,2,'214',2,'available',233.15,0,2,'35 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Coffee Maker\\\", \\\"Room Service\\\", \\\"Ergonomic Chair\\\", \\\"Blackout Curtains\\\", \\\"Bathrobes\\\", \\\"Refrigerator\\\", \\\"Sound System\\\", \\\"High-Speed Internet\\\"]\"','Spacious garden view accommodation featuring premium furnishings and world-class comfort.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(15,2,'215',2,'occupied',244.46,0,2,'42 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Blackout Curtains\\\", \\\"Free WiFi\\\", \\\"24/7 Concierge\\\", \\\"Room Service\\\", \\\"Minibar\\\", \\\"Climate Control\\\", \\\"Work Desk\\\", \\\"Air Conditioning\\\"]\"','Opulent garden view accommodation with bespoke interiors and premium amenities.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(16,2,'216',2,'available',218.33,0,2,'41 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Turndown Service\\\", \\\"Work Desk\\\", \\\"Free WiFi\\\", \\\"USB Charging Ports\\\", \\\"Smart TV\\\", \\\"Bluetooth Speaker\\\", \\\"Espresso Machine\\\", \\\"Minibar\\\"]\"','Opulent garden view accommodation with bespoke interiors and premium amenities.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(18,2,'318',3,'available',223.39,0,2,'37 sqm','Garden View','[]','\"[\\\"Climate Control\\\", \\\"Espresso Machine\\\", \\\"USB Charging Ports\\\", \\\"High-Speed Internet\\\", \\\"Bluetooth Speaker\\\", \\\"Minibar\\\", \\\"Ergonomic Chair\\\", \\\"Bathrobes\\\"]\"','Luxurious garden view room with sophisticated decor and exceptional attention to detail.','2025-11-21 12:24:00','2025-12-02 22:54:46'),(19,2,'319',3,'occupied',231.01,0,1,'35 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Room Service\\\", \\\"Air Conditioning\\\", \\\"Private Balcony\\\", \\\"Bluetooth Speaker\\\", \\\"USB Charging Ports\\\", \\\"Ergonomic Chair\\\", \\\"Free WiFi\\\", \\\"Iron & Ironing Board\\\"]\"','Spacious garden view accommodation featuring premium furnishings and world-class comfort.','2025-11-21 12:24:00','2025-12-02 23:22:36'),(20,1,'320',3,'available',173.02,0,2,'43 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Private Balcony\\\", \\\"Climate Control\\\", \\\"Netflix\\\", \\\"24/7 Concierge\\\", \\\"Ergonomic Chair\\\", \\\"Hair Dryer\\\", \\\"Minibar\\\", \\\"Refrigerator\\\"]\"','Elegantly designed garden view room with modern luxury amenities and breathtaking views.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(21,1,'321',3,'cleaning',174.76,0,2,'36 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Climate Control\\\", \\\"Bathrobes\\\", \\\"Work Desk\\\", \\\"Bluetooth Speaker\\\", \\\"City View\\\", \\\"Pillow Menu\\\", \\\"Refrigerator\\\", \\\"24/7 Concierge\\\"]\"','Exquisite garden view suite offering unparalleled elegance and personalized service.','2025-11-21 12:24:00','2025-12-02 23:22:36'),(22,1,'322',3,'available',179.24,0,2,'38 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Sound System\\\", \\\"Iron & Ironing Board\\\", \\\"Blackout Curtains\\\", \\\"Minibar\\\", \\\"Hair Dryer\\\", \\\"Room Service\\\", \\\"Refrigerator\\\", \\\"Work Desk\\\"]\"','Spacious garden view accommodation featuring premium furnishings and world-class comfort.','2025-11-21 12:24:00','2025-12-02 23:08:09'),(23,2,'323',3,'cleaning',226.53,0,2,'43 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"City View\\\", \\\"24/7 Concierge\\\", \\\"Ocean View\\\", \\\"Turndown Service\\\", \\\"Coffee Maker\\\", \\\"Iron & Ironing Board\\\", \\\"Slippers\\\", \\\"Air Conditioning\\\"]\"','Opulent garden view accommodation with bespoke interiors and premium amenities.','2025-11-21 12:24:00','2025-12-02 23:22:36'),(24,2,'324',3,'available',243.34,0,3,'43 sqm','Garden View','\"[\\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Espresso Machine\\\", \\\"Ergonomic Chair\\\", \\\"Air Conditioning\\\", \\\"Room Service\\\", \\\"High-Speed Internet\\\", \\\"Blackout Curtains\\\", \\\"Sound System\\\", \\\"Free WiFi\\\"]\"','Spacious garden view accommodation featuring premium furnishings and world-class comfort.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(25,1,'125',1,'available',174.10,0,2,'50 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Netflix\\\", \\\"Blackout Curtains\\\", \\\"Pillow Menu\\\", \\\"Climate Control\\\", \\\"Iron & Ironing Board\\\", \\\"Safe\\\", \\\"24/7 Concierge\\\", \\\"Refrigerator\\\", \\\"Hair Dryer\\\"]\"','Elegantly designed city view room with modern luxury amenities and breathtaking views.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(26,1,'126',1,'occupied',180.54,0,3,'49 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1566665797739-1674de7a421a?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Sound System\\\", \\\"Free WiFi\\\", \\\"High-Speed Internet\\\", \\\"Air Conditioning\\\", \\\"Safe\\\", \\\"Private Balcony\\\", \\\"Iron & Ironing Board\\\", \\\"USB Charging Ports\\\", \\\"Refrigerator\\\"]\"','Opulent city view accommodation with bespoke interiors and premium amenities.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(27,1,'127',1,'occupied',168.97,0,2,'43 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Climate Control\\\", \\\"Bathrobes\\\", \\\"Ergonomic Chair\\\", \\\"Refrigerator\\\", \\\"Pillow Menu\\\", \\\"Ocean View\\\", \\\"Hair Dryer\\\", \\\"Smart TV\\\", \\\"Private Balcony\\\"]\"','Opulent city view accommodation with bespoke interiors and premium amenities.','2025-11-21 12:24:00','2025-12-02 23:22:46'),(28,1,'128',1,'available',176.83,0,2,'49 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Ergonomic Chair\\\", \\\"Bathrobes\\\", \\\"Work Desk\\\", \\\"Sound System\\\", \\\"24/7 Concierge\\\", \\\"High-Speed Internet\\\", \\\"Iron & Ironing Board\\\", \\\"USB Charging Ports\\\", \\\"Netflix\\\"]\"','Luxurious city view room with sophisticated decor and exceptional attention to detail.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(29,1,'129',1,'available',177.06,0,2,'47 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1566665797739-1674de7a421a?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Blackout Curtains\\\", \\\"Sound System\\\", \\\"Turndown Service\\\", \\\"Room Service\\\", \\\"USB Charging Ports\\\", \\\"Coffee Maker\\\", \\\"Safe\\\", \\\"24/7 Concierge\\\", \\\"Ocean View\\\"]\"','Opulent city view accommodation with bespoke interiors and premium amenities.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(30,1,'130',1,'maintenance',169.85,0,2,'44 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Work Desk\\\", \\\"City View\\\", \\\"Premium Toiletries\\\", \\\"USB Charging Ports\\\", \\\"Slippers\\\", \\\"Pillow Menu\\\", \\\"24/7 Concierge\\\", \\\"Netflix\\\", \\\"Ocean View\\\"]\"','Luxurious city view room with sophisticated decor and exceptional attention to detail.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(31,1,'131',1,'available',180.83,0,2,'50 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Ocean View\\\", \\\"24/7 Concierge\\\", \\\"Private Balcony\\\", \\\"High-Speed Internet\\\", \\\"Free WiFi\\\", \\\"Refrigerator\\\", \\\"Blackout Curtains\\\", \\\"Air Conditioning\\\", \\\"Turndown Service\\\"]\"','Elegantly designed city view room with modern luxury amenities and breathtaking views.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(32,2,'132',1,'available',222.39,0,2,'43 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Pillow Menu\\\", \\\"High-Speed Internet\\\", \\\"City View\\\", \\\"Smart TV\\\", \\\"Espresso Machine\\\", \\\"Coffee Maker\\\", \\\"Bathrobes\\\", \\\"24/7 Concierge\\\", \\\"Bluetooth Speaker\\\"]\"','Exquisite city view suite offering unparalleled elegance and personalized service.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(33,1,'233',2,'occupied',191.07,0,1,'45 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Minibar\\\", \\\"24/7 Concierge\\\", \\\"Safe\\\", \\\"Premium Toiletries\\\", \\\"Bathrobes\\\", \\\"Pillow Menu\\\", \\\"Room Service\\\", \\\"Blackout Curtains\\\", \\\"Work Desk\\\"]\"','Luxurious city view room with sophisticated decor and exceptional attention to detail.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(34,1,'234',2,'occupied',183.64,0,2,'47 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Coffee Maker\\\", \\\"Blackout Curtains\\\", \\\"Work Desk\\\", \\\"Bluetooth Speaker\\\", \\\"24/7 Concierge\\\", \\\"Turndown Service\\\", \\\"Refrigerator\\\", \\\"Slippers\\\", \\\"Room Service\\\"]\"','Exquisite city view suite offering unparalleled elegance and personalized service.','2025-11-21 12:24:00','2025-12-02 23:22:46'),(35,1,'235',2,'occupied',171.40,0,2,'46 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Slippers\\\", \\\"Ocean View\\\", \\\"Netflix\\\", \\\"Ergonomic Chair\\\", \\\"Coffee Maker\\\", \\\"Free WiFi\\\", \\\"Work Desk\\\", \\\"Air Conditioning\\\", \\\"Refrigerator\\\"]\"','Spacious city view accommodation featuring premium furnishings and world-class comfort.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(36,1,'236',2,'available',178.56,0,2,'44 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1618221195710-dd6b41faaea8?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Blackout Curtains\\\", \\\"Work Desk\\\", \\\"Smart TV\\\", \\\"Ergonomic Chair\\\", \\\"Netflix\\\", \\\"Free WiFi\\\", \\\"Private Balcony\\\", \\\"Espresso Machine\\\", \\\"Bathrobes\\\"]\"','Exquisite city view suite offering unparalleled elegance and personalized service.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(37,2,'237',2,'cleaning',234.39,0,2,'43 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1618221195710-dd6b41faaea8?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Minibar\\\", \\\"Hair Dryer\\\", \\\"Room Service\\\", \\\"Blackout Curtains\\\", \\\"Ergonomic Chair\\\", \\\"24/7 Concierge\\\", \\\"City View\\\", \\\"Bluetooth Speaker\\\", \\\"Slippers\\\"]\"','Luxurious city view room with sophisticated decor and exceptional attention to detail.','2025-11-21 12:24:00','2025-12-02 23:22:22'),(38,1,'238',2,'available',188.73,0,2,'43 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Bathrobes\\\", \\\"Smart TV\\\", \\\"USB Charging Ports\\\", \\\"Bluetooth Speaker\\\", \\\"Sound System\\\", \\\"Minibar\\\", \\\"Turndown Service\\\", \\\"24/7 Concierge\\\", \\\"Hair Dryer\\\"]\"','Exquisite city view suite offering unparalleled elegance and personalized service.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(39,2,'239',2,'available',234.40,0,2,'42 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop\\\"]\"','[\"Hair Dryer\", \"Premium Toiletries\", \"Bathrobes\", \"Netflix\", \"Room Service\", \"Ergonomic Chair\", \"Smart TV\", \"Private Balcony\", \"Pillow Menu\"]','Elegantly designed city view room with modern luxury amenities and breathtaking views.','2025-11-21 12:24:00','2025-12-01 12:42:10'),(40,2,'240',2,'available',232.24,0,2,'45 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"City View\\\", \\\"Premium Toiletries\\\", \\\"High-Speed Internet\\\", \\\"Refrigerator\\\", \\\"Iron & Ironing Board\\\", \\\"Pillow Menu\\\", \\\"24/7 Concierge\\\", \\\"USB Charging Ports\\\", \\\"Ocean View\\\"]\"','Elegantly designed city view room with modern luxury amenities and breathtaking views.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(41,2,'341',3,'available',246.01,0,2,'42 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Bluetooth Speaker\\\", \\\"Pillow Menu\\\", \\\"Air Conditioning\\\", \\\"Sound System\\\", \\\"Ergonomic Chair\\\", \\\"Climate Control\\\", \\\"City View\\\", \\\"Ocean View\\\", \\\"Blackout Curtains\\\"]\"','Exquisite city view suite offering unparalleled elegance and personalized service.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(42,1,'342',3,'occupied',193.93,0,2,'46 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Pillow Menu\\\", \\\"Ergonomic Chair\\\", \\\"Netflix\\\", \\\"Minibar\\\", \\\"Iron & Ironing Board\\\", \\\"USB Charging Ports\\\", \\\"Safe\\\", \\\"High-Speed Internet\\\", \\\"Espresso Machine\\\"]\"','Opulent city view accommodation with bespoke interiors and premium amenities.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(43,2,'343',3,'cleaning',236.67,0,2,'49 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1566665797739-1674de7a421a?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"High-Speed Internet\\\", \\\"Climate Control\\\", \\\"Pillow Menu\\\", \\\"Room Service\\\", \\\"Bathrobes\\\", \\\"Ocean View\\\", \\\"Air Conditioning\\\", \\\"Sound System\\\", \\\"Slippers\\\"]\"','Opulent city view accommodation with bespoke interiors and premium amenities.','2025-11-21 12:24:00','2025-12-02 23:22:46'),(44,2,'344',3,'available',245.16,0,2,'41 sqm','City View','[\"https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop\", \"https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop\", \"https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop\", \"/uploads/rooms/room-635354b0-9233-4946-b081-a52faec5b61e.png\"]','\"[\\\"Ergonomic Chair\\\", \\\"Private Balcony\\\", \\\"City View\\\", \\\"High-Speed Internet\\\", \\\"Room Service\\\", \\\"Air Conditioning\\\", \\\"USB Charging Ports\\\", \\\"Smart TV\\\", \\\"Netflix\\\"]\"','Luxurious city view room with sophisticated decor and exceptional attention to detail.','2025-11-21 12:24:00','2025-12-02 08:39:40'),(45,1,'345',3,'cleaning',182.90,0,1,'41 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Hair Dryer\\\", \\\"24/7 Concierge\\\", \\\"High-Speed Internet\\\", \\\"USB Charging Ports\\\", \\\"Climate Control\\\", \\\"Slippers\\\", \\\"Coffee Maker\\\", \\\"Pillow Menu\\\", \\\"Smart TV\\\"]\"','Elegantly designed city view room with modern luxury amenities and breathtaking views.','2025-11-21 12:24:00','2025-12-02 23:22:36'),(46,2,'346',3,'available',246.03,0,1,'50 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"City View\\\", \\\"Work Desk\\\", \\\"Safe\\\", \\\"Bluetooth Speaker\\\", \\\"Climate Control\\\", \\\"Room Service\\\", \\\"Ergonomic Chair\\\", \\\"Free WiFi\\\", \\\"Sound System\\\"]\"','Exquisite city view suite offering unparalleled elegance and personalized service.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(47,2,'347',3,'available',249.73,0,2,'42 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Turndown Service\\\", \\\"Espresso Machine\\\", \\\"Work Desk\\\", \\\"Bathrobes\\\", \\\"USB Charging Ports\\\", \\\"Refrigerator\\\", \\\"High-Speed Internet\\\", \\\"Coffee Maker\\\", \\\"Netflix\\\"]\"','Luxurious city view room with sophisticated decor and exceptional attention to detail.','2025-11-21 12:24:00','2025-11-21 12:24:00'),(48,1,'348',3,'cleaning',178.38,0,2,'42 sqm','City View','\"[\\\"https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop\\\", \\\"https://images.unsplash.com/photo-1596394516093-501ba68a0ba6?w=1200&h=800&fit=crop\\\"]\"','\"[\\\"Turndown Service\\\", \\\"Private Balcony\\\", \\\"City View\\\", \\\"Work Desk\\\", \\\"Iron & Ironing Board\\\", \\\"Safe\\\", \\\"Sound System\\\", \\\"Hair Dryer\\\", \\\"Smart TV\\\"]\"','Luxurious city view room with sophisticated decor and exceptional attention to detail.','2025-11-21 12:24:00','2025-12-02 23:22:46'); +/*!40000 ALTER TABLE `rooms` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `security_events` +-- + +DROP TABLE IF EXISTS `security_events`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `security_events` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int DEFAULT NULL, + `event_type` enum('login_attempt','login_success','login_failure','logout','password_change','password_reset','account_locked','account_unlocked','permission_denied','suspicious_activity','data_access','data_modification','data_deletion','api_access','ip_blocked','rate_limit_exceeded','oauth_login','sso_login') NOT NULL, + `severity` enum('low','medium','high','critical') NOT NULL, + `ip_address` varchar(45) DEFAULT NULL, + `user_agent` varchar(500) DEFAULT NULL, + `request_path` varchar(500) DEFAULT NULL, + `request_method` varchar(10) DEFAULT NULL, + `request_id` varchar(36) DEFAULT NULL, + `description` text, + `details` json DEFAULT NULL, + `extra_data` json DEFAULT NULL, + `resolved` tinyint(1) NOT NULL, + `resolved_at` datetime DEFAULT NULL, + `resolved_by` int DEFAULT NULL, + `resolution_notes` text, + `country` varchar(100) DEFAULT NULL, + `city` varchar(100) DEFAULT NULL, + `latitude` varchar(20) DEFAULT NULL, + `longitude` varchar(20) DEFAULT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `resolved_by` (`resolved_by`), + KEY `ix_security_events_severity` (`severity`), + KEY `ix_security_events_user_id` (`user_id`), + KEY `ix_security_events_ip_address` (`ip_address`), + KEY `ix_security_events_created_at` (`created_at`), + KEY `ix_security_events_id` (`id`), + KEY `ix_security_events_event_type` (`event_type`), + KEY `ix_security_events_request_id` (`request_id`), + CONSTRAINT `security_events_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `security_events_ibfk_2` FOREIGN KEY (`resolved_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `security_events` +-- + +LOCK TABLES `security_events` WRITE; +/*!40000 ALTER TABLE `security_events` DISABLE KEYS */; +/*!40000 ALTER TABLE `security_events` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `service_booking_items` +-- + +DROP TABLE IF EXISTS `service_booking_items`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `service_booking_items` ( + `id` int NOT NULL AUTO_INCREMENT, + `service_booking_id` int NOT NULL, + `service_id` int NOT NULL, + `quantity` int NOT NULL, + `unit_price` decimal(10,2) NOT NULL, + `total_price` decimal(10,2) NOT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `service_booking_id` (`service_booking_id`), + KEY `service_id` (`service_id`), + KEY `ix_service_booking_items_id` (`id`), + CONSTRAINT `service_booking_items_ibfk_1` FOREIGN KEY (`service_booking_id`) REFERENCES `service_bookings` (`id`), + CONSTRAINT `service_booking_items_ibfk_2` FOREIGN KEY (`service_id`) REFERENCES `services` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `service_booking_items` +-- + +LOCK TABLES `service_booking_items` WRITE; +/*!40000 ALTER TABLE `service_booking_items` DISABLE KEYS */; +/*!40000 ALTER TABLE `service_booking_items` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `service_bookings` +-- + +DROP TABLE IF EXISTS `service_bookings`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `service_bookings` ( + `id` int NOT NULL AUTO_INCREMENT, + `booking_number` varchar(50) NOT NULL, + `user_id` int NOT NULL, + `total_amount` decimal(10,2) NOT NULL, + `status` enum('pending','confirmed','completed','cancelled') NOT NULL, + `notes` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_service_bookings_booking_number` (`booking_number`), + KEY `user_id` (`user_id`), + KEY `ix_service_bookings_id` (`id`), + CONSTRAINT `service_bookings_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `service_bookings` +-- + +LOCK TABLES `service_bookings` WRITE; +/*!40000 ALTER TABLE `service_bookings` DISABLE KEYS */; +/*!40000 ALTER TABLE `service_bookings` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `service_payments` +-- + +DROP TABLE IF EXISTS `service_payments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `service_payments` ( + `id` int NOT NULL AUTO_INCREMENT, + `service_booking_id` int NOT NULL, + `amount` decimal(10,2) NOT NULL, + `payment_method` enum('cash','stripe','bank_transfer') NOT NULL, + `payment_status` enum('pending','completed','failed','refunded') NOT NULL, + `transaction_id` varchar(100) DEFAULT NULL, + `payment_date` datetime DEFAULT NULL, + `notes` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `service_booking_id` (`service_booking_id`), + KEY `ix_service_payments_id` (`id`), + CONSTRAINT `service_payments_ibfk_1` FOREIGN KEY (`service_booking_id`) REFERENCES `service_bookings` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `service_payments` +-- + +LOCK TABLES `service_payments` WRITE; +/*!40000 ALTER TABLE `service_payments` DISABLE KEYS */; +/*!40000 ALTER TABLE `service_payments` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `service_usages` +-- + +DROP TABLE IF EXISTS `service_usages`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `service_usages` ( + `id` int NOT NULL AUTO_INCREMENT, + `booking_id` int NOT NULL, + `service_id` int NOT NULL, + `quantity` int NOT NULL, + `unit_price` decimal(10,2) NOT NULL, + `total_price` decimal(10,2) NOT NULL, + `usage_date` datetime NOT NULL, + `notes` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `booking_id` (`booking_id`), + KEY `service_id` (`service_id`), + KEY `ix_service_usages_id` (`id`), + CONSTRAINT `service_usages_ibfk_1` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `service_usages_ibfk_2` FOREIGN KEY (`service_id`) REFERENCES `services` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `service_usages` +-- + +LOCK TABLES `service_usages` WRITE; +/*!40000 ALTER TABLE `service_usages` DISABLE KEYS */; +/*!40000 ALTER TABLE `service_usages` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `services` +-- + +DROP TABLE IF EXISTS `services`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `services` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL, + `description` text, + `price` decimal(10,2) NOT NULL, + `category` varchar(50) DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_services_id` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `services` +-- + +LOCK TABLES `services` WRITE; +/*!40000 ALTER TABLE `services` DISABLE KEYS */; +/*!40000 ALTER TABLE `services` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `system_settings` +-- + +DROP TABLE IF EXISTS `system_settings`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `system_settings` ( + `id` int NOT NULL AUTO_INCREMENT, + `key` varchar(100) NOT NULL, + `value` text NOT NULL, + `description` text, + `updated_at` datetime NOT NULL, + `updated_by_id` int DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_system_settings_key` (`key`), + KEY `updated_by_id` (`updated_by_id`), + KEY `ix_system_settings_id` (`id`), + CONSTRAINT `system_settings_ibfk_1` FOREIGN KEY (`updated_by_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `system_settings` +-- + +LOCK TABLES `system_settings` WRITE; +/*!40000 ALTER TABLE `system_settings` DISABLE KEYS */; +INSERT INTO `system_settings` VALUES (1,'company_name','Luxury Hotel','Company name displayed throughout the application','2025-11-23 16:06:15',3),(2,'company_tagline','Experience Unparalleled Elegance','Company tagline or slogan','2025-11-23 16:06:15',3),(3,'company_logo_url','/uploads/company/logo.png','URL to company logo image (upload via admin dashboard)','2025-11-23 16:06:00',3),(4,'company_favicon_url','/uploads/company/favicon.png','URL to company favicon image (upload via admin dashboard)','2025-11-23 16:06:10',3),(5,'company_phone','+1 (555) 123-4567','Company contact phone number','2025-11-23 16:06:15',3),(6,'company_email','info@luxuryhotel.com','Company contact email address','2025-11-23 16:06:15',3),(7,'company_address','123 Luxury Avenue, Premium District, City 12345, Country','Company physical address','2025-11-23 16:06:15',3),(8,'tax_rate','10.0','Default tax rate percentage (e.g., 10.0 for 10%)','2025-11-23 16:06:15',3),(9,'platform_currency','EUR','Platform-wide currency setting for displaying prices','2025-11-23 14:01:13',3),(10,'loyalty_program_enabled','false','Enable or disable the loyalty program','2025-11-30 19:30:03',3),(11,'chat_working_hours_start','9',NULL,'2025-11-23 16:06:15',3),(12,'chat_working_hours_end','17',NULL,'2025-11-23 16:06:15',3); +/*!40000 ALTER TABLE `system_settings` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `task_comments` +-- + +DROP TABLE IF EXISTS `task_comments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `task_comments` ( + `id` int NOT NULL AUTO_INCREMENT, + `task_id` int NOT NULL, + `user_id` int NOT NULL, + `comment` text NOT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `task_id` (`task_id`), + KEY `user_id` (`user_id`), + KEY `ix_task_comments_id` (`id`), + CONSTRAINT `task_comments_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`), + CONSTRAINT `task_comments_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `task_comments` +-- + +LOCK TABLES `task_comments` WRITE; +/*!40000 ALTER TABLE `task_comments` DISABLE KEYS */; +/*!40000 ALTER TABLE `task_comments` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `tasks` +-- + +DROP TABLE IF EXISTS `tasks`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `tasks` ( + `id` int NOT NULL AUTO_INCREMENT, + `title` varchar(255) NOT NULL, + `description` text, + `task_type` varchar(100) NOT NULL, + `status` enum('pending','assigned','in_progress','completed','cancelled','overdue') NOT NULL, + `priority` enum('low','medium','high','urgent') NOT NULL, + `workflow_instance_id` int DEFAULT NULL, + `booking_id` int DEFAULT NULL, + `room_id` int DEFAULT NULL, + `assigned_to` int DEFAULT NULL, + `created_by` int NOT NULL, + `due_date` datetime DEFAULT NULL, + `completed_at` datetime DEFAULT NULL, + `estimated_duration_minutes` int DEFAULT NULL, + `actual_duration_minutes` int DEFAULT NULL, + `notes` text, + `meta_data` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `workflow_instance_id` (`workflow_instance_id`), + KEY `booking_id` (`booking_id`), + KEY `room_id` (`room_id`), + KEY `assigned_to` (`assigned_to`), + KEY `created_by` (`created_by`), + KEY `ix_tasks_id` (`id`), + CONSTRAINT `tasks_ibfk_1` FOREIGN KEY (`workflow_instance_id`) REFERENCES `workflow_instances` (`id`), + CONSTRAINT `tasks_ibfk_2` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `tasks_ibfk_3` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`id`), + CONSTRAINT `tasks_ibfk_4` FOREIGN KEY (`assigned_to`) REFERENCES `users` (`id`), + CONSTRAINT `tasks_ibfk_5` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `tasks` +-- + +LOCK TABLES `tasks` WRITE; +/*!40000 ALTER TABLE `tasks` DISABLE KEYS */; +/*!40000 ALTER TABLE `tasks` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `user_loyalty` +-- + +DROP TABLE IF EXISTS `user_loyalty`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `user_loyalty` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `tier_id` int NOT NULL, + `total_points` int NOT NULL, + `lifetime_points` int NOT NULL, + `available_points` int NOT NULL, + `expired_points` int NOT NULL, + `referral_code` varchar(50) DEFAULT NULL, + `referral_count` int NOT NULL, + `birthday` date DEFAULT NULL, + `anniversary_date` date DEFAULT NULL, + `last_points_earned_date` datetime DEFAULT NULL, + `tier_started_date` datetime DEFAULT NULL, + `next_tier_points_needed` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_user_loyalty_user_id` (`user_id`), + UNIQUE KEY `ix_user_loyalty_referral_code` (`referral_code`), + KEY `ix_user_loyalty_id` (`id`), + KEY `ix_user_loyalty_tier_id` (`tier_id`), + CONSTRAINT `user_loyalty_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `user_loyalty_ibfk_2` FOREIGN KEY (`tier_id`) REFERENCES `loyalty_tiers` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `user_loyalty` +-- + +LOCK TABLES `user_loyalty` WRITE; +/*!40000 ALTER TABLE `user_loyalty` DISABLE KEYS */; +INSERT INTO `user_loyalty` VALUES (1,5,1,167000,180000,167000,0,'USER0005',0,'1990-11-21','1990-11-21',NULL,'2025-11-21 19:37:22',NULL,'2025-11-21 19:37:22','2025-11-21 20:01:36'); +/*!40000 ALTER TABLE `user_loyalty` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `user_sessions` +-- + +DROP TABLE IF EXISTS `user_sessions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `user_sessions` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `session_token` varchar(255) NOT NULL, + `refresh_token` varchar(255) DEFAULT NULL, + `ip_address` varchar(45) DEFAULT NULL, + `user_agent` varchar(500) DEFAULT NULL, + `device_info` text, + `is_active` tinyint(1) NOT NULL, + `last_activity` datetime NOT NULL, + `expires_at` datetime NOT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_user_sessions_session_token` (`session_token`), + UNIQUE KEY `ix_user_sessions_refresh_token` (`refresh_token`), + KEY `ix_user_sessions_id` (`id`), + KEY `ix_user_sessions_user_id` (`user_id`), + KEY `ix_user_sessions_is_active` (`is_active`), + KEY `ix_user_sessions_last_activity` (`last_activity`), + KEY `ix_user_sessions_expires_at` (`expires_at`), + CONSTRAINT `user_sessions_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=69 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `user_sessions` +-- + +LOCK TABLES `user_sessions` WRITE; +/*!40000 ALTER TABLE `user_sessions` DISABLE KEYS */; +INSERT INTO `user_sessions` VALUES (1,5,'VGKTqmTmbFeMYdRVtM20vDVrya5J7v6hJOidEYeyoRfv7jMsX9dwTLcUzJH32E5u6OR3qSy2GuxzSaCR8rflPA','w2wVZvgpXgM5BatuYSgZIigzCV0UfsigGb_3uU571guNLk1xyzvQFFh8iVkWtYSVk9FJbAkP3ed0etgiA0i1zw','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',0,'2025-12-01 02:39:17','2025-12-01 03:09:17','2025-12-01 02:39:17'),(2,5,'CL7CuHy1XT7jP_TLtCl9i4hMO4VmUGZJayIRC3CmG2F29FMPmpW--3uPxmfXhWWPJtA78gPUCcFY0CnuCk9RdA','Yzu5RvBKH2wS4RVAHPYDpp7PKGGHUAq4LMH2vjfAUNX6FkX6i1f0vjeAI0zOLmF-X8gp0LAYIJxsZKcAW2YE-w','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',0,'2025-12-01 02:42:51','2025-12-01 03:12:51','2025-12-01 02:42:51'),(3,5,'RU3Q1rpEVA1VDmAcWWAxPv1YOBUXBBpGUhHa3L7zpxLwIMy3wOTb8PNqqp25LI6gpx581w9CAlhO6lj4zWqBGg','as568JtNu0SBoCGqYnMGLUuhb6zGDEz1RtiyTF_Xg_NsV9N3SbXyTbIxEKzGQqadxzGDj5KsadkMF2SmvOeWpA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',0,'2025-12-01 02:44:02','2025-12-01 03:14:02','2025-12-01 02:44:02'),(4,5,'XbnaoIz6Rr_AG_5uLBxhyjDvPkrbFlwBKj-_Iqyy_pS8ZCJX7uRaWcePR0JKDIZa15J8bBNZYASW9bYrjQsBMQ','XcHa65ug2HJWr94rEi2bZKVhW39Z_FsTfkIwwarBKL0fT0qImCC0llP05Hdh0sWznsVQ3_ZZ7y-TvMg5Phab6w','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',0,'2025-12-01 02:44:34','2025-12-01 03:14:34','2025-12-01 02:44:34'),(5,5,'ADX_BCq-re-QZjx4teg7AQ1uqCZTjs5dI1rtcw1SWcsEUTlGBQJg6gJYYDP8OWZvQfFfeYXRZyQyv6j-OMaogw','luDgaeEKAHovWlsl4uF0A53dtVmgiqLTIi_cDMHy5h7m88IlSsOjas2OC69-pB0Jtm4M8dKbabbn7HQLMQM_vg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',0,'2025-12-01 02:45:06','2025-12-01 03:15:06','2025-12-01 02:45:06'),(6,5,'s9CU7IPWzThAEPfA2irL3_Re3rdSecnaF_jzhHjLMezIZJK6_rXvHnYngr5gtwa32DbAmyUQuXBpqKUk6MIchQ','r8a46nGSmu6ZFY_TtJGcAGKN-fntvk_GNgvn50dHZC8YkFsiHi9XDhNoTHcAh8TpgmamaCwUgQ4Aq_jZ1-sD-Q','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',0,'2025-12-01 02:47:00','2025-12-01 03:17:00','2025-12-01 02:47:00'),(7,5,'mK9q9_kxi9rUKAvkhMNzJKAPhDZFaO3z_zKYYuI8M9ApsKy__lAkxejLt7H5MVM683tJ03ld9bA1qH9PZvRZnw','sqFTuotJlaPXBeTf90PL9q_ewcBMvrOGrzbDrZ7bfG2BNSNZuVIedof5YVJxkTU4245n7CW-tEZYGeVmaWpvEA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 02:47:27','2025-12-01 03:17:27','2025-12-01 02:47:27'),(8,3,'SfoGekQMZACHBQedbRwGj-wJcAKPXmsR4RfvZ10DmRKI8s1IHilse56jh6l5tfruSSB3brm8XRnKMPwgv0F01A','oAMtbka-epWTaVa6Znuz-zJGnagBpgKjT-mTWE2ljhHT98aRakg2C5xEVhKvhsGlxxi4DnmB0ZMuquqvurHndA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 02:57:56','2025-12-01 03:27:56','2025-12-01 02:57:56'),(9,5,'_gcVvbb6Yt1Y45k1zMI9MA_H1qp-kg1t5DhZ7JXzxX64AFEDdoVKFNIvNY3KEQfdLby-R7CltWq-HLw6yafK7g','Lv6AyXK62V2lZdUjYJyJgIj9WCpegFohSuh1IYQgfiPArGZ7i7gI9IZaoOUp_-gAxmgT3d9DTni-owUe2-L21w','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 03:07:02','2025-12-01 03:37:02','2025-12-01 03:07:02'),(10,3,'kCP4_4kF5760wQlaRiEUSxPOczW66Wu6woyFSXDLpvNe-QmADQVl5bO16GfLx1p4zmAxrCsDJo1eGF1FSmtWbg','iwGl0WL_TuNpoAf98eW23IPGgW3XifdWktrY149uEM0masekJXOcfGaN9mXxl2I57koKTAAyKqZKvPvwNRGegg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 03:17:59','2025-12-01 03:47:59','2025-12-01 03:17:59'),(11,5,'OedXMKM6z8wFS99zIr9E4FGdF79qJpEqbEK8UoWKOx8vdOng1taaNuLh10wknRnfXBJziN6MtKxN_KG6DmELhg','a3TofVyCF0ypaB5oFbP9ApglbLfQ5HLrhL5QcWDLjLV2ap5Z3YrknCX15JiHqaGUilh7I4eB5GhIHC0ssRN2-g','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 03:38:10','2025-12-01 04:08:10','2025-12-01 03:38:10'),(12,3,'zjyv28PqbpASRpksb72nn-5_WvG5kMuADNjJYo0JARrH0nO-LdMArrKyNcCabBw24UrfUDKtCE85NrABnJgXPw','F0kY6BCB2msCxZEYit1dWBvLgVjBszsUd1yp3VB-GlT-NB6IIGwkcmXH_1PogESu0iHVA887tSOIvc_6q5JSlA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 04:19:29','2025-12-01 04:49:29','2025-12-01 04:19:29'),(13,3,'8e1PXNnOAX7zcx06et7CGOWDMB5tvMPwM4zWabbL34tB2vdEvC1akgocFyEIFIPSX0ifJYhh0IfA4zdZVyJ-Ug','BIAjtQMOqf8LL18HTDbdZcEZ9h7pjffjooWIIohX8lmDGFRo07HmB7hkh-kQnY4VqpB_hbXP6x25irctTFZqlQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 04:54:06','2025-12-01 05:24:06','2025-12-01 04:54:06'),(14,3,'k8P5AKG6OTumzffoo76riJFKiakJ9M_9zStXXP_ravmRxj-zv1_z62NL2Z-n1qmW9ndPy04khMSowYzSehxYQw','OTbFZoqH0_-qTdY9j18O5lkc_zxuZQuphA1HCN9RZGNq5lonco06DBYQHv4BQAkSqf3PqWGqOBcidj3an38GjQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 05:16:26','2025-12-01 05:46:26','2025-12-01 05:16:26'),(15,3,'rdk7Hf3Q77QK1dU-svU50aAOB1Xqjbuh0rkRXmhBHVhJGI9i4Bss6Da0izMSJF2Ws5n2XRqUO2QX2kEKZeQ1pQ','a8pHmTvY7kWQ7hWnpAwd4Fse0SOaknEcAlTIyEpmDStWfz4bJZfeqsyPmKKbiQVASiZq8H1dqwekjB__6FF02g','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 05:22:34','2025-12-01 05:52:34','2025-12-01 05:22:34'),(16,3,'rXoyntxWoG1Ns6bwfo9_Wo0zLjA9T2SNiOezto_k4dMOH9fwru4qXXQnbvKHBGMYuhS0XDEUBF9kMvlkCW0PyA','hF3APPd2GZf2tAJE-tiTP73p6krTpeBDqsXmV7WjHLnNuWGn04N6Igk0SBPd3SqRs6TMhgP8lroWZ4P8Ae328A','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 11:43:48','2025-12-01 12:13:48','2025-12-01 11:43:48'),(17,3,'Dw7wNDXhEbRDD2TNz-1qsKgmO3ZD30FCiNuKEqzp7AX1sWtMx3Bhg22Grke-Vm_hEzPd84zvthiEoU7X_pa_pw','SQMLKfQhi8UT9YNPoJDKjOJhIqd5zu-rrW0UOt13B7EiaGt02o0yjZDAeIjurVlRFiJBED77r_ELaCxmoh0lYw','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 11:47:44','2025-12-01 12:17:44','2025-12-01 11:47:44'),(18,3,'zc8Gw5kWyAsAKKW78WR4KmG6HPdrJnmk3bztSr8o426AkxynVPTrPsupnr9gvfwWrz6MvpqIEOPSncUr_e7hJQ','UezxRi21bo9xM_6xtrbtSswHqmBCCKWYTZfmCIGQfzYPDDyQncceVWxOURc--SljY3trrHn3m7fX0SMP_zmung','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 11:48:43','2025-12-01 12:18:43','2025-12-01 11:48:43'),(19,3,'b7da-5qUajzgAqrT7D4xBmb5r0ufloPXKFMCyfbLbg4_ko6U0FpiyZTzACov8OCtZwR6TvkuL1pXi-4im2o0ow','SgUgJjNjFj_fhAwNH4OSIe8rdwaDUwo05QN9uRoYSNOMbgnJ01jiFskN9IF291PbmhcfZMfm9A88eT85B18Ohg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 11:49:46','2025-12-01 12:19:46','2025-12-01 11:49:46'),(20,3,'EsKUV81ZXJF-wZ6atku-LqBb3Dy1i6RADnX0t7wrPbEviY1jwS2PboctS_K5JDZ65bGiOdqYlSb6DmPatgt_-w','NXN8SDpSHcGj-qDTMxEjTN58LWrPTK81yh_pl5Iriqc0QqGBRmS5HS4Csz-kW1KypRMwi0ZK2MA0nIp45wqthA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 11:52:31','2025-12-01 12:22:31','2025-12-01 11:52:31'),(21,3,'Q1QRpPK4PZDBfZbkU0iyUZsWZqCUOtrnNzMcXLETpUFiz9j-H0KY0cC5gbv7ozLTqwZn9zWawG9dJfZBvikDJg','IBdjg-RaQmr2COZ9fUeKln5wF_G6h7sxcDSRxnznd7xnPlcP7GEhBRr6UER_vvLuLpYgA322pjakNzGYcXu1UQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 12:31:59','2025-12-01 13:01:59','2025-12-01 12:31:59'),(22,3,'p9fhzr_t5pRHIJtT1yL-S31Zc7ZVzdWNhFE396XBtf8wNLEiQdfjUCE8n5Az8F1jDAUMjt_aatfqSR0Ta_iriw','x5bVMVMAZllKZs0cebznb_T10fbC0ywD2f_DLocQ6Te2PXZoNeY44XiAf_icIsLDvPN9JapuI4JVjmGPFFONMg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 12:39:18','2025-12-01 13:09:18','2025-12-01 12:39:18'),(23,3,'0q2THerCt5pTgVk3I0_eoMR1X1xwuwl6gYQpEyw4Dss7oBO5-Fs4Y9IEVs0PWzi5MIvAnS2VpTvs3Anxr08Hmg','6lq84kupAd1kRAavGdOuBRHanK8P4gB_zlYBrC0GdCNhpwPGBBJoPo9X3vbVKBxNBvP9YjMCJe1vpo-p0nMUPw','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 13:10:50','2025-12-01 13:40:50','2025-12-01 13:10:50'),(24,13,'6C6M6WAPLp94n9eJAlW0hZXpSgORZ_CKzVe3XaVWfjmmfyrfuxLx7M_THjW_mqCvm5S_8-2zD_gDW68CJRUYxA','VAA7mKYWL5OOG6zUFzL4VK2W2fVMugL3ompMJlN_oFo7OohX2PqmMzWWc-qx1FouP_IUOUfvTZPL0RzYwwuHag','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 13:12:44','2025-12-01 13:42:44','2025-12-01 13:12:44'),(25,13,'TDCKVDYZVg7RFo2WFjVsdUaqZqUV6DHojN1qAiIx4EjHE_FMKoIIzBkuJqANLiUXXfA0jDbv27f1vR93b4XrvQ','e6Vo3pFdDc6j4fdTmHWjZFRbz3IXRoGRiNPaoKBUJ6yvCSdMc8Yot6Jo8nqVDgN-0X3mPZ6LV8S0dPITISRmCg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 13:15:04','2025-12-01 13:45:04','2025-12-01 13:15:04'),(26,13,'Z5N_tnwkoqJeihelflKXtTivvbccKukEY8NrkyZowEOfZVqIvNmukUcDj9y_NF5RM_26NgZtD4KuAfI-alOHjQ','pUrnOR4frLA4G5Of-KLhQwm_aJ6D-N-nOmi2_co61n3ryz0NDo7KY7I-unePmpU6k-gBpiEva0rHznxoPMqY2A','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 13:16:48','2025-12-01 13:46:48','2025-12-01 13:16:48'),(27,3,'w6wgQX6x31zQD-3O0PhiDv_GRTFJo1SH6yay8M2US95uMCA3rI9jZKFifgvRuNOVVJl18w_YmKxNVWJ6t3mw-w','aiDFepLM_GMgc7B117RHMR4_zqzt2p2lPN3kTrZA99cSD7-ZEmrJAlz6aqdMyXZ55VQV0n_pLXKTLjr6CMIUWA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 13:18:01','2025-12-01 13:48:01','2025-12-01 13:18:01'),(28,13,'Z9ZdX5QRCt9usKUwhQF9sKs99BvQTRumZP1-tK-GnWlKwxPkVw5BOAY_e2XbBKEmjVWdnP9omIycWzYf_e7oOQ','XybIjbgS84E-B9SLBEElK6kTTLGFbSUaXDX5HsasHL8xYv6H2i5SMWNMcgNDeEMkMU14NpTgKzjucto_uiFolQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 13:22:18','2025-12-01 13:52:18','2025-12-01 13:22:18'),(29,3,'mGguNfuHMvcE1ASgNqxU9E6qldc_bLkl6eiEzB_fgplhXrGu0sXvFSmuD-Btf53o--7zJSt0ymXuhVs7_oDTng','63cC2XEaSwfJo-sSryGMEocEwlubDDcTl04MEX6mlCTepaQQB9pZNp3i3UDEEhgUbE_46LVw3g7-IHx_nwXBUg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 13:27:29','2025-12-01 13:57:29','2025-12-01 13:27:29'),(30,13,'Qxaw3pLUwA9--iTxnk5d7v0oX6Z8rf1aleECOz368CmulIIHTnL28_w9Tc59R3jeBeNV-kNtIMWg8BR1dNdDWA','VY72L9obigcNRONHBcEzQGOzgn3EgN29ADPo-AittjHcxLGN96vdPUyun03P22wb_yKFCYaLTwLAYyYit1nCFA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 18:16:04','2025-12-01 18:46:04','2025-12-01 18:16:04'),(31,13,'i1jtCD1zbtacNXEQpXIinV7tR1F50TFmDXFEggkcEKlPsASla-6YUBuTR7VGPpB5yhJGJNJq15py8PT_Yd9TjA','1DbkxHtIJfzKnxB2xePDwuXYQCq_eplOfZCt_MSfqlGFboY_g0tQuEP5I_fxvhasq1DvUKVowmm3vvDbDocIIQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 18:47:56','2025-12-01 19:17:56','2025-12-01 18:47:56'),(32,3,'npFMtTGd3PB3rGEpm8tyv2r5d_8y2iDHO8MqHRNrh60oyElqX56Leroz0BHzwxt7QuFlMgBdD6s9tRatGaWwgw','P5QtPcJNuHegkgS_VaXDOgZE2gZzC49Y2_4whgT5ttVWMimytRpaQPV8cLSDsfdRpDa-uPrkGcMjjkCVAyGTiA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 18:56:20','2025-12-01 19:26:20','2025-12-01 18:56:20'),(33,3,'lhSyTygfUACiKpmKT4SAbsD43kxOUgrKRWmqxpjzz-sHcUzoS5QLDXyE8P8ankLq2VLTOcMBQ4gX7wFx8wfmkg','MIgktOf-WAMWXCWhnUKyv_x6mlFsLm6u8ICOrVI1yXm996-U0BOcUp7utANiCZ4aRWTiqFZLgKIo55dfQm-U_w','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 18:56:53','2025-12-01 19:26:53','2025-12-01 18:56:53'),(34,3,'v4WBnuu2wr3gws54vIfKk7Hb-p1iR5lDqyo7EGXbtfYjn-X-_lddp0Mfg0qFRkjkiCBumCkk6hs-5wofgH5STg','5l0AOc14y53-g5NhOF3QIjV7b9oog86E8jBx5y729eeH-rq0n198pZ0LnBxP9eDM7sS1xbmWEKBZj74PvejxTQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 20:18:42','2025-12-01 20:48:42','2025-12-01 20:18:42'),(35,13,'LCW1B7mmRJ5cdPHKldAinuyk-vl2TF5Z1ID7N252G4RIPHYxFEzaDWONLgXyt7HVxPIzZ-wZr3LkYJoDIF64SQ','G_aW_Wz3hHI_PSRbuc6Oa4sL-9btSNv1fQNVAAjpK_BbBPFqBkqWBAOUyRoRmnXPBSlYPMfXjOaitIIG7U9J9A','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 20:21:22','2025-12-01 20:51:22','2025-12-01 20:21:22'),(36,3,'PH5BnqzzzTDXZV38M0voSPbZKMayStTMQCzmhK7vWrDwRlm3musbcWlgKSDwOtAW7aR23MmbPOYty0eY3yUjQQ','DkrI0OprCK-IHf7w7S-TiafiNakaanQDi1eeXZDJYI4ioAV6NC5T92Qfko2f8pTfYSjB6EUtjpETnmU0qZiPbw','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 20:21:56','2025-12-01 20:51:56','2025-12-01 20:21:56'),(37,3,'SgwmaTWOirF6ta3gj5P9JyP3NnwYW3p4AIzgkCG0vDft0tk556NSnE4TtHbNyDH5gIXySF2HLePkbhJjfPuS7A','_xqJksTWWgQpzCP0dOX46ClGYgNy8Bt6xhfCFWTcxximze0p8EIsizpiMJx22vZCAE2KfELBJTFSoLPRkDIGfg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 20:23:24','2025-12-01 20:53:24','2025-12-01 20:23:24'),(38,3,'6zywl_SFJ854SEWX6ddQFEzJEhzKhkSYOYrv0xav3ZXkXfJ9g_WomllAdqw-6CkJtSHjcizKhnqg_26SUAY5Iw','Bws1RfNABUgo9TQ6akkgjoDt0Vyb0KSCV0enTgo3mqEczAdwC9qbxpFg2E85xKYTJqhzROAU8bPTb6Lc9dsIvQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 20:25:08','2025-12-01 20:55:08','2025-12-01 20:25:08'),(39,13,'NlHpSpH1Fa6k_hAaBYPjl40KiqABQ5_o452aTUnZCIJayic3N5RwC8oU62mMdoModODtSsVBGaVS-fltCB7kxg','vVn3CsT1IIoBvNoCYec7mYnyLOi2IsG4FBwrIUJn-nnnGj3hy8a-qZb35Dna_i-RnpNXlUVksbjgtyGUoVSLPg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 20:25:28','2025-12-01 20:55:28','2025-12-01 20:25:28'),(40,13,'HB9zfQEMhbNDE2DOYRd4IJsRaVGGEv2XUUnxk7ZJzuuPdp-y-jtfnpIYQlVqN9Z6AnrnLMg5iv5FtEC0kux1lA','_rAxem5C7w1hMZl82aUbCpDuwkuiJADKwFgF3B38pLj50l6jwJ1kYU651ZJrajgzkzUl151nL1Ae4LZIDb_Lqw','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 20:25:39','2025-12-01 20:55:39','2025-12-01 20:25:39'),(41,13,'Q4UovpQnZhaLRo-nfh1stw8mxJo01YoH2MBECidq1F8c953yQreqVRGJfnepjmtk3wwyqp4nJcXhXKXlE6Nirg','APuDUCgMgpsIWZdV-3n5p1-jatPXBYMuw65axzBH-uYxAjMIvWBnZCFvE9dWx8_FyGBFj5JaQVG6GbtircL-Og','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 20:25:50','2025-12-01 20:55:50','2025-12-01 20:25:50'),(42,5,'2GDIToM1B5G36eI-9eaPQ_QQbITnySs7ABVG3oDK2Sq1DVcGIfsl24ROjsECksuKhu_DNzDXa_iW1h9vXyH6SA','6i2i9F73dwGkX25c8tE0lZsXWtvduXJ7p2sSLmbfp2rw6PxKCqTQBR4XH5pR7g4tZQWTMrfnFDoFIv3ZvQOp-A','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-01 21:24:21','2025-12-01 21:54:21','2025-12-01 21:24:21'),(43,3,'PGNaVDk_SU4pg5SW0U9D9VRIYs4mVQvGD2vBQPwzfLK7WKpRdRi3Mzgdg39W9Adro3X-KkhXZWpOlpHvipYXiw','am4DS1tJ9IWJ1O-kY2VE88Ru7OOV5BG4-O84zYuVG7T0I8CQ_OIYSHe8eNrxgRMJOkJtd9pWzBzcjBH4x2XvUA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 05:54:57','2025-12-02 06:24:57','2025-12-02 05:54:57'),(44,3,'gpXrMx8xdOAm60JHA4nuRi4lrTA9B9N0ERzvkbkdEzvZhPiW7VIjDjosUuZRROSkCxxaSWym1Zu9WgDO_GHnhA','SwtlfqgjzHizoQWMA0vIablZHfnAVtRPRuTbkU0kPkQ0uSm5VaeoeIW0XFAJGU65DFnvBs0R41YF9TKFFAX3vQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 06:06:31','2025-12-02 06:36:31','2025-12-02 06:06:31'),(45,3,'P7-nQnvmmnCke-Pzm8u9z6HdDmZwzlGW5KXtzalm394u5KnjlursKC2SDQckCqd6l71Mq361xmDrvvPa_eLlGA','SpfI71wJPfi3iwwnifnN-aCszgNbIPc3vTwXNzMCDX0jgwOz-z-37SQUbRqiYdtBfM2-b46Kk7xQz_pFRefWXg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 06:37:07','2025-12-02 07:07:07','2025-12-02 06:37:07'),(46,3,'CW03xApuclFOby9NOhGZBKWXyD1UgIjBZh8iz3f_juzd-oRl_vJYnoafAl4uIvSuEU7Yk5Nkib3Nnfg_ciBa0g','P0hBMXjKPUZbFm8zDL_pi389S0Sd66iiFPlcFXk85b-IyE9g3TFb364hXOjbQpH_VSXeUa41RNFv6O-watMKKg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 06:38:07','2025-12-02 07:08:07','2025-12-02 06:38:07'),(47,3,'b21oGSQwAJqDiNqU0a6th4LqknAc2v1ubkIek2hSZCGxWie-KunTIH5KpB7htVckYOOD96XiYF6GxayQR9Wrdw','QJlBlDuHcvI9WrBS1W6hh4Tfd_MjU7Ys_HQntfxD78Qfx3ydt0IuhWah8dNfxCend1dtSB1Ik5exwlnIbLpG0w','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 06:52:28','2025-12-02 07:22:28','2025-12-02 06:52:28'),(48,3,'fixxQbt-6cPsgBhVE93uxQCp5L7P9OVzsIKEW2HTh00pATEPOAeCsKkKKNQCbb4lccadRQN8opYylIlI2gs0dw','n_qUTjk8maVY9oDIDc7rn8wSBPYqANQrkwy-1wGuRLaZM6Tf2ot_AV0VA3N61C9KrX3tYgJN5KNZhaXZJUinPQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 07:22:50','2025-12-02 07:52:50','2025-12-02 07:22:50'),(49,3,'hE0s5Ji3MAMzBQOPeJu7uAcWOsk0Ya6n4e3MgW9moD3xrtU6zwrXt9jMf9DZBe-ae9bLQVjs5dld5IZGku55aA','ud2hX972qvEANOwwg82GtTCQUKkKQ-enh6pTiardMT-zu0kzP7ydo6NkxsQdZAmal4cc1RqABeh1WA3wQPteEQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 07:35:56','2025-12-02 08:05:56','2025-12-02 07:35:56'),(50,3,'2r2iOmXm8zz1SJcgzT8gyxu8aEBvB1_A8ouhdLwQZAXw07ZP4T3BckQOFO-o70v3gCAQqFR2bEM7AkmplL_mUg','wxm5tVbg9ZQOEYdVBT3M2fwQZjJk2H6gXikmbg3iAGxlOW2AmvXsQtEB1g8Wm7ppAgyOnNSpfV2TY9pkNe03ig','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 07:48:45','2025-12-02 08:18:45','2025-12-02 07:48:45'),(51,3,'30p7TDGdz74a2udRfEP63TrB-ON3UMAqPb20EpaRZhV9bWwEve8WbQsf3aQ4VlA0Sj2F1SYjJW9HYbp4hGEUEQ','zuo8i-3lSwiUQ8n6ZPe_DuDoAW5d3LSRUROGhlHGZQN1fwdRvuaJM6plaN5r26njLGZLCv0Ui-pEFkdbLA48cw','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 08:13:14','2025-12-02 08:43:14','2025-12-02 08:13:14'),(52,3,'tz9cOnQdxVvkIUp5vyPNUGRQCaCQM_6ptrU4Um_Rv8_JgtSKaf8Oo1ZbR3suOwxiSvk6YXIrJIiQmO8o_fCEgQ','UGBvIA_Ase-L8Oii4j-XRCLe48zgzLTPiAJmwJdRU7c15v3Mhs-B6-Pg5URc-V2neMI_ZLq4Ecrlu7TTVgD3xQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 08:33:06','2025-12-02 09:03:06','2025-12-02 08:33:06'),(53,3,'oHA_G4fgtXs9PywgB0IelM1v4p8AyXcOedOW_PD9TFnKULsuk5inZ7r_a9JMiEZ-4afRub392lX1B5otxL6SiQ','zzSKYFTbPsTBigBw3ws7yUbgx08N1waz_AS2q-1PjgCEtP9-Jw46OMBGDkXA6WUhYsG4ccW1ykZTvjaHfoBvkw','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 15:35:03','2025-12-02 16:05:03','2025-12-02 15:35:03'),(54,3,'n-6whu1elbD7GWiDSecLzOWl3bebVUn1TmjIk-gkxgMYi817sxFl72tCU0c6GsAxYYDPq82s7onkDWicqrWYUQ','dOm1lNbLdmTowd7MvCP3aP3hlH9FgNlZIFYlXPOzUbGKdPYs1kP2sr90gYyumCaQygydnaATxPlyyHZZvQv0GA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 15:38:06','2025-12-02 16:08:06','2025-12-02 15:38:06'),(55,3,'B8bLjvWLgJ-5i4De4HN_zVrhAoayUZr5ctwsrD13wQrJO_W4FuAAgqvZcrDhyof8pdCCxeKv-ME58OhO84FXPw','pytKCdvUPZyiRs1yYm0Ib9meKTvJDWHX9USH2GJ395-tkyZL_KyfhWlIwbvmoIj5zTgR2zmJ9XJjky2UxCNsOg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 15:42:38','2025-12-02 16:12:38','2025-12-02 15:42:38'),(56,3,'IgaSR-2BYQ7V20yDLmfqcRCF5lkvSQinYuICl24GfSbA9k4TtxwDt2LomRNh6klzfEksyaYeaqJSUqFFx0v4WA','n93RLylVPMv0dC61Ka0CUcROLN8EcHfGWXVIZHEcrW8tUxOpvzX9OAyu4yw61am9dxT_VrS2Cd2_T5a9pAdfxw','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 15:47:34','2025-12-02 16:17:34','2025-12-02 15:47:34'),(57,3,'RLbe4mE0ghr_wVFN8XdI72nUqW582Cn9T7skhZtWVk5viR4WwP_TRIVLG0U3U0-JmuKFJYNXOwKc_FmSlD0eOg','eyoOmDweHlamp8nsUUq-iJj5ozFYEllLsY3HJq9lZqf9wqms77GLKx4SAMnQtCcHrgtFaOPJZquNB7XEjS3ovA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 22:48:51','2025-12-02 23:18:51','2025-12-02 22:48:51'),(58,3,'jWMBiM1G6rfRwPvw-WujL3IP0lHRIlyD8r8llaDt46peIip-rvNwWH-FiWmMX0tFPmjbIkyMcw63TJG8cLEn_A','bDyIekRRVHtQaP9TN_1DnyyeQoxqg9N69GVje2V7INWGC0SohaNQ4RCMfIhnsDTZEPIowHLHXZJFeXMY_7Ecwg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 22:49:32','2025-12-02 23:19:32','2025-12-02 22:49:32'),(59,13,'dIYClS-iLqEv8gU_3-eq-nsGxprlzCDFKyMEWyNfJ1cr-BVBqovpxDn8sZJY3yFNlgxmCsGwgSFMxGoySAKfnA','Wopm4FxfzOERkl-G3tA-UJiHy1Lt0SIJcy6HAA49nK9ugsXovkRllNAEWYnSGOjgZhEHf9lK9xMBS8ypze3DKA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 22:56:50','2025-12-02 23:26:50','2025-12-02 22:56:50'),(60,13,'pib0SyBmHM2t3k6GXPGy8kvI59FjBcYHdqq31pT3w-GkH3scX5tKnJhr5igFRL407i3w6yiTxuQeXoleO9dN-g','O9HzHfRbE0OSd2rT2C6h2hPfR8JU8XXxHVtxid43204fqAfou7dROi0Oapugtjp_0_gE1DIcVCevTm7FDWpONA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 22:59:14','2025-12-02 23:29:14','2025-12-02 22:59:14'),(61,13,'sMedPt8L5R0ODhEtMD95511YLXg42j9Ah0dpVkQDcce8clguaBgV0DOR83vfw-7Vp5IF504c-ZnuaEGOnyMtxg','ndPoDiKunkhmoa5zaOVfnAhP9kA6XfvT7emHzNR8Ri_k7WXkhps0LqSXpZL6DJyW0JVpHOwYqzeIB6CemJFNyQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 23:07:37','2025-12-02 23:37:37','2025-12-02 23:07:37'),(62,3,'uOVKW47J9vnM7PXIQK9A_Ily66tLLdgIJqWtrF0o3f8cmegqjg9A88PKUO6f227SjahdjVjr1sbFEaGlD7W34A','TYWlUEBRfbgC7ShUXd3AkN-qFL7jPrFuuIb7qTzKbdAjTrZmuWNeULQOPz1_lCiG8FSSSZ0jog_vuRQu49PnHg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 23:10:07','2025-12-02 23:40:07','2025-12-02 23:10:07'),(63,3,'v3HpP5sQXkdphLwFlkYFl-ECra70cpEHXDb5YIVoIrmGim6MCKy8Nas5a81zjoZeU5wu1cBtrUDTGCzS6sXIEw','hbKvd_UvbiXGD_X923wCZirBjxBZyfoJj2HdwJQ0qPx_BZ9nI-eSc8wPguONSHRmiroA9SZe4kbIg6reCD4bKw','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 23:10:33','2025-12-02 23:40:33','2025-12-02 23:10:33'),(64,3,'80YqR17YuBSFMUbFbDLwe-KCdhEI1noq-fCNExO-Qt4Rv2PLDKofDOz7t3U9Wk_wcwwf9r5-0zp9SfTNSxjKvw','5aLooLm_zLFjTZeuIrJBcWqFAwG57ralrqCMkfhnAG33Z0XT2bKRFN2tnLm7J3-JA6yOBoHwxz89aVyxOSIgrQ','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 23:18:44','2025-12-02 23:48:44','2025-12-02 23:18:44'),(65,13,'ZcS8fGo3H4i3vP2MHh5b5KkehrktgZvtAR5ZnBrgCMfP9e-xEVCj_bv6uAAUEvQc_OFfqMj4hMD564VsIIbTMA','Q1Q0BwfRRj-Db-6yAzD_uCkoO14BCNLA7zEb3UZqYZDIehK2DuiLyH-Uc6cTqTbOdFIPMqkOEnrwnyO0exoGSw','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 23:19:14','2025-12-02 23:49:14','2025-12-02 23:19:14'),(66,3,'E0sP51LwqCHxJ94h67z7LNHnmOYs3ZkFNYumtAZSlglntsXz2grHYPQBzGhW_f-7qj-EfXyGqUA6JI6HVcNJ_w','9CyeYNXA8u9rMc_JZ5hcrSlThqOOkB0-VqY7KNlBagbVknsKzhYPY3hn0ezle8MvFhOfl95gooxvOKd7c9yQzg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 23:20:44','2025-12-02 23:50:44','2025-12-02 23:20:44'),(67,13,'f_gGBME3He6lN1yWWDpthyrkweFDTqeLiBTLrIkCN-u81BscubO8VV6S5EgfZxOV0nkQVqeKl6EKpOu3uzZniw','wjQ8q7hsu82nQNOxY8uCQhWRMN8yQFnAJQRe_Po1hIQn4Wy6xOvqENnHInF6TEVOF0_oLi75kg2N9q5UNnFTPA','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 23:21:18','2025-12-02 23:51:18','2025-12-02 23:21:18'),(68,3,'9I_B0QI1UTBrAlAI6xovDPhdPzb8XmadhDJCo-M07lpTTEPXhjT2y89DERxLOMPeUvUMB-e7bZRb8iz91cn_XQ','AVCDGe4eOD2B1wFh_oHMtLLVC6gKqoKXyjrCktg-Jl5DCwz4GV0Y3NoHZ53qKnYyZNq1hwdOeZK1Iyal6sJ3Eg','127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','{\'user_agent\': \'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0\'}',1,'2025-12-02 23:23:46','2025-12-02 23:53:46','2025-12-02 23:23:46'); +/*!40000 ALTER TABLE `user_sessions` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `users` +-- + +DROP TABLE IF EXISTS `users`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `users` ( + `id` int NOT NULL AUTO_INCREMENT, + `role_id` int NOT NULL, + `email` varchar(100) NOT NULL, + `password` varchar(255) NOT NULL, + `full_name` varchar(100) NOT NULL, + `phone` varchar(20) DEFAULT NULL, + `address` text, + `avatar` varchar(255) DEFAULT NULL, + `currency` varchar(3) NOT NULL, + `is_active` tinyint(1) NOT NULL, + `mfa_enabled` tinyint(1) NOT NULL, + `mfa_secret` varchar(255) DEFAULT NULL, + `mfa_backup_codes` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `is_vip` tinyint(1) NOT NULL DEFAULT '0', + `lifetime_value` decimal(10,2) DEFAULT '0.00', + `satisfaction_score` decimal(3,2) DEFAULT NULL, + `last_visit_date` datetime DEFAULT NULL, + `total_visits` int NOT NULL DEFAULT '0', + `failed_login_attempts` int NOT NULL DEFAULT '0', + `locked_until` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_users_email` (`email`), + KEY `role_id` (`role_id`), + KEY `ix_users_id` (`id`), + CONSTRAINT `users_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `users` +-- + +LOCK TABLES `users` WRITE; +/*!40000 ALTER TABLE `users` DISABLE KEYS */; +INSERT INTO `users` VALUES (1,1,'admin@hotel.com','$2b$12$r8LxYLSOqe7LaV4scV24T.OcWbuZxx2xeXCBgGp2HEbP293EivzfW','Administrator',NULL,NULL,NULL,'EUR',1,0,NULL,NULL,'2025-11-21 12:23:51','2025-11-21 12:23:51',0,0.00,NULL,NULL,0,0,NULL),(2,1,'gnxsoft@gnxsoft.com','$2b$12$XI0iAIiqjf4KLR2vl7/RTemaBviPRQll1fRjgEkhWoG/r6U.b7g6u','GNXSoft Admin','+1 (555) 111-2222',NULL,NULL,'EUR',1,0,NULL,NULL,'2025-11-21 12:27:23','2025-11-21 12:27:23',0,0.00,NULL,NULL,0,0,NULL),(3,1,'admin@gnxsoft.com','$2b$12$dsnViGu0OW5dBpvW1GprwOYVflOSkvhz6ibcHgO6MjjmI6kTZGM/a','Administrator','+1 (555) 222-3333',NULL,'/uploads/avatars/avatar-3-8bb91db1-7522-40f4-834a-2b5e402546e9.png','EUR',1,0,NULL,NULL,'2025-11-21 12:27:23','2025-12-01 05:23:49',0,0.00,NULL,NULL,0,0,NULL),(4,2,'staff@gnxsoft.com','$2b$12$WITmjZWF3zpFzerHQPic4.SU7T1gfO3o0VkXrjboFA8OS7Q5q205y','Staff Member','+1 (555) 333-4444',NULL,NULL,'EUR',1,0,NULL,NULL,'2025-11-21 12:27:23','2025-11-21 12:27:23',0,0.00,NULL,NULL,0,0,NULL),(5,3,'customer@gnxsoft.com','$2b$12$uz5wFN4lpR.4kGuPITIOQuapEG8lgsXUuTNwLrLHk61vIOAAK1sEy','Customer User','+1 (555) 444-5555',NULL,'/uploads/avatars/avatar-5-240ae3b6-df83-49bf-be68-2bf3744bfc5c.png','EUR',1,0,NULL,NULL,'2025-11-21 12:27:23','2025-12-01 02:56:08',1,0.00,5.00,NULL,0,0,NULL),(6,3,'john.doe@gnxsoft.com','$2b$12$KwLQlpyujfxqykrJXZvy0.Yp66DVDXTPGye.4ckb7R.I0XBSe58Te','John Doe','+1 (555) 555-6666',NULL,NULL,'USD',1,0,NULL,NULL,'2025-11-21 12:27:23','2025-11-21 12:27:23',0,0.00,NULL,NULL,0,0,NULL),(7,3,'jane.smith@gnxsoft.com','$2b$12$hTjsh31CkNg1otHJlsIvW.3NlU9alU/j6VLjlXnejOw7r6OFKmybS','Jane Smith','+1 (555) 666-7777',NULL,NULL,'EUR',1,0,NULL,NULL,'2025-11-21 12:27:23','2025-11-21 12:27:23',0,0.00,NULL,NULL,0,0,NULL),(8,3,'robert.wilson@gnxsoft.com','$2b$12$v0acSUDhIHu/nxKHiy/v/eOw6Uh6abgUBz47EESyTVBESUA.INTIq','Robert Wilson','+1 (555) 777-8888',NULL,NULL,'GBP',1,0,NULL,NULL,'2025-11-21 12:27:23','2025-11-21 12:27:23',0,0.00,NULL,NULL,0,0,NULL),(9,3,'maria.garcia@gnxsoft.com','$2b$12$fjC5OXGieVjvt8Qd5E1VfeN39ANrsLM8HmSdE9Sr2ZIhZutVft4T6','Maria Garcia','+1 (555) 888-9999',NULL,NULL,'EUR',1,0,NULL,NULL,'2025-11-21 12:27:23','2025-11-21 12:27:23',0,0.00,NULL,NULL,0,0,NULL),(12,4,'anna@gnxsoft.com','$2b$12$kAcWyoREsLxrKZAPJI00Gu02QiEMbwvwqMfnNwNHA0TjeKmjtE58u','Anna Ivanova','068686868',NULL,NULL,'VND',1,0,NULL,NULL,'2025-11-21 12:38:50','2025-11-21 12:38:50',0,0.00,NULL,NULL,0,0,NULL),(13,5,'housekeeping@gnxsoft.com','$2b$12$J8GNVladTLJ.3H92ld8z1.ZeiWGYQL4QgviQDmDp1n2.mnhwfeCp.','Housekeeping Staff',NULL,NULL,NULL,'EUR',1,0,NULL,NULL,'2025-12-01 13:11:51','2025-12-01 13:12:44',0,0.00,NULL,NULL,0,0,NULL); +/*!40000 ALTER TABLE `users` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `webhook_deliveries` +-- + +DROP TABLE IF EXISTS `webhook_deliveries`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `webhook_deliveries` ( + `id` int NOT NULL AUTO_INCREMENT, + `webhook_id` int NOT NULL, + `event_type` varchar(100) NOT NULL, + `event_id` varchar(255) NOT NULL, + `status` enum('pending','success','failed','retrying') NOT NULL, + `payload` json NOT NULL, + `response_status` int DEFAULT NULL, + `response_body` text, + `error_message` text, + `attempt_count` int NOT NULL, + `next_retry_at` datetime DEFAULT NULL, + `delivered_at` datetime DEFAULT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_webhook_deliveries_id` (`id`), + KEY `ix_webhook_deliveries_webhook_id` (`webhook_id`), + KEY `ix_webhook_deliveries_event_type` (`event_type`), + KEY `ix_webhook_deliveries_event_id` (`event_id`), + KEY `ix_webhook_deliveries_status` (`status`), + KEY `ix_webhook_deliveries_created_at` (`created_at`), + CONSTRAINT `webhook_deliveries_ibfk_1` FOREIGN KEY (`webhook_id`) REFERENCES `webhooks` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `webhook_deliveries` +-- + +LOCK TABLES `webhook_deliveries` WRITE; +/*!40000 ALTER TABLE `webhook_deliveries` DISABLE KEYS */; +/*!40000 ALTER TABLE `webhook_deliveries` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `webhooks` +-- + +DROP TABLE IF EXISTS `webhooks`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `webhooks` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `url` varchar(500) NOT NULL, + `secret` varchar(255) NOT NULL, + `events` json NOT NULL, + `status` enum('active','inactive','paused') NOT NULL, + `retry_count` int NOT NULL, + `timeout_seconds` int NOT NULL, + `description` text, + `created_by` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `created_by` (`created_by`), + KEY `ix_webhooks_id` (`id`), + KEY `ix_webhooks_status` (`status`), + CONSTRAINT `webhooks_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `webhooks` +-- + +LOCK TABLES `webhooks` WRITE; +/*!40000 ALTER TABLE `webhooks` DISABLE KEYS */; +/*!40000 ALTER TABLE `webhooks` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `workflow_instances` +-- + +DROP TABLE IF EXISTS `workflow_instances`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `workflow_instances` ( + `id` int NOT NULL AUTO_INCREMENT, + `workflow_id` int NOT NULL, + `booking_id` int DEFAULT NULL, + `room_id` int DEFAULT NULL, + `user_id` int DEFAULT NULL, + `status` varchar(50) NOT NULL, + `started_at` datetime NOT NULL, + `completed_at` datetime DEFAULT NULL, + `due_date` datetime DEFAULT NULL, + `meta_data` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `workflow_id` (`workflow_id`), + KEY `booking_id` (`booking_id`), + KEY `room_id` (`room_id`), + KEY `user_id` (`user_id`), + KEY `ix_workflow_instances_id` (`id`), + CONSTRAINT `workflow_instances_ibfk_1` FOREIGN KEY (`workflow_id`) REFERENCES `workflows` (`id`), + CONSTRAINT `workflow_instances_ibfk_2` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `workflow_instances_ibfk_3` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`id`), + CONSTRAINT `workflow_instances_ibfk_4` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `workflow_instances` +-- + +LOCK TABLES `workflow_instances` WRITE; +/*!40000 ALTER TABLE `workflow_instances` DISABLE KEYS */; +/*!40000 ALTER TABLE `workflow_instances` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `workflows` +-- + +DROP TABLE IF EXISTS `workflows`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `workflows` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `description` text, + `workflow_type` enum('pre_arrival','room_preparation','maintenance','guest_communication','follow_up','custom') NOT NULL, + `status` enum('active','inactive','archived') NOT NULL, + `trigger` enum('booking_created','booking_confirmed','check_in','check_out','maintenance_request','guest_message','manual','scheduled') NOT NULL, + `trigger_config` json DEFAULT NULL, + `steps` json NOT NULL, + `sla_hours` int DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `created_by` int NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `created_by` (`created_by`), + KEY `ix_workflows_id` (`id`), + CONSTRAINT `workflows_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `workflows` +-- + +LOCK TABLES `workflows` WRITE; +/*!40000 ALTER TABLE `workflows` DISABLE KEYS */; +/*!40000 ALTER TABLE `workflows` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping routines for database 'hotel_booking_dev' +-- +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2025-12-03 1:29:32 diff --git a/Backend/seeds_data/__pycache__/seed_bookings.cpython-312.pyc b/Backend/seeds_data/__pycache__/seed_bookings.cpython-312.pyc new file mode 100644 index 00000000..61ca3ec7 Binary files /dev/null and b/Backend/seeds_data/__pycache__/seed_bookings.cpython-312.pyc differ diff --git a/Backend/seeds_data/__pycache__/seed_initial_data.cpython-312.pyc b/Backend/seeds_data/__pycache__/seed_initial_data.cpython-312.pyc new file mode 100644 index 00000000..53a54772 Binary files /dev/null and b/Backend/seeds_data/__pycache__/seed_initial_data.cpython-312.pyc differ diff --git a/Backend/seeds_data/seed_all_test_data.py b/Backend/seeds_data/seed_all_test_data.py new file mode 100755 index 00000000..116af888 --- /dev/null +++ b/Backend/seeds_data/seed_all_test_data.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python3 +""" +Master script to seed all test data for the hotel booking system. +This script runs all necessary seed scripts in the correct order. +""" + +import sys +import os +from pathlib import Path + +# Add the Backend directory to the path +backend_dir = Path(__file__).parent.parent +sys.path.insert(0, str(backend_dir)) +# Also add the seeds_data directory like other seed scripts +sys.path.insert(0, str(Path(__file__).parent)) + +import bcrypt + +def ensure_housekeeping_role(db): + """Ensure housekeeping role exists""" + from src.models.role import Role + housekeeping_role = db.query(Role).filter(Role.name == 'housekeeping').first() + if not housekeeping_role: + print('Creating housekeeping role...') + housekeeping_role = Role(name='housekeeping', description='Housekeeping staff role') + db.add(housekeeping_role) + db.commit() + db.refresh(housekeeping_role) + print('✓ Housekeeping role created') + return housekeeping_role + +def ensure_housekeeping_users(db): + """Ensure housekeeping users exist""" + from src.models.role import Role + from src.models.user import User + housekeeping_role = db.query(Role).filter(Role.name == 'housekeeping').first() + if not housekeeping_role: + print('❌ Housekeeping role not found!') + return + + housekeeping_users = [ + { + 'email': 'housekeeping@gnxsoft.com', + 'password': 'housekeeping123', + 'full_name': 'Housekeeping Staff', + 'phone': '+1 (555) 999-0000' + }, + { + 'email': 'housekeeping2@gnxsoft.com', + 'password': 'housekeeping123', + 'full_name': 'Housekeeping Staff 2', + 'phone': '+1 (555) 999-0001' + } + ] + + for user_data in housekeeping_users: + existing = db.query(User).filter(User.email == user_data['email']).first() + if not existing: + password_bytes = user_data['password'].encode('utf-8') + salt = bcrypt.gensalt() + hashed_password = bcrypt.hashpw(password_bytes, salt).decode('utf-8') + + user = User( + email=user_data['email'], + password=hashed_password, + full_name=user_data['full_name'], + phone=user_data['phone'], + role_id=housekeeping_role.id, + currency='EUR', + is_active=True + ) + db.add(user) + print(f' ✓ Created housekeeping user: {user_data["email"]} - Password: {user_data["password"]}') + else: + print(f' ⚠️ Housekeeping user "{user_data["email"]}" already exists') + + db.commit() + +def main(): + print('=' * 80) + print('SEEDING ALL TEST DATA FOR HOTEL BOOKING SYSTEM') + print('=' * 80) + print() + + from src.shared.config.database import SessionLocal + db = SessionLocal() + try: + # Step 1: Ensure housekeeping role exists + print('Step 1: Ensuring housekeeping role exists...') + ensure_housekeeping_role(db) + print() + + # Step 2: Ensure housekeeping users exist + print('Step 2: Ensuring housekeeping users exist...') + ensure_housekeeping_users(db) + print() + + # Step 3: Import and run seed scripts + print('Step 3: Running seed scripts...') + print() + + # Import seed modules + from seeds_data.seed_initial_data import seed_roles, seed_room_types, seed_admin_user + from seeds_data.seed_users import seed_users + from seeds_data.seed_rooms import seed_rooms + from seeds_data.seed_bookings import seed_bookings + + # Run seed scripts + print('Running seed_initial_data...') + seed_initial_data.seed_roles(db) + seed_initial_data.seed_room_types(db) + seed_initial_data.seed_admin_user(db) + print() + + print('Running seed_users...') + seed_users_module.seed_users(db) + print() + + print('Running seed_rooms...') + seed_rooms_module.seed_rooms(db) + print() + + print('Running seed_bookings...') + seed_bookings_module.seed_bookings(db) + print() + + print('=' * 80) + print('✅ ALL TEST DATA SEEDED SUCCESSFULLY!') + print('=' * 80) + print() + print('📋 Test Accounts:') + print(' Staff: staff@gnxsoft.com / staff123') + print(' Housekeeping: housekeeping@gnxsoft.com / housekeeping123') + print(' Housekeeping 2: housekeeping2@gnxsoft.com / housekeeping123') + print(' Customer: customer@gnxsoft.com / customer123') + print() + print('🧪 To test notifications:') + print(' 1. Log in as staff (staff@gnxsoft.com)') + print(' 2. Go to Bookings and mark a checked_in booking as checked_out') + print(' 3. Log in as housekeeping user in another browser/tab') + print(' 4. You should receive a real-time notification about the room needing cleaning') + print('=' * 80) + + except Exception as e: + print(f'\n❌ Error: {e}') + import traceback + traceback.print_exc() + db.rollback() + finally: + db.close() + +if __name__ == '__main__': + main() + diff --git a/Backend/seeds_data/seed_bookings.py b/Backend/seeds_data/seed_bookings.py new file mode 100755 index 00000000..ed200dda --- /dev/null +++ b/Backend/seeds_data/seed_bookings.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python3 +""" +Script to seed sample bookings for testing check-in/check-out and housekeeping notifications. +""" + +import sys +import os +from pathlib import Path +# Add both the seeds_data directory and the Backend directory to the path +sys.path.insert(0, str(Path(__file__).parent)) +sys.path.insert(0, str(Path(__file__).parent.parent)) +from sqlalchemy.orm import Session +from sqlalchemy import and_ +from src.shared.config.database import SessionLocal +# Import all models needed for SQLAlchemy relationship setup +# Import base models first +from src.auth.models.role import Role +from src.auth.models.user import User +from src.rooms.models.room import Room, RoomStatus +from src.rooms.models.room_type import RoomType # For Room relationship +from src.rooms.models.rate_plan import RatePlan # For RoomType relationship +from src.rooms.models.room_maintenance import RoomMaintenance # For Room relationship +from src.rooms.models.room_inspection import RoomInspection # For Room relationship +from src.rooms.models.room_attribute import RoomAttribute # For Room relationship +from src.hotel_services.models.housekeeping_task import HousekeepingTask # For Room relationship +from src.bookings.models.booking import Booking, BookingStatus +from src.bookings.models.group_booking import GroupBooking # For Booking relationship + +# Import all related models to satisfy SQLAlchemy relationships +# This is necessary because SQLAlchemy needs all related models loaded +try: + from src.auth.models.refresh_token import RefreshToken + from src.reviews.models.review import Review + from src.reviews.models.favorite import Favorite + from src.hotel_services.models.service import Service # For ServiceBooking relationship + from src.hotel_services.models.service_booking import ServiceBooking + from src.hotel_services.models.service_usage import ServiceUsage # For Booking relationship + from src.bookings.models.checkin_checkout import CheckInCheckOut + from src.payments.models.payment import Payment + from src.payments.models.invoice import Invoice + from src.ai.models.chat import Chat + from src.loyalty.models.user_loyalty import UserLoyalty + from src.loyalty.models.loyalty_tier import LoyaltyTier # For UserLoyalty relationship + from src.loyalty.models.loyalty_point_transaction import LoyaltyPointTransaction # For UserLoyalty relationship + from src.loyalty.models.referral import Referral + from src.loyalty.models.package import Package # For RoomType relationship + from src.guest_management.models.guest_preference import GuestPreference + from src.guest_management.models.guest_note import GuestNote + from src.guest_management.models.guest_communication import GuestCommunication + from src.guest_management.models.guest_tag import GuestTag, guest_tag_association + from src.guest_management.models.guest_segment import GuestSegment, guest_segment_association + # Import any other models that might be related +except ImportError: + pass # Some models might not exist, that's okay +from datetime import datetime, timedelta +import random +import secrets + +def get_db(): + db = SessionLocal() + try: + return db + finally: + pass + +def generate_booking_number() -> str: + """Generate a unique booking number""" + prefix = 'BK' + ts = int(datetime.utcnow().timestamp() * 1000) + rand = secrets.randbelow(9000) + 1000 + return f'{prefix}-{ts}-{rand}' + +def seed_bookings(db: Session): + print('=' * 80) + print('SEEDING SAMPLE BOOKINGS FOR TESTING') + print('=' * 80) + + # Get roles + customer_role = db.query(Role).filter(Role.name == 'customer').first() + staff_role = db.query(Role).filter(Role.name == 'staff').first() + admin_role = db.query(Role).filter(Role.name == 'admin').first() + + if not customer_role: + print(' ❌ Customer role not found! Please seed roles first.') + return + + # Get customers + customers = db.query(User).filter(User.role_id == customer_role.id).all() + if not customers: + print(' ❌ No customer users found! Please seed users first.') + return + + # Get available rooms + rooms = db.query(Room).all() + if not rooms: + print(' ❌ No rooms found! Please seed rooms first.') + return + + print(f'\n✓ Found {len(customers)} customer(s) and {len(rooms)} room(s)') + + # Delete existing bookings (optional - comment out if you want to keep existing bookings) + existing_bookings = db.query(Booking).all() + if existing_bookings: + print(f'\n🗑️ Deleting {len(existing_bookings)} existing booking(s)...') + booking_ids = [b.id for b in existing_bookings] + + # Delete related records first to avoid foreign key constraints + try: + from src.guest_management.models.guest_complaint import GuestComplaint, ComplaintUpdate + complaints = db.query(GuestComplaint).filter(GuestComplaint.booking_id.in_(booking_ids)).all() + if complaints: + complaint_ids = [c.id for c in complaints] + # Delete complaint updates first + updates = db.query(ComplaintUpdate).filter(ComplaintUpdate.complaint_id.in_(complaint_ids)).all() + if updates: + for update in updates: + db.delete(update) + print(f' ✓ Deleted {len(updates)} complaint update(s)') + # Then delete complaints + for complaint in complaints: + db.delete(complaint) + print(f' ✓ Deleted {len(complaints)} guest complaint(s)') + except ImportError: + pass + + for booking in existing_bookings: + db.delete(booking) + db.commit() + print(f'✓ Deleted {len(existing_bookings)} booking(s)') + + # Create sample bookings with different statuses + now = datetime.utcnow() + bookings_data = [] + + # 1. Past bookings (checked out) - These should trigger cleaning notifications + print('\n📅 Creating past bookings (checked out)...') + for i in range(3): + room = random.choice(rooms) + customer = random.choice(customers) + + # Check-out was 1-3 days ago + days_ago = random.randint(1, 3) + check_out_date = now - timedelta(days=days_ago) + check_in_date = check_out_date - timedelta(days=random.randint(1, 5)) + + # Calculate price + base_price = float(room.price) if room.price else 100.0 + num_nights = (check_out_date - check_in_date).days + total_price = base_price * num_nights + + booking = Booking( + booking_number=generate_booking_number(), + user_id=customer.id, + room_id=room.id, + check_in_date=check_in_date, + check_out_date=check_out_date, + num_guests=random.randint(1, min(room.capacity, 4)), + total_price=total_price, + status=BookingStatus.checked_out, + deposit_paid=True, + requires_deposit=False, + special_requests=f'Sample booking for testing - Checked out {days_ago} day(s) ago' + ) + db.add(booking) + db.flush() # Flush to get booking ID + + # Set room status to cleaning for checked out bookings + # Check if there's active maintenance first + try: + from src.rooms.models.room_maintenance import RoomMaintenance, MaintenanceStatus + active_maintenance = db.query(RoomMaintenance).filter( + and_( + RoomMaintenance.room_id == room.id, + RoomMaintenance.blocks_room == True, + RoomMaintenance.status.in_([MaintenanceStatus.scheduled, MaintenanceStatus.in_progress]) + ) + ).first() + if not active_maintenance: + room.status = RoomStatus.cleaning + + # Create housekeeping task for checkout cleaning + try: + from src.hotel_services.models.housekeeping_task import HousekeepingTask, HousekeepingStatus, HousekeepingType + checkout_checklist = [ + {'item': 'Bathroom cleaned', 'completed': False, 'notes': ''}, + {'item': 'Beds made with fresh linens', 'completed': False, 'notes': ''}, + {'item': 'Trash emptied', 'completed': False, 'notes': ''}, + {'item': 'Towels replaced', 'completed': False, 'notes': ''}, + {'item': 'Amenities restocked', 'completed': False, 'notes': ''}, + {'item': 'Floor vacuumed and mopped', 'completed': False, 'notes': ''}, + {'item': 'Surfaces dusted', 'completed': False, 'notes': ''}, + {'item': 'Windows and mirrors cleaned', 'completed': False, 'notes': ''}, + ] + + housekeeping_task = HousekeepingTask( + room_id=room.id, + booking_id=booking.id, + task_type=HousekeepingType.checkout, + status=HousekeepingStatus.pending, + scheduled_time=datetime.utcnow(), + created_by=admin_role.id if admin_role else (staff_role.id if staff_role else None), + checklist_items=checkout_checklist, + notes=f'Auto-created on checkout for booking {booking.booking_number}', + estimated_duration_minutes=45 + ) + db.add(housekeeping_task) + except ImportError: + pass # If housekeeping models not available, skip task creation + except ImportError: + # If maintenance model not available, just set to cleaning + room.status = RoomStatus.cleaning + bookings_data.append({ + 'number': booking.booking_number, + 'room': room.room_number, + 'status': 'checked_out', + 'check_out': check_out_date.strftime('%Y-%m-%d') + }) + print(f' ✓ Created booking {booking.booking_number} - Room {room.room_number}, Checked out {days_ago} day(s) ago') + + # 2. Current bookings (checked in) - Guests currently staying + print('\n📅 Creating current bookings (checked in)...') + for i in range(2): + room = random.choice(rooms) + customer = random.choice(customers) + + # Checked in 1-3 days ago, checking out in 1-3 days + days_ago = random.randint(1, 3) + check_in_date = now - timedelta(days=days_ago) + check_out_date = now + timedelta(days=random.randint(1, 3)) + + base_price = float(room.price) if room.price else 100.0 + num_nights = (check_out_date - check_in_date).days + total_price = base_price * num_nights + + booking = Booking( + booking_number=generate_booking_number(), + user_id=customer.id, + room_id=room.id, + check_in_date=check_in_date, + check_out_date=check_out_date, + num_guests=random.randint(1, min(room.capacity, 4)), + total_price=total_price, + status=BookingStatus.checked_in, + deposit_paid=True, + requires_deposit=False, + special_requests=f'Sample booking for testing - Currently checked in' + ) + db.add(booking) + db.flush() # Flush to get booking ID + + # Set room status to occupied for checked in bookings + room.status = RoomStatus.occupied + bookings_data.append({ + 'number': booking.booking_number, + 'room': room.room_number, + 'status': 'checked_in', + 'check_out': check_out_date.strftime('%Y-%m-%d') + }) + print(f' ✓ Created booking {booking.booking_number} - Room {room.room_number}, Checked in {days_ago} day(s) ago') + + # 3. Future bookings (confirmed) - Upcoming reservations + print('\n📅 Creating future bookings (confirmed)...') + for i in range(3): + room = random.choice(rooms) + customer = random.choice(customers) + + # Check-in in 1-7 days, staying for 2-5 days + days_ahead = random.randint(1, 7) + check_in_date = now + timedelta(days=days_ahead) + check_out_date = check_in_date + timedelta(days=random.randint(2, 5)) + + base_price = float(room.price) if room.price else 100.0 + num_nights = (check_out_date - check_in_date).days + total_price = base_price * num_nights + + booking = Booking( + booking_number=generate_booking_number(), + user_id=customer.id, + room_id=room.id, + check_in_date=check_in_date, + check_out_date=check_out_date, + num_guests=random.randint(1, min(room.capacity, 4)), + total_price=total_price, + status=BookingStatus.confirmed, + deposit_paid=random.choice([True, False]), + requires_deposit=random.choice([True, False]), + special_requests=f'Sample booking for testing - Future reservation' + ) + db.add(booking) + bookings_data.append({ + 'number': booking.booking_number, + 'room': room.room_number, + 'status': 'confirmed', + 'check_in': check_in_date.strftime('%Y-%m-%d') + }) + print(f' ✓ Created booking {booking.booking_number} - Room {room.room_number}, Check-in in {days_ahead} day(s)') + + db.commit() + + print(f'\n✅ Successfully created {len(bookings_data)} sample bookings!') + print(f'\n📊 Summary:') + checked_out = sum(1 for b in bookings_data if b['status'] == 'checked_out') + checked_in = sum(1 for b in bookings_data if b['status'] == 'checked_in') + confirmed = sum(1 for b in bookings_data if b['status'] == 'confirmed') + print(f' - Checked out: {checked_out} (rooms should be in cleaning status)') + print(f' - Checked in: {checked_in} (guests currently staying)') + print(f' - Confirmed: {confirmed} (upcoming reservations)') + print('\n💡 To test notifications:') + print(' 1. Log in as staff user (staff@gnxsoft.com / staff123)') + print(' 2. Go to Bookings and mark a checked_in booking as checked_out') + print(' 3. Log in as housekeeping user (housekeeping@gnxsoft.com / P4eli240453.)') + print(' 4. You should receive a notification about the room needing cleaning') + print('=' * 80) + +def main(): + db = get_db() + try: + seed_bookings(db) + except Exception as e: + print(f'\n❌ Error: {e}') + import traceback + traceback.print_exc() + db.rollback() + finally: + db.close() + +if __name__ == '__main__': + main() + diff --git a/Backend/seeds_data/seed_initial_data.py b/Backend/seeds_data/seed_initial_data.py index 5510251f..0cce2563 100644 --- a/Backend/seeds_data/seed_initial_data.py +++ b/Backend/seeds_data/seed_initial_data.py @@ -1,12 +1,18 @@ import sys import os from pathlib import Path +# Add both the seeds_data directory and the Backend directory to the path sys.path.insert(0, str(Path(__file__).parent)) +sys.path.insert(0, str(Path(__file__).parent.parent)) from sqlalchemy.orm import Session from src.shared.config.database import SessionLocal -from src.models.role import Role -from src.models.room_type import RoomType -from src.models.user import User +# Import all models needed for SQLAlchemy relationship setup +from src.auth.models.role import Role +from src.auth.models.user import User +from src.rooms.models.room_type import RoomType +from src.rooms.models.room import Room +from src.rooms.models.rate_plan import RatePlan # For RoomType relationship +from src.bookings.models.booking import Booking # For Room relationship import bcrypt from datetime import datetime diff --git a/Backend/seeds_data/seed_rooms.py b/Backend/seeds_data/seed_rooms.py index 064f8816..9f2c4ca4 100644 --- a/Backend/seeds_data/seed_rooms.py +++ b/Backend/seeds_data/seed_rooms.py @@ -1,11 +1,13 @@ import sys import os from pathlib import Path +# Add both the seeds_data directory and the Backend directory to the path sys.path.insert(0, str(Path(__file__).parent)) +sys.path.insert(0, str(Path(__file__).parent.parent)) from sqlalchemy.orm import Session from src.shared.config.database import SessionLocal, engine -from src.models.room import Room, RoomStatus -from src.models.room_type import RoomType +from src.rooms.models.room import Room, RoomStatus +from src.rooms.models.room_type import RoomType from datetime import datetime import json import random @@ -28,9 +30,9 @@ def seed_rooms(db: Session): print(f'\n✓ Found {len(room_types)} room type(s)') for rt in room_types: print(f' - {rt.name} (ID: {rt.id}, Base Price: {rt.base_price})') - from src.models.booking import Booking - from src.models.review import Review - from src.models.favorite import Favorite + from src.bookings.models.booking import Booking + from src.reviews.models.review import Review + from src.reviews.models.favorite import Favorite existing_rooms = db.query(Room).all() if existing_rooms: print(f'\n🗑️ Deleting {len(existing_rooms)} existing room(s)...') diff --git a/Backend/seeds_data/seed_users.py b/Backend/seeds_data/seed_users.py index b013a919..ec765224 100644 --- a/Backend/seeds_data/seed_users.py +++ b/Backend/seeds_data/seed_users.py @@ -1,11 +1,13 @@ import sys import os from pathlib import Path +# Add both the seeds_data directory and the Backend directory to the path sys.path.insert(0, str(Path(__file__).parent)) +sys.path.insert(0, str(Path(__file__).parent.parent)) from sqlalchemy.orm import Session from src.shared.config.database import SessionLocal -from src.models.role import Role -from src.models.user import User +from src.auth.models.role import Role +from src.auth.models.user import User import bcrypt from datetime import datetime @@ -25,6 +27,7 @@ def seed_users(db: Session): admin_role = db.query(Role).filter(Role.name == 'admin').first() staff_role = db.query(Role).filter(Role.name == 'staff').first() customer_role = db.query(Role).filter(Role.name == 'customer').first() + housekeeping_role = db.query(Role).filter(Role.name == 'housekeeping').first() if not admin_role or not staff_role or not customer_role: print(' ❌ Roles not found! Please seed roles first.') @@ -105,12 +108,38 @@ def seed_users(db: Session): } ] + # Add housekeeping users if role exists + if housekeeping_role: + users_data.extend([ + { + 'email': 'housekeeping@gnxsoft.com', + 'password': 'housekeeping123', + 'full_name': 'Housekeeping Staff', + 'phone': '+1 (555) 999-0000', + 'role': 'housekeeping', + 'currency': 'EUR', + 'is_active': True + }, + { + 'email': 'housekeeping2@gnxsoft.com', + 'password': 'housekeeping123', + 'full_name': 'Housekeeping Staff 2', + 'phone': '+1 (555) 999-0001', + 'role': 'housekeeping', + 'currency': 'EUR', + 'is_active': True + } + ]) + role_map = { 'admin': admin_role.id, 'staff': staff_role.id, 'customer': customer_role.id } + if housekeeping_role: + role_map['housekeeping'] = housekeeping_role.id + created_count = 0 skipped_count = 0 diff --git a/Backend/src/__pycache__/main.cpython-312.pyc b/Backend/src/__pycache__/main.cpython-312.pyc index 02847439..c4431ea3 100644 Binary files a/Backend/src/__pycache__/main.cpython-312.pyc and b/Backend/src/__pycache__/main.cpython-312.pyc differ diff --git a/Backend/src/auth/routes/__pycache__/auth_routes.cpython-312.pyc b/Backend/src/auth/routes/__pycache__/auth_routes.cpython-312.pyc index a53358e2..4fb2e107 100644 Binary files a/Backend/src/auth/routes/__pycache__/auth_routes.cpython-312.pyc and b/Backend/src/auth/routes/__pycache__/auth_routes.cpython-312.pyc differ diff --git a/Backend/src/auth/routes/auth_routes.py b/Backend/src/auth/routes/auth_routes.py index 9053b261..3b0d62ae 100644 --- a/Backend/src/auth/routes/auth_routes.py +++ b/Backend/src/auth/routes/auth_routes.py @@ -504,6 +504,11 @@ async def upload_avatar(request: Request, image: UploadFile=File(...), current_u # Validate file completely (MIME type, size, magic bytes, integrity) content = await validate_uploaded_image(image, max_avatar_size) + + # Optimize image before saving + from ...shared.utils.image_optimization import optimize_image_async, ImageType + optimized_content, optimized_ext = await optimize_image_async(content, ImageType.AVATAR) + # Use same path calculation as main.py: go from Backend/src/auth/routes/auth_routes.py # to Backend/uploads/avatars upload_dir = Path(__file__).parent.parent.parent.parent / 'uploads' / 'avatars' @@ -519,12 +524,17 @@ async def upload_avatar(request: Request, image: UploadFile=File(...), current_u from ...shared.utils.sanitization import sanitize_filename original_filename = image.filename or 'avatar.png' sanitized_filename = sanitize_filename(original_filename) - ext = Path(sanitized_filename).suffix or '.png' + ext = Path(sanitized_filename).suffix or optimized_ext or '.webp' + + # Update extension if format changed + if optimized_ext: + ext = optimized_ext + # Generate secure filename with user ID and UUID to prevent collisions filename = f'avatar-{current_user.id}-{uuid.uuid4()}{ext}' file_path = upload_dir / filename async with aiofiles.open(file_path, 'wb') as f: - await f.write(content) + await f.write(optimized_content) image_url = f'/uploads/avatars/{filename}' current_user.avatar = image_url db.commit() diff --git a/Backend/src/bookings/routes/__pycache__/booking_routes.cpython-312.pyc b/Backend/src/bookings/routes/__pycache__/booking_routes.cpython-312.pyc index 367ca479..cca1b89f 100644 Binary files a/Backend/src/bookings/routes/__pycache__/booking_routes.cpython-312.pyc and b/Backend/src/bookings/routes/__pycache__/booking_routes.cpython-312.pyc differ diff --git a/Backend/src/bookings/routes/booking_routes.py b/Backend/src/bookings/routes/booking_routes.py index 3dfe052e..80e8e71e 100644 --- a/Backend/src/bookings/routes/booking_routes.py +++ b/Backend/src/bookings/routes/booking_routes.py @@ -770,6 +770,31 @@ async def update_booking(id: int, booking_data: UpdateBookingRequest, current_us ) db.add(housekeeping_task) db.flush() # Flush to get the task ID if needed for notifications + + # Send notification to all housekeeping users via dedicated notification system + try: + from ...notifications.routes.notification_routes import notification_manager + + task_data_notification = { + 'id': housekeeping_task.id, + 'room_id': housekeeping_task.room_id, + 'room_number': room.room_number, + 'task_type': housekeeping_task.task_type.value, + 'status': housekeeping_task.status.value, + 'scheduled_time': housekeeping_task.scheduled_time.isoformat() if housekeeping_task.scheduled_time else None, + 'assigned_to': housekeeping_task.assigned_to, + 'booking_number': booking.booking_number, + 'created_at': housekeeping_task.created_at.isoformat() if housekeeping_task.created_at else None + } + notification_data = { + 'type': 'housekeeping_task_available', + 'data': task_data_notification + } + + # Send notification to all housekeeping users + await notification_manager.send_to_role('housekeeping', notification_data) + except Exception as e: + logger.error(f'Error sending housekeeping notification: {str(e)}', exc_info=True) elif new_status == BookingStatus.cancelled: # Update room status when booking is cancelled if booking.payments: diff --git a/Backend/src/content/routes/__pycache__/banner_routes.cpython-312.pyc b/Backend/src/content/routes/__pycache__/banner_routes.cpython-312.pyc index 9f637fde..9e22c9be 100644 Binary files a/Backend/src/content/routes/__pycache__/banner_routes.cpython-312.pyc and b/Backend/src/content/routes/__pycache__/banner_routes.cpython-312.pyc differ diff --git a/Backend/src/content/routes/__pycache__/blog_routes.cpython-312.pyc b/Backend/src/content/routes/__pycache__/blog_routes.cpython-312.pyc index fa65499d..e1ca137d 100644 Binary files a/Backend/src/content/routes/__pycache__/blog_routes.cpython-312.pyc and b/Backend/src/content/routes/__pycache__/blog_routes.cpython-312.pyc differ diff --git a/Backend/src/content/routes/__pycache__/page_content_routes.cpython-312.pyc b/Backend/src/content/routes/__pycache__/page_content_routes.cpython-312.pyc index e7451587..ed328601 100644 Binary files a/Backend/src/content/routes/__pycache__/page_content_routes.cpython-312.pyc and b/Backend/src/content/routes/__pycache__/page_content_routes.cpython-312.pyc differ diff --git a/Backend/src/content/routes/banner_routes.py b/Backend/src/content/routes/banner_routes.py index 83d018fb..5e9ce8e3 100644 --- a/Backend/src/content/routes/banner_routes.py +++ b/Backend/src/content/routes/banner_routes.py @@ -109,7 +109,7 @@ async def delete_banner(id: int, current_user: User=Depends(authorize_roles('adm if not banner: raise HTTPException(status_code=404, detail='Banner not found') if banner.image_url and banner.image_url.startswith('/uploads/banners/'): - file_path = Path(__file__).parent.parent.parent / 'uploads' / 'banners' / Path(banner.image_url).name + file_path = Path(__file__).parent.parent.parent.parent / 'uploads' / 'banners' / Path(banner.image_url).name if file_path.exists(): file_path.unlink() db.delete(banner) @@ -130,7 +130,7 @@ async def upload_banner_image(request: Request, image: UploadFile=File(...), cur raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f'File must be an image. Received: {image.content_type}') if not image.filename: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Filename is required') - upload_dir = Path(__file__).parent.parent.parent / 'uploads' / 'banners' + upload_dir = Path(__file__).parent.parent.parent.parent / 'uploads' / 'banners' upload_dir.mkdir(parents=True, exist_ok=True) ext = Path(image.filename).suffix or '.jpg' filename = f'banner-{uuid.uuid4()}{ext}' @@ -143,8 +143,17 @@ async def upload_banner_image(request: Request, image: UploadFile=File(...), cur # Validate file completely (MIME type, size, magic bytes, integrity) content = await validate_uploaded_image(image, max_size) + # Optimize image before saving + from ...shared.utils.image_optimization import optimize_image_async, ImageType + optimized_content, optimized_ext = await optimize_image_async(content, ImageType.BANNER) + + # Update filename extension if format changed + if optimized_ext and optimized_ext != ext: + filename = f'banner-{uuid.uuid4()}{optimized_ext}' + file_path = upload_dir / filename + async with aiofiles.open(file_path, 'wb') as f: - await f.write(content) + await f.write(optimized_content) image_url = f'/uploads/banners/{filename}' base_url = get_base_url(request) full_url = normalize_image_url(image_url, base_url) diff --git a/Backend/src/content/routes/blog_routes.py b/Backend/src/content/routes/blog_routes.py index e65f5786..e711f898 100644 --- a/Backend/src/content/routes/blog_routes.py +++ b/Backend/src/content/routes/blog_routes.py @@ -532,7 +532,7 @@ async def upload_blog_image( if not image.filename: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Filename is required') - upload_dir = Path(__file__).parent.parent.parent / 'uploads' / 'blog' + upload_dir = Path(__file__).parent.parent.parent.parent / 'uploads' / 'blog' upload_dir.mkdir(parents=True, exist_ok=True) ext = Path(image.filename).suffix or '.jpg' @@ -546,8 +546,17 @@ async def upload_blog_image( content = await validate_uploaded_image(image, max_size) + # Optimize image before saving + from ...shared.utils.image_optimization import optimize_image_async, ImageType + optimized_content, optimized_ext = await optimize_image_async(content, ImageType.BLOG) + + # Update filename extension if format changed + if optimized_ext and optimized_ext != ext: + filename = f'blog-{uuid.uuid4()}{optimized_ext}' + file_path = upload_dir / filename + async with aiofiles.open(file_path, 'wb') as f: - await f.write(content) + await f.write(optimized_content) image_url = f'/uploads/blog/{filename}' base_url = get_base_url(request) diff --git a/Backend/src/content/routes/page_content_routes.py b/Backend/src/content/routes/page_content_routes.py index 5aa676be..b3b6f542 100644 --- a/Backend/src/content/routes/page_content_routes.py +++ b/Backend/src/content/routes/page_content_routes.py @@ -56,7 +56,7 @@ async def upload_page_content_image(request: Request, image: UploadFile=File(... if not image.filename: logger.error('No filename provided in upload request') raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Filename is required') - upload_dir = Path(__file__).parent.parent.parent / 'uploads' / 'page-content' + upload_dir = Path(__file__).parent.parent.parent.parent / 'uploads' / 'page-content' upload_dir.mkdir(parents=True, exist_ok=True) logger.info(f'Upload directory: {upload_dir}') ext = Path(image.filename).suffix or '.jpg' @@ -70,9 +70,18 @@ async def upload_page_content_image(request: Request, image: UploadFile=File(... # Validate file completely (MIME type, size, magic bytes, integrity) content = await validate_uploaded_image(image, max_size) + # Optimize image before saving + from ...shared.utils.image_optimization import optimize_image_async, ImageType + optimized_content, optimized_ext = await optimize_image_async(content, ImageType.PAGE_CONTENT) + + # Update filename extension if format changed + if optimized_ext and optimized_ext != ext: + filename = f'page-content-{uuid.uuid4()}{optimized_ext}' + file_path = upload_dir / filename + async with aiofiles.open(file_path, 'wb') as f: - await f.write(content) - logger.info(f'File saved successfully: {file_path}, size: {len(content)} bytes') + await f.write(optimized_content) + logger.info(f'File saved successfully: {file_path}, size: {len(optimized_content)} bytes') image_url = f'/uploads/page-content/{filename}' base_url = get_base_url(request) full_url = normalize_image_url(image_url, base_url) diff --git a/Backend/src/main.py b/Backend/src/main.py index f38d217b..eb2a55cf 100644 --- a/Backend/src/main.py +++ b/Backend/src/main.py @@ -246,8 +246,22 @@ async def serve_upload_file(file_path: str, request: Request): # Get origin from request origin = request.headers.get('origin') - # Prepare response - response = FileResponse(str(file_location)) + # Determine media type based on file extension + media_type = None + file_ext = file_location.suffix.lower() + if file_ext == '.webp': + media_type = 'image/webp' + elif file_ext in ['.jpg', '.jpeg']: + media_type = 'image/jpeg' + elif file_ext == '.png': + media_type = 'image/png' + elif file_ext == '.gif': + media_type = 'image/gif' + elif file_ext == '.ico': + media_type = 'image/x-icon' + + # Prepare response with appropriate media type + response = FileResponse(str(file_location), media_type=media_type) # Add CORS headers if origin matches if origin: diff --git a/Backend/src/notifications/routes/__pycache__/chat_routes.cpython-312.pyc b/Backend/src/notifications/routes/__pycache__/chat_routes.cpython-312.pyc index 89fe20f4..c4d8e4fd 100644 Binary files a/Backend/src/notifications/routes/__pycache__/chat_routes.cpython-312.pyc and b/Backend/src/notifications/routes/__pycache__/chat_routes.cpython-312.pyc differ diff --git a/Backend/src/notifications/routes/__pycache__/notification_routes.cpython-312.pyc b/Backend/src/notifications/routes/__pycache__/notification_routes.cpython-312.pyc index ad9fc924..ba0d9248 100644 Binary files a/Backend/src/notifications/routes/__pycache__/notification_routes.cpython-312.pyc and b/Backend/src/notifications/routes/__pycache__/notification_routes.cpython-312.pyc differ diff --git a/Backend/src/notifications/routes/chat_routes.py b/Backend/src/notifications/routes/chat_routes.py index ff3026bb..51ed1b4b 100644 --- a/Backend/src/notifications/routes/chat_routes.py +++ b/Backend/src/notifications/routes/chat_routes.py @@ -338,7 +338,7 @@ async def websocket_staff_notifications(websocket: WebSocket): await websocket.close(code=1008, reason='User not found') return role = db.query(Role).filter(Role.id == current_user.role_id).first() - if not role or role.name not in ['staff', 'admin']: + if not role or role.name not in ['staff', 'admin', 'housekeeping']: await websocket.close(code=1008, reason='Unauthorized role') return finally: diff --git a/Backend/src/notifications/routes/notification_routes.py b/Backend/src/notifications/routes/notification_routes.py index 8cee6787..a3312a06 100644 --- a/Backend/src/notifications/routes/notification_routes.py +++ b/Backend/src/notifications/routes/notification_routes.py @@ -1,16 +1,115 @@ -from fastapi import APIRouter, Depends, HTTPException, Query, Body +from fastapi import APIRouter, Depends, HTTPException, Query, Body, WebSocket, WebSocketDisconnect from sqlalchemy.orm import Session from typing import Optional, List, Dict, Any from ...shared.config.database import get_db +from ...shared.config.logging_config import get_logger from ...security.middleware.auth import authorize_roles, get_current_user from ...auth.models.user import User +from ...auth.models.role import Role from ..models.notification import NotificationChannel, NotificationStatus, NotificationType from ..services.notification_service import NotificationService from pydantic import BaseModel from datetime import datetime +import json +logger = get_logger(__name__) router = APIRouter(prefix='/notifications', tags=['notifications']) +# Dedicated Notification Connection Manager (separate from chat) +class NotificationConnectionManager: + """Manages WebSocket connections for real-time notifications""" + + def __init__(self): + self.user_connections: dict[int, WebSocket] = {} + self.role_connections: dict[str, List[WebSocket]] = { + 'admin': [], + 'staff': [], + 'housekeeping': [], + 'accountant': [] + } + + def connect_user(self, user_id: int, websocket: WebSocket, role_name: str): + """Connect a user to the notification system""" + self.user_connections[user_id] = websocket + if role_name in self.role_connections: + if websocket not in self.role_connections[role_name]: + self.role_connections[role_name].append(websocket) + logger.debug(f'User {user_id} ({role_name}) connected to notification system') + + def disconnect_user(self, user_id: int, role_name: str): + """Disconnect a user from the notification system""" + websocket = None + if user_id in self.user_connections: + websocket = self.user_connections[user_id] + del self.user_connections[user_id] + if role_name in self.role_connections and websocket: + self.role_connections[role_name] = [ + ws for ws in self.role_connections[role_name] + if ws != websocket + ] + logger.debug(f'User {user_id} ({role_name}) disconnected from notification system') + + async def send_to_user(self, user_id: int, message: dict): + """Send notification to a specific user""" + if user_id in self.user_connections: + try: + websocket = self.user_connections[user_id] + await websocket.send_json(message) + return True + except Exception as e: + logger.error(f'Error sending notification to user {user_id}: {str(e)}', exc_info=True) + # Remove broken connection + if user_id in self.user_connections: + del self.user_connections[user_id] + return False + return False + + async def send_to_role(self, role_name: str, message: dict): + """Send notification to all users with a specific role""" + if role_name not in self.role_connections: + return 0 + + disconnected = [] + sent_count = 0 + + for websocket in self.role_connections[role_name]: + try: + await websocket.send_json(message) + sent_count += 1 + except Exception as e: + logger.error(f'Error sending notification to {role_name} user: {str(e)}', exc_info=True) + disconnected.append(websocket) + + # Clean up disconnected websockets + for ws in disconnected: + if ws in self.role_connections[role_name]: + self.role_connections[role_name].remove(ws) + + return sent_count + + async def broadcast(self, message: dict): + """Broadcast notification to all connected users""" + disconnected = [] + sent_count = 0 + + for user_id, websocket in self.user_connections.items(): + try: + await websocket.send_json(message) + sent_count += 1 + except Exception as e: + logger.error(f'Error broadcasting to user {user_id}: {str(e)}', exc_info=True) + disconnected.append(user_id) + + # Clean up disconnected websockets + for user_id in disconnected: + if user_id in self.user_connections: + del self.user_connections[user_id] + + return sent_count + +# Global notification manager instance +notification_manager = NotificationConnectionManager() + # Request/Response Models class NotificationSendRequest(BaseModel): user_id: Optional[int] = None @@ -304,3 +403,98 @@ async def update_preferences( except Exception as e: raise HTTPException(status_code=500, detail=str(e)) +# WebSocket endpoint for real-time notifications +@router.websocket('/ws') +async def websocket_notifications(websocket: WebSocket): + """WebSocket endpoint for real-time notifications (separate from chat)""" + current_user = None + role_name = None + try: + await websocket.accept() + + # Security: Read token from cookies + token = None + if websocket.cookies: + token = websocket.cookies.get('accessToken') + + # Fallback to query parameter for backward compatibility + if not token: + query_params = dict(websocket.query_params) + token = query_params.get('token') + + if not token: + await websocket.close(code=1008, reason='Token required') + return + + try: + from ...security.middleware.auth import verify_token + from ...shared.config.database import get_db + payload = verify_token(token) + user_id = payload.get('userId') + if not user_id: + await websocket.close(code=1008, reason='Invalid token payload') + return + + db_gen = get_db() + db = next(db_gen) + try: + current_user = db.query(User).filter(User.id == user_id).first() + if not current_user: + await websocket.close(code=1008, reason='User not found') + return + + role = db.query(Role).filter(Role.id == current_user.role_id).first() + if not role: + await websocket.close(code=1008, reason='User role not found') + return + + role_name = role.name + finally: + db.close() + except Exception as e: + logger.error(f'WebSocket token verification error: {str(e)}', exc_info=True) + await websocket.close(code=1008, reason=f'Token verification failed: {str(e)}') + return + + # Connect user to notification system + notification_manager.connect_user(current_user.id, websocket, role_name) + + try: + await websocket.send_json({ + 'type': 'connected', + 'data': { + 'message': 'Connected to notification system', + 'user_id': current_user.id, + 'role': role_name + } + }) + except Exception as e: + logger.error(f'Error sending initial notification message: {str(e)}', exc_info=True, extra={'user_id': current_user.id}) + + # Keep connection alive and handle ping/pong + while True: + try: + data = await websocket.receive_text() + try: + message_data = json.loads(data) + if message_data.get('type') == 'ping': + await websocket.send_json({'type': 'pong', 'data': 'pong'}) + except json.JSONDecodeError: + await websocket.send_json({'type': 'pong', 'data': 'pong'}) + except WebSocketDisconnect: + logger.info('Notification WebSocket disconnected normally', extra={'user_id': current_user.id}) + break + except Exception as e: + logger.error(f'Notification WebSocket receive error: {str(e)}', exc_info=True, extra={'user_id': current_user.id}) + break + except WebSocketDisconnect: + logger.info('Notification WebSocket disconnected') + except Exception as e: + logger.error(f'Notification WebSocket error: {str(e)}', exc_info=True) + finally: + if current_user and role_name: + try: + notification_manager.disconnect_user(current_user.id, role_name) + except: + pass + diff --git a/Backend/src/rooms/routes/__pycache__/advanced_room_routes.cpython-312.pyc b/Backend/src/rooms/routes/__pycache__/advanced_room_routes.cpython-312.pyc index e921a20c..3e0eb023 100644 Binary files a/Backend/src/rooms/routes/__pycache__/advanced_room_routes.cpython-312.pyc and b/Backend/src/rooms/routes/__pycache__/advanced_room_routes.cpython-312.pyc differ diff --git a/Backend/src/rooms/routes/__pycache__/room_routes.cpython-312.pyc b/Backend/src/rooms/routes/__pycache__/room_routes.cpython-312.pyc index 586b0efb..44877587 100644 Binary files a/Backend/src/rooms/routes/__pycache__/room_routes.cpython-312.pyc and b/Backend/src/rooms/routes/__pycache__/room_routes.cpython-312.pyc differ diff --git a/Backend/src/rooms/routes/advanced_room_routes.py b/Backend/src/rooms/routes/advanced_room_routes.py index 5350cf25..d77973ad 100644 --- a/Backend/src/rooms/routes/advanced_room_routes.py +++ b/Backend/src/rooms/routes/advanced_room_routes.py @@ -346,10 +346,11 @@ async def get_housekeeping_tasks( date: Optional[str] = Query(None), page: int = Query(1, ge=1), limit: int = Query(20, ge=1, le=100), + include_cleaning_rooms: bool = Query(True, description='Include rooms in cleaning status even without tasks'), current_user: User = Depends(authorize_roles('admin', 'staff', 'housekeeping')), db: Session = Depends(get_db) ): - """Get housekeeping tasks with filtering""" + """Get housekeeping tasks with filtering. Also includes rooms in cleaning status.""" try: # Check user role - housekeeping and staff users should only see their assigned tasks role = db.query(Role).filter(Role.id == current_user.role_id).first() @@ -359,8 +360,14 @@ async def get_housekeeping_tasks( query = db.query(HousekeepingTask) # Filter by assigned_to for housekeeping and staff users (not admin) + # But also include unassigned tasks so they can pick them up if is_housekeeping_or_staff: - query = query.filter(HousekeepingTask.assigned_to == current_user.id) + query = query.filter( + or_( + HousekeepingTask.assigned_to == current_user.id, + HousekeepingTask.assigned_to.is_(None) + ) + ) if room_id: query = query.filter(HousekeepingTask.room_id == room_id) @@ -379,7 +386,11 @@ async def get_housekeeping_tasks( tasks = query.offset(offset).limit(limit).all() result = [] + task_room_ids = set() + + # Process existing tasks for task in tasks: + task_room_ids.add(task.room_id) result.append({ 'id': task.id, 'room_id': task.room_id, @@ -396,9 +407,84 @@ async def get_housekeeping_tasks( 'notes': task.notes, 'quality_score': task.quality_score, 'estimated_duration_minutes': task.estimated_duration_minutes, - 'actual_duration_minutes': task.actual_duration_minutes + 'actual_duration_minutes': task.actual_duration_minutes, + 'room_status': task.room.status.value if task.room else None }) + # Include rooms in cleaning status that don't have tasks (or have unassigned tasks for housekeeping users) + if include_cleaning_rooms: + rooms_query = db.query(Room).filter(Room.status == RoomStatus.cleaning) + + if room_id: + rooms_query = rooms_query.filter(Room.id == room_id) + + # For housekeeping/staff users, also include rooms with unassigned tasks + if is_housekeeping_or_staff: + # Get room IDs with unassigned tasks + unassigned_task_rooms = db.query(HousekeepingTask.room_id).filter( + and_( + HousekeepingTask.assigned_to.is_(None), + HousekeepingTask.status.in_([HousekeepingStatus.pending, HousekeepingStatus.in_progress]) + ) + ).distinct().all() + unassigned_room_ids = [r[0] for r in unassigned_task_rooms] + + # Include rooms in cleaning status OR rooms with unassigned tasks + if unassigned_room_ids: + rooms_query = db.query(Room).filter( + or_( + Room.status == RoomStatus.cleaning, + Room.id.in_(unassigned_room_ids) + ) + ) + if room_id: + rooms_query = rooms_query.filter(Room.id == room_id) + + cleaning_rooms = rooms_query.all() + + # Add rooms in cleaning status that don't have tasks in current page results + for room in cleaning_rooms: + if room.id not in task_room_ids: + # Check if there are any pending tasks for this room + pending_tasks = db.query(HousekeepingTask).filter( + and_( + HousekeepingTask.room_id == room.id, + HousekeepingTask.status.in_([HousekeepingStatus.pending, HousekeepingStatus.in_progress]) + ) + ).all() + + # For housekeeping/staff, only show if there are unassigned tasks or if room is in cleaning + if is_housekeeping_or_staff: + has_unassigned = any(t.assigned_to is None for t in pending_tasks) + if not has_unassigned and room.status != RoomStatus.cleaning: + continue + + # Create a virtual task entry for rooms in cleaning status + result.append({ + 'id': None, # No task ID since this is a room status entry + 'room_id': room.id, + 'room_number': room.room_number, + 'booking_id': None, + 'task_type': 'vacant', # Default task type + 'status': 'pending', + 'scheduled_time': datetime.utcnow().isoformat(), + 'started_at': None, + 'completed_at': None, + 'assigned_to': None, + 'assigned_staff_name': None, + 'checklist_items': [], + 'notes': 'Room is in cleaning mode', + 'quality_score': None, + 'estimated_duration_minutes': None, + 'actual_duration_minutes': None, + 'room_status': room.status.value, + 'is_room_status_only': True # Flag to indicate this is from room status, not a task + }) + + # Update total count to include cleaning rooms + if include_cleaning_rooms: + total = len(result) + return { 'status': 'success', 'data': { @@ -418,11 +504,16 @@ async def get_housekeeping_tasks( @router.post('/housekeeping') async def create_housekeeping_task( task_data: dict, - current_user: User = Depends(authorize_roles('admin', 'staff')), + current_user: User = Depends(authorize_roles('admin', 'staff', 'housekeeping')), db: Session = Depends(get_db) ): """Create a new housekeeping task""" try: + # Check user role - housekeeping users can only assign tasks to themselves + role = db.query(Role).filter(Role.id == current_user.role_id).first() + is_admin = role and role.name == 'admin' + is_housekeeping = role and role.name == 'housekeeping' + room = db.query(Room).filter(Room.id == task_data.get('room_id')).first() if not room: raise HTTPException(status_code=404, detail='Room not found') @@ -430,6 +521,14 @@ async def create_housekeeping_task( scheduled_time = datetime.fromisoformat(task_data['scheduled_time'].replace('Z', '+00:00')) assigned_to = task_data.get('assigned_to') + # Housekeeping users can only assign tasks to themselves + if is_housekeeping and assigned_to and assigned_to != current_user.id: + raise HTTPException(status_code=403, detail='Housekeeping users can only assign tasks to themselves') + + # If housekeeping user doesn't specify assigned_to, assign to themselves + if is_housekeeping and not assigned_to: + assigned_to = current_user.id + task = HousekeepingTask( room_id=task_data['room_id'], booking_id=task_data.get('booking_id'), @@ -450,8 +549,7 @@ async def create_housekeeping_task( # Send notification to assigned staff member if task is assigned if assigned_to: try: - from ..routes.chat_routes import manager - assigned_staff = db.query(User).filter(User.id == assigned_to).first() + from ...notifications.routes.notification_routes import notification_manager task_data_notification = { 'id': task.id, 'room_id': task.room_id, @@ -467,13 +565,9 @@ async def create_housekeeping_task( 'data': task_data_notification } # Send notification to the specific staff member - if assigned_to in manager.staff_connections: - try: - await manager.staff_connections[assigned_to].send_json(notification_data) - except Exception as e: - logger.error(f'Error sending housekeeping task notification to staff {assigned_to}: {str(e)}', exc_info=True, extra={'staff_id': assigned_to}) + await notification_manager.send_to_user(assigned_to, notification_data) except Exception as e: - logger.error(f'Error setting up housekeeping task notification: {str(e)}', exc_info=True) + logger.error(f'Error sending housekeeping task notification: {str(e)}', exc_info=True) return { 'status': 'success', @@ -504,21 +598,34 @@ async def update_housekeeping_task( is_housekeeping_or_staff = role and role.name in ('housekeeping', 'staff') if is_housekeeping_or_staff: - # Housekeeping and staff can only update tasks assigned to them - if task.assigned_to != current_user.id: + # Housekeeping and staff can start unassigned tasks (assign to themselves) + if task.assigned_to is None: + # Allow housekeeping users to assign unassigned tasks to themselves + if 'status' in task_data and task_data['status'] == 'in_progress': + task.assigned_to = current_user.id + task_data['assigned_to'] = current_user.id + elif task.assigned_to != current_user.id: + # If task is assigned, only the assigned user can update it raise HTTPException(status_code=403, detail='You can only update tasks assigned to you') - # Housekeeping and staff cannot change assignment - if 'assigned_to' in task_data and task_data.get('assigned_to') != task.assigned_to: + # Housekeeping and staff cannot change assignment of already assigned tasks + if 'assigned_to' in task_data and task.assigned_to is not None and task_data.get('assigned_to') != task.assigned_to: raise HTTPException(status_code=403, detail='You cannot change task assignment') old_assigned_to = task.assigned_to assigned_to_changed = False - if 'assigned_to' in task_data and is_admin: - new_assigned_to = task_data.get('assigned_to') - if new_assigned_to != old_assigned_to: - task.assigned_to = new_assigned_to - assigned_to_changed = True + # Handle assignment - admin can assign, housekeeping can self-assign unassigned tasks + if 'assigned_to' in task_data: + if is_admin: + new_assigned_to = task_data.get('assigned_to') + if new_assigned_to != old_assigned_to: + task.assigned_to = new_assigned_to + assigned_to_changed = True + elif is_housekeeping_or_staff and task.assigned_to is None: + # Housekeeping can assign unassigned tasks to themselves when starting + if task_data.get('assigned_to') == current_user.id: + task.assigned_to = current_user.id + assigned_to_changed = True if 'status' in task_data: new_status = HousekeepingStatus(task_data['status']) @@ -534,6 +641,9 @@ async def update_housekeeping_task( if new_status == HousekeepingStatus.in_progress and not task.started_at: task.started_at = datetime.utcnow() + # If task was unassigned, assign it to the current user + if task.assigned_to is None and is_housekeeping_or_staff: + task.assigned_to = current_user.id elif new_status == HousekeepingStatus.completed and not task.completed_at: task.completed_at = datetime.utcnow() if task.started_at: @@ -568,8 +678,23 @@ async def update_housekeeping_task( # Keep room as cleaning if there are other pending tasks room.status = RoomStatus.cleaning else: - # No pending tasks and no maintenance - room is ready - room.status = RoomStatus.available + # No pending tasks and no maintenance - room is ready for check-in + # Check if there are any upcoming bookings for this room + from ...bookings.models.booking import Booking, BookingStatus + upcoming_booking = db.query(Booking).filter( + and_( + Booking.room_id == room.id, + Booking.status == BookingStatus.confirmed, + Booking.check_in_date <= datetime.utcnow() + timedelta(days=1) + ) + ).first() + + if upcoming_booking: + # Room has upcoming booking, keep as available (ready for check-in) + room.status = RoomStatus.available + else: + # No upcoming bookings, room is available + room.status = RoomStatus.available if 'checklist_items' in task_data: task.checklist_items = task_data['checklist_items'] @@ -591,7 +716,7 @@ async def update_housekeeping_task( # Send notification if assignment changed if assigned_to_changed and task.assigned_to: try: - from ..routes.chat_routes import manager + from ...notifications.routes.notification_routes import notification_manager room = db.query(Room).filter(Room.id == task.room_id).first() task_data_notification = { 'id': task.id, @@ -608,13 +733,9 @@ async def update_housekeeping_task( 'data': task_data_notification } # Send notification to the newly assigned staff member - if task.assigned_to in manager.staff_connections: - try: - await manager.staff_connections[task.assigned_to].send_json(notification_data) - except Exception as e: - logger.error(f'Error sending housekeeping task notification to staff {task.assigned_to}: {str(e)}', exc_info=True, extra={'staff_id': task.assigned_to}) + await notification_manager.send_to_user(task.assigned_to, notification_data) except Exception as e: - logger.error(f'Error setting up housekeeping task notification: {str(e)}', exc_info=True) + logger.error(f'Error sending housekeeping task notification: {str(e)}', exc_info=True) return { 'status': 'success', diff --git a/Backend/src/rooms/routes/room_routes.py b/Backend/src/rooms/routes/room_routes.py index a38b900f..c343c622 100644 --- a/Backend/src/rooms/routes/room_routes.py +++ b/Backend/src/rooms/routes/room_routes.py @@ -14,6 +14,7 @@ from ..schemas.room import CreateRoomRequest, UpdateRoomRequest, BulkDeleteRooms from ...shared.utils.response_helpers import success_response from ...reviews.models.review import Review, ReviewStatus from ...bookings.models.booking import Booking, BookingStatus +from ...hotel_services.models.housekeeping_task import HousekeepingTask, HousekeepingStatus, HousekeepingType from ..services.room_service import get_rooms_with_ratings, get_amenities_list, normalize_images, get_base_url import os import aiofiles @@ -424,8 +425,39 @@ async def update_room(id: int, room_data: UpdateRoomRequest, request: Request, c if room_data.floor is not None: room.floor = room_data.floor + old_status = room.status if room_data.status is not None: - room.status = RoomStatus(room_data.status) + new_status = RoomStatus(room_data.status) + room.status = new_status + + # If room status is changed to cleaning, create a housekeeping task if one doesn't exist + if new_status == RoomStatus.cleaning and old_status != RoomStatus.cleaning: + # Check if there's already a pending housekeeping task for this room + existing_task = db.query(HousekeepingTask).filter( + and_( + HousekeepingTask.room_id == room.id, + HousekeepingTask.status.in_([HousekeepingStatus.pending, HousekeepingStatus.in_progress]) + ) + ).first() + + if not existing_task: + # Create a new housekeeping task for the cleaning room + cleaning_task = HousekeepingTask( + room_id=room.id, + task_type=HousekeepingType.vacant, + status=HousekeepingStatus.pending, + scheduled_time=datetime.utcnow(), + created_by=current_user.id, + checklist_items=[ + {'item': 'Deep clean bathroom', 'completed': False, 'notes': ''}, + {'item': 'Change linens', 'completed': False, 'notes': ''}, + {'item': 'Vacuum and mop', 'completed': False, 'notes': ''}, + {'item': 'Dust surfaces', 'completed': False, 'notes': ''}, + {'item': 'Check amenities', 'completed': False, 'notes': ''} + ], + notes='Room set to cleaning mode' + ) + db.add(cleaning_task) if room_data.featured is not None: room.featured = room_data.featured if room_data.price is not None: @@ -545,24 +577,55 @@ async def upload_room_images(id: int, images: List[UploadFile]=File(...), curren room = db.query(Room).filter(Room.id == id).first() if not room: raise HTTPException(status_code=404, detail='Room not found') - upload_dir = Path(__file__).parent.parent.parent / 'uploads' / 'rooms' + # Calculate upload directory to match main.py (Backend/uploads/rooms) + # From Backend/src/rooms/routes/room_routes.py -> Backend/ + upload_dir = Path(__file__).parent.parent.parent.parent / 'uploads' / 'rooms' upload_dir.mkdir(parents=True, exist_ok=True) + + # Import validation and optimization utilities + from ...shared.config.settings import settings + from ...shared.utils.file_validation import validate_uploaded_image + from ...shared.utils.image_optimization import optimize_image_async, ImageType + image_urls = [] for image in images: if not image.content_type or not image.content_type.startswith('image/'): continue if not image.filename: continue - import uuid - ext = Path(image.filename).suffix or '.jpg' - filename = f'room-{uuid.uuid4()}{ext}' - file_path = upload_dir / filename - async with aiofiles.open(file_path, 'wb') as f: - content = await image.read() - if not content: + + try: + # Validate the image + content = await validate_uploaded_image(image, settings.MAX_UPLOAD_SIZE) + + # Optimize image before saving + optimized_content, optimized_ext = await optimize_image_async(content, ImageType.ROOM) + + import uuid + ext = Path(image.filename).suffix or '.jpg' + # Update extension if format changed + if optimized_ext: + ext = optimized_ext + filename = f'room-{uuid.uuid4()}{ext}' + file_path = upload_dir / filename + + async with aiofiles.open(file_path, 'wb') as f: + await f.write(optimized_content) + + # Verify file was saved + if not file_path.exists(): + logger.error(f'File was not saved: {file_path}') continue - await f.write(content) - image_urls.append(f'/uploads/rooms/{filename}') + + logger.info(f'Successfully uploaded and optimized image: {filename} ({len(optimized_content)} bytes)') + image_urls.append(f'/uploads/rooms/{filename}') + except HTTPException: + # Skip invalid images and continue with others + logger.warning(f'Skipping invalid image: {image.filename}') + continue + except Exception as e: + logger.error(f'Error processing image {image.filename}: {str(e)}', exc_info=True) + continue # Handle existing_images - it might be a list, a JSON string, or None existing_images = room.images or [] @@ -595,20 +658,44 @@ async def delete_room_images(id: int, image_url: str=Query(..., description='Ima room = db.query(Room).filter(Room.id == id).first() if not room: raise HTTPException(status_code=404, detail='Room not found') - # For external URLs, keep the full URL for matching - # For local files, normalize to path + + # Normalize the input URL to extract the path part + # The frontend may send a full URL like "http://localhost:8000/uploads/rooms/image.webp" + # but the database stores relative paths like "/uploads/rooms/image.webp" is_external_url = image_url.startswith('http://') or image_url.startswith('https://') - normalized_url = image_url + normalized_path = image_url filename = None if is_external_url: - # For external URLs, use the full URL as-is for matching - normalized_url = image_url + # Extract the path from the full URL + try: + from urllib.parse import urlparse + parsed_url = urlparse(image_url) + normalized_path = parsed_url.path # Extract path like "/uploads/rooms/image.webp" + + # Check if it's a local uploads path (not an external image service) + if normalized_path.startswith('/uploads/'): + is_external_url = False # It's a local file with full URL + filename = Path(normalized_path).name + else: + # Truly external URL (like Unsplash) + normalized_path = image_url + except Exception as e: + logger.warning(f'Error parsing URL {image_url}: {str(e)}') + # Fallback: try to extract path manually + if '/uploads/' in image_url: + match = image_url.split('/uploads/', 1) + if len(match) == 2: + normalized_path = f'/uploads/{match[1]}' + is_external_url = False + filename = Path(normalized_path).name else: - # For local files, normalize the path - if not normalized_url.startswith('/'): - normalized_url = f'/{normalized_url}' - filename = Path(normalized_url).name + # Local file path - normalize it + if not normalized_path.startswith('/'): + normalized_path = f'/{normalized_path}' + filename = Path(normalized_path).name + + logger.info(f'Deleting image: original={image_url}, normalized_path={normalized_path}, filename={filename}, is_external={is_external_url}') # Handle existing_images - it might be a list, a JSON string, or None existing_images = room.images or [] @@ -626,24 +713,52 @@ async def delete_room_images(id: int, image_url: str=Query(..., description='Ima updated_images = [] for img in existing_images: - # For external URLs, match by full URL (keep images that don't match) - if is_external_url: - # Keep the image if it doesn't match the URL we're deleting - if img != normalized_url: + # Convert stored image to string for comparison + img_str = str(img).strip() + if not img_str: + continue + + # Normalize stored image path + stored_path = img_str + stored_is_external = stored_path.startswith('http://') or stored_path.startswith('https://') + + if stored_is_external and is_external_url: + # Both are external URLs - match exactly + if img_str != image_url: updated_images.append(img) + elif stored_is_external and not is_external_url: + # Stored is external, deleting is local - keep it + updated_images.append(img) + elif not stored_is_external and is_external_url: + # Stored is local, deleting is external - keep it + updated_images.append(img) else: - # For local files, match by path or filename (keep images that don't match) - stored_path = img if img.startswith('/') else f'/{img}' - stored_filename = Path(stored_path).name if '/' in str(stored_path) else stored_path - # Keep the image if it doesn't match any of the comparison criteria - if img != normalized_url and stored_path != normalized_url and (not filename or stored_filename != filename): + # Both are local paths - normalize both for comparison + stored_normalized = stored_path if stored_path.startswith('/') else f'/{stored_path}' + stored_filename = Path(stored_normalized).name if '/' in stored_normalized else stored_path + + # Match by full path or by filename + path_matches = (stored_normalized == normalized_path or stored_path == normalized_path) + filename_matches = (filename and stored_filename == filename) + + if not (path_matches or filename_matches): + # Keep images that don't match updated_images.append(img) - # Only try to delete the file if it's a local file (filename exists) + logger.info(f'Images before: {len(existing_images)}, after: {len(updated_images)}') + + # Only try to delete the physical file if it's a local file (filename exists) if filename: - file_path = Path(__file__).parent.parent.parent / 'uploads' / 'rooms' / filename + file_path = Path(__file__).parent.parent.parent.parent / 'uploads' / 'rooms' / filename if file_path.exists(): - file_path.unlink() + try: + file_path.unlink() + logger.info(f'Deleted file: {file_path}') + except Exception as e: + logger.warning(f'Could not delete file {file_path}: {str(e)}') + else: + logger.warning(f'File does not exist: {file_path}') + room.images = updated_images db.commit() return {'status': 'success', 'message': 'Image deleted successfully', 'data': {'images': updated_images}} @@ -651,6 +766,7 @@ async def delete_room_images(id: int, image_url: str=Query(..., description='Ima raise except Exception as e: db.rollback() + logger.error(f'Error deleting room image: {str(e)}', exc_info=True, extra={'room_id': id, 'image_url': image_url}) raise HTTPException(status_code=500, detail=str(e)) @router.get('/{id}/booked-dates') diff --git a/Backend/src/shared/utils/__pycache__/image_optimization.cpython-312.pyc b/Backend/src/shared/utils/__pycache__/image_optimization.cpython-312.pyc new file mode 100644 index 00000000..5f0a77ac Binary files /dev/null and b/Backend/src/shared/utils/__pycache__/image_optimization.cpython-312.pyc differ diff --git a/Backend/src/shared/utils/image_optimization.py b/Backend/src/shared/utils/image_optimization.py new file mode 100644 index 00000000..fd1eea99 --- /dev/null +++ b/Backend/src/shared/utils/image_optimization.py @@ -0,0 +1,252 @@ +""" +Image optimization utility for compressing and resizing images before serving to frontend. +Reduces file size while maintaining visual quality. +""" +from PIL import Image, ImageOps +import io +from typing import Optional, Tuple +from enum import Enum +from ...shared.config.logging_config import get_logger + +logger = get_logger(__name__) + + +class ImageType(Enum): + """Image types with different optimization settings""" + AVATAR = "avatar" # Small profile images + BANNER = "banner" # Large banner images + ROOM = "room" # Room gallery images + BLOG = "blog" # Blog post images + PAGE_CONTENT = "page_content" # General page content images + COMPANY = "company" # Company logos/favicons + GALLERY = "gallery" # General gallery images + + +# Optimization settings for different image types +IMAGE_OPTIMIZATION_CONFIG = { + ImageType.AVATAR: { + "max_width": 400, + "max_height": 400, + "quality": 85, + "convert_to_webp": True, + "webp_quality": 80, + }, + ImageType.BANNER: { + "max_width": 1920, + "max_height": 1080, + "quality": 85, + "convert_to_webp": True, + "webp_quality": 82, + }, + ImageType.ROOM: { + "max_width": 1920, + "max_height": 1920, + "quality": 85, + "convert_to_webp": True, + "webp_quality": 85, + }, + ImageType.BLOG: { + "max_width": 1920, + "max_height": 1920, + "quality": 85, + "convert_to_webp": True, + "webp_quality": 85, + }, + ImageType.PAGE_CONTENT: { + "max_width": 1920, + "max_height": 1920, + "quality": 85, + "convert_to_webp": True, + "webp_quality": 85, + }, + ImageType.COMPANY: { + "max_width": 512, + "max_height": 512, + "quality": 90, + "convert_to_webp": True, + "webp_quality": 88, + }, + ImageType.GALLERY: { + "max_width": 1920, + "max_height": 1920, + "quality": 85, + "convert_to_webp": True, + "webp_quality": 85, + }, +} + + +def optimize_image( + image_bytes: bytes, + image_type: ImageType, + preserve_original_format: bool = False +) -> Tuple[bytes, str]: + """ + Optimize an image by resizing, compressing, and optionally converting to WebP. + + Args: + image_bytes: Original image as bytes + image_type: Type of image (determines optimization settings) + preserve_original_format: If True, keep original format. If False, convert to WebP when beneficial. + + Returns: + Tuple of (optimized_image_bytes, file_extension) + """ + try: + # Get optimization config for this image type + config = IMAGE_OPTIMIZATION_CONFIG.get(image_type, IMAGE_OPTIMIZATION_CONFIG[ImageType.GALLERY]) + + # Open and process image + img = Image.open(io.BytesIO(image_bytes)) + + # Convert to RGB if necessary (removes transparency, necessary for JPEG) + # For WebP, we can preserve transparency if original format supports it + original_format = img.format + has_transparency = img.mode in ('RGBA', 'LA', 'P') and 'transparency' in img.info + + # Auto-orient image based on EXIF data + try: + img = ImageOps.exif_transpose(img) + except Exception: + # If EXIF orientation fails, continue with original image + pass + + # Calculate new dimensions while maintaining aspect ratio + width, height = img.size + max_width = config["max_width"] + max_height = config["max_height"] + + if width > max_width or height > max_height: + # Calculate scaling factor + scale = min(max_width / width, max_height / height) + new_width = int(width * scale) + new_height = int(height * scale) + + # Use high-quality resampling for downscaling + # Fallback for older Pillow versions + try: + resampling = Image.Resampling.LANCZOS + except AttributeError: + resampling = Image.LANCZOS + img = img.resize((new_width, new_height), resampling) + logger.debug( + f"Resized image from {width}x{height} to {new_width}x{new_height} " + f"(scale: {scale:.2f})" + ) + + # Decide on output format + output_format = original_format or 'JPEG' + output_extension = '.jpg' + + # Convert to WebP if configured and beneficial + if config.get("convert_to_webp", True) and not preserve_original_format: + # WebP typically provides 25-35% better compression + output_format = 'WEBP' + output_extension = '.webp' + + # Preserve transparency for WebP if original had it + if has_transparency: + img = img.convert('RGBA') + else: + img = img.convert('RGB') + else: + # For JPEG/other formats, convert to RGB (removes transparency) + if output_format in ('JPEG', 'JPG'): + if img.mode != 'RGB': + # Create white background for images with transparency + if img.mode in ('RGBA', 'LA'): + background = Image.new('RGB', img.size, (255, 255, 255)) + if img.mode == 'RGBA': + background.paste(img, mask=img.split()[3]) # Use alpha channel as mask + else: + background.paste(img) + img = background + else: + img = img.convert('RGB') + + # Keep original format extension + if original_format: + output_extension = f'.{original_format.lower()}' + + # Compress and save to bytes + output = io.BytesIO() + + if output_format == 'WEBP': + quality = config.get("webp_quality", 85) + img.save( + output, + format='WEBP', + quality=quality, + method=6 # Method 6 is slower but produces better compression + ) + elif output_format in ('JPEG', 'JPG'): + quality = config.get("quality", 85) + img.save( + output, + format='JPEG', + quality=quality, + optimize=True, # Enable JPEG optimization + progressive=True # Progressive JPEG for better perceived loading + ) + elif output_format == 'PNG': + # PNG compression + img.save( + output, + format='PNG', + optimize=True, + compress_level=9 # Maximum compression (0-9) + ) + else: + # For other formats (GIF, etc.), save as-is with optimization + img.save(output, format=output_format, optimize=True) + + optimized_bytes = output.getvalue() + + # Log optimization results + original_size = len(image_bytes) + optimized_size = len(optimized_bytes) + reduction_percent = ((original_size - optimized_size) / original_size * 100) if original_size > 0 else 0 + + logger.info( + f"Image optimized: {original_size} bytes -> {optimized_size} bytes " + f"({reduction_percent:.1f}% reduction, type: {image_type.value})" + ) + + return optimized_bytes, output_extension + + except Exception as e: + logger.error(f"Error optimizing image: {str(e)}", exc_info=True) + # Return original image if optimization fails + logger.warning("Returning original image due to optimization error") + original_format = Image.open(io.BytesIO(image_bytes)).format or 'JPEG' + extension = f'.{original_format.lower()}' if original_format else '.jpg' + return image_bytes, extension + + +async def optimize_image_async( + image_bytes: bytes, + image_type: ImageType, + preserve_original_format: bool = False +) -> Tuple[bytes, str]: + """ + Async wrapper for optimize_image (for use in async endpoints). + + Args: + image_bytes: Original image as bytes + image_type: Type of image (determines optimization settings) + preserve_original_format: If True, keep original format. If False, convert to WebP when beneficial. + + Returns: + Tuple of (optimized_image_bytes, file_extension) + """ + import asyncio + # Run the CPU-intensive optimization in a thread pool to avoid blocking + loop = asyncio.get_event_loop() + return await loop.run_in_executor( + None, + optimize_image, + image_bytes, + image_type, + preserve_original_format + ) + diff --git a/Backend/src/system/routes/__pycache__/system_settings_routes.cpython-312.pyc b/Backend/src/system/routes/__pycache__/system_settings_routes.cpython-312.pyc index ace06d82..c09b0ceb 100644 Binary files a/Backend/src/system/routes/__pycache__/system_settings_routes.cpython-312.pyc and b/Backend/src/system/routes/__pycache__/system_settings_routes.cpython-312.pyc differ diff --git a/Backend/src/system/routes/system_settings_routes.py b/Backend/src/system/routes/system_settings_routes.py index 0c9f91d4..bd5114a8 100644 --- a/Backend/src/system/routes/system_settings_routes.py +++ b/Backend/src/system/routes/system_settings_routes.py @@ -740,7 +740,7 @@ async def upload_borica_certificate( ) # Create upload directory - upload_dir = Path(__file__).parent.parent.parent / "uploads" / "certificates" / "borica" + upload_dir = Path(__file__).parent.parent.parent.parent / "uploads" / "certificates" / "borica" upload_dir.mkdir(parents=True, exist_ok=True) # Generate unique filename @@ -1370,22 +1370,18 @@ async def upload_company_logo( ): try: - if not image.content_type or not image.content_type.startswith('image/'): - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="File must be an image" - ) + # Validate image using comprehensive validation + from ...shared.config.settings import settings + from ...shared.utils.file_validation import validate_uploaded_image + from ...shared.utils.image_optimization import optimize_image_async, ImageType - - content = await image.read() - if len(content) > 2 * 1024 * 1024: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="Logo file size must be less than 2MB" - ) + max_size = 2 * 1024 * 1024 # 2MB for logos + content = await validate_uploaded_image(image, max_size) + # Optimize image before saving + optimized_content, optimized_ext = await optimize_image_async(content, ImageType.COMPANY, preserve_original_format=False) - upload_dir = Path(__file__).parent.parent.parent / "uploads" / "company" + upload_dir = Path(__file__).parent.parent.parent.parent / "uploads" / "company" upload_dir.mkdir(parents=True, exist_ok=True) @@ -1394,7 +1390,7 @@ async def upload_company_logo( ).first() if old_logo_setting and old_logo_setting.value: - old_logo_path = Path(__file__).parent.parent.parent / old_logo_setting.value.lstrip('/') + old_logo_path = Path(__file__).parent.parent.parent.parent / old_logo_setting.value.lstrip('/') if old_logo_path.exists() and old_logo_path.is_file(): try: old_logo_path.unlink() @@ -1402,14 +1398,14 @@ async def upload_company_logo( logger.warning(f"Could not delete old logo: {e}") - ext = Path(image.filename).suffix or '.png' - - filename = "logo.png" + # Use optimized extension, default to webp or png + ext = optimized_ext or '.webp' + filename = f"logo{ext}" file_path = upload_dir / filename async with aiofiles.open(file_path, 'wb') as f: - await f.write(content) + await f.write(optimized_content) image_url = f"/uploads/company/{filename}" @@ -1462,32 +1458,54 @@ async def upload_company_favicon( ): try: - if not image.content_type: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="File type could not be determined" - ) + # Validate image + from ...shared.config.settings import settings + from ...shared.utils.file_validation import validate_uploaded_image + from ...shared.utils.image_optimization import optimize_image_async, ImageType - allowed_types = ['image/x-icon', 'image/vnd.microsoft.icon', 'image/png', 'image/svg+xml', 'image/ico'] - if image.content_type not in allowed_types: - - filename_lower = (image.filename or '').lower() - if not any(filename_lower.endswith(ext) for ext in ['.ico', '.png', '.svg']): + max_size = 500 * 1024 # 500KB for favicons + + # For favicons, we need to check if it's SVG (text format) or image format + filename_lower = (image.filename or '').lower() + is_svg = filename_lower.endswith('.svg') + + if is_svg: + # For SVG, just validate size (can't optimize SVG with PIL) + content = await image.read() + if len(content) > max_size: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, - detail="Favicon must be .ico, .png, or .svg file" + detail="Favicon file size must be less than 500KB" ) - - - content = await image.read() - if len(content) > 500 * 1024: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="Favicon file size must be less than 500KB" + # Keep SVG as-is + optimized_content = content + optimized_ext = '.svg' + else: + # For ICO/PNG, validate and optimize + if not image.content_type: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="File type could not be determined" + ) + + allowed_types = ['image/x-icon', 'image/vnd.microsoft.icon', 'image/png', 'image/ico'] + if image.content_type not in allowed_types: + if not any(filename_lower.endswith(ext) for ext in ['.ico', '.png']): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Favicon must be .ico or .png file" + ) + + content = await validate_uploaded_image(image, max_size) + + # Optimize favicon but preserve format (ICO/PNG) + optimized_content, optimized_ext = await optimize_image_async( + content, + ImageType.COMPANY, + preserve_original_format=True # Keep original format for favicons ) - - upload_dir = Path(__file__).parent.parent.parent / "uploads" / "company" + upload_dir = Path(__file__).parent.parent.parent.parent / "uploads" / "company" upload_dir.mkdir(parents=True, exist_ok=True) @@ -1496,7 +1514,7 @@ async def upload_company_favicon( ).first() if old_favicon_setting and old_favicon_setting.value: - old_favicon_path = Path(__file__).parent.parent.parent / old_favicon_setting.value.lstrip('/') + old_favicon_path = Path(__file__).parent.parent.parent.parent / old_favicon_setting.value.lstrip('/') if old_favicon_path.exists() and old_favicon_path.is_file(): try: old_favicon_path.unlink() @@ -1504,11 +1522,11 @@ async def upload_company_favicon( logger.warning(f"Could not delete old favicon: {e}") - filename_lower = (image.filename or '').lower() - if filename_lower.endswith('.ico'): - filename = "favicon.ico" - elif filename_lower.endswith('.svg'): + # Determine filename based on original or optimized extension + if is_svg or filename_lower.endswith('.svg'): filename = "favicon.svg" + elif optimized_ext == '.ico' or filename_lower.endswith('.ico'): + filename = "favicon.ico" else: filename = "favicon.png" @@ -1516,7 +1534,7 @@ async def upload_company_favicon( async with aiofiles.open(file_path, 'wb') as f: - await f.write(content) + await f.write(optimized_content) image_url = f"/uploads/company/{filename}" diff --git a/Frontend/src/features/hotel_services/components/HousekeepingManagement.tsx b/Frontend/src/features/hotel_services/components/HousekeepingManagement.tsx index eefac3b2..3a7d5da1 100644 --- a/Frontend/src/features/hotel_services/components/HousekeepingManagement.tsx +++ b/Frontend/src/features/hotel_services/components/HousekeepingManagement.tsx @@ -7,6 +7,8 @@ import { X, CheckCircle, Clock, + RefreshCw, + Play, } from 'lucide-react'; import { toast } from 'react-toastify'; import Loading from '../../../shared/components/Loading'; @@ -66,10 +68,23 @@ const HousekeepingManagement: React.FC = () => { fetchTasks(); }, [currentPage, filters]); + // Auto-refresh every 30 seconds for real-time updates + useEffect(() => { + const interval = setInterval(() => { + fetchTasks(); + }, 30000); // Refresh every 30 seconds + + return () => clearInterval(interval); + }, [currentPage, filters]); + const fetchTasks = async () => { try { setLoading(true); - const params: any = { page: currentPage, limit: 10 }; + const params: any = { + page: currentPage, + limit: 10, + include_cleaning_rooms: true // Include rooms in cleaning status + }; if (filters.room_id) params.room_id = parseInt(filters.room_id); if (filters.status) params.status = filters.status; if (filters.task_type) params.task_type = filters.task_type; @@ -176,7 +191,30 @@ const HousekeepingManagement: React.FC = () => { setShowModal(true); }; + const handleStartTask = async (task: HousekeepingTask) => { + if (!task.id) { + toast.error('Cannot start task: Invalid task ID'); + return; + } + + try { + await advancedRoomService.updateHousekeepingTask(task.id, { + status: 'in_progress', + assigned_to: userInfo?.id, // Assign to current user when starting + }); + toast.success('Task started successfully'); + fetchTasks(); + } catch (error: any) { + toast.error(error.response?.data?.detail || 'Failed to start task'); + } + }; + const handleMarkAsDone = async (task: HousekeepingTask) => { + if (!task.id) { + toast.error('Cannot complete task: Invalid task ID'); + return; + } + // Double check that the task is assigned to the current user if (!task.assigned_to) { toast.error('Task must be assigned before it can be marked as done'); @@ -192,7 +230,7 @@ const HousekeepingManagement: React.FC = () => { status: 'completed', checklist_items: task.checklist_items?.map(item => ({ ...item, completed: true })) || [], }); - toast.success('Task marked as completed successfully'); + toast.success('Task marked as completed successfully. Room is now ready for check-in.'); fetchTasks(); } catch (error: any) { toast.error(error.response?.data?.detail || 'Failed to mark task as done'); @@ -322,15 +360,26 @@ const HousekeepingManagement: React.FC = () => { className="border border-gray-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500" /> - {(isAdmin || userInfo?.role === 'staff') && ( +