diff --git a/Backend/=1.0.1 b/Backend/=1.0.1 deleted file mode 100644 index e69de29b..00000000 diff --git a/Backend/alembic/versions/316d876b1b71_add_newsletter_subscribers_table.py b/Backend/alembic/versions/316d876b1b71_add_newsletter_subscribers_table.py new file mode 100644 index 00000000..65591c0f --- /dev/null +++ b/Backend/alembic/versions/316d876b1b71_add_newsletter_subscribers_table.py @@ -0,0 +1,55 @@ +"""add_newsletter_subscribers_table + +Revision ID: 316d876b1b71 +Revises: add_enterprise_homepage_fields +Create Date: 2025-12-05 15:33:09.120967 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '316d876b1b71' +down_revision = 'add_enterprise_homepage_fields' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # Check if table exists + from sqlalchemy import inspect + conn = op.get_bind() + inspector = inspect(conn) + tables = inspector.get_table_names() + + if 'newsletter_subscribers' not in tables: + # Create newsletter_subscribers table + op.create_table( + 'newsletter_subscribers', + sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), + sa.Column('email', sa.String(255), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=True), + sa.Column('name', sa.String(255), nullable=True), + sa.Column('subscribed_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.Column('is_active', sa.Boolean(), nullable=False, server_default='1'), + sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='SET NULL'), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('email') + ) + op.create_index(op.f('ix_newsletter_subscribers_email'), 'newsletter_subscribers', ['email'], unique=False) + op.create_index(op.f('ix_newsletter_subscribers_id'), 'newsletter_subscribers', ['id'], unique=False) + op.create_index(op.f('ix_newsletter_subscribers_is_active'), 'newsletter_subscribers', ['is_active'], unique=False) + op.create_index(op.f('ix_newsletter_subscribers_subscribed_at'), 'newsletter_subscribers', ['subscribed_at'], unique=False) + op.create_index(op.f('ix_newsletter_subscribers_user_id'), 'newsletter_subscribers', ['user_id'], unique=False) + + +def downgrade() -> None: + op.drop_index(op.f('ix_newsletter_subscribers_user_id'), table_name='newsletter_subscribers') + op.drop_index(op.f('ix_newsletter_subscribers_subscribed_at'), table_name='newsletter_subscribers') + op.drop_index(op.f('ix_newsletter_subscribers_is_active'), table_name='newsletter_subscribers') + op.drop_index(op.f('ix_newsletter_subscribers_id'), table_name='newsletter_subscribers') + op.drop_index(op.f('ix_newsletter_subscribers_email'), table_name='newsletter_subscribers') + op.drop_table('newsletter_subscribers') + diff --git a/Backend/alembic/versions/87e29a777cb3_add_recipient_type_to_campaigns.py b/Backend/alembic/versions/87e29a777cb3_add_recipient_type_to_campaigns.py new file mode 100644 index 00000000..5b914ecf --- /dev/null +++ b/Backend/alembic/versions/87e29a777cb3_add_recipient_type_to_campaigns.py @@ -0,0 +1,40 @@ +"""add_recipient_type_to_campaigns + +Revision ID: 87e29a777cb3 +Revises: 316d876b1b71 +Create Date: 2025-12-05 15:36:11.095669 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '87e29a777cb3' +down_revision = '316d876b1b71' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # Add recipient_type column to email_campaigns table + from sqlalchemy import inspect + conn = op.get_bind() + inspector = inspect(conn) + + # Check if column exists + columns = [col['name'] for col in inspector.get_columns('email_campaigns')] + if 'recipient_type' not in columns: + op.add_column('email_campaigns', sa.Column('recipient_type', sa.String(50), nullable=True, server_default='users')) + + +def downgrade() -> None: + # Remove recipient_type column + from sqlalchemy import inspect + conn = op.get_bind() + inspector = inspect(conn) + + columns = [col['name'] for col in inspector.get_columns('email_campaigns')] + if 'recipient_type' in columns: + op.drop_column('email_campaigns', 'recipient_type') + diff --git a/Backend/alembic/versions/__pycache__/316d876b1b71_add_newsletter_subscribers_table.cpython-312.pyc b/Backend/alembic/versions/__pycache__/316d876b1b71_add_newsletter_subscribers_table.cpython-312.pyc new file mode 100644 index 00000000..8719cf01 Binary files /dev/null and b/Backend/alembic/versions/__pycache__/316d876b1b71_add_newsletter_subscribers_table.cpython-312.pyc differ diff --git a/Backend/alembic/versions/__pycache__/87e29a777cb3_add_recipient_type_to_campaigns.cpython-312.pyc b/Backend/alembic/versions/__pycache__/87e29a777cb3_add_recipient_type_to_campaigns.cpython-312.pyc new file mode 100644 index 00000000..5c89e8e3 Binary files /dev/null and b/Backend/alembic/versions/__pycache__/87e29a777cb3_add_recipient_type_to_campaigns.cpython-312.pyc differ diff --git a/Backend/alembic/versions/__pycache__/add_enterprise_homepage_fields_to_page_content.cpython-312.pyc b/Backend/alembic/versions/__pycache__/add_enterprise_homepage_fields_to_page_content.cpython-312.pyc new file mode 100644 index 00000000..53c8dd67 Binary files /dev/null and b/Backend/alembic/versions/__pycache__/add_enterprise_homepage_fields_to_page_content.cpython-312.pyc differ diff --git a/Backend/alembic/versions/add_enterprise_homepage_fields_to_page_content.py b/Backend/alembic/versions/add_enterprise_homepage_fields_to_page_content.py new file mode 100644 index 00000000..a3c8189f --- /dev/null +++ b/Backend/alembic/versions/add_enterprise_homepage_fields_to_page_content.py @@ -0,0 +1,127 @@ +from alembic import op +import sqlalchemy as sa +from sqlalchemy import inspect +revision = 'add_enterprise_homepage_fields' +down_revision = 'service_detail_001' # Latest migration head +branch_labels = None +depends_on = None + +def column_exists(table_name, column_name, connection): + """Check if a column exists in a table.""" + inspector = inspect(connection) + columns = [col['name'] for col in inspector.get_columns(table_name)] + return column_name in columns + +def upgrade() -> None: + connection = op.get_bind() + + # Helper function to add column if it doesn't exist + def add_column_if_not_exists(table_name, column, column_name): + if not column_exists(table_name, column_name, connection): + op.add_column(table_name, column) + + # Hero video fields - use TEXT to avoid row size limit + add_column_if_not_exists('page_contents', sa.Column('hero_video_url', sa.Text(), nullable=True), 'hero_video_url') + add_column_if_not_exists('page_contents', sa.Column('hero_video_poster', sa.Text(), nullable=True), 'hero_video_poster') + + # Features section fields - use TEXT for subtitles + add_column_if_not_exists('page_contents', sa.Column('features_section_title', sa.Text(), nullable=True), 'features_section_title') + add_column_if_not_exists('page_contents', sa.Column('features_section_subtitle', sa.Text(), nullable=True), 'features_section_subtitle') + + # Stats section fields - use TEXT for subtitles + add_column_if_not_exists('page_contents', sa.Column('stats_section_title', sa.Text(), nullable=True), 'stats_section_title') + add_column_if_not_exists('page_contents', sa.Column('stats_section_subtitle', sa.Text(), nullable=True), 'stats_section_subtitle') + + # Rooms section fields - use TEXT for all string fields + add_column_if_not_exists('page_contents', sa.Column('rooms_section_title', sa.Text(), nullable=True), 'rooms_section_title') + add_column_if_not_exists('page_contents', sa.Column('rooms_section_subtitle', sa.Text(), nullable=True), 'rooms_section_subtitle') + add_column_if_not_exists('page_contents', sa.Column('rooms_section_button_text', sa.Text(), nullable=True), 'rooms_section_button_text') + add_column_if_not_exists('page_contents', sa.Column('rooms_section_button_link', sa.Text(), nullable=True), 'rooms_section_button_link') + add_column_if_not_exists('page_contents', sa.Column('rooms_section_enabled', sa.Boolean(), nullable=True, server_default='1'), 'rooms_section_enabled') + + # Services section fields - use TEXT for all string fields + add_column_if_not_exists('page_contents', sa.Column('services_section_button_text', sa.Text(), nullable=True), 'services_section_button_text') + add_column_if_not_exists('page_contents', sa.Column('services_section_button_link', sa.Text(), nullable=True), 'services_section_button_link') + add_column_if_not_exists('page_contents', sa.Column('services_section_limit', sa.Integer(), nullable=True), 'services_section_limit') + + # Sections enabled (JSON field for toggling sections) + add_column_if_not_exists('page_contents', sa.Column('sections_enabled', sa.Text(), nullable=True), 'sections_enabled') + + # Newsletter section fields - use TEXT for all string fields + add_column_if_not_exists('page_contents', sa.Column('newsletter_section_title', sa.Text(), nullable=True), 'newsletter_section_title') + add_column_if_not_exists('page_contents', sa.Column('newsletter_section_subtitle', sa.Text(), nullable=True), 'newsletter_section_subtitle') + add_column_if_not_exists('page_contents', sa.Column('newsletter_placeholder', sa.Text(), nullable=True), 'newsletter_placeholder') + add_column_if_not_exists('page_contents', sa.Column('newsletter_button_text', sa.Text(), nullable=True), 'newsletter_button_text') + add_column_if_not_exists('page_contents', sa.Column('newsletter_enabled', sa.Boolean(), nullable=True, server_default='0'), 'newsletter_enabled') + + # Trust badges section fields - use TEXT for subtitles + add_column_if_not_exists('page_contents', sa.Column('trust_badges_section_title', sa.Text(), nullable=True), 'trust_badges_section_title') + add_column_if_not_exists('page_contents', sa.Column('trust_badges_section_subtitle', sa.Text(), nullable=True), 'trust_badges_section_subtitle') + add_column_if_not_exists('page_contents', sa.Column('trust_badges', sa.Text(), nullable=True), 'trust_badges') + add_column_if_not_exists('page_contents', sa.Column('trust_badges_enabled', sa.Boolean(), nullable=True, server_default='0'), 'trust_badges_enabled') + + # Promotions section fields - use TEXT for subtitles + add_column_if_not_exists('page_contents', sa.Column('promotions_section_title', sa.Text(), nullable=True), 'promotions_section_title') + add_column_if_not_exists('page_contents', sa.Column('promotions_section_subtitle', sa.Text(), nullable=True), 'promotions_section_subtitle') + add_column_if_not_exists('page_contents', sa.Column('promotions', sa.Text(), nullable=True), 'promotions') + add_column_if_not_exists('page_contents', sa.Column('promotions_enabled', sa.Boolean(), nullable=True, server_default='0'), 'promotions_enabled') + + # Blog section fields - use TEXT for subtitles + add_column_if_not_exists('page_contents', sa.Column('blog_section_title', sa.Text(), nullable=True), 'blog_section_title') + add_column_if_not_exists('page_contents', sa.Column('blog_section_subtitle', sa.Text(), nullable=True), 'blog_section_subtitle') + add_column_if_not_exists('page_contents', sa.Column('blog_posts_limit', sa.Integer(), nullable=True), 'blog_posts_limit') + add_column_if_not_exists('page_contents', sa.Column('blog_enabled', sa.Boolean(), nullable=True, server_default='0'), 'blog_enabled') + +def downgrade() -> None: + # Blog section fields + op.drop_column('page_contents', 'blog_enabled') + op.drop_column('page_contents', 'blog_posts_limit') + op.drop_column('page_contents', 'blog_section_subtitle') + op.drop_column('page_contents', 'blog_section_title') + + # Promotions section fields + op.drop_column('page_contents', 'promotions_enabled') + op.drop_column('page_contents', 'promotions') + op.drop_column('page_contents', 'promotions_section_subtitle') + op.drop_column('page_contents', 'promotions_section_title') + + # Trust badges section fields + op.drop_column('page_contents', 'trust_badges_enabled') + op.drop_column('page_contents', 'trust_badges') + op.drop_column('page_contents', 'trust_badges_section_subtitle') + op.drop_column('page_contents', 'trust_badges_section_title') + + # Newsletter section fields + op.drop_column('page_contents', 'newsletter_enabled') + op.drop_column('page_contents', 'newsletter_button_text') + op.drop_column('page_contents', 'newsletter_placeholder') + op.drop_column('page_contents', 'newsletter_section_subtitle') + op.drop_column('page_contents', 'newsletter_section_title') + + # Sections enabled + op.drop_column('page_contents', 'sections_enabled') + + # Services section fields + op.drop_column('page_contents', 'services_section_limit') + op.drop_column('page_contents', 'services_section_button_link') + op.drop_column('page_contents', 'services_section_button_text') + + # Rooms section fields + op.drop_column('page_contents', 'rooms_section_enabled') + op.drop_column('page_contents', 'rooms_section_button_link') + op.drop_column('page_contents', 'rooms_section_button_text') + op.drop_column('page_contents', 'rooms_section_subtitle') + op.drop_column('page_contents', 'rooms_section_title') + + # Stats section fields + op.drop_column('page_contents', 'stats_section_subtitle') + op.drop_column('page_contents', 'stats_section_title') + + # Features section fields + op.drop_column('page_contents', 'features_section_subtitle') + op.drop_column('page_contents', 'features_section_title') + + # Hero video fields + op.drop_column('page_contents', 'hero_video_poster') + op.drop_column('page_contents', 'hero_video_url') + diff --git a/Backend/backups/backup_hotel_booking_dev_20251205_144357.json b/Backend/backups/backup_hotel_booking_dev_20251205_144357.json new file mode 100644 index 00000000..0348258f --- /dev/null +++ b/Backend/backups/backup_hotel_booking_dev_20251205_144357.json @@ -0,0 +1,9 @@ +{ + "filename": "backup_hotel_booking_dev_20251205_144357.sql", + "path": "backups/backup_hotel_booking_dev_20251205_144357.sql", + "size_bytes": 653233, + "size_mb": 0.62, + "created_at": "2025-12-05T14:43:58.328707", + "database": "hotel_booking_dev", + "status": "success" +} \ No newline at end of file diff --git a/Backend/backups/backup_hotel_booking_dev_20251205_144357.sql b/Backend/backups/backup_hotel_booking_dev_20251205_144357.sql new file mode 100644 index 00000000..61b48b16 --- /dev/null +++ b/Backend/backups/backup_hotel_booking_dev_20251205_144357.sql @@ -0,0 +1,4850 @@ +-- 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 `accountant_activity_logs` +-- + +DROP TABLE IF EXISTS `accountant_activity_logs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `accountant_activity_logs` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `session_id` int DEFAULT NULL, + `activity_type` varchar(50) NOT NULL, + `activity_description` text NOT NULL, + `ip_address` varchar(45) DEFAULT NULL, + `user_agent` text, + `country` varchar(2) DEFAULT NULL, + `city` varchar(100) DEFAULT NULL, + `risk_level` varchar(20) NOT NULL, + `is_unusual` tinyint(1) NOT NULL, + `activity_metadata` json DEFAULT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `idx_accountant_activity_user_date` (`user_id`,`created_at`), + KEY `ix_accountant_activity_logs_id` (`id`), + KEY `ix_accountant_activity_logs_session_id` (`session_id`), + KEY `idx_accountant_activity_unusual` (`is_unusual`,`risk_level`,`created_at`), + KEY `ix_accountant_activity_logs_user_id` (`user_id`), + KEY `ix_accountant_activity_logs_created_at` (`created_at`), + KEY `idx_accountant_activity_type` (`activity_type`,`created_at`), + KEY `ix_accountant_activity_logs_is_unusual` (`is_unusual`), + KEY `ix_accountant_activity_logs_activity_type` (`activity_type`), + CONSTRAINT `accountant_activity_logs_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `accountant_activity_logs_ibfk_2` FOREIGN KEY (`session_id`) REFERENCES `accountant_sessions` (`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 `accountant_activity_logs` +-- + +LOCK TABLES `accountant_activity_logs` WRITE; +/*!40000 ALTER TABLE `accountant_activity_logs` DISABLE KEYS */; +/*!40000 ALTER TABLE `accountant_activity_logs` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `accountant_sessions` +-- + +DROP TABLE IF EXISTS `accountant_sessions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `accountant_sessions` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` int NOT NULL, + `session_token` varchar(255) NOT NULL, + `ip_address` varchar(45) DEFAULT NULL, + `user_agent` text, + `device_fingerprint` varchar(255) DEFAULT NULL, + `country` varchar(2) DEFAULT NULL, + `city` varchar(100) DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `last_activity` datetime NOT NULL, + `step_up_authenticated` tinyint(1) NOT NULL, + `step_up_expires_at` datetime DEFAULT NULL, + `session_metadata` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `expires_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_accountant_sessions_session_token` (`session_token`), + KEY `idx_accountant_session_user_active` (`user_id`,`is_active`,`last_activity`), + KEY `ix_accountant_sessions_id` (`id`), + KEY `ix_accountant_sessions_is_active` (`is_active`), + KEY `ix_accountant_sessions_created_at` (`created_at`), + KEY `idx_accountant_session_expires` (`expires_at`,`is_active`), + KEY `ix_accountant_sessions_user_id` (`user_id`), + KEY `ix_accountant_sessions_last_activity` (`last_activity`), + KEY `ix_accountant_sessions_expires_at` (`expires_at`), + CONSTRAINT `accountant_sessions_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 `accountant_sessions` +-- + +LOCK TABLES `accountant_sessions` WRITE; +/*!40000 ALTER TABLE `accountant_sessions` DISABLE KEYS */; +/*!40000 ALTER TABLE `accountant_sessions` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- 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,118,0,'admin',0,NULL,'2025-11-30 19:15:58','2025-12-05 13:47:21',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,116,0,'admin',0,NULL,'2025-11-30 19:18:25','2025-12-05 13:47:21',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,116,0,'admin',0,NULL,'2025-11-30 19:20:31','2025-12-05 13:47:21',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,116,0,'admin',0,NULL,'2025-11-30 19:21:00','2025-12-05 13:47:21',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,115,0,'admin',0,NULL,'2025-11-30 19:21:24','2025-12-05 13:47:21',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,115,0,'admin',0,NULL,'2025-11-30 19:21:25','2025-12-05 13:47:21',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,113,0,'admin',0,NULL,'2025-11-30 20:41:01','2025-12-05 13:47:21',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,103,0,'admin',0,NULL,'2025-11-30 23:06:47','2025-12-05 13:47:21',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,356,1,1,'admin',1,'2025-11-30 19:15:58','2025-12-05 13:47:21','2025-12-05 13:47:21'),(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,117,1,3,'admin',1,'2025-11-30 19:20:31','2025-12-05 13:47:21','2025-12-05 13:47:21'),(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,117,1,5,'admin',1,'2025-11-30 19:21:00','2025-12-05 13:47:21','2025-12-05 13:47:21'),(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,116,1,6,'admin',1,'2025-11-30 19:21:25','2025-12-05 13:47:21','2025-12-05 13:47:21'),(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,114,1,7,'admin',1,'2025-11-30 20:41:01','2025-12-05 13:47:21','2025-12-05 13:47:21'),(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,104,1,8,'admin',1,'2025-11-30 23:06:47','2025-12-05 13:47:21','2025-12-05 13:47:21'); +/*!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=7 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'),(4,'2025-12-03 20:37:29',8,6,0,127,NULL,NULL,NULL,NULL,NULL,'2025-12-03 20:37:29'),(5,'2025-12-04 09:44:46',8,6,0,127,NULL,NULL,NULL,NULL,NULL,'2025-12-04 09:44:46'),(6,'2025-12-05 11:12:36',8,6,0,127,NULL,NULL,NULL,NULL,NULL,'2025-12-05 11:12:36'); +/*!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 ('87e29a777cb3'); +/*!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=291 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'),(216,3,'gdpr_deletion_requested','gdpr_request',4,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0',NULL,'{\"email\": \"admin@gnxsoft.com\", \"is_anonymous\": false, \"request_type\": \"data_deletion\"}','success',NULL,'2025-12-02 23:29:51'),(217,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','5585f9dc-03a0-4365-b5a9-e5e9859fdbc7','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-03 20:37:11'),(218,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','7b16975a-408a-4d6d-9797-3c4213c6011e','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-03 20:52:33'),(219,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','138643b0-1414-42b3-9984-2a713b477ab3','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-03 20:53:37'),(220,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','5ffb8b94-bfa8-47f1-9ce8-6383a23343e5','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-03 21:00:00'),(221,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','61c4e8af-7137-4e03-b00a-2b2c3c7ec4fb','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-03 21:00:09'),(222,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','1212ab96-5fcb-493b-a68a-4fc12c35e5f5','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-03 21:07:22'),(223,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','14a9ee28-5457-4544-80c1-ac71f96355b4','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-03 21:44:14'),(224,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','98c3cdd2-2235-48fd-81ab-3ba0f6574d78','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-03 21:57:59'),(225,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','ffdc9bc1-de64-4b76-a5a0-d50d1f78e99b','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-03 21:59:57'),(226,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','68dec92e-3ad9-4292-aec9-f3070df56bf6','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-03 22:16:56'),(227,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','dfb84027-3309-424a-87c5-3a47f3adf97f','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-03 22:17:04'),(228,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','c27c1316-582f-45f0-b148-99c40ba24ae0','{\"email\": \"staff@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-03 22:48:51'),(229,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','2a8cd43c-28b9-4ef8-ae26-7fa45fb7c041','{\"email\": \"staff@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-03 23:05:30'),(230,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','67d85b63-5210-4ee6-a5fe-22f9723ad6c1','{\"email\": \"staff@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 09:44:08'),(231,4,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','bcd8d4c3-f4d8-4dfb-a9d1-8b0d5c640020','{\"email\": \"staff@gnxsoft.com\"}','success',NULL,'2025-12-04 09:52:57'),(232,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','91255a35-cf56-47c9-9d60-a86c938e8348','{\"email\": \"anna@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 09:53:08'),(233,12,'login_blocked_mfa_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','3a7c2b10-36c1-4876-80c4-1a80b51f35dc','{\"email\": \"anna@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','failed',NULL,'2025-12-04 10:36:26'),(234,12,'login_blocked_mfa_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ae1e7348-1404-4ff9-a0ed-29c82429a857','{\"email\": \"anna@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','failed',NULL,'2025-12-04 10:37:01'),(235,12,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','75a0ba32-2985-44a4-baf4-2f6bac76311e','{\"email\": \"anna@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 10:38:21'),(236,12,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','9f66a667-2f87-4de6-8d82-722781979822','{\"email\": \"anna@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 10:38:22'),(237,12,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','63b0ae4d-d69b-4ffc-8171-f061ca7be1fe','{\"email\": \"anna@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 10:39:05'),(238,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','63b0ae4d-d69b-4ffc-8171-f061ca7be1fe','{\"email\": \"anna@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 10:39:05'),(239,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','52fb2ef9-7576-425f-b8cd-84dc0d234b85','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 13:09:33'),(240,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','52fb2ef9-7576-425f-b8cd-84dc0d234b85','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 13:09:33'),(241,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','7826b0aa-6b28-46cb-8512-625b3bbb1ada','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 18:04:50'),(242,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','7826b0aa-6b28-46cb-8512-625b3bbb1ada','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 18:04:50'),(243,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e67286a7-6813-4130-b916-0bd95b6c4ff7','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-04 18:05:22'),(244,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','292bf47d-84c8-4373-9c82-80f9b4bb697d','{\"email\": \"housekeeping@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 18:05:30'),(245,13,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','480ac0f2-9698-4416-9153-fa9c6b136d5b','{\"email\": \"housekeeping@gnxsoft.com\"}','success',NULL,'2025-12-04 18:06:04'),(246,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','11f3dfd3-6247-4434-900b-d442a8f589f0','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 18:06:25'),(247,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','11f3dfd3-6247-4434-900b-d442a8f589f0','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 18:06:25'),(248,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','90d32622-9ef9-4768-bfdf-0f817b9ab2c4','{\"email\": \"staff@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 20:41:12'),(249,4,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','6240bb2b-fead-4594-b60b-359185a3c375','{\"email\": \"staff@gnxsoft.com\"}','success',NULL,'2025-12-04 20:41:40'),(250,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','c29d0dbe-d4c0-48e3-9a07-3760245a6425','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 20:41:45'),(251,5,'complaint_created','complaint',2,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','a9238581-9539-428b-851e-85a0d523218b','{\"title\": \"test\", \"status\": \"open\", \"room_id\": null, \"category\": \"room_quality\", \"priority\": \"urgent\", \"booking_id\": 56, \"complaint_id\": 2}','success',NULL,'2025-12-04 20:42:18'),(252,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','a7cf42b7-1cfa-4923-914c-6b1344630443','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-12-04 20:42:22'),(253,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','aecb78de-f81d-4a00-a595-a7f740f85314','{\"email\": \"staff@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 20:42:30'),(254,4,'complaint_status_changed','complaint',2,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','4218f788-50eb-483f-bf9c-603bf9ddd5fd','{\"guest_id\": 5, \"new_status\": \"in_progress\", \"old_status\": \"open\", \"resolved_by\": null, \"complaint_id\": 2}','success',NULL,'2025-12-04 20:42:48'),(255,4,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','14e87576-0172-4b18-9ce8-265f59285856','{\"email\": \"staff@gnxsoft.com\"}','success',NULL,'2025-12-04 20:43:02'),(256,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','356958ee-f107-4a32-aaec-3ac2be9d07ba','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 20:43:09'),(257,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','639d386d-e267-42fd-bd57-ec4df8fd2eaf','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-12-04 20:49:01'),(258,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','fd4865ac-8232-4581-b974-2b3be5c14370','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 20:49:11'),(259,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','fd4865ac-8232-4581-b974-2b3be5c14370','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 20:49:11'),(260,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','8eb55314-bcc1-43ac-8b67-fa817f20a272','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-04 20:49:43'),(261,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','e538158c-7636-48a0-80f2-bceeff77e6c9','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 20:53:12'),(262,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','e538158c-7636-48a0-80f2-bceeff77e6c9','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 20:53:12'),(263,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','170127ac-56dd-4d72-af8c-26949ae270ef','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-04 20:53:52'),(264,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','fd3b1482-351d-4b4d-8c3a-0993a4fadc3b','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 20:56:51'),(265,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','fd3b1482-351d-4b4d-8c3a-0993a4fadc3b','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 20:56:51'),(266,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','0c950030-0759-4ee9-983c-131b415160e3','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-04 21:09:45'),(267,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','30f620c2-bb7b-4c84-bf04-9820d802a3d6','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 21:10:53'),(268,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','943810d8-9a1e-4b58-b942-67da3973232f','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 21:16:36'),(269,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','943810d8-9a1e-4b58-b942-67da3973232f','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 21:16:36'),(270,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','30aa673a-ee56-4c01-96cb-af06b66ec977','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-04 21:30:11'),(271,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','7b84b166-5ae1-45ce-977c-8883ad50b551','{\"email\": \"customer@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 21:30:22'),(272,5,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','294c04b4-434e-4418-bc26-09d831f5fdaf','{\"email\": \"customer@gnxsoft.com\"}','success',NULL,'2025-12-04 21:57:00'),(273,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','5ed2d286-1719-49c6-865c-143e61891557','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 21:57:12'),(274,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','5ed2d286-1719-49c6-865c-143e61891557','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 21:57:12'),(275,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ca8da459-cf77-4fc0-9811-915ae57e57cb','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 23:09:51'),(276,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','ca8da459-cf77-4fc0-9811-915ae57e57cb','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 23:09:51'),(277,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','ccd56cc5-3723-47cd-995d-e6fc17c45361','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-04 23:48:07'),(278,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','ccd56cc5-3723-47cd-995d-e6fc17c45361','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-04 23:48:07'),(279,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','5467d789-5266-4139-99d3-c8d4e4c10a09','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-05 12:30:39'),(280,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','5467d789-5266-4139-99d3-c8d4e4c10a09','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-05 12:30:39'),(281,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','333561fb-aac4-4b5f-bab1-2417ef24a763','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-05 13:00:56'),(282,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','333561fb-aac4-4b5f-bab1-2417ef24a763','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-05 13:00:56'),(283,3,'logout','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','0693c048-d53e-4f4b-a5f3-ec5f25ae5ac7','{\"email\": \"admin@gnxsoft.com\"}','success',NULL,'2025-12-05 13:07:07'),(284,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','a118fe09-9cd5-45a1-a75e-4b95519971e6','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-05 13:25:12'),(285,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','a118fe09-9cd5-45a1-a75e-4b95519971e6','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-05 13:25:12'),(286,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','9b510577-38a3-48c5-8102-9bf8f4375b04','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-05 13:27:24'),(287,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','9b510577-38a3-48c5-8102-9bf8f4375b04','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-05 13:27:24'),(288,3,'login_mfa_setup_required','authentication',NULL,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0','cc12c821-decd-42c2-98eb-6117abbddb73','{\"email\": \"admin@gnxsoft.com\", \"reason\": \"MFA is required for accountant/admin roles but not enabled\"}','success',NULL,'2025-12-05 14:39:38'),(289,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','cc12c821-decd-42c2-98eb-6117abbddb73','{\"email\": \"admin@gnxsoft.com\", \"remember_me\": false}','success',NULL,'2025-12-05 14:39:38'),(290,3,'gdpr_export_requested','gdpr_request',5,'127.0.0.1','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0',NULL,'{\"email\": \"admin@gnxsoft.com\", \"is_anonymous\": false, \"request_type\": \"data_export\"}','success',NULL,'2025-12-05 14:43:25'); +/*!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

Introduction

\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 \n

1. Book Directly with the Hotel

\n

Booking directly with the hotel often provides better rates, room upgrades, and exclusive perks. Plus, you\'ll have direct communication with the property.

\n \n

2. Join the Loyalty Program

\n

Most hotels offer loyalty programs that provide points, discounts, and special benefits. Sign up before your stay to start earning rewards.

\n \n

3. Communicate Special Requests Early

\n

Whether you need a late checkout, extra pillows, or have dietary restrictions, communicate your needs when booking or at least 24 hours before arrival.

\n \n

4. Check-In Online

\n

Many 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 \n

5. Explore Hotel Amenities

\n

Take 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 \n

6. Be Polite to Staff

\n

A 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 \n

7. Use the Concierge

\n

The concierge can provide local recommendations, make reservations, and help with transportation. They\'re a valuable resource for making your stay memorable.

\n \n

8. Review Your Bill

\n

Before checking out, review your bill carefully. Check for any unexpected charges and ensure all services match what you received.

\n \n

9. Leave a Review

\n

Share your experience by leaving a review. This helps future guests and provides valuable feedback to the hotel.

\n \n

10. Stay Connected

\n

Follow the hotel on social media for special offers, events, and updates. You might discover exclusive deals or experiences.

\n \n

Conclusion

\n

By 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.','\n

Introduction

\n

Luxury 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 \n

Personalized Service

\n

True luxury hotels excel at personalization. From remembering guest preferences to anticipating needs, personalized service creates a sense of being truly valued.

\n \n

Attention to Detail

\n

Every 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 \n

Exceptional Design

\n

Luxury hotels are architectural and design masterpieces. They blend local culture with contemporary elegance, creating spaces that inspire and delight.

\n \n

World-Class Dining

\n

Fine dining is a cornerstone of luxury hospitality. Award-winning restaurants, celebrity chefs, and exceptional culinary experiences define premium hotels.

\n \n

Exclusive Amenities

\n

From private butlers to exclusive spa treatments, luxury hotels offer amenities that go beyond the ordinary, creating unique and memorable experiences.

\n \n

Conclusion

\n

Luxury 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.','\n

Introduction

\n

Sustainable 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 \n

Energy Efficiency

\n

Modern hotels are investing in renewable energy, LED lighting, and smart systems that reduce energy consumption without compromising guest comfort.

\n \n

Water Conservation

\n

From low-flow fixtures to water recycling systems, hotels are finding innovative ways to conserve water while maintaining the luxury experience guests expect.

\n \n

Waste Reduction

\n

Comprehensive recycling programs, composting, and reducing single-use plastics are becoming standard practices in environmentally conscious hotels.

\n \n

Local Sourcing

\n

Supporting local communities through sourcing local products, hiring local staff, and preserving local culture benefits both the environment and the community.

\n \n

Green Certifications

\n

Many hotels are pursuing green certifications like LEED and Green Key, demonstrating their commitment to sustainability and environmental responsibility.

\n \n

Guest Education

\n

Hotels are educating guests about sustainable practices, encouraging participation in conservation efforts, and making it easy to make eco-friendly choices.

\n \n

Conclusion

\n

Sustainable 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',10,'2025-11-28 22:28:27','2025-12-05 13:48:24',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.','\n

Introduction

\n

Understanding 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 \n

Standard Rooms

\n

Standard rooms are the most basic accommodation, typically featuring a bed, bathroom, and essential amenities. Perfect for short stays or budget-conscious travelers.

\n \n

Deluxe Rooms

\n

Deluxe rooms offer more space and upgraded amenities. They often feature better views, larger bathrooms, and additional seating areas.

\n \n

Suites

\n

Suites provide separate living and sleeping areas, making them ideal for longer stays or guests who need extra space for work or relaxation.

\n \n

Presidential Suites

\n

The pinnacle of hotel accommodations, presidential suites offer multiple rooms, premium amenities, and often include butler service and exclusive access.

\n \n

Specialty Rooms

\n

Many hotels offer specialty rooms like honeymoon suites, family rooms, or themed accommodations designed for specific guest needs or occasions.

\n \n

Choosing the Right Room

\n

Consider your needs: space requirements, view preferences, length of stay, and budget. Don\'t hesitate to contact the hotel directly for recommendations.

\n \n

Conclusion

\n

Understanding 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',1,'2025-11-28 22:28:27','2025-12-05 13:05:37',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.','\n

Introduction

\n

Wellness 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 \n

State-of-the-Art Spas

\n

Modern hotel spas offer more than massages. They provide holistic treatments, thermal experiences, and wellness consultations tailored to individual needs.

\n \n

Fitness and Movement

\n

From fully equipped gyms to yoga studios and personal training, hotels are making it easy for guests to maintain their fitness routines while traveling.

\n \n

Healthy Dining Options

\n

Wellness-focused hotels offer nutritious menus, dietary accommodations, and nutritionist consultations, making healthy eating effortless during your stay.

\n \n

Mindfulness and Meditation

\n

Many hotels now offer meditation spaces, mindfulness programs, and stress-reduction activities to help guests find balance and peace.

\n \n

Outdoor Activities

\n

Wellness hotels often provide access to nature, outdoor activities, and adventure experiences that promote physical activity and connection with the environment.

\n \n

Sleep Optimization

\n

Recognizing the importance of rest, wellness hotels focus on sleep quality with premium bedding, blackout curtains, and sleep enhancement programs.

\n \n

Conclusion

\n

Wellness 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.','\n

Introduction

\n

Technology is transforming the hotel industry, making stays more convenient, personalized, and enjoyable. From mobile check-in to smart room controls, innovation is everywhere.

\n \n

Mobile Check-In and Keyless Entry

\n

Guests 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 \n

Smart Room Controls

\n

Voice-activated assistants and smart controls allow guests to adjust lighting, temperature, and entertainment systems with simple commands or mobile apps.

\n \n

Personalized Recommendations

\n

AI-powered systems analyze guest preferences to provide personalized recommendations for dining, activities, and services, enhancing the overall experience.

\n \n

Contactless Services

\n

From contactless payments to digital menus and virtual concierge services, hotels are reducing physical contact while maintaining high service standards.

\n \n

Virtual Reality and Augmented Reality

\n

Some hotels are using VR and AR to provide virtual tours, immersive experiences, and enhanced wayfinding, helping guests explore and navigate properties.

\n \n

Data Analytics

\n

Hotels use data analytics to understand guest behavior, optimize operations, and predict needs, ensuring every stay is better than the last.

\n \n

Conclusion

\n

Technology 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.','\n

Introduction

\n

Modern 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 \n

Spa and Wellness Facilities

\n

Luxury hotels often feature world-class spas offering massages, facials, and holistic treatments. These facilities provide relaxation and rejuvenation during your stay.

\n \n

Fitness Centers

\n

State-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 \n

Swimming Pools

\n

From rooftop infinity pools to heated indoor pools, swimming facilities provide relaxation and recreation. Some hotels offer poolside service and cabanas for ultimate comfort.

\n \n

Dining Options

\n

Fine dining restaurants, casual cafes, room service, and bars create diverse culinary experiences. Many hotels feature award-winning chefs and unique dining concepts.

\n \n

Business Facilities

\n

Business centers, meeting rooms, and conference facilities cater to corporate travelers. High-speed internet and printing services ensure productivity.

\n \n

Concierge Services

\n

Professional concierge teams can arrange restaurant reservations, transportation, tickets, and local experiences, making your stay seamless and memorable.

\n \n

Conclusion

\n

Hotel 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.','\n

Introduction

\n

Business travel requires efficiency and comfort. These tips will help you make the most of your hotel stay while maintaining productivity and well-being.

\n \n

Choose the Right Location

\n

Select hotels close to your meetings or with excellent transportation links. This saves time and reduces stress during your business trip.

\n \n

Leverage Business Services

\n

Take advantage of business centers, meeting rooms, and high-speed internet. Many hotels offer complimentary business services for corporate guests.

\n \n

Maintain Your Routine

\n

Use hotel fitness centers to maintain your exercise routine. Regular workouts help manage stress and maintain energy levels during business trips.

\n \n

Optimize Your Room

\n

Request a quiet room away from elevators and high-traffic areas. Ensure your room has adequate workspace and lighting for productivity.

\n \n

Use Concierge Services

\n

Hotel concierges can handle restaurant reservations, transportation, and local recommendations, freeing your time for business matters.

\n \n

Join Loyalty Programs

\n

Business travelers benefit significantly from hotel loyalty programs, earning points, upgrades, and exclusive perks that enhance every stay.

\n \n

Conclusion

\n

Strategic 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.','\n

Introduction

\n

Traveling with family requires special considerations. Family-friendly hotels offer amenities and services designed to make stays comfortable and enjoyable for all ages.

\n \n

Family Room Options

\n

Look for hotels offering family rooms, suites, or connecting rooms. These provide space for everyone and often include extra beds or pull-out sofas.

\n \n

Kid-Friendly Amenities

\n

Children\'s programs, kids\' clubs, playgrounds, and game rooms keep young guests entertained. Some hotels offer babysitting services for parents\' peace of mind.

\n \n

Dining Options

\n

Family-friendly hotels provide children\'s menus, flexible dining times, and room service options. Buffet breakfasts are particularly convenient for families.

\n \n

Safety Features

\n

Safety 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 \n

Entertainment Facilities

\n

Pools, game rooms, and outdoor spaces provide entertainment for children while allowing parents to relax. Some hotels offer family activities and events.

\n \n

Location Considerations

\n

Choose hotels near family attractions, parks, or beaches. Easy access to activities reduces travel time and keeps children engaged.

\n \n

Conclusion

\n

Family-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.','\n

Introduction

\n

Romantic getaways require special attention to detail. The right hotel can transform a trip into an unforgettable romantic experience.

\n \n

Intimate Settings

\n

Look for hotels with intimate atmospheres, private balconies, and romantic room designs. Boutique hotels often excel at creating romantic environments.

\n \n

Special Packages

\n

Many hotels offer romantic packages including champagne, flowers, couples\' spa treatments, and special dining experiences. These packages add magic to your stay.

\n \n

Scenic Locations

\n

Hotels with stunning views, beachfront locations, or mountain settings create romantic backdrops. Sunsets and scenic vistas enhance the romantic atmosphere.

\n \n

Fine Dining

\n

Romantic restaurants with candlelit dinners, private dining options, and exceptional cuisine create memorable experiences. Room service can also be romantic.

\n \n

Spa and Wellness

\n

Couples\' spa treatments, private hot tubs, and wellness facilities provide relaxation and connection. Many hotels offer romantic spa packages.

\n \n

Privacy and Seclusion

\n

Private villas, secluded rooms, and adults-only areas ensure privacy and intimacy. These features are essential for romantic getaways.

\n \n

Conclusion

\n

The 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.','\n

Introduction

\n

Smart booking strategies can save significant money while securing better rooms and amenities. Learn the secrets to getting the best hotel deals.

\n \n

Book Directly

\n

Booking directly with hotels often provides better rates, room upgrades, and exclusive perks not available through third-party sites.

\n \n

Flexible Dates

\n

Flexibility with travel dates can result in substantial savings. Mid-week stays and off-peak seasons typically offer better rates.

\n \n

Join Loyalty Programs

\n

Hotel loyalty programs provide points, discounts, and member-exclusive rates. Frequent travelers benefit significantly from these programs.

\n \n

Last-Minute Deals

\n

Hotels often offer last-minute deals to fill empty rooms. If you\'re flexible, these can provide excellent value.

\n \n

Package Deals

\n

Bundling hotel stays with flights or activities can result in savings. Compare package prices with individual bookings.

\n \n

Negotiate

\n

Don\'t hesitate to call hotels directly and negotiate rates, especially for longer stays or group bookings. Hotels often have flexibility.

\n \n

Conclusion

\n

Strategic 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.','\n

Introduction

\n

Luxury 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 \n

Ancient Origins

\n

Hospitality dates back to ancient civilizations where travelers found shelter in inns and guesthouses. These early establishments laid the foundation for modern hospitality.

\n \n

Grand Hotels Era

\n

The 19th century saw the rise of grand hotels in Europe and America. These magnificent establishments set new standards for luxury, service, and architecture.

\n \n

Modern Luxury

\n

Today\'s luxury hotels combine traditional elegance with modern amenities, technology, and personalized service. The definition of luxury continues to evolve.

\n \n

Iconic Properties

\n

Legendary hotels like The Ritz, The Savoy, and The Plaza have become symbols of luxury hospitality, setting benchmarks for excellence worldwide.

\n \n

Contemporary Trends

\n

Modern luxury emphasizes experiences, sustainability, wellness, and personalization. Hotels adapt to changing guest expectations while maintaining timeless elegance.

\n \n

Conclusion

\n

The 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.','\n

Introduction

\n

Proper hotel etiquette ensures pleasant experiences for everyone. Understanding expected behavior helps create positive interactions with staff and fellow guests.

\n \n

Check-In and Check-Out

\n

Arrive on time for check-in and respect check-out times. Be patient and courteous with front desk staff, especially during busy periods.

\n \n

Room Behavior

\n

Keep noise levels reasonable, especially during quiet hours. Respect room capacity limits and treat hotel property with care.

\n \n

Staff Interactions

\n

Treat all hotel staff with respect and kindness. A friendly attitude often results in better service and assistance with special requests.

\n \n

Common Areas

\n

Respect shared spaces like lobbies, pools, and restaurants. Follow dress codes, keep areas clean, and be mindful of other guests.

\n \n

Tipping Guidelines

\n

Tip housekeeping, bellhops, and concierge staff appropriately. Tipping shows appreciation for good service and is standard practice.

\n \n

Special Requests

\n

Make special requests in advance when possible. Be reasonable and understanding if requests cannot be accommodated.

\n \n

Conclusion

\n

Good 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.','\n

Introduction

\n

Choosing between boutique and chain hotels depends on your preferences, travel style, and priorities. Each offers distinct advantages.

\n \n

Boutique Hotels

\n

Boutique hotels offer unique character, personalized service, and distinctive design. They provide intimate experiences and local flavor, perfect for travelers seeking authenticity.

\n \n

Chain Hotels

\n

Chain hotels provide consistency, loyalty programs, and predictable experiences. They\'re ideal for business travelers and those who value reliability and familiarity.

\n \n

Service Comparison

\n

Boutique hotels excel in personalized, attentive service, while chains offer standardized, efficient service. Choose based on your preference for customization vs. consistency.

\n \n

Amenities and Facilities

\n

Chain hotels typically offer extensive amenities and facilities, while boutiques focus on curated, high-quality experiences. Consider what matters most to you.

\n \n

Location and Design

\n

Boutique hotels often feature unique, locally-inspired designs in interesting neighborhoods. Chains provide familiar layouts in convenient, predictable locations.

\n \n

Value and Pricing

\n

Both 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 \n

Conclusion

\n

The 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.','\n

Introduction

\n

Accessible hotels ensure comfortable stays for all guests. Understanding accessibility features helps travelers with disabilities find suitable accommodations.

\n \n

Accessible Rooms

\n

Accessible rooms feature wider doorways, roll-in showers, grab bars, and lower fixtures. These rooms meet ADA standards and provide comfort and safety.

\n \n

Common Areas

\n

Accessible hotels provide ramps, elevators, and accessible paths throughout. Restaurants, pools, and facilities should be accessible to all guests.

\n \n

Communication Access

\n

Hotels should offer visual alarms, TTY devices, and staff trained in sign language or communication assistance for guests with hearing impairments.

\n \n

Service Animals

\n

Hotels must accommodate service animals. Understanding policies and communicating needs ensures smooth stays for guests with service animals.

\n \n

Booking Considerations

\n

When booking, specify accessibility needs clearly. Contact hotels directly to confirm specific features and ensure your requirements are met.

\n \n

Staff Training

\n

Well-trained staff understand accessibility needs and can assist effectively. Choose hotels known for excellent accessibility service.

\n \n

Conclusion

\n

Accessible 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.','\n

Introduction

\n

Hotel security is a shared responsibility between guests and hotels. Following security best practices ensures safe, worry-free stays.

\n \n

Room Security

\n

Always lock your room door and use deadbolts. Never leave doors propped open, and verify room numbers before entering. Use room safes for valuables.

\n \n

Valuables Protection

\n

Use 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 \n

Personal Information

\n

Protect personal information. Be cautious with Wi-Fi networks, and avoid sharing room numbers publicly. Use secure payment methods.

\n \n

Hotel Facilities

\n

Be 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 \n

Emergency Procedures

\n

Familiarize yourself with emergency exits and procedures. Know the location of fire exits and emergency contact information.

\n \n

Trust Your Instincts

\n

If something feels wrong, trust your instincts. Report suspicious activity to hotel security immediately. Your safety is the priority.

\n \n

Conclusion

\n

Following 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.','\n

Introduction

\n

Traveling with pets requires special planning. Pet-friendly hotels make it possible to bring your furry friends along, ensuring everyone enjoys the trip.

\n \n

Finding Pet-Friendly Hotels

\n

Research hotels that explicitly welcome pets. Check policies regarding size limits, breed restrictions, and number of pets allowed per room.

\n \n

Pet Amenities

\n

Many pet-friendly hotels offer special amenities like pet beds, bowls, treats, and walking services. Some even have pet spas and play areas.

\n \n

Pet Fees and Policies

\n

Understand pet fees, which can vary significantly. Some hotels charge per night, while others have flat fees. Review cancellation policies for pet-related issues.

\n \n

Pet Etiquette

\n

Keep pets leashed in common areas, clean up after them, and respect other guests. Don\'t leave pets unattended in rooms for extended periods.

\n \n

Preparing Your Pet

\n

Bring familiar items like beds and toys. Ensure pets are well-behaved and up-to-date on vaccinations. Bring necessary documentation.

\n \n

Local Pet Services

\n

Research nearby veterinarians, pet stores, and dog parks. Hotels in pet-friendly areas often provide recommendations and assistance.

\n \n

Conclusion

\n

Pet-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.','\n

Introduction

\n

Hotel concierges are valuable resources for enhancing your stay. Understanding how to work with them unlocks local expertise and exclusive access.

\n \n

What Concierges Offer

\n

Concierges provide restaurant reservations, event tickets, transportation, local recommendations, and assistance with special requests. They\'re your local experts.

\n \n

Restaurant Reservations

\n

Concierges often have relationships with popular restaurants, securing tables at hard-to-book establishments. They know the best local dining options.

\n \n

Local Insights

\n

Tap into concierges\' local knowledge for hidden gems, cultural experiences, and authentic recommendations beyond tourist guides.

\n \n

Special Occasions

\n

Concierges excel at arranging special occasions—anniversaries, proposals, birthdays. They coordinate flowers, cakes, decorations, and surprises.

\n \n

Transportation and Logistics

\n

From airport transfers to car rentals and private drivers, concierges handle transportation needs efficiently and reliably.

\n \n

Building Relationships

\n

Building rapport with concierges through courtesy and clear communication often results in better service and special considerations.

\n \n

Conclusion

\n

Concierge 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.','\n

Introduction

\n

Timing your hotel stay can significantly impact your experience, costs, and enjoyment. Understanding seasonal patterns helps you choose the perfect time to visit.

\n \n

Peak Season

\n

Peak seasons offer ideal weather and full amenities but come with higher prices and crowds. Book well in advance and expect premium rates.

\n \n

Shoulder Season

\n

Shoulder seasons provide a balance of good weather, reasonable prices, and fewer crowds. These periods often offer the best value and experience.

\n \n

Off-Season Benefits

\n

Off-season travel offers significant savings, fewer crowds, and more personalized service. Some amenities may be limited, but value is exceptional.

\n \n

Weather Considerations

\n

Research destination weather patterns. Some locations are beautiful year-round, while others have distinct seasons affecting activities and experiences.

\n \n

Special Events

\n

Consider local festivals, holidays, and events. These can enhance experiences but also increase prices and require early booking.

\n \n

Business vs. Leisure

\n

Business travelers may prefer off-peak times for better rates and availability. Leisure travelers can choose based on weather and activities.

\n \n

Conclusion

\n

Choosing 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.','\n

Introduction

\n

Hotel loyalty programs offer significant value for frequent travelers. Understanding how to maximize these programs enhances every stay with rewards and perks.

\n \n

Choosing the Right Program

\n

Select programs aligned with your travel patterns. Consider hotel locations, frequency of travel, and program benefits that matter most to you.

\n \n

Earning Points

\n

Maximize point earning through direct bookings, credit card partnerships, and promotional offers. Some programs offer bonus points for specific activities.

\n \n

Elite Status Benefits

\n

Elite status provides room upgrades, late checkout, breakfast, and lounge access. Focus on one program to achieve status faster.

\n \n

Point Redemption

\n

Redeem points strategically for maximum value. Award nights, upgrades, and experiences offer different redemption values—choose wisely.

\n \n

Credit Card Partnerships

\n

Hotel-branded credit cards accelerate point earning and provide automatic elite status. Evaluate annual fees against benefits received.

\n \n

Promotions and Bonuses

\n

Take advantage of promotions, bonus point offers, and special events. Sign up for program emails to stay informed about opportunities.

\n \n

Conclusion

\n

Strategic 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.','\n

Introduction

\n

Room service offers convenience and privacy, allowing guests to dine in their rooms. Understanding how to use this service enhances your hotel experience.

\n \n

Menu Options

\n

Room 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 \n

Ordering Process

\n

Order through phone, in-room tablets, or hotel apps. Specify delivery time, special requests, and dietary requirements when ordering.

\n \n

Pricing Considerations

\n

Room service typically includes service charges and delivery fees. Prices are often higher than restaurant dining, but convenience may justify the cost.

\n \n

Timing Your Orders

\n

Order during off-peak hours for faster service. Breakfast orders placed the night before ensure timely morning delivery.

\n \n

Special Requests

\n

Hotels accommodate dietary restrictions, allergies, and special requests. Communicate needs clearly when ordering for best results.

\n \n

Tipping Etiquette

\n

Tip room service staff appropriately, typically 15-20% of the bill. Some hotels include service charges, but additional tips are appreciated.

\n \n

Conclusion

\n

Room 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.','\n

Introduction

\n

Extended stay hotels provide comfortable, convenient accommodations for longer visits. These properties are designed specifically for guests staying weeks or months.

\n \n

Apartment-Style Living

\n

Extended stay hotels offer apartment-like rooms with kitchens, living areas, and separate bedrooms. These features make long stays comfortable and practical.

\n \n

Cost Effectiveness

\n

Extended stay rates are typically lower than traditional hotels for longer periods. Weekly and monthly rates provide significant savings.

\n \n

Home-Like Amenities

\n

Full kitchens, laundry facilities, and larger spaces create home-like environments. These amenities are essential for comfortable extended stays.

\n \n

Location Benefits

\n

Extended stay hotels are often located near business districts, hospitals, or universities, providing convenient access for work or study.

\n \n

Flexible Stays

\n

Flexible booking options accommodate changing schedules. Many properties offer month-to-month arrangements without long-term commitments.

\n \n

Services and Support

\n

Housekeeping, maintenance, and front desk services provide support while maintaining independence. Balance of service and privacy is key.

\n \n

Conclusion

\n

Extended 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.','\n

Introduction

\n

Hotel photography preserves memories and shares experiences. Whether for personal keepsakes or social media, great photos enhance your travel documentation.

\n \n

Room Photography

\n

Capture rooms in natural light, showing key features and ambiance. Include details like views, amenities, and design elements that make the room special.

\n \n

Common Areas

\n

Photograph lobbies, restaurants, and facilities to document the full hotel experience. These spaces often showcase the hotel\'s character and style.

\n \n

Food and Dining

\n

Food photography requires good lighting and composition. Capture presentation, ambiance, and memorable meals to preserve dining experiences.

\n \n

Views and Scenery

\n

Hotel views are often highlights. Capture sunrises, sunsets, and scenic vistas from rooms, balconies, and hotel terraces.

\n \n

Respect and Etiquette

\n

Respect other guests\' privacy when photographing. Avoid photographing staff without permission and follow hotel photography policies.

\n \n

Editing and Sharing

\n

Edit photos to enhance colors and composition while maintaining authenticity. Share thoughtfully, respecting the hotel and other guests.

\n \n

Conclusion

\n

Hotel 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.','\n

Introduction

\n

Eco-friendly hotels combine luxury with environmental responsibility. Choosing sustainable accommodations supports conservation while enjoying comfortable stays.

\n \n

Sustainability Certifications

\n

Look for hotels with recognized certifications like LEED, Green Key, or EarthCheck. These certifications verify genuine environmental commitments.

\n \n

Energy Efficiency

\n

Eco-friendly hotels use renewable energy, efficient systems, and smart technology to reduce energy consumption without compromising comfort.

\n \n

Water Conservation

\n

Sustainable hotels implement water-saving measures, recycling systems, and responsible water management practices throughout their operations.

\n \n

Waste Reduction

\n

Comprehensive recycling, composting, and waste reduction programs minimize environmental impact. Some hotels eliminate single-use plastics entirely.

\n \n

Local Sourcing

\n

Sustainable hotels source locally, supporting communities and reducing transportation impacts. Local food, materials, and services benefit everyone.

\n \n

Guest Participation

\n

Eco-friendly hotels encourage guest participation through towel reuse programs, energy conservation, and educational initiatives about sustainability.

\n \n

Conclusion

\n

Choosing 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.','\n

Introduction

\n

Well-written hotel reviews help travelers make informed decisions and provide valuable feedback to hotels. Learning to write effective reviews benefits everyone.

\n \n

Be Specific

\n

Provide specific details about your experience—room features, service interactions, amenities used. Specific information is more helpful than general statements.

\n \n

Balance Positives and Negatives

\n

Honest reviews include both positive aspects and areas for improvement. Balanced perspectives help readers understand the full experience.

\n \n

Focus on Facts

\n

Stick to factual observations about your stay. Avoid speculation or assumptions about things you didn\'t directly experience.

\n \n

Consider Context

\n

Mention relevant context—travel purpose, time of year, special occasions. This helps readers understand if your experience applies to their situation.

\n \n

Be Respectful

\n

Write respectfully, even when reporting negative experiences. Constructive criticism is more valuable than harsh complaints.

\n \n

Include Photos

\n

Photos enhance reviews significantly, showing actual conditions and experiences. Include images of rooms, amenities, and notable features.

\n \n

Conclusion

\n

Helpful 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.','\n

Introduction

\n

Reliable hotel Wi-Fi is essential for modern travelers. Understanding Wi-Fi options and how to optimize connections ensures productivity and connectivity.

\n \n

Wi-Fi Tiers

\n

Many hotels offer multiple Wi-Fi tiers—basic free service and premium high-speed options. Choose based on your needs and usage.

\n \n

Connection Tips

\n

Position devices near routers, avoid peak usage times, and disconnect unused devices. These simple steps improve connection quality.

\n \n

Security Considerations

\n

Use hotel Wi-Fi cautiously. Avoid sensitive transactions on public networks. Consider VPN services for enhanced security when traveling.

\n \n

Business Travel Needs

\n

Business travelers may need premium Wi-Fi for video calls and large file transfers. Verify speeds and reliability before booking.

\n \n

Troubleshooting

\n

Hotel IT support can assist with connection issues. Don\'t hesitate to contact them for help with Wi-Fi problems.

\n \n

Alternative Options

\n

Mobile hotspots and data plans provide alternatives to hotel Wi-Fi. Consider these options for critical connectivity needs.

\n \n

Conclusion

\n

Understanding 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.','\n

Introduction

\n

Hotel breakfasts set the tone for your day. Understanding options and making the most of breakfast services enhances your stay experience.

\n \n

Breakfast Types

\n

Hotels offer various breakfast options—continental, buffet, à la carte, and room service. Each provides different experiences and value.

\n \n

Buffet Benefits

\n

Breakfast buffets offer variety and value, allowing you to sample different items and eat as much as you like. They\'re perfect for families.

\n \n

Timing Considerations

\n

Breakfast service hours vary. Early risers and late sleepers should check times. Some hotels offer extended or 24-hour breakfast options.

\n \n

Dietary Accommodations

\n

Hotels accommodate dietary restrictions, allergies, and preferences. Communicate needs in advance for best results.

\n \n

Included vs. Paid

\n

Some hotels include breakfast in rates, while others charge separately. Compare total costs when evaluating hotel options.

\n \n

Local Specialties

\n

Hotel breakfasts often feature local specialties, providing cultural experiences and authentic flavors of the destination.

\n \n

Conclusion

\n

Hotel 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.','\n

Introduction

\n

Hotel pools provide relaxation and recreation. Understanding pool facilities and etiquette ensures enjoyable experiences for all guests.

\n \n

Pool Types

\n

Hotels offer various pool types—outdoor, indoor, rooftop, infinity, and heated pools. Each provides unique experiences and benefits.

\n \n

Poolside Service

\n

Many hotels offer poolside service for food and beverages. Enjoy meals and drinks without leaving the pool area.

\n \n

Pool Etiquette

\n

Respect other guests, follow pool rules, and maintain cleanliness. Proper etiquette ensures pleasant experiences for everyone.

\n \n

Family Considerations

\n

Family-friendly pools often have shallow areas, lifeguards, and children\'s activities. Some hotels offer separate adult pools for quiet relaxation.

\n \n

Pool Hours

\n

Check pool operating hours, which may vary by season or day. Some pools offer extended hours or 24-hour access.

\n \n

Pool Amenities

\n

Hotels may offer pool amenities like cabanas, loungers, towels, and changing facilities. Inquire about available services.

\n \n

Conclusion

\n

Hotel 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.','\n

Introduction

\n

Hotel spas provide sanctuary for relaxation and rejuvenation. Understanding spa offerings helps you choose treatments and maximize your experience.

\n \n

Spa Treatments

\n

Hotel spas offer diverse treatments—massages, facials, body wraps, and holistic therapies. Each addresses different wellness needs.

\n \n

Booking Considerations

\n

Book spa appointments in advance, especially for popular treatments and peak times. Early booking ensures preferred times and availability.

\n \n

Treatment Packages

\n

Many spas offer packages combining multiple treatments at discounted rates. Packages provide comprehensive wellness experiences.

\n \n

Spa Facilities

\n

Hotel spas often include saunas, steam rooms, hot tubs, and relaxation areas. Arrive early to enjoy these facilities before treatments.

\n \n

Wellness Programs

\n

Some hotel spas offer comprehensive wellness programs including fitness, nutrition, and mindfulness components for holistic health.

\n \n

Couples Experiences

\n

Couples\' treatments and private spa suites create romantic, intimate experiences perfect for special occasions or getaways.

\n \n

Conclusion

\n

Hotel 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.','\n

Introduction

\n

Hotel bars and lounges provide sophisticated settings for evening entertainment, socializing, and enjoying craft beverages in elegant atmospheres.

\n \n

Cocktail Culture

\n

Hotel bars often feature expert mixologists creating craft cocktails with premium ingredients. These establishments showcase beverage artistry.

\n \n

Atmosphere and Design

\n

Hotel bars create distinct atmospheres through design, lighting, and music. From rooftop bars to speakeasies, each offers unique experiences.

\n \n

Live Entertainment

\n

Many hotel bars feature live music, DJs, or entertainment. These elements enhance evening experiences and create memorable nights.

\n \n

Bar Food

\n

Hotel bars often serve excellent bar food, from small plates to full meals. Quality food complements beverage experiences.

\n \n

Social Spaces

\n

Bars and lounges serve as social hubs, perfect for meeting other travelers, business networking, or simply relaxing after a day of activities.

\n \n

Rooftop Experiences

\n

Rooftop bars offer stunning views and unique atmospheres. These elevated spaces provide exceptional evening experiences.

\n \n

Conclusion

\n

Hotel 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.','\n

Introduction

\n

Hotel fitness centers allow travelers to maintain exercise routines while away from home. Modern facilities provide comprehensive workout options.

\n \n

Equipment Quality

\n

Hotel fitness centers vary in equipment quality and variety. Premium hotels offer state-of-the-art equipment matching commercial gyms.

\n \n

Operating Hours

\n

Many hotel fitness centers offer 24-hour access, accommodating early risers and late-night exercisers. Check hours when booking.

\n \n

Group Classes

\n

Some hotels offer fitness classes like yoga, Pilates, or spinning. These classes provide structured workouts and social interaction.

\n \n

Personal Training

\n

Premium hotels may offer personal training services. These sessions provide personalized guidance and motivation during your stay.

\n \n

Outdoor Options

\n

Hotels in scenic locations may offer outdoor fitness options like running trails, tennis courts, or water sports facilities.

\n \n

Wellness Integration

\n

Fitness centers often integrate with hotel spas and wellness programs, providing comprehensive health and fitness experiences.

\n \n

Conclusion

\n

Hotel 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.','\n

Introduction

\n

Hotel meeting spaces provide professional settings for business events, conferences, and social gatherings. Understanding options ensures successful events.

\n \n

Space Types

\n

Hotels offer various meeting spaces—boardrooms, ballrooms, conference halls, and breakout rooms. Each serves different event types and sizes.

\n \n

Technology and Equipment

\n

Modern meeting spaces include AV equipment, high-speed internet, video conferencing, and presentation technology. Verify available equipment when booking.

\n \n

Catering Services

\n

Hotel catering provides meals, breaks, and beverages for events. Professional catering ensures quality food service throughout your event.

\n \n

Event Planning Support

\n

Hotel event coordinators assist with planning, setup, and execution. Their expertise ensures smooth, professional events.

\n \n

Flexible Configurations

\n

Meeting spaces can be configured for various setups—theater, classroom, banquet, or boardroom styles. Choose configurations matching your needs.

\n \n

Accommodation Packages

\n

Hotels often offer packages combining meeting spaces with guest rooms, providing convenience and value for event attendees.

\n \n

Conclusion

\n

Hotel 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 AUTO_INCREMENT=2 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 */; +INSERT INTO `campaign_segments` VALUES (1,'Newsletter Subscribers','Users who have subscribed to the newsletter','{\"subscribed\": true}',1,'2025-12-05 13:34:23',1,NULL,'2025-12-05 13:18:34','2025-12-05 13:34:23'); +/*!40000 ALTER TABLE `campaign_segments` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `chart_of_accounts` +-- + +DROP TABLE IF EXISTS `chart_of_accounts`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `chart_of_accounts` ( + `id` int NOT NULL AUTO_INCREMENT, + `account_code` varchar(20) NOT NULL, + `account_name` varchar(255) NOT NULL, + `account_type` enum('asset','liability','equity','revenue','expense','cogs') NOT NULL, + `account_category` enum('current_assets','fixed_assets','current_liabilities','long_term_liabilities','equity','retained_earnings','operating_revenue','other_revenue','operating_expenses','cogs','other_expenses') DEFAULT NULL, + `description` text, + `parent_account_id` int DEFAULT NULL, + `is_active` varchar(10) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_chart_of_accounts_account_code` (`account_code`), + KEY `parent_account_id` (`parent_account_id`), + KEY `ix_chart_of_accounts_id` (`id`), + KEY `idx_chart_of_accounts_category` (`account_category`,`is_active`), + KEY `ix_chart_of_accounts_account_type` (`account_type`), + KEY `ix_chart_of_accounts_account_category` (`account_category`), + KEY `idx_chart_of_accounts_type` (`account_type`,`is_active`), + CONSTRAINT `chart_of_accounts_ibfk_1` FOREIGN KEY (`parent_account_id`) REFERENCES `chart_of_accounts` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `chart_of_accounts` +-- + +LOCK TABLES `chart_of_accounts` WRITE; +/*!40000 ALTER TABLE `chart_of_accounts` DISABLE KEYS */; +/*!40000 ALTER TABLE `chart_of_accounts` 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=4 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'),(2,3,'Administrator','admin@gnxsoft.com',NULL,'closed','2025-12-05 12:35:16','2025-12-05 12:35:22','2025-12-05 12:35:22'),(3,3,'Administrator','admin@gnxsoft.com',NULL,'closed','2025-12-05 12:35:31','2025-12-05 12:35:38','2025-12-05 12:35:38'); +/*!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=5 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 */; +INSERT INTO `complaint_updates` VALUES (3,2,'status_change','Complaint created: test',5,'2025-12-04 20:42:18','{\"status\": \"open\", \"priority\": \"urgent\"}'),(4,2,'status_change','Status changed from open to in_progress',4,'2025-12-04 20:42:48',NULL); +/*!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, + `recipient_type` varchar(50) DEFAULT 'users', + 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 `financial_approvals` +-- + +DROP TABLE IF EXISTS `financial_approvals`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `financial_approvals` ( + `id` int NOT NULL AUTO_INCREMENT, + `action_type` enum('large_refund','payment_status_override','invoice_write_off','large_discount','tax_rate_change','manual_payment_adjustment') NOT NULL, + `action_description` text NOT NULL, + `status` enum('pending','approved','rejected','cancelled') NOT NULL, + `payment_id` int DEFAULT NULL, + `invoice_id` int DEFAULT NULL, + `booking_id` int DEFAULT NULL, + `amount` decimal(10,2) DEFAULT NULL, + `previous_value` json DEFAULT NULL, + `new_value` json DEFAULT NULL, + `requested_by` int NOT NULL, + `requested_by_email` varchar(255) DEFAULT NULL, + `request_reason` text, + `approved_by` int DEFAULT NULL, + `approved_by_email` varchar(255) DEFAULT NULL, + `approval_notes` text, + `approved_at` datetime DEFAULT NULL, + `rejected_by` int DEFAULT NULL, + `rejection_reason` text, + `rejected_at` datetime DEFAULT NULL, + `approval_metadata` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `rejected_by` (`rejected_by`), + KEY `ix_financial_approvals_id` (`id`), + KEY `ix_financial_approvals_invoice_id` (`invoice_id`), + KEY `ix_financial_approvals_status` (`status`), + KEY `idx_financial_approval_approver` (`approved_by`,`created_at`), + KEY `ix_financial_approvals_payment_id` (`payment_id`), + KEY `ix_financial_approvals_created_at` (`created_at`), + KEY `ix_financial_approvals_action_type` (`action_type`), + KEY `ix_financial_approvals_approved_by` (`approved_by`), + KEY `ix_financial_approvals_requested_by` (`requested_by`), + KEY `idx_financial_approval_status` (`status`,`created_at`), + KEY `ix_financial_approvals_booking_id` (`booking_id`), + KEY `idx_financial_approval_action` (`action_type`,`status`), + KEY `idx_financial_approval_requester` (`requested_by`,`status`), + CONSTRAINT `financial_approvals_ibfk_1` FOREIGN KEY (`payment_id`) REFERENCES `payments` (`id`), + CONSTRAINT `financial_approvals_ibfk_2` FOREIGN KEY (`invoice_id`) REFERENCES `invoices` (`id`), + CONSTRAINT `financial_approvals_ibfk_3` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `financial_approvals_ibfk_4` FOREIGN KEY (`requested_by`) REFERENCES `users` (`id`), + CONSTRAINT `financial_approvals_ibfk_5` FOREIGN KEY (`approved_by`) REFERENCES `users` (`id`), + CONSTRAINT `financial_approvals_ibfk_6` FOREIGN KEY (`rejected_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 `financial_approvals` +-- + +LOCK TABLES `financial_approvals` WRITE; +/*!40000 ALTER TABLE `financial_approvals` DISABLE KEYS */; +/*!40000 ALTER TABLE `financial_approvals` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `financial_audit_trail` +-- + +DROP TABLE IF EXISTS `financial_audit_trail`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `financial_audit_trail` ( + `id` int NOT NULL AUTO_INCREMENT, + `action_type` enum('payment_created','payment_completed','payment_refunded','payment_failed','invoice_created','invoice_updated','invoice_paid','refund_processed','price_modified','discount_applied','promotion_applied') NOT NULL, + `action_description` text NOT NULL, + `payment_id` int DEFAULT NULL, + `invoice_id` int DEFAULT NULL, + `booking_id` int DEFAULT NULL, + `amount` decimal(10,2) DEFAULT NULL, + `previous_amount` decimal(10,2) DEFAULT NULL, + `currency` varchar(3) DEFAULT 'USD', + `performed_by` int NOT NULL, + `performed_by_email` varchar(255) DEFAULT NULL, + `audit_metadata` json DEFAULT NULL, + `notes` text, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `ix_financial_audit_trail_id` (`id`), + KEY `ix_financial_audit_trail_action_type` (`action_type`), + KEY `ix_financial_audit_trail_payment_id` (`payment_id`), + KEY `ix_financial_audit_trail_invoice_id` (`invoice_id`), + KEY `ix_financial_audit_trail_booking_id` (`booking_id`), + KEY `ix_financial_audit_trail_performed_by` (`performed_by`), + KEY `ix_financial_audit_trail_created_at` (`created_at`), + KEY `idx_financial_audit_created` (`created_at`), + KEY `idx_financial_audit_action` (`action_type`,`created_at`), + KEY `idx_financial_audit_user` (`performed_by`,`created_at`), + KEY `idx_financial_audit_booking` (`booking_id`,`created_at`), + CONSTRAINT `fk_financial_audit_booking` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `fk_financial_audit_invoice` FOREIGN KEY (`invoice_id`) REFERENCES `invoices` (`id`), + CONSTRAINT `fk_financial_audit_payment` FOREIGN KEY (`payment_id`) REFERENCES `payments` (`id`), + CONSTRAINT `fk_financial_audit_user` FOREIGN KEY (`performed_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 `financial_audit_trail` +-- + +LOCK TABLES `financial_audit_trail` WRITE; +/*!40000 ALTER TABLE `financial_audit_trail` DISABLE KEYS */; +/*!40000 ALTER TABLE `financial_audit_trail` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `fiscal_periods` +-- + +DROP TABLE IF EXISTS `fiscal_periods`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `fiscal_periods` ( + `id` int NOT NULL AUTO_INCREMENT, + `period_name` varchar(50) NOT NULL, + `period_type` varchar(20) NOT NULL, + `start_date` datetime NOT NULL, + `end_date` datetime NOT NULL, + `status` enum('open','closed','locked') NOT NULL, + `is_current` tinyint(1) NOT NULL, + `closed_by` int DEFAULT NULL, + `closed_at` datetime DEFAULT NULL, + `notes` varchar(500) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_fiscal_periods_period_name` (`period_name`), + KEY `ix_fiscal_periods_status` (`status`), + KEY `idx_fiscal_period_status` (`status`,`is_current`), + KEY `ix_fiscal_periods_is_current` (`is_current`), + KEY `idx_fiscal_period_dates` (`start_date`,`end_date`), + KEY `ix_fiscal_periods_start_date` (`start_date`), + KEY `ix_fiscal_periods_id` (`id`), + KEY `ix_fiscal_periods_end_date` (`end_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `fiscal_periods` +-- + +LOCK TABLES `fiscal_periods` WRITE; +/*!40000 ALTER TABLE `fiscal_periods` DISABLE KEYS */; +/*!40000 ALTER TABLE `fiscal_periods` 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=6 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=3 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 */; +INSERT INTO `guest_complaints` VALUES (2,5,56,NULL,'room_quality','urgent','in_progress','test','iyggygyiggiu',NULL,NULL,NULL,NULL,NULL,'2025-12-04 20:42:18','2025-12-04 20:42:48',NULL,NULL,NULL,NULL,'[]',0,NULL,0); +/*!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_requests` +-- + +DROP TABLE IF EXISTS `guest_requests`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `guest_requests` ( + `id` int NOT NULL AUTO_INCREMENT, + `booking_id` int NOT NULL, + `room_id` int NOT NULL, + `user_id` int NOT NULL, + `request_type` enum('extra_towels','extra_pillows','room_cleaning','turndown_service','amenities','maintenance','room_service','other') NOT NULL, + `status` enum('pending','in_progress','fulfilled','cancelled') NOT NULL, + `priority` enum('low','normal','high','urgent') NOT NULL, + `title` varchar(255) NOT NULL, + `description` text, + `assigned_to` int DEFAULT NULL, + `fulfilled_by` int DEFAULT NULL, + `requested_at` datetime NOT NULL, + `started_at` datetime DEFAULT NULL, + `fulfilled_at` datetime DEFAULT NULL, + `guest_notes` text, + `staff_notes` text, + `response_time_minutes` int DEFAULT NULL, + `fulfillment_time_minutes` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `user_id` (`user_id`), + KEY `assigned_to` (`assigned_to`), + KEY `fulfilled_by` (`fulfilled_by`), + KEY `ix_guest_requests_requested_at` (`requested_at`), + KEY `ix_guest_requests_booking_id` (`booking_id`), + KEY `ix_guest_requests_id` (`id`), + KEY `ix_guest_requests_room_id` (`room_id`), + CONSTRAINT `guest_requests_ibfk_1` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `guest_requests_ibfk_2` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`id`), + CONSTRAINT `guest_requests_ibfk_3` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `guest_requests_ibfk_4` FOREIGN KEY (`assigned_to`) REFERENCES `users` (`id`), + CONSTRAINT `guest_requests_ibfk_5` FOREIGN KEY (`fulfilled_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 `guest_requests` +-- + +LOCK TABLES `guest_requests` WRITE; +/*!40000 ALTER TABLE `guest_requests` DISABLE KEYS */; +/*!40000 ALTER TABLE `guest_requests` 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, + `photos` json DEFAULT 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=20 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',NULL),(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',NULL),(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',NULL),(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',NULL),(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',NULL),(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',NULL),(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',NULL),(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',NULL),(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',NULL),(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',NULL),(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',NULL),(12,21,NULL,'vacant','completed','2025-12-03 20:37:21','2025-12-03 20:37:21','2025-12-03 20:37:35',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-03 20:37:21','2025-12-03 20:37:35',NULL),(13,2,NULL,'vacant','completed','2025-12-03 20:59:46','2025-12-03 20:59:46','2025-12-03 20:59:56',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-03 20:59:46','2025-12-03 20:59:56',NULL),(14,4,NULL,'vacant','completed','2025-12-03 22:15:30','2025-12-03 22:15:33','2025-12-03 22:16:20',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-03 22:15:33','2025-12-03 22:16:20','[\"/uploads/housekeeping/housekeeping_task_14_4dc37729.png\"]'),(15,37,NULL,'vacant','completed','2025-12-04 18:05:35','2025-12-04 18:05:35','2025-12-04 18:05:38',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-04 18:05:35','2025-12-04 18:05:38',NULL),(16,23,NULL,'vacant','completed','2025-12-04 18:05:42','2025-12-04 18:05:42','2025-12-04 18:05:44',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-04 18:05:42','2025-12-04 18:05:44',NULL),(17,43,NULL,'vacant','completed','2025-12-04 18:05:44','2025-12-04 18:05:44','2025-12-04 18:05:48',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-04 18:05:44','2025-12-04 18:05:48',NULL),(18,48,NULL,'vacant','completed','2025-12-04 18:05:49','2025-12-04 18:05:49','2025-12-04 18:05:52',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-04 18:05:49','2025-12-04 18:05:52',NULL),(19,45,NULL,'vacant','completed','2025-12-04 18:05:52','2025-12-04 18:05:52','2025-12-04 18:05:54',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-04 18:05:52','2025-12-04 18:05:54',NULL); +/*!40000 ALTER TABLE `housekeeping_tasks` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `inventory_items` +-- + +DROP TABLE IF EXISTS `inventory_items`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `inventory_items` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `description` text, + `category` enum('cleaning_supplies','linens','toiletries','amenities','maintenance','food_beverage','other') NOT NULL, + `unit` enum('piece','box','bottle','roll','pack','liter','kilogram','meter','other') NOT NULL, + `current_quantity` decimal(10,2) NOT NULL, + `minimum_quantity` decimal(10,2) NOT NULL, + `maximum_quantity` decimal(10,2) DEFAULT NULL, + `reorder_quantity` decimal(10,2) DEFAULT NULL, + `unit_cost` decimal(10,2) DEFAULT NULL, + `supplier` varchar(255) DEFAULT NULL, + `supplier_contact` text, + `storage_location` varchar(255) DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `is_tracked` tinyint(1) NOT NULL, + `barcode` varchar(100) DEFAULT NULL, + `sku` varchar(100) DEFAULT NULL, + `notes` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `created_by` int DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_inventory_items_barcode` (`barcode`), + UNIQUE KEY `ix_inventory_items_sku` (`sku`), + KEY `created_by` (`created_by`), + KEY `ix_inventory_items_id` (`id`), + KEY `ix_inventory_items_name` (`name`), + CONSTRAINT `inventory_items_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 `inventory_items` +-- + +LOCK TABLES `inventory_items` WRITE; +/*!40000 ALTER TABLE `inventory_items` DISABLE KEYS */; +/*!40000 ALTER TABLE `inventory_items` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `inventory_reorder_requests` +-- + +DROP TABLE IF EXISTS `inventory_reorder_requests`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `inventory_reorder_requests` ( + `id` int NOT NULL AUTO_INCREMENT, + `item_id` int NOT NULL, + `requested_quantity` decimal(10,2) NOT NULL, + `current_quantity` decimal(10,2) NOT NULL, + `minimum_quantity` decimal(10,2) NOT NULL, + `status` enum('pending','approved','ordered','received','cancelled') NOT NULL, + `priority` varchar(20) NOT NULL, + `requested_by` int NOT NULL, + `requested_at` datetime NOT NULL, + `notes` text, + `approved_by` int DEFAULT NULL, + `approved_at` datetime DEFAULT NULL, + `approval_notes` text, + `order_number` varchar(100) DEFAULT NULL, + `expected_delivery_date` datetime DEFAULT NULL, + `received_quantity` decimal(10,2) DEFAULT NULL, + `received_at` datetime DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `requested_by` (`requested_by`), + KEY `approved_by` (`approved_by`), + KEY `ix_inventory_reorder_requests_order_number` (`order_number`), + KEY `ix_inventory_reorder_requests_id` (`id`), + KEY `ix_inventory_reorder_requests_item_id` (`item_id`), + KEY `ix_inventory_reorder_requests_requested_at` (`requested_at`), + CONSTRAINT `inventory_reorder_requests_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `inventory_items` (`id`), + CONSTRAINT `inventory_reorder_requests_ibfk_2` FOREIGN KEY (`requested_by`) REFERENCES `users` (`id`), + CONSTRAINT `inventory_reorder_requests_ibfk_3` FOREIGN KEY (`approved_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 `inventory_reorder_requests` +-- + +LOCK TABLES `inventory_reorder_requests` WRITE; +/*!40000 ALTER TABLE `inventory_reorder_requests` DISABLE KEYS */; +/*!40000 ALTER TABLE `inventory_reorder_requests` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `inventory_task_consumptions` +-- + +DROP TABLE IF EXISTS `inventory_task_consumptions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `inventory_task_consumptions` ( + `id` int NOT NULL AUTO_INCREMENT, + `task_id` int NOT NULL, + `item_id` int NOT NULL, + `quantity` decimal(10,2) NOT NULL, + `notes` text, + `recorded_by` int DEFAULT NULL, + `recorded_at` datetime NOT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `recorded_by` (`recorded_by`), + KEY `ix_inventory_task_consumptions_task_id` (`task_id`), + KEY `ix_inventory_task_consumptions_id` (`id`), + KEY `ix_inventory_task_consumptions_recorded_at` (`recorded_at`), + KEY `ix_inventory_task_consumptions_item_id` (`item_id`), + CONSTRAINT `inventory_task_consumptions_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `housekeeping_tasks` (`id`), + CONSTRAINT `inventory_task_consumptions_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `inventory_items` (`id`), + CONSTRAINT `inventory_task_consumptions_ibfk_3` FOREIGN KEY (`recorded_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 `inventory_task_consumptions` +-- + +LOCK TABLES `inventory_task_consumptions` WRITE; +/*!40000 ALTER TABLE `inventory_task_consumptions` DISABLE KEYS */; +/*!40000 ALTER TABLE `inventory_task_consumptions` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `inventory_transactions` +-- + +DROP TABLE IF EXISTS `inventory_transactions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `inventory_transactions` ( + `id` int NOT NULL AUTO_INCREMENT, + `item_id` int NOT NULL, + `transaction_type` enum('consumption','adjustment','received','transfer','damaged','returned') NOT NULL, + `quantity` decimal(10,2) NOT NULL, + `quantity_before` decimal(10,2) NOT NULL, + `quantity_after` decimal(10,2) NOT NULL, + `reference_type` varchar(50) DEFAULT NULL, + `reference_id` int DEFAULT NULL, + `notes` text, + `cost` decimal(10,2) DEFAULT NULL, + `performed_by` int DEFAULT NULL, + `transaction_date` datetime NOT NULL, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `performed_by` (`performed_by`), + KEY `ix_inventory_transactions_item_id` (`item_id`), + KEY `ix_inventory_transactions_reference_id` (`reference_id`), + KEY `ix_inventory_transactions_transaction_date` (`transaction_date`), + KEY `ix_inventory_transactions_id` (`id`), + CONSTRAINT `inventory_transactions_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `inventory_items` (`id`), + CONSTRAINT `inventory_transactions_ibfk_2` FOREIGN KEY (`performed_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 `inventory_transactions` +-- + +LOCK TABLES `inventory_transactions` WRITE; +/*!40000 ALTER TABLE `inventory_transactions` DISABLE KEYS */; +/*!40000 ALTER TABLE `inventory_transactions` 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=6 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 */; +INSERT INTO `invoice_items` VALUES (3,3,'Room: 237 - Superior Room (3 nights)',3.00,234.39,10.00,0.00,703.17,37,NULL,'2025-12-04 09:49:49'),(4,4,'Room: 343 - Superior Room (4 nights)',4.00,236.67,10.00,0.00,946.68,43,NULL,'2025-12-04 09:50:58'),(5,5,'Room: 343 - Superior Room (4 nights)',4.00,236.67,10.00,0.00,946.68,43,NULL,'2025-12-04 09:52:05'); +/*!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=6 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 */; +INSERT INTO `invoices` VALUES (3,'INV-20251204-0001',51,7,'2025-12-04 09:49:49','2026-01-03 09:49:49',NULL,703.17,10.00,70.32,0.00,773.49,0.00,773.49,'draft',0,'Luxury Hotel','123 Luxury Avenue, Premium District, City 12345, Country','+1 (555) 123-4567','info@luxuryhotel.com',NULL,'/uploads/company/logo.png','Jane Smith','jane.smith@gnxsoft.com',NULL,'+1 (555) 666-7777',NULL,NULL,NULL,NULL,4,NULL,'2025-12-04 09:49:49','2025-12-04 09:49:49'),(4,'INV-20251204-0002',53,7,'2025-12-04 09:50:58','2026-01-03 09:50:58',NULL,946.68,10.00,94.67,0.00,1041.35,0.00,1041.35,'draft',0,'Luxury Hotel','123 Luxury Avenue, Premium District, City 12345, Country','+1 (555) 123-4567','info@luxuryhotel.com',NULL,'/uploads/company/logo.png','Jane Smith','jane.smith@gnxsoft.com',NULL,'+1 (555) 666-7777',NULL,NULL,NULL,NULL,4,NULL,'2025-12-04 09:50:58','2025-12-04 09:50:58'),(5,'INV-20251204-0003',53,7,'2025-12-04 09:52:05','2026-01-03 09:52:05',NULL,946.68,10.00,94.67,0.00,1041.35,0.00,1041.35,'draft',0,'Luxury Hotel','123 Luxury Avenue, Premium District, City 12345, Country','+1 (555) 123-4567','info@luxuryhotel.com',NULL,'/uploads/company/logo.png','Jane Smith','jane.smith@gnxsoft.com',NULL,'+1 (555) 666-7777',NULL,NULL,NULL,NULL,4,NULL,'2025-12-04 09:52:05','2025-12-04 09:52:05'); +/*!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 `journal_entries` +-- + +DROP TABLE IF EXISTS `journal_entries`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `journal_entries` ( + `id` int NOT NULL AUTO_INCREMENT, + `entry_number` varchar(50) NOT NULL, + `entry_date` datetime NOT NULL, + `status` enum('draft','posted','reversed') NOT NULL, + `fiscal_period_id` int NOT NULL, + `reference_type` varchar(50) DEFAULT NULL, + `reference_id` int DEFAULT NULL, + `description` text NOT NULL, + `notes` text, + `created_by` int NOT NULL, + `posted_by` int DEFAULT NULL, + `posted_at` datetime DEFAULT NULL, + `reversed_by` int DEFAULT NULL, + `reversed_at` datetime DEFAULT NULL, + `reversal_reason` text, + `original_entry_id` int DEFAULT NULL, + `entry_metadata` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_journal_entries_entry_number` (`entry_number`), + KEY `created_by` (`created_by`), + KEY `posted_by` (`posted_by`), + KEY `reversed_by` (`reversed_by`), + KEY `original_entry_id` (`original_entry_id`), + KEY `ix_journal_entries_fiscal_period_id` (`fiscal_period_id`), + KEY `idx_journal_entry_date` (`entry_date`,`status`), + KEY `ix_journal_entries_entry_date` (`entry_date`), + KEY `ix_journal_entries_created_at` (`created_at`), + KEY `idx_journal_entry_reference` (`reference_type`,`reference_id`), + KEY `ix_journal_entries_id` (`id`), + KEY `idx_journal_entry_period` (`fiscal_period_id`,`status`), + KEY `ix_journal_entries_status` (`status`), + KEY `ix_journal_entries_reference_id` (`reference_id`), + CONSTRAINT `journal_entries_ibfk_1` FOREIGN KEY (`fiscal_period_id`) REFERENCES `fiscal_periods` (`id`), + CONSTRAINT `journal_entries_ibfk_2` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`), + CONSTRAINT `journal_entries_ibfk_3` FOREIGN KEY (`posted_by`) REFERENCES `users` (`id`), + CONSTRAINT `journal_entries_ibfk_4` FOREIGN KEY (`reversed_by`) REFERENCES `users` (`id`), + CONSTRAINT `journal_entries_ibfk_5` FOREIGN KEY (`original_entry_id`) REFERENCES `journal_entries` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `journal_entries` +-- + +LOCK TABLES `journal_entries` WRITE; +/*!40000 ALTER TABLE `journal_entries` DISABLE KEYS */; +/*!40000 ALTER TABLE `journal_entries` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `journal_lines` +-- + +DROP TABLE IF EXISTS `journal_lines`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `journal_lines` ( + `id` int NOT NULL AUTO_INCREMENT, + `journal_entry_id` int NOT NULL, + `line_number` int NOT NULL, + `account_id` int NOT NULL, + `debit_amount` decimal(10,2) DEFAULT NULL, + `credit_amount` decimal(10,2) DEFAULT NULL, + `description` text, + `created_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `journal_entry_id` (`journal_entry_id`), + KEY `account_id` (`account_id`), + CONSTRAINT `journal_lines_ibfk_1` FOREIGN KEY (`journal_entry_id`) REFERENCES `journal_entries` (`id`), + CONSTRAINT `journal_lines_ibfk_2` FOREIGN KEY (`account_id`) REFERENCES `chart_of_accounts` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `journal_lines` +-- + +LOCK TABLES `journal_lines` WRITE; +/*!40000 ALTER TABLE `journal_lines` DISABLE KEYS */; +/*!40000 ALTER TABLE `journal_lines` 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 `newsletter_subscribers` +-- + +DROP TABLE IF EXISTS `newsletter_subscribers`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `newsletter_subscribers` ( + `id` int NOT NULL AUTO_INCREMENT, + `email` varchar(255) NOT NULL, + `user_id` int DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `subscribed_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `is_active` tinyint(1) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_newsletter_subscribers_email` (`email`), + KEY `ix_newsletter_subscribers_subscribed_at` (`subscribed_at`), + KEY `ix_newsletter_subscribers_user_id` (`user_id`), + KEY `ix_newsletter_subscribers_is_active` (`is_active`), + KEY `ix_newsletter_subscribers_id` (`id`), + CONSTRAINT `newsletter_subscribers_ibfk_1` FOREIGN KEY (`user_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 `newsletter_subscribers` +-- + +LOCK TABLES `newsletter_subscribers` WRITE; +/*!40000 ALTER TABLE `newsletter_subscribers` DISABLE KEYS */; +INSERT INTO `newsletter_subscribers` VALUES (1,'fifi@fifwj.bb',NULL,NULL,'2025-12-05 13:34:23','2025-12-05 13:34:23',1); +/*!40000 ALTER TABLE `newsletter_subscribers` 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, + `hero_video_url` text, + `hero_video_poster` text, + `features_section_title` text, + `features_section_subtitle` text, + `stats_section_title` text, + `stats_section_subtitle` text, + `rooms_section_title` text, + `rooms_section_subtitle` text, + `rooms_section_button_text` text, + `rooms_section_button_link` text, + `rooms_section_enabled` tinyint(1) DEFAULT '1', + `services_section_button_text` text, + `services_section_button_link` text, + `services_section_limit` int DEFAULT NULL, + `sections_enabled` text, + `newsletter_section_title` text, + `newsletter_section_subtitle` text, + `newsletter_placeholder` text, + `newsletter_button_text` text, + `newsletter_enabled` tinyint(1) DEFAULT '0', + `trust_badges_section_title` text, + `trust_badges_section_subtitle` text, + `trust_badges` text, + `trust_badges_enabled` tinyint(1) DEFAULT '0', + `promotions_section_title` text, + `promotions_section_subtitle` text, + `promotions` text, + `promotions_enabled` tinyint(1) DEFAULT '0', + `blog_section_title` text, + `blog_section_subtitle` text, + `blog_posts_limit` int DEFAULT NULL, + `blog_enabled` tinyint(1) DEFAULT '0', + 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',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0),(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\", \"slug\": \"fine-dining\", \"category\": \"Dining\", \"content\": \"

Experience culinary excellence at our Michelin-starred restaurants. Our world-renowned chefs craft exquisite dishes using the finest ingredients sourced from around the globe. From intimate dining experiences to grand celebrations, we offer a variety of settings to suit every occasion.

Our restaurants feature seasonal menus that showcase the best of local and international cuisine, paired with an extensive wine collection curated by our master sommelier.

\", \"sections\": [], \"meta_title\": \"Fine Dining Experience - Luxury Hotel\", \"meta_description\": \"Discover our Michelin-starred restaurants offering world-class cuisine in elegant settings.\", \"meta_keywords\": \"fine dining, michelin star, luxury restaurant, gourmet cuisine\"}, {\"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\", \"slug\": \"premium-bar\", \"category\": \"Dining\", \"content\": \"

Unwind in sophistication at our premium bar, featuring an extensive collection of rare wines, vintage spirits, and expertly crafted cocktails. Our master mixologists create unique beverages tailored to your preferences.

The elegant ambiance, combined with live music on select evenings, creates the perfect setting for business meetings, romantic evenings, or casual gatherings with friends.

\", \"sections\": [], \"meta_title\": \"Premium Bar & Lounge - Luxury Hotel\", \"meta_description\": \"Enjoy an extensive wine collection and craft cocktails in our elegant bar and lounge.\", \"meta_keywords\": \"premium bar, wine collection, craft cocktails, luxury lounge\"}, {\"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\", \"slug\": \"spa-wellness\", \"category\": \"Wellness\", \"content\": \"

Escape to tranquility at our world-class spa and wellness center. Indulge in a range of rejuvenating treatments designed to restore balance and vitality. Our expert therapists use premium products and ancient techniques to provide an unparalleled wellness experience.

Our state-of-the-art fitness center is equipped with the latest equipment and offers personal training sessions, yoga classes, and wellness programs tailored to your needs.

\", \"sections\": [], \"meta_title\": \"Spa & Wellness Center - Luxury Hotel\", \"meta_description\": \"Rejuvenate with our spa treatments and state-of-the-art fitness facilities.\", \"meta_keywords\": \"spa, wellness, fitness center, massage, luxury spa\"}, {\"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\", \"slug\": \"concierge-services\", \"category\": \"Services\", \"content\": \"

Our dedicated concierge team is available 24/7 to ensure your stay is nothing short of extraordinary. From restaurant reservations and event tickets to private tours and transportation arrangements, we handle every detail with precision and care.

Whether you need assistance with business arrangements, special celebrations, or unique local experiences, our concierge team has the expertise and connections to make it happen.

\", \"sections\": [], \"meta_title\": \"Concierge Services - Luxury Hotel\", \"meta_description\": \"Personalized assistance for all your travel and entertainment needs, available 24/7.\", \"meta_keywords\": \"concierge, personal assistant, travel services, luxury service\"}]','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-05 13:01:12','https://videos.unsplash.com/video-1564501049412-61c2a3083791','https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200','Why Choose Us','Discover what makes us the perfect choice for your stay','Our Achievements','Numbers that speak for themselves','Luxurious Rooms & Suites','Experience comfort and elegance in every room','View All Rooms','/rooms',1,'Explore All Services','/services',4,'{\"features\": true, \"luxury\": true, \"gallery\": true, \"testimonials\": true, \"stats\": true, \"amenities\": true, \"about_preview\": true, \"services\": true, \"experiences\": true, \"awards\": true, \"cta\": true, \"partners\": true, \"rooms\": true, \"newsletter\": true, \"trust_badges\": true, \"promotions\": true, \"blog\": true}','Stay Connected','Subscribe to our newsletter for exclusive offers and updates','Enter your email address','Subscribe',1,'Trusted & Recognized','Awards and certifications that validate our commitment to excellence','[{\"name\": \"5-Star Rating\", \"logo\": \"https://images.unsplash.com/photo-1579783902614-a3fb3927b6a5?w=200\", \"description\": \"Awarded 5 stars by leading travel organizations\", \"link\": \"#\"}, {\"name\": \"TripAdvisor Excellence\", \"logo\": \"https://images.unsplash.com/photo-1606761568499-6d2451b23c66?w=200\", \"description\": \"Certificate of Excellence winner\", \"link\": \"#\"}, {\"name\": \"Green Certified\", \"logo\": \"https://images.unsplash.com/photo-1473341304170-971dccb5ac1e?w=200\", \"description\": \"Eco-friendly and sustainable practices\", \"link\": \"#\"}, {\"name\": \"Luxury Collection\", \"logo\": \"https://images.unsplash.com/photo-1599305445671-ac291c95aaa9?w=200\", \"description\": \"Member of the world\'s finest luxury hotels\", \"link\": \"#\"}]',1,'Special Offers','Exclusive deals and packages designed just for you','[{\"title\": \"Summer Special\", \"description\": \"Enjoy 25% off on all room bookings this summer. Limited time offer!\", \"image\": \"https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=600\", \"discount\": \"25% OFF\", \"valid_until\": \"2024-08-31\", \"link\": \"/rooms\", \"button_text\": \"Book Now\"}, {\"title\": \"Weekend Getaway\", \"description\": \"Perfect weekend escape with complimentary breakfast and spa access\", \"image\": \"https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=600\", \"discount\": \"30% OFF\", \"valid_until\": \"2024-12-31\", \"link\": \"/rooms\", \"button_text\": \"Learn More\"}, {\"title\": \"Honeymoon Package\", \"description\": \"Romantic getaway with champagne, flowers, and special amenities\", \"image\": \"https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=600\", \"discount\": \"Special Rate\", \"valid_until\": \"2024-12-31\", \"link\": \"/rooms\", \"button_text\": \"Book Package\"}]',1,'Latest News & Updates','Stay informed about our latest news, events, and travel tips',3,1),(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',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0),(4,'privacy','Privacy Policy','Your privacy is important to us','Learn how we collect, use, and protect your personal information.','\n

Introduction

\n

At 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 \n

Information We Collect

\n

We collect information that you provide directly to us, including:

\n \n \n

How We Use Your Information

\n

We use the information we collect to:

\n \n \n

Data Security

\n

We implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, disclosure, or destruction.

\n \n

Your Rights

\n

You have the right to:

\n \n \n

Contact Us

\n

If you have any questions about this Privacy Policy, please contact us at privacy@hotel.com.

\n \n

Last 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',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0),(5,'terms','Terms & Conditions','Please read these terms carefully','Terms and conditions governing your use of our hotel booking services.','\n

Agreement to Terms

\n

By 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 \n

Booking Terms

\n

When making a reservation with us, you agree to:

\n \n \n

Payment Terms

\n

Payment terms include:

\n \n \n

Cancellation Policy

\n

Our cancellation policy is as follows:

\n \n \n

Check-in and Check-out

\n

Standard 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 \n

Guest Responsibilities

\n

Guests are responsible for:

\n \n \n

Limitation of Liability

\n

The 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 \n

Modifications to Terms

\n

We reserve the right to modify these terms at any time. Changes will be effective immediately upon posting on our website.

\n \n

Contact Information

\n

For questions about these terms, please contact us at legal@hotel.com.

\n \n

Last 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',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0),(6,'refunds','Refunds Policy','Our commitment to fair refunds','Learn about our refund policies and procedures for bookings and cancellations.','\n

Refund Policy Overview

\n

At our hotel, we understand that plans can change. This policy outlines our refund procedures and timelines for various scenarios.

\n \n

Booking Cancellations

\n

Refunds for cancelled bookings are processed as follows:

\n \n \n

Early Check-out

\n

If you check out earlier than your reserved departure date:

\n \n \n

Service Issues

\n

If you experience service issues during your stay:

\n \n \n

Refund Processing Time

\n

Refunds are typically processed within:

\n \n \n

Refund Method

\n

Refunds 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 \n

Non-Refundable Bookings

\n

Some special offers or promotional rates may be non-refundable. This will be clearly stated at the time of booking.

\n \n

Force Majeure

\n

In 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 \n

Dispute Resolution

\n

If you have concerns about a refund decision, please contact our customer service team. We are committed to resolving all disputes fairly and promptly.

\n \n

Contact Us

\n

For refund inquiries, please contact us at refunds@hotel.com or call our customer service line.

\n \n

Last 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',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0),(7,'cancellation','Cancellation Policy','Flexible cancellation options for your peace of mind','Learn about our cancellation policy, fees, and refund procedures.','\n

Cancellation Policy Overview

\n

We understand that plans can change. This policy outlines our cancellation procedures and fees.

\n \n

Standard Cancellation Terms

\n

For standard bookings, the following cancellation terms apply:

\n \n \n

Special Rate Bookings

\n

Some special rates or promotional offers may have different cancellation terms. Please review your booking confirmation for specific details.

\n \n

How to Cancel

\n

To cancel your booking:

\n \n \n

Refund Processing

\n

Refunds will be processed to the original payment method within 5-10 business days after cancellation confirmation.

\n \n

Last 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',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0),(8,'accessibility','Accessibility','Committed to providing an inclusive experience for all guests','Learn about our accessibility features and accommodations.','\n

Our Commitment to Accessibility

\n

We 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 \n

Hotel Accessibility Features

\n

Our hotel offers the following accessibility features:

\n \n \n

Website Accessibility

\n

We are continuously working to improve the accessibility of our website. Our website includes:

\n \n \n

Requesting Accommodations

\n

If 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 \n

Feedback

\n

We welcome feedback on how we can improve accessibility. Please contact us with your suggestions or concerns.

\n \n

Last 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',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0),(9,'faq','Frequently Asked Questions','Find answers to common questions','Get answers to frequently asked questions about bookings, services, and policies.','\n

Frequently Asked Questions

\n

Find answers to common questions about our hotel, bookings, and services.

\n \n

Booking & Reservations

\n

How do I make a reservation?

\n

You 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 \n

What is the deposit requirement?

\n

A 20% deposit is required to secure your booking. The remaining balance is due upon arrival at the hotel.

\n \n

Can I modify my booking?

\n

Yes, 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 \n

Check-in & Check-out

\n

What are your check-in and check-out times?

\n

Check-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 \n

Do you offer early check-in or late check-out?

\n

Early check-in and late check-out are available upon request, subject to availability. Additional fees may apply.

\n \n

Payment & Cancellation

\n

What payment methods do you accept?

\n

We accept major credit cards, debit cards, and bank transfers. Payment can be made online or at the hotel.

\n \n

What is your cancellation policy?

\n

For 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 \n

Hotel Services & Amenities

\n

What amenities are included?

\n

Our hotel offers complimentary Wi-Fi, parking, fitness center access, and more. Please check the room details for specific amenities.

\n \n

Do you have parking available?

\n

Yes, we offer complimentary parking for all guests. Valet parking is also available for an additional fee.

\n \n

Is Wi-Fi available?

\n

Yes, complimentary high-speed Wi-Fi is available throughout the hotel.

\n \n

Special Requests

\n

Can I request a specific room?

\n

Yes, you can make special requests when booking. We will do our best to accommodate your preferences, subject to availability.

\n \n

Do you accommodate dietary restrictions?

\n

Yes, please inform us of any dietary restrictions or allergies when making your reservation, and we will do our best to accommodate your needs.

\n \n

Contact & Support

\n

How can I contact the hotel?

\n

You can contact us by phone, email, or through our website\'s contact form. Our team is available 24/7 to assist you.

\n \n

Last 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',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0,NULL,NULL,NULL,0); +/*!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 `reconciliation_exceptions` +-- + +DROP TABLE IF EXISTS `reconciliation_exceptions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `reconciliation_exceptions` ( + `id` int NOT NULL AUTO_INCREMENT, + `exception_type` enum('missing_invoice','missing_payment','amount_mismatch','duplicate_payment','orphaned_payment','date_mismatch') NOT NULL, + `status` enum('open','assigned','in_review','resolved','closed') NOT NULL, + `severity` varchar(20) NOT NULL, + `payment_id` int DEFAULT NULL, + `invoice_id` int DEFAULT NULL, + `booking_id` int DEFAULT NULL, + `description` text NOT NULL, + `expected_amount` decimal(10,2) DEFAULT NULL, + `actual_amount` decimal(10,2) DEFAULT NULL, + `difference` decimal(10,2) DEFAULT NULL, + `assigned_to` int DEFAULT NULL, + `assigned_at` datetime DEFAULT NULL, + `resolved_by` int DEFAULT NULL, + `resolved_at` datetime DEFAULT NULL, + `resolution_notes` text, + `comments` json DEFAULT NULL, + `exception_metadata` json DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `resolved_by` (`resolved_by`), + KEY `ix_reconciliation_exceptions_booking_id` (`booking_id`), + KEY `ix_reconciliation_exceptions_assigned_to` (`assigned_to`), + KEY `ix_reconciliation_exceptions_id` (`id`), + KEY `ix_reconciliation_exceptions_status` (`status`), + KEY `idx_reconciliation_exception_assigned` (`assigned_to`,`status`), + KEY `ix_reconciliation_exceptions_invoice_id` (`invoice_id`), + KEY `idx_reconciliation_exception_status` (`status`,`created_at`), + KEY `ix_reconciliation_exceptions_exception_type` (`exception_type`), + KEY `ix_reconciliation_exceptions_payment_id` (`payment_id`), + KEY `ix_reconciliation_exceptions_created_at` (`created_at`), + KEY `idx_reconciliation_exception_type` (`exception_type`,`status`), + CONSTRAINT `reconciliation_exceptions_ibfk_1` FOREIGN KEY (`payment_id`) REFERENCES `payments` (`id`), + CONSTRAINT `reconciliation_exceptions_ibfk_2` FOREIGN KEY (`invoice_id`) REFERENCES `invoices` (`id`), + CONSTRAINT `reconciliation_exceptions_ibfk_3` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `reconciliation_exceptions_ibfk_4` FOREIGN KEY (`assigned_to`) REFERENCES `users` (`id`), + CONSTRAINT `reconciliation_exceptions_ibfk_5` 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 `reconciliation_exceptions` +-- + +LOCK TABLES `reconciliation_exceptions` WRITE; +/*!40000 ALTER TABLE `reconciliation_exceptions` DISABLE KEYS */; +/*!40000 ALTER TABLE `reconciliation_exceptions` 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=236 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 (213,12,'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyLCJleHAiOjE3NjU0NDk1NDQsImlhdCI6MTc2NDg0NDc0NCwiaXNzIjoiSG90ZWwgQm9va2luZyBBUEkiLCJ0eXBlIjoicmVmcmVzaCJ9.2bRx3i4L_Ma3f1P9I_4CRnOJu_s5s5_ESj__TYS7C4Q','2025-12-05 10:39:04','2025-12-04 10:39:04'),(235,3,'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjMsImV4cCI6MTc2NTU1MDM3NywiaWF0IjoxNzY0OTQ1NTc3LCJpc3MiOiJIb3RlbCBCb29raW5nIEFQSSIsInR5cGUiOiJyZWZyZXNoIn0.g6AsZVC14s9XN_78_lkdkWFoXDgy9etVSp4loISZD4E','2025-12-06 14:39:38','2025-12-05 14:39:38'); +/*!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 AUTO_INCREMENT=2 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 */; +INSERT INTO `room_inspections` VALUES (1,26,NULL,'routine','pending','2025-12-03 22:00:22',NULL,NULL,13,13,NULL,'[{\"item\": \"Overall room condition\", \"notes\": \"\", \"status\": \"not_applicable\", \"category\": \"General\"}, {\"item\": \"Maintenance needs\", \"notes\": \"\", \"status\": \"not_applicable\", \"category\": \"General\"}]',NULL,NULL,NULL,NULL,0,NULL,NULL,'2025-12-03 22:00:22','2025-12-03 22:00:22'); +/*!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 AUTO_INCREMENT=2 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 */; +INSERT INTO `room_maintenance` VALUES (1,4,'corrective','scheduled','Issue in Room 104','Reported from housekeeping task.\n\nTask Notes: Task created by housekeeping staff\n\nIssue Description: broken WC','2025-12-03 22:16:15',NULL,NULL,NULL,NULL,13,NULL,NULL,1,NULL,NULL,'high','Reported from housekeeping task #14',NULL,'2025-12-03 22:16:15','2025-12-03 22:16:15'); +/*!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,'available',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-03 20:59:56'),(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,'maintenance',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-03 22:16:20'),(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','[\"/uploads/rooms/room-1927d31c-ab99-4263-b6a9-a5830812972b.webp\"]','\"[\\\"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-03 21:36:11'),(19,2,'319',3,'available',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-04 18:05:13'),(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,'available',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-03 20:37:35'),(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,'available',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-04 18:05:44'),(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,'available',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-04 18:05:54'),(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, + `slug` varchar(200) DEFAULT NULL, + `image` varchar(1000) DEFAULT NULL, + `content` text, + `sections` text, + `meta_title` varchar(500) DEFAULT NULL, + `meta_description` text, + `meta_keywords` varchar(1000) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ix_services_slug` (`slug`), + KEY `ix_services_id` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=37 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 */; +INSERT INTO `services` VALUES (24,'Luxury Spa & Wellness Retreat','Indulge in our world-class spa treatments designed to restore balance and vitality. Experience ultimate relaxation with our expert therapists.',250.00,'Wellness',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','luxury-spa-wellness-retreat','https://images.unsplash.com/photo-1544161515-4ab6ce6db874?w=1200&h=800&fit=crop','
\n

Experience Ultimate Relaxation

\n

Our Luxury Spa & Wellness Retreat offers an unparalleled journey of rejuvenation and tranquility. Nestled in a serene environment, our spa combines ancient healing traditions with modern wellness techniques to create a transformative experience.

\n \n

What\'s Included

\n \n \n

Our Signature Treatments

\n

Choose from our curated selection of treatments including Swedish massage, deep tissue therapy, hot stone massage, and aromatherapy sessions. Each treatment is customized to your specific needs and preferences.

\n \n

Expert Therapists

\n

Our team of certified therapists brings years of experience and a deep understanding of holistic wellness. They are trained in various massage techniques and wellness practices to ensure you receive the highest quality care.

\n
','[{\"type\": \"hero\", \"title\": \"Transform Your Wellbeing\", \"content\": \"Discover a sanctuary of peace and rejuvenation where every detail is designed to restore your mind, body, and spirit.\", \"image\": \"https://images.unsplash.com/photo-1544161515-4ab6ce6db874?w=1200&h=600&fit=crop\"}, {\"type\": \"features\", \"title\": \"Why Choose Our Spa\", \"features\": [{\"title\": \"Expert Therapists\", \"description\": \"Certified professionals with years of experience\", \"icon\": \"User\"}, {\"title\": \"Premium Products\", \"description\": \"Luxury skincare and aromatherapy products\", \"icon\": \"Sparkles\"}, {\"title\": \"Customized Treatments\", \"description\": \"Personalized sessions tailored to your needs\", \"icon\": \"Heart\"}, {\"title\": \"Serene Environment\", \"description\": \"Peaceful setting designed for relaxation\", \"icon\": \"Leaf\"}]}, {\"type\": \"quote\", \"quote\": \"The most luxurious spa experience I\'ve ever had. Truly transformative.\", \"author\": \"Sarah M., Guest\"}]','Luxury Spa & Wellness Retreat - Premium Hotel Services','Experience ultimate relaxation with our world-class spa treatments. Expert therapists, premium products, and a serene environment await you.','luxury spa, wellness retreat, massage therapy, hotel spa, relaxation, aromatherapy, wellness services'),(25,'Fine Dining Experience','Savor culinary excellence at our Michelin-starred restaurants. World-renowned chefs craft exquisite dishes using the finest ingredients.',150.00,'Dining',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','fine-dining-experience','https://images.unsplash.com/photo-1414235077428-338989a2e8c0?w=1200&h=800&fit=crop','
\n

Culinary Excellence Awaits

\n

Embark on a gastronomic journey at our award-winning restaurants, where culinary artistry meets exceptional service. Our Michelin-starred chefs create masterpieces that celebrate both local traditions and international flavors.

\n \n

Our Restaurants

\n \n \n

What\'s Included

\n \n \n

Reservation Information

\n

Reservations are recommended and can be made through our concierge or directly at the restaurant. Special dietary requirements and preferences are accommodated with advance notice.

\n
','[{\"type\": \"hero\", \"title\": \"A Culinary Journey Like No Other\", \"content\": \"Where every dish tells a story and every meal becomes a memory.\", \"image\": \"https://images.unsplash.com/photo-1414235077428-338989a2e8c0?w=1200&h=600&fit=crop\"}, {\"type\": \"gallery\", \"title\": \"Our Culinary Creations\", \"images\": [\"https://images.unsplash.com/photo-1414235077428-338989a2e8c0?w=800\", \"https://images.unsplash.com/photo-1556911220-bff31c812dba?w=800\", \"https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?w=800\"]}, {\"type\": \"quote\", \"quote\": \"An extraordinary dining experience that exceeded all expectations. The attention to detail is remarkable.\", \"author\": \"Michael R., Food Critic\"}]','Fine Dining Experience - Michelin-Starred Restaurant','Savor culinary excellence at our Michelin-starred restaurants. World-renowned chefs, exquisite dishes, and exceptional service.','fine dining, michelin star, luxury restaurant, gourmet cuisine, fine dining hotel'),(26,'24/7 Premium Room Service','Enjoy the convenience of round-the-clock in-room dining with our extensive menu featuring international cuisine and premium beverages.',35.00,'Dining',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','premium-room-service','https://images.unsplash.com/photo-1556911220-bff31c812dba?w=1200&h=800&fit=crop','
\n

Dining at Your Convenience

\n

Experience the ultimate in-room dining service available 24 hours a day. From breakfast in bed to late-night snacks, our extensive menu caters to every craving with the highest standards of quality and presentation.

\n \n

Menu Highlights

\n \n \n

Service Features

\n \n \n

How to Order

\n

Simply call our room service line from your in-room phone or use our mobile app. Our team is available 24/7 to take your order and ensure prompt delivery.

\n
','[{\"type\": \"features\", \"title\": \"Why Choose Our Room Service\", \"features\": [{\"title\": \"24/7 Availability\", \"description\": \"Order anytime, day or night\", \"icon\": \"Clock\"}, {\"title\": \"Fast Delivery\", \"description\": \"Average 25-30 minute delivery time\", \"icon\": \"Zap\"}, {\"title\": \"Premium Quality\", \"description\": \"Restaurant-quality meals in your room\", \"icon\": \"Award\"}, {\"title\": \"Professional Service\", \"description\": \"Elegant table setup and presentation\", \"icon\": \"UserCheck\"}]}]','24/7 Premium Room Service - Luxury Hotel','Enjoy round-the-clock in-room dining with our extensive menu. International cuisine, premium beverages, and professional service delivered to your room.','room service, in-room dining, 24/7 service, hotel dining, room service menu'),(27,'Executive Business Center','Fully equipped business center with private meeting rooms, high-speed internet, printing services, and professional secretarial support.',75.00,'Business',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','executive-business-center','https://images.unsplash.com/photo-1497366216548-37526070297c?w=1200&h=800&fit=crop','
\n

Your Office Away From Office

\n

Stay productive with our state-of-the-art Executive Business Center, designed to meet all your professional needs. Whether you need a quiet workspace, a meeting room, or professional support services, we have everything you need.

\n \n

Facilities & Services

\n \n \n

Meeting Room Features

\n \n \n

Reservation

\n

Meeting rooms can be reserved in advance through our concierge or business center. Hourly and daily rates available. Special packages for extended stays.

\n
','[{\"type\": \"hero\", \"title\": \"Productivity Meets Luxury\", \"content\": \"A professional workspace designed for success, equipped with everything you need to stay productive.\", \"image\": \"https://images.unsplash.com/photo-1497366216548-37526070297c?w=1200&h=600&fit=crop\"}, {\"type\": \"features\", \"title\": \"Everything You Need\", \"features\": [{\"title\": \"Private Meeting Rooms\", \"description\": \"Various sizes for any business need\", \"icon\": \"Users\"}, {\"title\": \"High-Speed Internet\", \"description\": \"Fiber-optic connection with secure Wi-Fi\", \"icon\": \"Wifi\"}, {\"title\": \"Professional Support\", \"description\": \"Secretarial and administrative services\", \"icon\": \"Briefcase\"}, {\"title\": \"Modern Equipment\", \"description\": \"Latest technology and presentation tools\", \"icon\": \"Monitor\"}]}]','Executive Business Center - Professional Workspace','Fully equipped business center with meeting rooms, high-speed internet, printing services, and professional support. Your office away from office.','business center, meeting room, conference room, office services, hotel business center'),(28,'Luxury Airport Transfer','Travel in comfort and style with our premium airport transfer service. Luxury vehicles, professional drivers, and flight monitoring for a seamless journey.',85.00,'Transportation',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','luxury-airport-transfer','https://images.unsplash.com/photo-1449824913935-59a10b8d2000?w=1200&h=800&fit=crop','
\n

Arrive in Style

\n

Begin or end your journey with our premium airport transfer service. Our fleet of luxury vehicles and professional drivers ensure a comfortable, punctual, and stress-free experience.

\n \n

Our Fleet

\n \n \n

Service Features

\n \n \n

Booking Information

\n

Reservations should be made at least 24 hours in advance. Please provide flight details for arrival transfers. Our team monitors flights and adjusts pickup times accordingly.

\n
','[{\"type\": \"hero\", \"title\": \"Your Journey Starts Here\", \"content\": \"Experience the comfort and convenience of premium airport transfers.\", \"image\": \"https://images.unsplash.com/photo-1449824913935-59a10b8d2000?w=1200&h=600&fit=crop\"}, {\"type\": \"features\", \"title\": \"Why Choose Our Transfer Service\", \"features\": [{\"title\": \"Luxury Fleet\", \"description\": \"Premium vehicles for every need\", \"icon\": \"Car\"}, {\"title\": \"Professional Drivers\", \"description\": \"Licensed, experienced, and courteous\", \"icon\": \"User\"}, {\"title\": \"Flight Monitoring\", \"description\": \"Automatic updates for delays\", \"icon\": \"Plane\"}, {\"title\": \"Complimentary Amenities\", \"description\": \"Water, Wi-Fi, and newspapers\", \"icon\": \"Gift\"}]}]','Luxury Airport Transfer - Premium Transportation','Travel in comfort with our premium airport transfer service. Luxury vehicles, professional drivers, and flight monitoring for a seamless journey.','airport transfer, luxury transportation, airport shuttle, hotel transfer, airport service'),(29,'Personal Concierge Service','Dedicated 24/7 concierge assistance for restaurant reservations, event tickets, tours, transportation, and all your special requests.',0.00,'Concierge',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','personal-concierge-service','https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1200&h=800&fit=crop','
\n

Your Personal Assistant

\n

Our dedicated concierge team is available 24/7 to ensure your stay is nothing short of extraordinary. From restaurant reservations and event tickets to private tours and unique experiences, we handle every detail with precision and care.

\n \n

Services We Provide

\n \n \n

How We Can Help

\n

Whether you need last-minute reservations at a popular restaurant, tickets to a sold-out show, or help planning a special celebration, our concierge team has the expertise and connections to make it happen. No request is too big or too small.

\n \n

Contact Us

\n

Reach our concierge team 24/7 via phone, email, or in-person at the concierge desk. We\'re here to make your stay unforgettable.

\n
','[{\"type\": \"hero\", \"title\": \"Making Your Dreams Come True\", \"content\": \"Your personal assistant, available 24/7 to fulfill every request.\", \"image\": \"https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1200&h=600&fit=crop\"}, {\"type\": \"cta\", \"title\": \"Need Assistance?\", \"cta_text\": \"Contact Our Concierge\", \"cta_link\": \"/contact\", \"content\": \"Our team is standing by to help with any request, big or small.\"}]','Personal Concierge Service - 24/7 Assistance','Dedicated 24/7 concierge service for restaurant reservations, event tickets, tours, and all your special requests. Making your stay extraordinary.','concierge service, personal assistant, hotel concierge, travel services, luxury service'),(30,'State-of-the-Art Fitness Center','Access our fully equipped fitness center with modern equipment, personal training options, and group fitness classes. Open 24/7 for your convenience.',30.00,'Wellness',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','fitness-center-access','https://images.unsplash.com/photo-1534438327276-14e5300c3a48?w=1200&h=800&fit=crop','
\n

Stay Fit, Stay Strong

\n

Maintain your fitness routine at our state-of-the-art fitness center featuring the latest cardio and strength training equipment. Our facilities are designed to meet the needs of both casual exercisers and serious athletes.

\n \n

Equipment & Facilities

\n \n \n

Additional Services

\n \n \n

Operating Hours

\n

Our fitness center is open 24/7 for your convenience. Personal training and group classes are available by appointment. Check the schedule at the front desk or contact our fitness team.

\n
','[{\"type\": \"hero\", \"title\": \"Your Fitness Journey Continues\", \"content\": \"World-class equipment and expert guidance to help you achieve your fitness goals.\", \"image\": \"https://images.unsplash.com/photo-1534438327276-14e5300c3a48?w=1200&h=600&fit=crop\"}, {\"type\": \"features\", \"title\": \"Why Our Fitness Center\", \"features\": [{\"title\": \"24/7 Access\", \"description\": \"Work out on your schedule\", \"icon\": \"Clock\"}, {\"title\": \"Modern Equipment\", \"description\": \"Latest cardio and strength training machines\", \"icon\": \"Activity\"}, {\"title\": \"Expert Trainers\", \"description\": \"Certified personal trainers available\", \"icon\": \"User\"}, {\"title\": \"Group Classes\", \"description\": \"Yoga, Pilates, and more\", \"icon\": \"Users\"}]}]','State-of-the-Art Fitness Center - 24/7 Access','Fully equipped fitness center with modern equipment, personal training, and group classes. Open 24/7 for your convenience.','fitness center, gym, hotel gym, workout, exercise, personal training, 24/7 gym'),(31,'Premium Laundry & Dry Cleaning','Professional laundry and dry cleaning service with same-day express or next-day standard delivery. Expert care for all your garments.',20.00,'Housekeeping',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','premium-laundry-dry-cleaning','https://images.unsplash.com/photo-1582735689369-4fe89db7114c?w=1200&h=800&fit=crop','
\n

Expert Garment Care

\n

Keep your wardrobe fresh and impeccably maintained with our professional laundry and dry cleaning service. We handle everything from delicate silk garments to business suits with the utmost care and attention to detail.

\n \n

Our Services

\n \n \n

Delivery Options

\n \n \n

How to Use

\n

Simply place your items in the laundry bag provided in your room and call housekeeping. Our team will collect your items, process them with care, and return them to your room at the specified time.

\n
','[{\"type\": \"features\", \"title\": \"Why Choose Our Service\", \"features\": [{\"title\": \"Expert Care\", \"description\": \"Professional handling of all garment types\", \"icon\": \"Shield\"}, {\"title\": \"Fast Service\", \"description\": \"Same-day express option available\", \"icon\": \"Zap\"}, {\"title\": \"Quality Guarantee\", \"description\": \"Satisfaction guaranteed on all services\", \"icon\": \"CheckCircle\"}, {\"title\": \"Eco-Friendly\", \"description\": \"Environmentally conscious cleaning methods\", \"icon\": \"Leaf\"}]}]','Premium Laundry & Dry Cleaning - Professional Service','Professional laundry and dry cleaning with same-day or next-day delivery. Expert care for all your garments.','laundry service, dry cleaning, hotel laundry, garment care, cleaning service'),(32,'Valet Parking Service','Secure valet parking with 24/7 vehicle care, quick retrieval, and optional car wash services. Your vehicle is in safe hands.',45.00,'Transportation',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','valet-parking-service','https://images.unsplash.com/photo-1502877338535-766e1452684a?w=1200&h=800&fit=crop','
\n

Secure & Convenient Parking

\n

Enjoy the ultimate convenience of valet parking with our professional service. Your vehicle will be safely parked and secured, ready for quick retrieval whenever you need it. Our valet team is available 24/7 to assist you.

\n \n

Service Features

\n \n \n

Additional Services

\n \n \n

Pricing

\n

Daily rates available for extended stays. Weekly and monthly packages offer significant savings. Contact our valet team for special rates.

\n
','[{\"type\": \"features\", \"title\": \"Why Choose Our Valet Service\", \"features\": [{\"title\": \"Secure Facility\", \"description\": \"Monitored and protected parking\", \"icon\": \"Shield\"}, {\"title\": \"Quick Service\", \"description\": \"Average 5-minute retrieval time\", \"icon\": \"Clock\"}, {\"title\": \"24/7 Availability\", \"description\": \"Service available around the clock\", \"icon\": \"Sun\"}, {\"title\": \"Additional Services\", \"description\": \"Car wash and detailing available\", \"icon\": \"Sparkles\"}]}]','Valet Parking Service - Secure & Convenient','Secure valet parking with 24/7 service, quick retrieval, and optional car care services. Your vehicle is in safe hands.','valet parking, parking service, hotel parking, car service, valet'),(33,'Professional Babysitting Service','Certified and experienced babysitters available for in-room care and supervised activities. Background-checked professionals for your peace of mind.',35.00,'Family',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','professional-babysitting-service','https://images.unsplash.com/photo-1503454537195-1dcabb73ffb9?w=1200&h=800&fit=crop','
\n

Your Children in Safe Hands

\n

Enjoy your time knowing your children are in the care of our professional babysitting service. Our certified caregivers are experienced, background-checked, and trained in child safety and first aid.

\n \n

Our Caregivers

\n \n \n

Services Offered

\n \n \n

Booking Information

\n

Reservations should be made at least 4 hours in advance. Same-day service may be available subject to caregiver availability. Minimum booking: 2 hours.

\n
','[{\"type\": \"hero\", \"title\": \"Peace of Mind for Parents\", \"content\": \"Certified professionals ensuring your children are safe, happy, and well-cared for.\", \"image\": \"https://images.unsplash.com/photo-1503454537195-1dcabb73ffb9?w=1200&h=600&fit=crop\"}, {\"type\": \"features\", \"title\": \"Why Parents Trust Us\", \"features\": [{\"title\": \"Certified Caregivers\", \"description\": \"CPR and first aid certified\", \"icon\": \"Shield\"}, {\"title\": \"Background Checked\", \"description\": \"Thoroughly vetted professionals\", \"icon\": \"UserCheck\"}, {\"title\": \"Experienced\", \"description\": \"Years of childcare experience\", \"icon\": \"Heart\"}, {\"title\": \"Flexible Service\", \"description\": \"In-room or activity supervision\", \"icon\": \"Clock\"}]}]','Professional Babysitting Service - Certified Caregivers','Certified and experienced babysitters for in-room care and supervised activities. Background-checked professionals for your peace of mind.','babysitting service, childcare, hotel babysitting, kids care, family services'),(34,'Pet Care & Accommodation','Pet-friendly accommodations with professional pet care services including walking, feeding, grooming, and pet-sitting. Your furry friends are welcome!',25.00,'Pet Services',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','pet-care-accommodation','https://images.unsplash.com/photo-1601758228041-f3b2795255f1?w=1200&h=800&fit=crop','
\n

Your Pets Are Family Too

\n

We welcome your furry family members! Our pet-friendly accommodations and professional pet care services ensure your pets are as comfortable and well-cared for as you are during your stay.

\n \n

Pet Amenities

\n \n \n

Pet Care Services

\n \n \n

Pet Policy

\n

Pets up to 50 lbs are welcome. A pet fee applies per night. Please inform us in advance about your pet\'s stay. We ask that pets be leashed in public areas and that owners clean up after their pets.

\n
','[{\"type\": \"hero\", \"title\": \"A Home Away From Home for Your Pets\", \"content\": \"Because your pets deserve the same luxury experience as you.\", \"image\": \"https://images.unsplash.com/photo-1601758228041-f3b2795255f1?w=1200&h=600&fit=crop\"}, {\"type\": \"features\", \"title\": \"Pet-Friendly Features\", \"features\": [{\"title\": \"Pet Amenities\", \"description\": \"Beds, bowls, treats, and toys provided\", \"icon\": \"Heart\"}, {\"title\": \"Professional Care\", \"description\": \"Walking, feeding, and grooming services\", \"icon\": \"User\"}, {\"title\": \"Designated Areas\", \"description\": \"Pet relief areas and walking paths\", \"icon\": \"MapPin\"}, {\"title\": \"Vet Referrals\", \"description\": \"Local veterinary recommendations\", \"icon\": \"Stethoscope\"}]}]','Pet Care & Accommodation - Pet-Friendly Hotel','Pet-friendly accommodations with professional pet care services. Walking, feeding, grooming, and pet-sitting available. Your pets are welcome!','pet care, pet friendly hotel, dog walking, pet services, pet accommodation'),(35,'Premium Wine & Spirits Collection','Extensive collection of fine wines, premium spirits, and craft cocktails. Expert sommelier service and private wine tastings available.',0.00,'Dining',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','premium-wine-spirits-collection','https://images.unsplash.com/photo-1514362545857-3bc16c4c7d1b?w=1200&h=800&fit=crop','
\n

Curated Excellence

\n

Discover our extensive collection of fine wines, premium spirits, and artisanal cocktails. Our master sommelier has curated a selection that spans the globe, featuring rare vintages, limited editions, and exceptional spirits.

\n \n

Our Collection

\n \n \n

Services

\n \n \n

Locations

\n

Enjoy our collection at our signature bars, restaurants, or through our room service. Our sommelier is available for consultations and recommendations.

\n
','[{\"type\": \"hero\", \"title\": \"A World of Flavors\", \"content\": \"Curated by experts, enjoyed by connoisseurs.\", \"image\": \"https://images.unsplash.com/photo-1514362545857-3bc16c4c7d1b?w=1200&h=600&fit=crop\"}, {\"type\": \"quote\", \"quote\": \"An exceptional collection that rivals the finest establishments in the world.\", \"author\": \"Wine Enthusiast Magazine\"}]','Premium Wine & Spirits Collection - Fine Beverages','Extensive collection of fine wines, premium spirits, and craft cocktails. Expert sommelier service and private tastings available.','wine collection, premium spirits, sommelier, wine tasting, luxury bar, craft cocktails'),(36,'Private Event & Catering Services','Professional event planning and catering services for weddings, corporate events, celebrations, and private gatherings. Make your special occasion unforgettable.',0.00,'Entertainment',1,'2025-12-04 21:46:55','2025-12-04 21:46:55','private-event-catering-services','https://images.unsplash.com/photo-1519167758481-83f550bb49b3?w=1200&h=800&fit=crop','
\n

Unforgettable Events

\n

From intimate gatherings to grand celebrations, our professional event planning and catering team will ensure your special occasion is executed flawlessly. We handle every detail so you can enjoy your event.

\n \n

Event Types

\n \n \n

Our Services

\n \n \n

Planning Process

\n

Our event specialists will work with you from initial consultation through event execution. We offer flexible packages and can customize services to meet your specific needs and budget.

\n
','[{\"type\": \"hero\", \"title\": \"Making Memories That Last\", \"content\": \"Professional event planning and catering for your most important occasions.\", \"image\": \"https://images.unsplash.com/photo-1519167758481-83f550bb49b3?w=1200&h=600&fit=crop\"}, {\"type\": \"cta\", \"title\": \"Planning an Event?\", \"cta_text\": \"Contact Our Event Team\", \"cta_link\": \"/contact\", \"content\": \"Let us help you create an unforgettable experience.\"}]','Private Event & Catering Services - Professional Planning','Professional event planning and catering for weddings, corporate events, and celebrations. Make your special occasion unforgettable.','event planning, catering, wedding planning, corporate events, private events, hotel events'); +/*!40000 ALTER TABLE `services` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `staff_shifts` +-- + +DROP TABLE IF EXISTS `staff_shifts`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `staff_shifts` ( + `id` int NOT NULL AUTO_INCREMENT, + `staff_id` int NOT NULL, + `shift_date` datetime NOT NULL, + `shift_type` enum('morning','afternoon','night','full_day','custom') NOT NULL, + `start_time` time NOT NULL, + `end_time` time NOT NULL, + `status` enum('scheduled','in_progress','completed','cancelled','no_show') NOT NULL, + `actual_start_time` datetime DEFAULT NULL, + `actual_end_time` datetime DEFAULT NULL, + `break_duration_minutes` int DEFAULT NULL, + `assigned_by` int DEFAULT NULL, + `department` varchar(100) DEFAULT NULL, + `notes` text, + `handover_notes` text, + `tasks_completed` int DEFAULT NULL, + `tasks_assigned` int DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `assigned_by` (`assigned_by`), + KEY `ix_staff_shifts_staff_id` (`staff_id`), + KEY `ix_staff_shifts_shift_date` (`shift_date`), + KEY `ix_staff_shifts_id` (`id`), + CONSTRAINT `staff_shifts_ibfk_1` FOREIGN KEY (`staff_id`) REFERENCES `users` (`id`), + CONSTRAINT `staff_shifts_ibfk_2` FOREIGN KEY (`assigned_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 `staff_shifts` +-- + +LOCK TABLES `staff_shifts` WRITE; +/*!40000 ALTER TABLE `staff_shifts` DISABLE KEYS */; +/*!40000 ALTER TABLE `staff_shifts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `staff_tasks` +-- + +DROP TABLE IF EXISTS `staff_tasks`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `staff_tasks` ( + `id` int NOT NULL AUTO_INCREMENT, + `shift_id` int DEFAULT NULL, + `staff_id` int NOT NULL, + `title` varchar(255) NOT NULL, + `description` text, + `task_type` varchar(100) NOT NULL, + `priority` enum('low','normal','high','urgent') NOT NULL, + `status` enum('pending','assigned','in_progress','completed','cancelled','on_hold') NOT NULL, + `scheduled_start` datetime DEFAULT NULL, + `scheduled_end` datetime DEFAULT NULL, + `actual_start` datetime DEFAULT NULL, + `actual_end` datetime DEFAULT NULL, + `estimated_duration_minutes` int DEFAULT NULL, + `actual_duration_minutes` int DEFAULT NULL, + `assigned_by` int DEFAULT NULL, + `due_date` datetime DEFAULT NULL, + `related_booking_id` int DEFAULT NULL, + `related_room_id` int DEFAULT NULL, + `related_guest_request_id` int DEFAULT NULL, + `related_maintenance_id` int DEFAULT NULL, + `notes` text, + `completion_notes` text, + `is_recurring` tinyint(1) NOT NULL, + `recurrence_pattern` varchar(100) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `assigned_by` (`assigned_by`), + KEY `related_booking_id` (`related_booking_id`), + KEY `related_room_id` (`related_room_id`), + KEY `related_guest_request_id` (`related_guest_request_id`), + KEY `related_maintenance_id` (`related_maintenance_id`), + KEY `ix_staff_tasks_shift_id` (`shift_id`), + KEY `ix_staff_tasks_id` (`id`), + KEY `ix_staff_tasks_staff_id` (`staff_id`), + CONSTRAINT `staff_tasks_ibfk_1` FOREIGN KEY (`shift_id`) REFERENCES `staff_shifts` (`id`), + CONSTRAINT `staff_tasks_ibfk_2` FOREIGN KEY (`staff_id`) REFERENCES `users` (`id`), + CONSTRAINT `staff_tasks_ibfk_3` FOREIGN KEY (`assigned_by`) REFERENCES `users` (`id`), + CONSTRAINT `staff_tasks_ibfk_4` FOREIGN KEY (`related_booking_id`) REFERENCES `bookings` (`id`), + CONSTRAINT `staff_tasks_ibfk_5` FOREIGN KEY (`related_room_id`) REFERENCES `rooms` (`id`), + CONSTRAINT `staff_tasks_ibfk_6` FOREIGN KEY (`related_guest_request_id`) REFERENCES `guest_requests` (`id`), + CONSTRAINT `staff_tasks_ibfk_7` FOREIGN KEY (`related_maintenance_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 `staff_tasks` +-- + +LOCK TABLES `staff_tasks` WRITE; +/*!40000 ALTER TABLE `staff_tasks` DISABLE KEYS */; +/*!40000 ALTER TABLE `staff_tasks` 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=104 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'),(69,13,'jQqHJXKU2zBBZr17i3tsglhaCagJ0ECBvX-LJt7D5E730LOI0h_jbAxd5wtacMYe45Qb7qQdQ2i9RYGqtfTC9A','ctW0urXBQT2wqFAjXoi3qF9kYy2PoYGWJXHBviQPOnxYvObIpGJu_RGph1impcDqmRJcSojpxTZNRY8Sc7qTbA','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-03 20:37:11','2025-12-03 21:07:11','2025-12-03 20:37:11'),(70,13,'XrRkMi2xwahCxj4KTvX-o1PHQ3RjWikeugsLBT133uU54_F8QrgaWFAOOLwR0YG42UFR_O4UzkJFSZh2w6P2sg','qs4__-UqTw5GRq2ua-Vn232M4UTvFEBnsC3ACrQP1xFFaI0ZHBXBaeg_jsiYyLw0ycuKVBjygy0sZo_sOat3sg','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-03 20:53:37','2025-12-03 21:23:37','2025-12-03 20:53:37'),(71,3,'TjcLDAkOboGqqf5gjfGyHp4wOzbRr2fFNYhhm1d-9xmXZoeOphQ-vg8_BjuGXgbr2qKK0C_-MOXOaR86mF5q2Q','ZWVNbFSvkm_IKlq5zLT47XWWkgwZT-P9Cq0ditebBs0oW5Ur7zQ8KKypQpiCvCjhj7KPY_RRvtWpOnaN3GDdiQ','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-03 21:00:09','2025-12-03 21:30:09','2025-12-03 21:00:09'),(72,3,'tf4GHI0ntERn6iayQWL0777G_qthkZGk_7QnmbIrp_pF-HM3L6EG_lEVCUCDtWUGMr2qMfJQwF8g908De5KNdg','HxuYPcNQfnCai1f1JYR48-3mIIv-aIcrxtSr6qvcoCnSBXJVy5SA_ouzJGHnxdiz1STQbDDPusH2YDmjCAi9kg','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-03 21:07:22','2025-12-03 21:37:22','2025-12-03 21:07:22'),(73,13,'gOQ7Ze6aqadr3ANG4G3HLK8d8H0IE7YyM1MG5BMT19Skk1GhX7vtIxeAX6EjDU1lYs3so6OZakq5sC0a3gFrEw','FJjBMdUNhEUAZy5d7Ab6sFl3vDRvCBXP-rFdbU91fxBGOvYEqIhWlVQGxKl2EPESohChCxz6nW0df7RsBCafjQ','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-03 21:44:14','2025-12-03 22:14:14','2025-12-03 21:44:14'),(74,13,'2HJJ-bQWNTfKO_a0FvqPV5VJM-il5iUJdgGVol9eEiWGFNE8J18xw1R1TWU90PC61AxKk4W2l8X8AkhBU4k_Wg','jwsX04VseFmBG1sJ3qW-Ak2VVpT96pTtcSuwp3S6b4mTspHab-YqW-kAHr1mNWpSvfxDWMVjtLzt6MCZWml04w','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-03 21:57:59','2025-12-03 22:27:59','2025-12-03 21:57:59'),(75,13,'eZQWqGZtR2Cm6_hIOZUUixRUX0WHPSdWjZQFoj2njuXd_QZG_g1V1CGySPjrmADisvz65nNnTK2uiTGMUJYpjQ','9Fdtg8ZEiwKb-LHDruw5DeOYw7umHm3DsWyLN6DNs8QppgOeUXY1Pkk5jza6nYGaNhQ5kw4TJmBO893adiVJQw','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-03 21:59:57','2025-12-03 22:29:57','2025-12-03 21:59:57'),(76,3,'epoutWUM4EwdfMW6tcPwktiNiDrxBTNHPCQPHFla2MJbFvwZz3WWR1Iib812aKxZYnP0Wiiy-j12hx7s4l2V7Q','ytZ-GIUOrLUpdgJrvVer2egiPZwBTZeLyDa2GAbZFBnkWxtK6uPnp_M2wmE1rgjNBwQTp78Eruci-fFsIft8_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\'}',1,'2025-12-03 22:17:04','2025-12-03 22:47:04','2025-12-03 22:17:04'),(77,4,'pu26xxGeTpRORzyWnT5-FqrU8YrKyZnhqjPHfOHZEV4u-ceRacY-VlBVIWEOQXdamD5cCSw8HzVypACtTPGOpQ','FAYvg0hSKbYH4CdyZLYn9fGjXu02kW-Bw845fvlDzKzlM_EmuFXuxZeKbuvZg2_UI5OZfyR-GZzCUAWgmaS6IQ','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-03 22:48:51','2025-12-03 23:18:51','2025-12-03 22:48:51'),(78,4,'OMyf06zu3qF1drEwMFyOtnXLeEKpbjTC_nnCcv5z5DmlOsjzXQefhphwpHD-5BFI-78_7d8T0c81NDK3vTtHxg','SskD4qvwApDDo-PIPZ8OJPzX-AfpDLr3Rzmcak_O1Tm4-LMKmSxuNsC2n14avaBhawNR46vOxJ5g6ZpdbBBHvw','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-03 23:05:30','2025-12-03 23:35:30','2025-12-03 23:05:30'),(79,4,'k4qkJ5qM2bajCQjX0loM2PItCzeOq5czM7YG5XXF2zqez8SyPDNggrGownv3uHbv6z8B93FAUFF40TrhWwaLZQ','nwpu10l1yJjYnc8TFe5w2d2ABP60kdEB-omTXZUip4bpEfQF5RPyxV5fUUfRFAnJulynkxjc9gy8GkfTHFDm2g','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-04 09:44:08','2025-12-04 10:14:08','2025-12-04 09:44:08'),(80,12,'k5TCou9P3hzoQ4K-9GgWmGMA2-PGOYjWPOV26vm4BtjpUd1IQ3dtBHvWmhRqSu5rJ8nNqogjAUgryOjfuvmb8Q','DzCd3DnPbvHvmUUIuXEAh65-n3_sBvITDkGOrnI88I2VGyn7Oq9fo095VBdDm2gKGnRJPWCHCafK8E2JExxaGQ','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-04 09:53:08','2025-12-04 10:23:08','2025-12-04 09:53:08'),(81,12,'UMfyGsHNhuFH5iV8JMuxQAxpsm3V-Cz8QXn29DskIftYL6aL9-q9mL6FS6CtAEMXLgiTbC0Gu76j3wblWmKgUA','W5CaSezwAPE0pJLpGDGsvVNELe4HnCkNdPCvdzrS4gwswqCicWEg5OO1Z7noDHr30dt7A3xOYu8cgPs1a7Lp7g','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-04 10:39:05','2025-12-04 11:09:05','2025-12-04 10:39:05'),(82,3,'i7y3SwipUcNGntkZ7aSS5Gsqz-aUms0YDqTSuVAG0j_O0dNfkFX6_cYlz8rmb2FImXuY2v65L0CfBlpEm_Biww','gu6KTGtQ-5ndRyC94lVMPDCEtVN5tgTwoMR3FOCnkhgkH8k7KhXkFUXSVG1iPQBFPyQQSV6K4M28Rn_RjjzMFw','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-04 13:09:33','2025-12-04 13:39:33','2025-12-04 13:09:33'),(83,3,'61CLXwO-lhy1j4OqixG2QGqkbEXFOqkL8Baw7VI3chJ7gaF5bpbUQgmDHJSA-tGWZu5Xm8j3GWdf5fefpSquJw','LE5veAnU5qIXQoU3ovXJZkR4XKUvkS10ZKHeIoRsHRq7fRwMB1p6jpXzt7KofUUe_YMRLiwEpcBZA_9dPlhODw','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-04 18:04:50','2025-12-04 18:34:50','2025-12-04 18:04:50'),(84,13,'yYbWf2Ref7wwDs2dRl-GW-dtW2jxtC02m6tICJgZYFddNIlmxpjpzZt9DITikAkRWOjcmZb_Pm925NTCYxGhcQ','R2xrOUaFuTia_eUUrNZ47741FEcM1P5vPpWVGLfSwu-4dHra_RTOBu-QKlViZXIZRn2tEeiY5iNhk5hbshFq2Q','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-04 18:05:30','2025-12-04 18:35:30','2025-12-04 18:05:30'),(85,3,'0z01B-XQWemvC721efuEt8Fge201rxlyJWIHzKxDBn30CuKCWBmFPuutJUFD9BBsfXkm4uT5Xo9NMJRtTHvzEA','PE5aYsVSS92xXezzjTJZ8kv9ISQMr4rXeISblWVsYQ7BdZbuLo64Ez78MbxRjFGtAnVpyVXa7ycRJzUqTT8k8A','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-04 18:06:25','2025-12-04 18:36:25','2025-12-04 18:06:25'),(86,4,'zadZwfaHq1Gcr_RezYTxKiKbxF2WPDWDy8DFNwth6TbbRwGc491nsF_XldMsDbpJk_g3x6F0wi0FSp0Q1sQNDg','45p50d2uZzf6vd8F0htqvtt1I0o1XogBsyXfHj1T5Kb0EXvCU0sp-wr9Kw2d_eC8Y26G9YKbqDIRWQ7Zdcc6nw','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-04 20:41:12','2025-12-04 21:11:12','2025-12-04 20:41:12'),(87,5,'LaX9JNJxJMoasfNUECYY-NcmruzV6OHzkbUUZH0QzczIKwwNXjZ3QjeF-WrbxRtwiXq4tZmYYHEapYK9Syx0oA','uDmBEHtQpxJ8sIzZU7d_fdGK1RvO8Hkx02QyiKleVwVnSLX3IxTzdOdGq3tpLXsuwK5niSjLM7iV-n0ziiYFXw','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-04 20:41:45','2025-12-04 21:11:45','2025-12-04 20:41:45'),(88,4,'O5iyBYK_dEcCl45xr4AEusmJkNFUMf5ynnMYgaJB9whXAPgtznsJrnWgu9yI1zlxXPDowXTZS77AGp1EKbRvJA','mhrgvakjfOK_qorpwnvymMcb_75MeoYlGR5BnxAlvl5AYkfjOxVlFG-ZObGuKHuS1GOaG0zN-Nqgl0sMFT5pvA','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-04 20:42:30','2025-12-04 21:12:30','2025-12-04 20:42:30'),(89,5,'r5YPhBrF1awd3UaU_dN0eKdJ0ZV32dA875DI4oNQ7tTgM7CrcTZY2ilqszzFSQIULPsy6to3g7CXvKzlbbtSrg','bCCGPJjAjXjQZwfe6Lrzd1Xx6NPSCnzX3o4GYBURXI-4n1Zv0RtqXy8yyFNRd66eYfdpqdxkJsPnn-4wD0baAQ','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-04 20:43:09','2025-12-04 21:13:09','2025-12-04 20:43:09'),(90,3,'QOuucF2MJiNQpz74ltxh159k2LX_pfdXWp1TiS4BMC377nxAmyepepdJUeBAkJrhqUXDyDPlDl0chV_ehi3UHg','1SSRrHkGkBbI8v1IWtVIqH0RGhWofdxdTsK2aBDHwQIteB98Vlr-vZ2auvippcknjiyLR0q01fBuoJnMrpo3_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-04 20:49:11','2025-12-04 21:19:11','2025-12-04 20:49:11'),(91,3,'4ybD9wrActWMNwqeDDY3H0dNS_0Yhe5mo3c9kD9w4ilIj05A_Bt7OfjsKHjL-680MNXQxT3FIR6TBOvRFC32lw','GAcaKL6AhbY6Uvm6w6OlHfmNAudJkuxoXqgVm6UScflHC424j0eBV_WDpr31l9OI_ZNgajNTBuY7HHP7KMXFYw','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-04 20:53:12','2025-12-04 21:23:12','2025-12-04 20:53:12'),(92,3,'6VbdNmqEASv_DLEp4ROY3YqzF3eOjcntpTwdDx_YgGZNl35uY4AI0KAMA-EaK-TLBkTX5ZYfcRizBXM4B0h4lA','PsO68hWNZTLhUH00DVgJC2594MFPl7Fb23Nmwe6Eea301qAiQEe0aQKYNIGpw9pY7YdczfimWmFXw2-qN2SunQ','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-04 20:56:51','2025-12-04 21:26:51','2025-12-04 20:56:51'),(93,5,'HfStEqtMW7UYwUj6bpNfjzzGpyD-zyhQ30MJQ-OACPeNErRgdxDTth9l-5I9jr1mSC9fuFGr0TKOQxZoVTJY9Q','vnw2GG7HCk8dr9OE2vQQfbK5wUaDhrg8EuHGjCcIbi0USqelHBWRWE5i1M8uNBGEuPbo2JD3gsmTyz7nR-cZbA','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-04 21:10:53','2025-12-04 21:40:53','2025-12-04 21:10:53'),(94,3,'wnm4X9PlrkVGucRZhx2NYhBsrSOPzH-4TjRa6o7lcdAvNqwaSAeC6w3kPtpJuhDVk8HqZqNJJHUgAXien_YayQ','-T-4ESm4LhSGB-RmYutS7zh5gaiS3e3zyoBHs__xKH7CRqYyEjH1wKrFGt-602xMkG403l4xIW_TjfQcZ5CH5A','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-04 21:16:36','2025-12-04 21:46:36','2025-12-04 21:16:36'),(95,5,'RWmpq9D366Lcyd5PIs0nYCQvG8bp1aUVvvW2dixHzwqGM1raUiRa3hq4r-6ejld3epTPqMhCmtjGMQ5y6lZCvA','fRBbr7CCgjEW1vy6Or07JURPMOgQfduH0OaQO7EGOthlL2OwqeVJdRzxkzwel2JWix5FClH1t_QJfhI1MgwLtg','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-04 21:30:22','2025-12-04 22:00:22','2025-12-04 21:30:22'),(96,3,'vZW0SZ5gQ7T90yQQo9QL4BuP_jkc2XMqqtPnlzaJqfz6b7RsV0T0y-d3-6kIbxj6sdsj5cslrT-l59RnRd9OEA','x2dSnCxHxsMMt7uZP2aJbX6w9w0uWHac6la_pP-7fUURJftMEw7vYVYi2_D0n2WgItYanYm67FoUp7KynckclQ','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-04 21:57:12','2025-12-04 22:27:12','2025-12-04 21:57:12'),(97,3,'orCyfn68xka47vF4sFk6w_JkEeIyNrxgxCTIw5UqNj0pqIOVA1_SgvpKdva94xcgZ5B991QHh4BtfdMARq7nBQ','ybY8PvjLOYWUI6lPyy-LICFuvFyRj4g5gcJ9KyKbErrOktcpAgVhUnoDvV0AQCcMB55RM9bdyESNctIEGXPUXg','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-04 23:09:51','2025-12-04 23:39:51','2025-12-04 23:09:51'),(98,3,'UyatHXWy91EuNT4C4MlDu4CONhYvduSCJP3g1iahTfKIMusyWc_bQIOx2B4BstOgySHSp4r_94ZHs88PjrxvDw','dX6r2yGhbBxhgJI_bQ1QjU5PN033pvwfx1ar73T4SRgfx60TxDcpYHG_FgEomNGvlGe6Q_wMsHXSw_0QhXPXKg','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-04 23:48:07','2025-12-05 00:18:07','2025-12-04 23:48:07'),(99,3,'SxT_HNmY58nK5-SxgoCJeU0Az3LgvPD-lE-q6olV-nb1eqf6A-BeKiB9oqyh_mKYOvShKXFL2NnB-uU7NHPFNA','iRAWDsTXElzcWkZeTCnbYAS9rYFtmP5Uc9M0B5XRXOac6nMGd4c8rWIRk6OQIIoXv4DbOILy2zc69NgATII_7A','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-05 12:30:39','2025-12-05 13:00:39','2025-12-05 12:30:39'),(100,3,'0bu4gqAZUnkwbP-fmqZTCZtQHEKFzud1f_uF_TbCIUZK2DCITgYZCMCkijAzvUf23erVo7UPvVaFG1LQM23WwQ','S9lVhomfu0EQnwztJIwMXEI2Vhb1escIzQ9CFKRisSKpYpBN1QXe9m4DOw46-BcAH5YxOS2_ySRRfgDEuhW1Jw','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-05 13:00:56','2025-12-05 13:30:56','2025-12-05 13:00:56'),(101,3,'AuqMRRDrIKGTWsBBWGKTJWJHCZTDtD99lGs6MEBKiKd6ySGQYEinC9hPupHX5s7xH0EjCE7Uco_3wwWAcfompQ','aoWF2BQC4rGsciGVew6eIgBDVr8PokdokgliIIIi-bNHfw6flG17nMfIfZN6UqDug_aYMBKcz2cWJxhPwypp5A','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-05 13:25:12','2025-12-05 13:55:12','2025-12-05 13:25:12'),(102,3,'RuGwW4pgEuCKcov5b85mFbRUgX9_8HxuomevCIMITqipEj-v3Suu3ywVE04r1xzNrX9V481ldN094_Bul3hm_w','IcKm6R0LTQNN61kWpoG53NLE8sCTYeB3nSO_FWBnW3Twu0mcTk8nOn35TWRvc1-Kaq77qWqNdlEvZnIWpyIH7g','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-05 13:27:24','2025-12-05 13:57:24','2025-12-05 13:27:24'),(103,3,'X1isG0b7UEmXFHJYj2OW1CaVhAl5n17rDFALDthrWfR-VMpvQ5_EpvgPtL0ytcZ9iRzQa1EbOsO0jM8LrnDygw','XhOcTQ3XKsQpFVm9iQOiAKEfLS4iRVOEQH4G6yCZFeLyelrEGii1BzNZ-IiQFqYFK6Eyj1CEBBSaDKDT56vgmw','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-05 14:39:38','2025-12-05 15:09:38','2025-12-05 14:39:38'); +/*!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,'/uploads/avatars/avatar-12-fc6e2952-2e6d-45a6-900a-56cd31f89bf4.webp','VND',1,0,NULL,NULL,'2025-11-21 12:38:50','2025-12-04 09:53:29',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-05 16:43:58 diff --git a/Backend/seeds_data/seed_homepage_footer.py b/Backend/seeds_data/seed_homepage_footer.py index e41e5654..8b1dd1b4 100644 --- a/Backend/seeds_data/seed_homepage_footer.py +++ b/Backend/seeds_data/seed_homepage_footer.py @@ -74,7 +74,206 @@ def seed_homepage_content(db: Session): features = [{'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'}] testimonials = [{'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.'}] gallery_images = ['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'] - homepage_data = {'page_type': PageType.HOME, 'title': 'Luxury Hotel - Experience Unparalleled Elegance', 'subtitle': 'Where timeless luxury meets modern sophistication', 'description': 'Discover a world of refined elegance and exceptional service', 'hero_title': 'Welcome to Luxury', 'hero_subtitle': 'Experience the pinnacle of hospitality', 'hero_image': 'https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200', 'features': json.dumps(features), 'luxury_section_title': 'Experience Unparalleled Luxury', 'luxury_section_subtitle': 'Where elegance meets comfort in every detail', 'luxury_section_image': 'https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=1200', 'luxury_features': json.dumps(luxury_features), 'luxury_gallery_section_title': 'Our Luxury Gallery', 'luxury_gallery_section_subtitle': 'A glimpse into our world of elegance', 'luxury_gallery': json.dumps(luxury_gallery), 'luxury_testimonials_section_title': 'What Our Guests Say', 'luxury_testimonials_section_subtitle': 'Testimonials from our valued guests', 'luxury_testimonials': json.dumps(luxury_testimonials), 'luxury_services_section_title': 'Premium Services', 'luxury_services_section_subtitle': 'Indulge in our world-class amenities', 'luxury_services': json.dumps(luxury_services), 'luxury_experiences_section_title': 'Exclusive Experiences', 'luxury_experiences_section_subtitle': 'Create unforgettable memories', 'luxury_experiences': json.dumps(luxury_experiences), 'awards_section_title': 'Awards & Recognition', 'awards_section_subtitle': 'Recognized for excellence worldwide', 'awards': json.dumps(awards), 'partners_section_title': 'Our Partners', 'partners_section_subtitle': 'Trusted by leading brands', 'partners': json.dumps(partners), 'amenities_section_title': 'Premium Amenities', 'amenities_section_subtitle': 'Everything you need for a perfect stay', 'amenities': json.dumps(amenities), 'testimonials_section_title': 'Guest Reviews', 'testimonials_section_subtitle': 'Hear from our satisfied guests', 'testimonials': json.dumps(testimonials), 'gallery_section_title': 'Photo Gallery', 'gallery_section_subtitle': 'Explore our beautiful spaces', 'gallery_images': json.dumps(gallery_images), 'about_preview_title': 'About Our Luxury Hotel', 'about_preview_subtitle': 'A legacy of excellence', 'about_preview_content': '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.', 'about_preview_image': 'https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=800', 'stats': json.dumps(stats), 'cta_title': 'Ready to Experience Luxury?', 'cta_subtitle': 'Book your stay today and discover the difference', 'cta_button_text': 'Book Now', 'cta_button_link': '/rooms', 'cta_image': 'https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200', 'is_active': True} + + # Enterprise homepage fields + hero_video_url = 'https://videos.unsplash.com/video-1564501049412-61c2a3083791' + hero_video_poster = 'https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200' + features_section_title = 'Why Choose Us' + features_section_subtitle = 'Discover what makes us the perfect choice for your stay' + stats_section_title = 'Our Achievements' + stats_section_subtitle = 'Numbers that speak for themselves' + rooms_section_title = 'Luxurious Rooms & Suites' + rooms_section_subtitle = 'Experience comfort and elegance in every room' + rooms_section_button_text = 'View All Rooms' + rooms_section_button_link = '/rooms' + rooms_section_enabled = True + services_section_button_text = 'Explore All Services' + services_section_button_link = '/services' + services_section_limit = 4 + + # Sections enabled configuration + sections_enabled = { + 'features': True, + 'luxury': True, + 'gallery': True, + 'testimonials': True, + 'stats': True, + 'amenities': True, + 'about_preview': True, + 'services': True, + 'experiences': True, + 'awards': True, + 'cta': True, + 'partners': True, + 'rooms': True, + 'newsletter': True, + 'trust_badges': True, + 'promotions': True, + 'blog': True + } + + # Newsletter section + newsletter_section_title = 'Stay Connected' + newsletter_section_subtitle = 'Subscribe to our newsletter for exclusive offers and updates' + newsletter_placeholder = 'Enter your email address' + newsletter_button_text = 'Subscribe' + newsletter_enabled = True + + # Trust badges + trust_badges = [ + { + 'name': '5-Star Rating', + 'logo': 'https://images.unsplash.com/photo-1579783902614-a3fb3927b6a5?w=200', + 'description': 'Awarded 5 stars by leading travel organizations', + 'link': '#' + }, + { + 'name': 'TripAdvisor Excellence', + 'logo': 'https://images.unsplash.com/photo-1606761568499-6d2451b23c66?w=200', + 'description': 'Certificate of Excellence winner', + 'link': '#' + }, + { + 'name': 'Green Certified', + 'logo': 'https://images.unsplash.com/photo-1473341304170-971dccb5ac1e?w=200', + 'description': 'Eco-friendly and sustainable practices', + 'link': '#' + }, + { + 'name': 'Luxury Collection', + 'logo': 'https://images.unsplash.com/photo-1599305445671-ac291c95aaa9?w=200', + 'description': 'Member of the world\'s finest luxury hotels', + 'link': '#' + } + ] + trust_badges_section_title = 'Trusted & Recognized' + trust_badges_section_subtitle = 'Awards and certifications that validate our commitment to excellence' + trust_badges_enabled = True + + # Promotions + promotions = [ + { + 'title': 'Summer Special', + 'description': 'Enjoy 25% off on all room bookings this summer. Limited time offer!', + 'image': 'https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=600', + 'discount': '25% OFF', + 'valid_until': '2024-08-31', + 'link': '/rooms', + 'button_text': 'Book Now' + }, + { + 'title': 'Weekend Getaway', + 'description': 'Perfect weekend escape with complimentary breakfast and spa access', + 'image': 'https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=600', + 'discount': '30% OFF', + 'valid_until': '2024-12-31', + 'link': '/rooms', + 'button_text': 'Learn More' + }, + { + 'title': 'Honeymoon Package', + 'description': 'Romantic getaway with champagne, flowers, and special amenities', + 'image': 'https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=600', + 'discount': 'Special Rate', + 'valid_until': '2024-12-31', + 'link': '/rooms', + 'button_text': 'Book Package' + } + ] + promotions_section_title = 'Special Offers' + promotions_section_subtitle = 'Exclusive deals and packages designed just for you' + promotions_enabled = True + + # Blog section + blog_section_title = 'Latest News & Updates' + blog_section_subtitle = 'Stay informed about our latest news, events, and travel tips' + blog_posts_limit = 3 + blog_enabled = True + + homepage_data = { + 'page_type': PageType.HOME, + 'title': 'Luxury Hotel - Experience Unparalleled Elegance', + 'subtitle': 'Where timeless luxury meets modern sophistication', + 'description': 'Discover a world of refined elegance and exceptional service', + 'hero_title': 'Welcome to Luxury', + 'hero_subtitle': 'Experience the pinnacle of hospitality', + 'hero_image': 'https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200', + 'hero_video_url': hero_video_url, + 'hero_video_poster': hero_video_poster, + 'features': json.dumps(features), + 'features_section_title': features_section_title, + 'features_section_subtitle': features_section_subtitle, + 'luxury_section_title': 'Experience Unparalleled Luxury', + 'luxury_section_subtitle': 'Where elegance meets comfort in every detail', + 'luxury_section_image': 'https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=1200', + 'luxury_features': json.dumps(luxury_features), + 'luxury_gallery_section_title': 'Our Luxury Gallery', + 'luxury_gallery_section_subtitle': 'A glimpse into our world of elegance', + 'luxury_gallery': json.dumps(luxury_gallery), + 'luxury_testimonials_section_title': 'What Our Guests Say', + 'luxury_testimonials_section_subtitle': 'Testimonials from our valued guests', + 'luxury_testimonials': json.dumps(luxury_testimonials), + 'luxury_services_section_title': 'Premium Services', + 'luxury_services_section_subtitle': 'Indulge in our world-class amenities', + 'luxury_services': json.dumps(luxury_services), + 'services_section_button_text': services_section_button_text, + 'services_section_button_link': services_section_button_link, + 'services_section_limit': services_section_limit, + 'luxury_experiences_section_title': 'Exclusive Experiences', + 'luxury_experiences_section_subtitle': 'Create unforgettable memories', + 'luxury_experiences': json.dumps(luxury_experiences), + 'awards_section_title': 'Awards & Recognition', + 'awards_section_subtitle': 'Recognized for excellence worldwide', + 'awards': json.dumps(awards), + 'partners_section_title': 'Our Partners', + 'partners_section_subtitle': 'Trusted by leading brands', + 'partners': json.dumps(partners), + 'amenities_section_title': 'Premium Amenities', + 'amenities_section_subtitle': 'Everything you need for a perfect stay', + 'amenities': json.dumps(amenities), + 'testimonials_section_title': 'Guest Reviews', + 'testimonials_section_subtitle': 'Hear from our satisfied guests', + 'testimonials': json.dumps(testimonials), + 'gallery_section_title': 'Photo Gallery', + 'gallery_section_subtitle': 'Explore our beautiful spaces', + 'gallery_images': json.dumps(gallery_images), + 'about_preview_title': 'About Our Luxury Hotel', + 'about_preview_subtitle': 'A legacy of excellence', + 'about_preview_content': '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.', + 'about_preview_image': 'https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=800', + 'stats': json.dumps(stats), + 'stats_section_title': stats_section_title, + 'stats_section_subtitle': stats_section_subtitle, + 'rooms_section_title': rooms_section_title, + 'rooms_section_subtitle': rooms_section_subtitle, + 'rooms_section_button_text': rooms_section_button_text, + 'rooms_section_button_link': rooms_section_button_link, + 'rooms_section_enabled': rooms_section_enabled, + 'sections_enabled': json.dumps(sections_enabled), + 'newsletter_section_title': newsletter_section_title, + 'newsletter_section_subtitle': newsletter_section_subtitle, + 'newsletter_placeholder': newsletter_placeholder, + 'newsletter_button_text': newsletter_button_text, + 'newsletter_enabled': newsletter_enabled, + 'trust_badges_section_title': trust_badges_section_title, + 'trust_badges_section_subtitle': trust_badges_section_subtitle, + 'trust_badges': json.dumps(trust_badges), + 'trust_badges_enabled': trust_badges_enabled, + 'promotions_section_title': promotions_section_title, + 'promotions_section_subtitle': promotions_section_subtitle, + 'promotions': json.dumps(promotions), + 'promotions_enabled': promotions_enabled, + 'blog_section_title': blog_section_title, + 'blog_section_subtitle': blog_section_subtitle, + 'blog_posts_limit': blog_posts_limit, + 'blog_enabled': blog_enabled, + 'cta_title': 'Ready to Experience Luxury?', + 'cta_subtitle': 'Book your stay today and discover the difference', + 'cta_button_text': 'Book Now', + 'cta_button_link': '/rooms', + 'cta_image': 'https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200', + 'is_active': True + } if existing: for key, value in homepage_data.items(): if key != 'page_type': diff --git a/Backend/src/__pycache__/main.cpython-312.pyc b/Backend/src/__pycache__/main.cpython-312.pyc index 023dbee5..4382fed8 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/content/models/__pycache__/page_content.cpython-312.pyc b/Backend/src/content/models/__pycache__/page_content.cpython-312.pyc index 1f3365cf..d6b11905 100644 Binary files a/Backend/src/content/models/__pycache__/page_content.cpython-312.pyc and b/Backend/src/content/models/__pycache__/page_content.cpython-312.pyc differ diff --git a/Backend/src/content/models/page_content.py b/Backend/src/content/models/page_content.py index f2c466f3..53ee6c83 100644 --- a/Backend/src/content/models/page_content.py +++ b/Backend/src/content/models/page_content.py @@ -41,9 +41,13 @@ class PageContent(Base): hero_title = Column(String(500), nullable=True) hero_subtitle = Column(String(1000), nullable=True) hero_image = Column(String(1000), nullable=True) + hero_video_url = Column(Text, nullable=True) + hero_video_poster = Column(Text, nullable=True) story_content = Column(Text, nullable=True) values = Column(Text, nullable=True) features = Column(Text, nullable=True) + features_section_title = Column(Text, nullable=True) + features_section_subtitle = Column(Text, nullable=True) about_hero_image = Column(Text, nullable=True) mission = Column(Text, nullable=True) vision = Column(Text, nullable=True) @@ -74,8 +78,18 @@ class PageContent(Base): about_preview_content = Column(Text, nullable=True) about_preview_image = Column(String(1000), nullable=True) stats = Column(Text, nullable=True) + stats_section_title = Column(Text, nullable=True) + stats_section_subtitle = Column(Text, nullable=True) + rooms_section_title = Column(Text, nullable=True) + rooms_section_subtitle = Column(Text, nullable=True) + rooms_section_button_text = Column(Text, nullable=True) + rooms_section_button_link = Column(Text, nullable=True) + rooms_section_enabled = Column(Boolean, default=True, nullable=True) luxury_services_section_title = Column(Text, nullable=True) luxury_services_section_subtitle = Column(Text, nullable=True) + services_section_button_text = Column(Text, nullable=True) + services_section_button_link = Column(Text, nullable=True) + services_section_limit = Column(Integer, nullable=True) luxury_services = Column(Text, nullable=True) luxury_experiences_section_title = Column(Text, nullable=True) luxury_experiences_section_subtitle = Column(Text, nullable=True) @@ -91,6 +105,24 @@ class PageContent(Base): partners_section_title = Column(Text, nullable=True) partners_section_subtitle = Column(Text, nullable=True) partners = Column(Text, nullable=True) + sections_enabled = Column(Text, nullable=True) + newsletter_section_title = Column(Text, nullable=True) + newsletter_section_subtitle = Column(Text, nullable=True) + newsletter_placeholder = Column(Text, nullable=True) + newsletter_button_text = Column(Text, nullable=True) + newsletter_enabled = Column(Boolean, default=False, nullable=True) + trust_badges_section_title = Column(Text, nullable=True) + trust_badges_section_subtitle = Column(Text, nullable=True) + trust_badges = Column(Text, nullable=True) + trust_badges_enabled = Column(Boolean, default=False, nullable=True) + promotions_section_title = Column(Text, nullable=True) + promotions_section_subtitle = Column(Text, nullable=True) + promotions = Column(Text, nullable=True) + promotions_enabled = Column(Boolean, default=False, nullable=True) + blog_section_title = Column(Text, nullable=True) + blog_section_subtitle = Column(Text, nullable=True) + blog_posts_limit = Column(Integer, nullable=True) + blog_enabled = Column(Boolean, default=False, nullable=True) is_active = Column(Boolean, default=True, nullable=False) created_at = Column(DateTime, default=datetime.utcnow, nullable=False) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) \ No newline at end of file diff --git a/Backend/src/content/routes/__pycache__/contact_routes.cpython-312.pyc b/Backend/src/content/routes/__pycache__/contact_routes.cpython-312.pyc index 961fbb12..563a58a6 100644 Binary files a/Backend/src/content/routes/__pycache__/contact_routes.cpython-312.pyc and b/Backend/src/content/routes/__pycache__/contact_routes.cpython-312.pyc differ diff --git a/Backend/src/content/routes/__pycache__/home_routes.cpython-312.pyc b/Backend/src/content/routes/__pycache__/home_routes.cpython-312.pyc index bfe13d86..28d5bd2c 100644 Binary files a/Backend/src/content/routes/__pycache__/home_routes.cpython-312.pyc and b/Backend/src/content/routes/__pycache__/home_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 8fee1c20..820ac405 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/contact_routes.py b/Backend/src/content/routes/contact_routes.py index 3470cc05..2a8a101f 100644 --- a/Backend/src/content/routes/contact_routes.py +++ b/Backend/src/content/routes/contact_routes.py @@ -8,7 +8,7 @@ from ...auth.models.user import User from ...auth.models.role import Role from ...system.models.system_settings import SystemSettings from ...shared.utils.mailer import send_email -from ...shared.utils.html_sanitizer import sanitize_text_for_html +from ...shared.utils.sanitization import sanitize_text_for_html logger = logging.getLogger(__name__) router = APIRouter(prefix='/contact', tags=['contact']) diff --git a/Backend/src/content/routes/home_routes.py b/Backend/src/content/routes/home_routes.py index 85f809e8..9ab2684e 100644 --- a/Backend/src/content/routes/home_routes.py +++ b/Backend/src/content/routes/home_routes.py @@ -41,9 +41,13 @@ def serialize_page_content(content: PageContent) -> dict: 'hero_title': content.hero_title, 'hero_subtitle': content.hero_subtitle, 'hero_image': content.hero_image, + 'hero_video_url': content.hero_video_url, + 'hero_video_poster': content.hero_video_poster, 'story_content': content.story_content, 'values': safe_json_loads(content.values, []), 'features': safe_json_loads(content.features, []), + 'features_section_title': content.features_section_title, + 'features_section_subtitle': content.features_section_subtitle, 'about_hero_image': content.about_hero_image, 'mission': content.mission, 'vision': content.vision, @@ -74,8 +78,18 @@ def serialize_page_content(content: PageContent) -> dict: 'about_preview_content': content.about_preview_content, 'about_preview_image': content.about_preview_image, 'stats': safe_json_loads(content.stats, []), + 'stats_section_title': content.stats_section_title, + 'stats_section_subtitle': content.stats_section_subtitle, + 'rooms_section_title': content.rooms_section_title, + 'rooms_section_subtitle': content.rooms_section_subtitle, + 'rooms_section_button_text': content.rooms_section_button_text, + 'rooms_section_button_link': content.rooms_section_button_link, + 'rooms_section_enabled': content.rooms_section_enabled, 'luxury_services_section_title': content.luxury_services_section_title, 'luxury_services_section_subtitle': content.luxury_services_section_subtitle, + 'services_section_button_text': content.services_section_button_text, + 'services_section_button_link': content.services_section_button_link, + 'services_section_limit': content.services_section_limit, 'luxury_services': safe_json_loads(content.luxury_services, []), 'luxury_experiences_section_title': content.luxury_experiences_section_title, 'luxury_experiences_section_subtitle': content.luxury_experiences_section_subtitle, @@ -91,6 +105,24 @@ def serialize_page_content(content: PageContent) -> dict: 'partners_section_title': content.partners_section_title, 'partners_section_subtitle': content.partners_section_subtitle, 'partners': safe_json_loads(content.partners, []), + 'sections_enabled': safe_json_loads(content.sections_enabled, {}), + 'newsletter_section_title': content.newsletter_section_title, + 'newsletter_section_subtitle': content.newsletter_section_subtitle, + 'newsletter_placeholder': content.newsletter_placeholder, + 'newsletter_button_text': content.newsletter_button_text, + 'newsletter_enabled': content.newsletter_enabled, + 'trust_badges_section_title': content.trust_badges_section_title, + 'trust_badges_section_subtitle': content.trust_badges_section_subtitle, + 'trust_badges': safe_json_loads(content.trust_badges, []), + 'trust_badges_enabled': content.trust_badges_enabled, + 'promotions_section_title': content.promotions_section_title, + 'promotions_section_subtitle': content.promotions_section_subtitle, + 'promotions': safe_json_loads(content.promotions, []), + 'promotions_enabled': content.promotions_enabled, + 'blog_section_title': content.blog_section_title, + 'blog_section_subtitle': content.blog_section_subtitle, + 'blog_posts_limit': content.blog_posts_limit, + 'blog_enabled': content.blog_enabled, 'is_active': content.is_active, 'created_at': content.created_at.isoformat() if content.created_at else None, 'updated_at': content.updated_at.isoformat() if content.updated_at else None diff --git a/Backend/src/content/routes/page_content_routes.py b/Backend/src/content/routes/page_content_routes.py index 47e881fc..6c5d7d61 100644 --- a/Backend/src/content/routes/page_content_routes.py +++ b/Backend/src/content/routes/page_content_routes.py @@ -14,17 +14,143 @@ from ...security.middleware.auth import get_current_user, authorize_roles from ...auth.models.user import User from ..models.page_content import PageContent, PageType from ..schemas.page_content import PageContentUpdateRequest -from ...shared.utils.html_sanitizer import sanitize_html +from ...shared.utils.sanitization import sanitize_html logger = get_logger(__name__) router = APIRouter(prefix='/page-content', tags=['page-content']) +def build_content_dict(content: PageContent) -> dict: + """Helper function to build content dictionary from PageContent model.""" + json_fields = ['contact_info', 'social_links', 'footer_links', 'badges', 'values', 'features', + 'amenities', 'testimonials', 'gallery_images', 'stats', 'luxury_features', + 'luxury_gallery', 'luxury_testimonials', 'luxury_services', 'luxury_experiences', + 'awards', 'partners', 'team', 'timeline', 'achievements', 'sections_enabled', + 'trust_badges', 'promotions'] + + def parse_json_field(field_value): + if field_value is None: + return None + try: + return json.loads(field_value) if isinstance(field_value, str) else field_value + except (json.JSONDecodeError, TypeError): + return field_value + + return { + 'id': content.id, + 'page_type': content.page_type.value, + 'title': content.title, + 'subtitle': content.subtitle, + 'description': content.description, + 'content': content.content, + 'meta_title': content.meta_title, + 'meta_description': content.meta_description, + 'meta_keywords': content.meta_keywords, + 'og_title': content.og_title, + 'og_description': content.og_description, + 'og_image': content.og_image, + 'canonical_url': content.canonical_url, + 'contact_info': parse_json_field(content.contact_info), + 'map_url': content.map_url, + 'social_links': parse_json_field(content.social_links), + 'footer_links': parse_json_field(content.footer_links), + 'badges': parse_json_field(content.badges), + 'copyright_text': content.copyright_text, + 'hero_title': content.hero_title, + 'hero_subtitle': content.hero_subtitle, + 'hero_image': content.hero_image, + 'hero_video_url': content.hero_video_url, + 'hero_video_poster': content.hero_video_poster, + 'story_content': content.story_content, + 'values': parse_json_field(content.values), + 'features': parse_json_field(content.features), + 'features_section_title': content.features_section_title, + 'features_section_subtitle': content.features_section_subtitle, + 'about_hero_image': content.about_hero_image, + 'mission': content.mission, + 'vision': content.vision, + 'team': parse_json_field(content.team), + 'timeline': parse_json_field(content.timeline), + 'achievements': parse_json_field(content.achievements), + 'amenities_section_title': content.amenities_section_title, + 'amenities_section_subtitle': content.amenities_section_subtitle, + 'amenities': parse_json_field(content.amenities), + 'testimonials_section_title': content.testimonials_section_title, + 'testimonials_section_subtitle': content.testimonials_section_subtitle, + 'testimonials': parse_json_field(content.testimonials), + 'gallery_section_title': content.gallery_section_title, + 'gallery_section_subtitle': content.gallery_section_subtitle, + 'gallery_images': parse_json_field(content.gallery_images), + 'luxury_section_title': content.luxury_section_title, + 'luxury_section_subtitle': content.luxury_section_subtitle, + 'luxury_section_image': content.luxury_section_image, + 'luxury_features': parse_json_field(content.luxury_features), + 'luxury_gallery_section_title': content.luxury_gallery_section_title, + 'luxury_gallery_section_subtitle': content.luxury_gallery_section_subtitle, + 'luxury_gallery': parse_json_field(content.luxury_gallery), + 'luxury_testimonials_section_title': content.luxury_testimonials_section_title, + 'luxury_testimonials_section_subtitle': content.luxury_testimonials_section_subtitle, + 'luxury_testimonials': parse_json_field(content.luxury_testimonials), + 'about_preview_title': content.about_preview_title, + 'about_preview_subtitle': content.about_preview_subtitle, + 'about_preview_content': content.about_preview_content, + 'about_preview_image': content.about_preview_image, + 'stats': parse_json_field(content.stats), + 'stats_section_title': content.stats_section_title, + 'stats_section_subtitle': content.stats_section_subtitle, + 'rooms_section_title': content.rooms_section_title, + 'rooms_section_subtitle': content.rooms_section_subtitle, + 'rooms_section_button_text': content.rooms_section_button_text, + 'rooms_section_button_link': content.rooms_section_button_link, + 'rooms_section_enabled': content.rooms_section_enabled, + 'luxury_services_section_title': content.luxury_services_section_title, + 'luxury_services_section_subtitle': content.luxury_services_section_subtitle, + 'services_section_button_text': content.services_section_button_text, + 'services_section_button_link': content.services_section_button_link, + 'services_section_limit': content.services_section_limit, + 'luxury_services': parse_json_field(content.luxury_services), + 'luxury_experiences_section_title': content.luxury_experiences_section_title, + 'luxury_experiences_section_subtitle': content.luxury_experiences_section_subtitle, + 'luxury_experiences': parse_json_field(content.luxury_experiences), + 'awards_section_title': content.awards_section_title, + 'awards_section_subtitle': content.awards_section_subtitle, + 'awards': parse_json_field(content.awards), + 'cta_title': content.cta_title, + 'cta_subtitle': content.cta_subtitle, + 'cta_button_text': content.cta_button_text, + 'cta_button_link': content.cta_button_link, + 'cta_image': content.cta_image, + 'partners_section_title': content.partners_section_title, + 'partners_section_subtitle': content.partners_section_subtitle, + 'partners': parse_json_field(content.partners), + 'sections_enabled': parse_json_field(content.sections_enabled), + 'newsletter_section_title': content.newsletter_section_title, + 'newsletter_section_subtitle': content.newsletter_section_subtitle, + 'newsletter_placeholder': content.newsletter_placeholder, + 'newsletter_button_text': content.newsletter_button_text, + 'newsletter_enabled': content.newsletter_enabled, + 'trust_badges_section_title': content.trust_badges_section_title, + 'trust_badges_section_subtitle': content.trust_badges_section_subtitle, + 'trust_badges': parse_json_field(content.trust_badges), + 'trust_badges_enabled': content.trust_badges_enabled, + 'promotions_section_title': content.promotions_section_title, + 'promotions_section_subtitle': content.promotions_section_subtitle, + 'promotions': parse_json_field(content.promotions), + 'promotions_enabled': content.promotions_enabled, + 'blog_section_title': content.blog_section_title, + 'blog_section_subtitle': content.blog_section_subtitle, + 'blog_posts_limit': content.blog_posts_limit, + 'blog_enabled': content.blog_enabled, + 'is_active': content.is_active, + 'created_at': content.created_at.isoformat() if content.created_at else None, + 'updated_at': content.updated_at.isoformat() if content.updated_at else None + } + @router.get('/') async def get_all_page_contents(db: Session=Depends(get_db)): try: contents = db.query(PageContent).all() result = [] for content in contents: - content_dict = {'id': content.id, 'page_type': content.page_type.value, 'title': content.title, 'subtitle': content.subtitle, 'description': content.description, 'content': content.content, 'meta_title': content.meta_title, 'meta_description': content.meta_description, 'meta_keywords': content.meta_keywords, 'og_title': content.og_title, 'og_description': content.og_description, 'og_image': content.og_image, 'canonical_url': content.canonical_url, 'contact_info': json.loads(content.contact_info) if content.contact_info else None, 'map_url': content.map_url, 'social_links': json.loads(content.social_links) if content.social_links else None, 'footer_links': json.loads(content.footer_links) if content.footer_links else None, 'badges': json.loads(content.badges) if content.badges else None, 'copyright_text': content.copyright_text, 'hero_title': content.hero_title, 'hero_subtitle': content.hero_subtitle, 'hero_image': content.hero_image, 'story_content': content.story_content, 'values': json.loads(content.values) if content.values else None, 'features': json.loads(content.features) if content.features else None, 'about_hero_image': content.about_hero_image, 'mission': content.mission, 'vision': content.vision, 'team': json.loads(content.team) if content.team else None, 'timeline': json.loads(content.timeline) if content.timeline else None, 'achievements': json.loads(content.achievements) if content.achievements else None, 'amenities_section_title': content.amenities_section_title, 'amenities_section_subtitle': content.amenities_section_subtitle, 'amenities': json.loads(content.amenities) if content.amenities else None, 'testimonials_section_title': content.testimonials_section_title, 'testimonials_section_subtitle': content.testimonials_section_subtitle, 'testimonials': json.loads(content.testimonials) if content.testimonials else None, 'gallery_section_title': content.gallery_section_title, 'gallery_section_subtitle': content.gallery_section_subtitle, 'gallery_images': json.loads(content.gallery_images) if content.gallery_images else None, 'luxury_section_title': content.luxury_section_title, 'luxury_section_subtitle': content.luxury_section_subtitle, 'luxury_section_image': content.luxury_section_image, 'luxury_features': json.loads(content.luxury_features) if content.luxury_features else None, 'luxury_gallery_section_title': content.luxury_gallery_section_title, 'luxury_gallery_section_subtitle': content.luxury_gallery_section_subtitle, 'luxury_gallery': json.loads(content.luxury_gallery) if content.luxury_gallery else None, 'luxury_testimonials_section_title': content.luxury_testimonials_section_title, 'luxury_testimonials_section_subtitle': content.luxury_testimonials_section_subtitle, 'luxury_testimonials': json.loads(content.luxury_testimonials) if content.luxury_testimonials else None, 'about_preview_title': content.about_preview_title, 'about_preview_subtitle': content.about_preview_subtitle, 'about_preview_content': content.about_preview_content, 'about_preview_image': content.about_preview_image, 'stats': json.loads(content.stats) if content.stats else None, 'luxury_services_section_title': content.luxury_services_section_title, 'luxury_services_section_subtitle': content.luxury_services_section_subtitle, 'luxury_services': json.loads(content.luxury_services) if content.luxury_services else None, 'luxury_experiences_section_title': content.luxury_experiences_section_title, 'luxury_experiences_section_subtitle': content.luxury_experiences_section_subtitle, 'luxury_experiences': json.loads(content.luxury_experiences) if content.luxury_experiences else None, 'awards_section_title': content.awards_section_title, 'awards_section_subtitle': content.awards_section_subtitle, 'awards': json.loads(content.awards) if content.awards else None, 'cta_title': content.cta_title, 'cta_subtitle': content.cta_subtitle, 'cta_button_text': content.cta_button_text, 'cta_button_link': content.cta_button_link, 'cta_image': content.cta_image, 'partners_section_title': content.partners_section_title, 'partners_section_subtitle': content.partners_section_subtitle, 'partners': json.loads(content.partners) if content.partners else None, 'is_active': content.is_active, 'created_at': content.created_at.isoformat() if content.created_at else None, 'updated_at': content.updated_at.isoformat() if content.updated_at else None} + content_dict = build_content_dict(content) result.append(content_dict) return {'status': 'success', 'data': {'page_contents': result}} except Exception as e: @@ -101,7 +227,7 @@ async def get_page_content(page_type: PageType, db: Session=Depends(get_db)): content = db.query(PageContent).filter(PageContent.page_type == page_type).first() if not content: return {'status': 'success', 'data': {'page_content': None}} - content_dict = {'id': content.id, 'page_type': content.page_type.value, 'title': content.title, 'subtitle': content.subtitle, 'description': content.description, 'content': content.content, 'meta_title': content.meta_title, 'meta_description': content.meta_description, 'meta_keywords': content.meta_keywords, 'og_title': content.og_title, 'og_description': content.og_description, 'og_image': content.og_image, 'canonical_url': content.canonical_url, 'contact_info': json.loads(content.contact_info) if content.contact_info else None, 'map_url': content.map_url, 'social_links': json.loads(content.social_links) if content.social_links else None, 'footer_links': json.loads(content.footer_links) if content.footer_links else None, 'badges': json.loads(content.badges) if content.badges else None, 'copyright_text': content.copyright_text, 'hero_title': content.hero_title, 'hero_subtitle': content.hero_subtitle, 'hero_image': content.hero_image, 'story_content': content.story_content, 'values': json.loads(content.values) if content.values else None, 'features': json.loads(content.features) if content.features else None, 'about_hero_image': content.about_hero_image, 'mission': content.mission, 'vision': content.vision, 'team': json.loads(content.team) if content.team else None, 'timeline': json.loads(content.timeline) if content.timeline else None, 'achievements': json.loads(content.achievements) if content.achievements else None, 'amenities_section_title': content.amenities_section_title, 'amenities_section_subtitle': content.amenities_section_subtitle, 'amenities': json.loads(content.amenities) if content.amenities else None, 'testimonials_section_title': content.testimonials_section_title, 'testimonials_section_subtitle': content.testimonials_section_subtitle, 'testimonials': json.loads(content.testimonials) if content.testimonials else None, 'gallery_section_title': content.gallery_section_title, 'gallery_section_subtitle': content.gallery_section_subtitle, 'gallery_images': json.loads(content.gallery_images) if content.gallery_images else None, 'luxury_section_title': content.luxury_section_title, 'luxury_section_subtitle': content.luxury_section_subtitle, 'luxury_section_image': content.luxury_section_image, 'luxury_features': json.loads(content.luxury_features) if content.luxury_features else None, 'luxury_gallery_section_title': content.luxury_gallery_section_title, 'luxury_gallery_section_subtitle': content.luxury_gallery_section_subtitle, 'luxury_gallery': json.loads(content.luxury_gallery) if content.luxury_gallery else None, 'luxury_testimonials_section_title': content.luxury_testimonials_section_title, 'luxury_testimonials_section_subtitle': content.luxury_testimonials_section_subtitle, 'luxury_testimonials': json.loads(content.luxury_testimonials) if content.luxury_testimonials else None, 'about_preview_title': content.about_preview_title, 'about_preview_subtitle': content.about_preview_subtitle, 'about_preview_content': content.about_preview_content, 'about_preview_image': content.about_preview_image, 'stats': json.loads(content.stats) if content.stats else None, 'luxury_services_section_title': content.luxury_services_section_title, 'luxury_services_section_subtitle': content.luxury_services_section_subtitle, 'luxury_services': json.loads(content.luxury_services) if content.luxury_services else None, 'luxury_experiences_section_title': content.luxury_experiences_section_title, 'luxury_experiences_section_subtitle': content.luxury_experiences_section_subtitle, 'luxury_experiences': json.loads(content.luxury_experiences) if content.luxury_experiences else None, 'awards_section_title': content.awards_section_title, 'awards_section_subtitle': content.awards_section_subtitle, 'awards': json.loads(content.awards) if content.awards else None, 'cta_title': content.cta_title, 'cta_subtitle': content.cta_subtitle, 'cta_button_text': content.cta_button_text, 'cta_button_link': content.cta_button_link, 'cta_image': content.cta_image, 'partners_section_title': content.partners_section_title, 'partners_section_subtitle': content.partners_section_subtitle, 'partners': json.loads(content.partners) if content.partners else None, 'is_active': content.is_active, 'created_at': content.created_at.isoformat() if content.created_at else None, 'updated_at': content.updated_at.isoformat() if content.updated_at else None} + content_dict = build_content_dict(content) return {'status': 'success', 'data': {'page_content': content_dict}} except Exception as e: db.rollback() @@ -299,7 +425,7 @@ async def update_page_content(page_type: PageType, page_data: PageContentUpdateR for key, value in update_dict.items(): if hasattr(existing_content, key): # Convert dict/list to JSON string for JSON fields - json_fields = ['contact_info', 'social_links', 'footer_links', 'badges', 'values', 'features', 'amenities', 'testimonials', 'gallery_images', 'stats', 'luxury_features', 'luxury_gallery', 'luxury_testimonials', 'luxury_services', 'luxury_experiences', 'awards', 'partners', 'team', 'timeline', 'achievements'] + json_fields = ['contact_info', 'social_links', 'footer_links', 'badges', 'values', 'features', 'amenities', 'testimonials', 'gallery_images', 'stats', 'luxury_features', 'luxury_gallery', 'luxury_testimonials', 'luxury_services', 'luxury_experiences', 'awards', 'partners', 'team', 'timeline', 'achievements', 'sections_enabled', 'trust_badges', 'promotions'] if key in json_fields and value is not None: if isinstance(value, (dict, list)): value = json.dumps(value) @@ -318,7 +444,7 @@ async def update_page_content(page_type: PageType, page_data: PageContentUpdateR existing_content.updated_at = datetime.utcnow() db.commit() db.refresh(existing_content) - content_dict = {'id': existing_content.id, 'page_type': existing_content.page_type.value, 'title': existing_content.title, 'subtitle': existing_content.subtitle, 'description': existing_content.description, 'content': existing_content.content, 'meta_title': existing_content.meta_title, 'meta_description': existing_content.meta_description, 'meta_keywords': existing_content.meta_keywords, 'og_title': existing_content.og_title, 'og_description': existing_content.og_description, 'og_image': existing_content.og_image, 'canonical_url': existing_content.canonical_url, 'contact_info': json.loads(existing_content.contact_info) if existing_content.contact_info else None, 'map_url': existing_content.map_url, 'social_links': json.loads(existing_content.social_links) if existing_content.social_links else None, 'footer_links': json.loads(existing_content.footer_links) if existing_content.footer_links else None, 'badges': json.loads(existing_content.badges) if existing_content.badges else None, 'copyright_text': existing_content.copyright_text, 'hero_title': existing_content.hero_title, 'hero_subtitle': existing_content.hero_subtitle, 'hero_image': existing_content.hero_image, 'story_content': existing_content.story_content, 'values': json.loads(existing_content.values) if existing_content.values else None, 'features': json.loads(existing_content.features) if existing_content.features else None, 'about_hero_image': existing_content.about_hero_image, 'mission': existing_content.mission, 'vision': existing_content.vision, 'team': json.loads(existing_content.team) if existing_content.team else None, 'timeline': json.loads(existing_content.timeline) if existing_content.timeline else None, 'achievements': json.loads(existing_content.achievements) if existing_content.achievements else None, 'amenities_section_title': existing_content.amenities_section_title, 'amenities_section_subtitle': existing_content.amenities_section_subtitle, 'amenities': json.loads(existing_content.amenities) if existing_content.amenities else None, 'testimonials_section_title': existing_content.testimonials_section_title, 'testimonials_section_subtitle': existing_content.testimonials_section_subtitle, 'testimonials': json.loads(existing_content.testimonials) if existing_content.testimonials else None, 'gallery_section_title': existing_content.gallery_section_title, 'gallery_section_subtitle': existing_content.gallery_section_subtitle, 'gallery_images': json.loads(existing_content.gallery_images) if existing_content.gallery_images else None, 'luxury_section_title': existing_content.luxury_section_title, 'luxury_section_subtitle': existing_content.luxury_section_subtitle, 'luxury_section_image': existing_content.luxury_section_image, 'luxury_features': json.loads(existing_content.luxury_features) if existing_content.luxury_features else None, 'luxury_gallery_section_title': existing_content.luxury_gallery_section_title, 'luxury_gallery_section_subtitle': existing_content.luxury_gallery_section_subtitle, 'luxury_gallery': json.loads(existing_content.luxury_gallery) if existing_content.luxury_gallery else None, 'luxury_testimonials_section_title': existing_content.luxury_testimonials_section_title, 'luxury_testimonials_section_subtitle': existing_content.luxury_testimonials_section_subtitle, 'luxury_testimonials': json.loads(existing_content.luxury_testimonials) if existing_content.luxury_testimonials else None, 'about_preview_title': existing_content.about_preview_title, 'about_preview_subtitle': existing_content.about_preview_subtitle, 'about_preview_content': existing_content.about_preview_content, 'about_preview_image': existing_content.about_preview_image, 'stats': json.loads(existing_content.stats) if existing_content.stats else None, 'luxury_services_section_title': existing_content.luxury_services_section_title, 'luxury_services_section_subtitle': existing_content.luxury_services_section_subtitle, 'luxury_services': json.loads(existing_content.luxury_services) if existing_content.luxury_services else None, 'luxury_experiences_section_title': existing_content.luxury_experiences_section_title, 'luxury_experiences_section_subtitle': existing_content.luxury_experiences_section_subtitle, 'luxury_experiences': json.loads(existing_content.luxury_experiences) if existing_content.luxury_experiences else None, 'awards_section_title': existing_content.awards_section_title, 'awards_section_subtitle': existing_content.awards_section_subtitle, 'awards': json.loads(existing_content.awards) if existing_content.awards else None, 'cta_title': existing_content.cta_title, 'cta_subtitle': existing_content.cta_subtitle, 'cta_button_text': existing_content.cta_button_text, 'cta_button_link': existing_content.cta_button_link, 'cta_image': existing_content.cta_image, 'partners_section_title': existing_content.partners_section_title, 'partners_section_subtitle': existing_content.partners_section_subtitle, 'partners': json.loads(existing_content.partners) if existing_content.partners else None, 'is_active': existing_content.is_active, 'updated_at': existing_content.updated_at.isoformat() if existing_content.updated_at else None} + content_dict = build_content_dict(existing_content) return {'status': 'success', 'message': 'Page content updated successfully', 'data': {'page_content': content_dict}} except ValidationError as e: db.rollback() diff --git a/Backend/src/content/schemas/__pycache__/page_content.cpython-312.pyc b/Backend/src/content/schemas/__pycache__/page_content.cpython-312.pyc index 94dd9de0..ac941a19 100644 Binary files a/Backend/src/content/schemas/__pycache__/page_content.cpython-312.pyc and b/Backend/src/content/schemas/__pycache__/page_content.cpython-312.pyc differ diff --git a/Backend/src/content/schemas/page_content.py b/Backend/src/content/schemas/page_content.py index e58507cb..f110e3c0 100644 --- a/Backend/src/content/schemas/page_content.py +++ b/Backend/src/content/schemas/page_content.py @@ -27,9 +27,13 @@ class PageContentUpdateRequest(BaseModel): hero_title: Optional[str] = Field(None, max_length=500) hero_subtitle: Optional[str] = Field(None, max_length=1000) hero_image: Optional[str] = Field(None, max_length=1000) + hero_video_url: Optional[str] = Field(None, max_length=1000) + hero_video_poster: Optional[str] = Field(None, max_length=1000) story_content: Optional[str] = None values: Optional[Union[str, List[Dict[str, Any]]]] = None features: Optional[Union[str, List[Dict[str, Any]]]] = None + features_section_title: Optional[str] = Field(None, max_length=500) + features_section_subtitle: Optional[str] = Field(None, max_length=1000) about_hero_image: Optional[str] = Field(None, max_length=1000) mission: Optional[str] = Field(None, max_length=2000) vision: Optional[str] = Field(None, max_length=2000) @@ -60,8 +64,18 @@ class PageContentUpdateRequest(BaseModel): about_preview_content: Optional[str] = None about_preview_image: Optional[str] = Field(None, max_length=1000) stats: Optional[Union[str, List[Dict[str, Any]]]] = None + stats_section_title: Optional[str] = Field(None, max_length=500) + stats_section_subtitle: Optional[str] = Field(None, max_length=1000) + rooms_section_title: Optional[str] = Field(None, max_length=500) + rooms_section_subtitle: Optional[str] = Field(None, max_length=1000) + rooms_section_button_text: Optional[str] = Field(None, max_length=200) + rooms_section_button_link: Optional[str] = Field(None, max_length=1000) + rooms_section_enabled: Optional[bool] = None luxury_services_section_title: Optional[str] = Field(None, max_length=500) luxury_services_section_subtitle: Optional[str] = Field(None, max_length=1000) + services_section_button_text: Optional[str] = Field(None, max_length=200) + services_section_button_link: Optional[str] = Field(None, max_length=1000) + services_section_limit: Optional[int] = None luxury_services: Optional[Union[str, List[Dict[str, Any]]]] = None luxury_experiences_section_title: Optional[str] = Field(None, max_length=500) luxury_experiences_section_subtitle: Optional[str] = Field(None, max_length=1000) @@ -77,6 +91,24 @@ class PageContentUpdateRequest(BaseModel): partners_section_title: Optional[str] = Field(None, max_length=500) partners_section_subtitle: Optional[str] = Field(None, max_length=1000) partners: Optional[Union[str, List[Dict[str, Any]]]] = None + sections_enabled: Optional[Union[str, Dict[str, bool]]] = None + newsletter_section_title: Optional[str] = Field(None, max_length=500) + newsletter_section_subtitle: Optional[str] = Field(None, max_length=1000) + newsletter_placeholder: Optional[str] = Field(None, max_length=200) + newsletter_button_text: Optional[str] = Field(None, max_length=200) + newsletter_enabled: Optional[bool] = None + trust_badges_section_title: Optional[str] = Field(None, max_length=500) + trust_badges_section_subtitle: Optional[str] = Field(None, max_length=1000) + trust_badges: Optional[Union[str, List[Dict[str, Any]]]] = None + trust_badges_enabled: Optional[bool] = None + promotions_section_title: Optional[str] = Field(None, max_length=500) + promotions_section_subtitle: Optional[str] = Field(None, max_length=1000) + promotions: Optional[Union[str, List[Dict[str, Any]]]] = None + promotions_enabled: Optional[bool] = None + blog_section_title: Optional[str] = Field(None, max_length=500) + blog_section_subtitle: Optional[str] = Field(None, max_length=1000) + blog_posts_limit: Optional[int] = None + blog_enabled: Optional[bool] = None copyright_text: Optional[str] = Field(None, max_length=500) is_active: Optional[bool] = True @@ -84,7 +116,8 @@ class PageContentUpdateRequest(BaseModel): 'features', 'amenities', 'testimonials', 'gallery_images', 'stats', 'luxury_features', 'luxury_gallery', 'luxury_testimonials', 'luxury_services', 'luxury_experiences', 'awards', 'partners', - 'team', 'timeline', 'achievements', mode='before') + 'team', 'timeline', 'achievements', 'sections_enabled', 'trust_badges', + 'promotions', mode='before') @classmethod def validate_json_fields(cls, v): """Validate and parse JSON string fields.""" diff --git a/Backend/src/main.py b/Backend/src/main.py index 9598aa87..3132864a 100644 --- a/Backend/src/main.py +++ b/Backend/src/main.py @@ -44,8 +44,7 @@ else: PageContent.__table__.create(bind=engine, checkfirst=True) except Exception as e: logger.error(f'Failed to ensure required tables exist: {e}') -from .auth.routes import auth_routes -from .content.routes import privacy_routes + app = FastAPI(title=settings.APP_NAME, description='Enterprise-grade Hotel Booking API', version=settings.APP_VERSION, docs_url='/api/docs' if not settings.is_production else None, redoc_url='/api/redoc' if not settings.is_production else None, openapi_url='/api/openapi.json' if not settings.is_production else None) app.add_middleware(RequestIDMiddleware) app.add_middleware(CookieConsentMiddleware) @@ -193,7 +192,6 @@ async def metrics( # Custom route for serving uploads with CORS headers # This route takes precedence over the mount below from fastapi.responses import FileResponse -import re @app.options('/uploads/{file_path:path}') async def serve_upload_file_options(file_path: str, request: Request): diff --git a/Backend/src/notifications/models/__pycache__/email_campaign.cpython-312.pyc b/Backend/src/notifications/models/__pycache__/email_campaign.cpython-312.pyc index df4efc86..c630a475 100644 Binary files a/Backend/src/notifications/models/__pycache__/email_campaign.cpython-312.pyc and b/Backend/src/notifications/models/__pycache__/email_campaign.cpython-312.pyc differ diff --git a/Backend/src/notifications/models/email_campaign.py b/Backend/src/notifications/models/email_campaign.py index 260250cd..c04f6d26 100644 --- a/Backend/src/notifications/models/email_campaign.py +++ b/Backend/src/notifications/models/email_campaign.py @@ -52,6 +52,7 @@ class Campaign(Base): # Segmentation segment_id = Column(Integer, ForeignKey('campaign_segments.id'), nullable=True) segment_criteria = Column(JSON, nullable=True) # Store segment criteria as JSON + recipient_type = Column(String(50), nullable=True, default='users') # 'users', 'subscribers', 'both' # A/B Testing is_ab_test = Column(Boolean, nullable=False, default=False) @@ -283,3 +284,18 @@ class Unsubscribe(Base): user = relationship('User') campaign = relationship('Campaign') +class NewsletterSubscriber(Base): + __tablename__ = 'newsletter_subscribers' + + id = Column(Integer, primary_key=True, index=True, autoincrement=True) + email = Column(String(255), nullable=False, unique=True, index=True) + user_id = Column(Integer, ForeignKey('users.id'), nullable=True, index=True) + name = Column(String(255), nullable=True) + + subscribed_at = Column(DateTime, default=datetime.utcnow, nullable=False, index=True) + updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) + is_active = Column(Boolean, nullable=False, default=True, index=True) + + # Relationships + user = relationship('User') + diff --git a/Backend/src/notifications/routes/__pycache__/email_campaign_routes.cpython-312.pyc b/Backend/src/notifications/routes/__pycache__/email_campaign_routes.cpython-312.pyc index 23966993..7c6e0a3b 100644 Binary files a/Backend/src/notifications/routes/__pycache__/email_campaign_routes.cpython-312.pyc and b/Backend/src/notifications/routes/__pycache__/email_campaign_routes.cpython-312.pyc differ diff --git a/Backend/src/notifications/routes/email_campaign_routes.py b/Backend/src/notifications/routes/email_campaign_routes.py index 11c2aa92..abd464cb 100644 --- a/Backend/src/notifications/routes/email_campaign_routes.py +++ b/Backend/src/notifications/routes/email_campaign_routes.py @@ -1,5 +1,6 @@ from fastapi import APIRouter, Depends, HTTPException, status, Query, Request from sqlalchemy.orm import Session, selectinload +from sqlalchemy import func from typing import Optional, List, Union from datetime import datetime from pydantic import BaseModel, EmailStr, field_validator @@ -10,7 +11,7 @@ from ...auth.models.user import User from ..models.email_campaign import ( Campaign, CampaignStatus, CampaignType, CampaignSegment, EmailTemplate, CampaignEmail, EmailStatus, - DripSequence, DripSequenceStep, Unsubscribe + DripSequence, DripSequenceStep, Unsubscribe, NewsletterSubscriber ) from ..services.email_campaign_service import email_campaign_service @@ -31,6 +32,7 @@ class CampaignCreate(BaseModel): reply_to_email: Optional[str] = None track_opens: bool = True track_clicks: bool = True + recipient_type: Optional[str] = 'users' # 'users', 'subscribers', 'both' @field_validator('segment_id', 'template_id', mode='before') @classmethod @@ -408,7 +410,8 @@ async def create_campaign( from_email=data.from_email, reply_to_email=data.reply_to_email, track_opens=data.track_opens, - track_clicks=data.track_clicks + track_clicks=data.track_clicks, + recipient_type=data.recipient_type or 'users' ) return {"status": "success", "campaign_id": campaign.id} @@ -533,6 +536,139 @@ async def track_email_click( from fastapi.responses import RedirectResponse return RedirectResponse(url=url) +# Newsletter Subscription Routes +class NewsletterSubscribeRequest(BaseModel): + email: EmailStr + name: Optional[str] = None + +@router.post("/newsletter/subscribe") +async def subscribe_to_newsletter( + request: NewsletterSubscribeRequest, + db: Session = Depends(get_db) +): + """Subscribe to newsletter""" + email = request.email + name = request.name + + # Check if already unsubscribed + existing_unsubscribe = db.query(Unsubscribe).filter( + Unsubscribe.email == email, + Unsubscribe.unsubscribe_all == True + ).first() + + if existing_unsubscribe: + # Remove unsubscribe record to re-subscribe + db.delete(existing_unsubscribe) + db.commit() + + # Check if user exists + user = db.query(User).filter(User.email == email).first() + + # Check if already subscribed + existing_subscriber = db.query(NewsletterSubscriber).filter( + NewsletterSubscriber.email == email + ).first() + + if existing_subscriber: + # Re-activate if was deactivated + if not existing_subscriber.is_active: + existing_subscriber.is_active = True + existing_subscriber.subscribed_at = datetime.utcnow() + if name and not existing_subscriber.name: + existing_subscriber.name = name + if user and not existing_subscriber.user_id: + existing_subscriber.user_id = user.id + db.commit() + else: + # Create new subscriber record + subscriber = NewsletterSubscriber( + email=email, + user_id=user.id if user else None, + name=name or (user.full_name if user else None), + is_active=True + ) + db.add(subscriber) + db.commit() + + # Find or create newsletter segment + newsletter_segment = db.query(CampaignSegment).filter( + CampaignSegment.name == "Newsletter Subscribers" + ).first() + + if not newsletter_segment: + # Create newsletter segment if it doesn't exist + newsletter_segment = CampaignSegment( + name="Newsletter Subscribers", + description="Users who have subscribed to the newsletter", + criteria={"subscribed": True} + ) + db.add(newsletter_segment) + db.commit() + db.refresh(newsletter_segment) + + # Update segment estimated count - count active subscribers + subscriber_count = db.query(func.count(NewsletterSubscriber.id)).filter( + NewsletterSubscriber.is_active == True + ).scalar() or 0 + + newsletter_segment.estimated_count = subscriber_count + newsletter_segment.last_calculated_at = datetime.utcnow() + db.commit() + + return { + "status": "success", + "message": "Successfully subscribed to newsletter", + "email": email + } + +@router.get("/newsletter/subscribers") +async def get_newsletter_subscribers( + current_user: User = Depends(authorize_roles("admin")), + db: Session = Depends(get_db), + page: int = Query(1, ge=1), + limit: int = Query(50, ge=1, le=100) +): + """Get list of newsletter subscribers""" + try: + # Get all active newsletter subscribers + subscribers_query = db.query(NewsletterSubscriber).filter( + NewsletterSubscriber.is_active == True + ).order_by(NewsletterSubscriber.subscribed_at.desc()) + + # Get total count + total = subscribers_query.count() + + # Pagination + offset = (page - 1) * limit + paginated_subscribers = subscribers_query.offset(offset).limit(limit).all() + + # Format subscribers + subscribers_list = [] + for subscriber in paginated_subscribers: + subscribers_list.append({ + "email": subscriber.email, + "user_id": subscriber.user_id, + "name": subscriber.name or (subscriber.user.full_name if subscriber.user else None), + "type": "user" if subscriber.user_id else "guest", + "subscribed_at": subscriber.subscribed_at.isoformat() if subscriber.subscribed_at else None + }) + + return { + "status": "success", + "data": { + "subscribers": subscribers_list, + "total": total, + "page": page, + "limit": limit, + "total_pages": (total + limit - 1) // limit if limit > 0 else 1 + } + } + except Exception as e: + from ...shared.config.logging_config import get_logger + logger = get_logger(__name__) + logger.error(f"Error fetching newsletter subscribers: {str(e)}", exc_info=True) + raise HTTPException(status_code=500, detail=f"Failed to fetch subscribers: {str(e)}") + # Unsubscribe Routes @router.post("/unsubscribe") async def unsubscribe( @@ -553,6 +689,24 @@ async def unsubscribe( user = db.query(User).filter(User.email == email).first() + # Mark newsletter subscriber as inactive if unsubscribing from all + if unsubscribe_all: + subscriber = db.query(NewsletterSubscriber).filter( + NewsletterSubscriber.email == email + ).first() + if subscriber: + subscriber.is_active = False + # Update segment count + newsletter_segment = db.query(CampaignSegment).filter( + CampaignSegment.name == "Newsletter Subscribers" + ).first() + if newsletter_segment: + subscriber_count = db.query(func.count(NewsletterSubscriber.id)).filter( + NewsletterSubscriber.is_active == True + ).scalar() or 0 + newsletter_segment.estimated_count = subscriber_count + newsletter_segment.last_calculated_at = datetime.utcnow() + unsubscribe_record = Unsubscribe( email=email, user_id=user.id if user else None, diff --git a/Backend/src/notifications/services/__pycache__/email_campaign_service.cpython-312.pyc b/Backend/src/notifications/services/__pycache__/email_campaign_service.cpython-312.pyc index 321cd625..f4582c0b 100644 Binary files a/Backend/src/notifications/services/__pycache__/email_campaign_service.cpython-312.pyc and b/Backend/src/notifications/services/__pycache__/email_campaign_service.cpython-312.pyc differ diff --git a/Backend/src/notifications/services/email_campaign_service.py b/Backend/src/notifications/services/email_campaign_service.py index c62dce35..b2efd38b 100644 --- a/Backend/src/notifications/services/email_campaign_service.py +++ b/Backend/src/notifications/services/email_campaign_service.py @@ -4,7 +4,7 @@ from datetime import datetime, timedelta from ..models.email_campaign import ( Campaign, CampaignStatus, CampaignType, EmailStatus, CampaignSegment, EmailTemplate, CampaignEmail, EmailClick, - DripSequence, DripSequenceStep, DripSequenceEnrollment, Unsubscribe + DripSequence, DripSequenceStep, DripSequenceEnrollment, Unsubscribe, NewsletterSubscriber ) from ...auth.models.user import User from ...bookings.models.booking import Booking @@ -51,19 +51,54 @@ class EmailCampaignService: db: Session, campaign: Campaign ) -> List[User]: - """Get list of recipients for a campaign based on segment""" - if campaign.segment_id: - segment = db.query(CampaignSegment).filter( - CampaignSegment.id == campaign.segment_id - ).first() - if segment: - return EmailCampaignService._apply_segment_criteria(db, segment.criteria) + """Get list of recipients for a campaign based on segment and recipient_type""" + recipient_type = getattr(campaign, 'recipient_type', 'users') or 'users' + recipients = [] - # If no segment, return all active users (or based on campaign type) - if campaign.campaign_type == CampaignType.newsletter: - return db.query(User).filter(User.is_active == True).all() + # Get users if recipient_type is 'users' or 'both' + if recipient_type in ['users', 'both']: + if campaign.segment_id: + segment = db.query(CampaignSegment).filter( + CampaignSegment.id == campaign.segment_id + ).first() + if segment: + recipients.extend(EmailCampaignService._apply_segment_criteria(db, segment.criteria)) + else: + # If segment not found, get all active users + recipients.extend(db.query(User).filter(User.is_active == True).all()) + else: + # If no segment, return all active users + recipients.extend(db.query(User).filter(User.is_active == True).all()) - return [] + # Get subscribers if recipient_type is 'subscribers' or 'both' + if recipient_type in ['subscribers', 'both']: + subscribers = db.query(NewsletterSubscriber).filter( + NewsletterSubscriber.is_active == True + ).all() + + # Convert subscribers to User-like objects or get their User records + for subscriber in subscribers: + if subscriber.user_id: + # If subscriber is a user, get the User object (avoid duplicates) + user = db.query(User).filter(User.id == subscriber.user_id).first() + if user and user not in recipients: + recipients.append(user) + else: + # Guest subscriber - create a minimal User-like object for sending + # We'll handle this in send_campaign by using the email directly + # For now, we'll skip guest subscribers in the User list + # They'll be handled separately in send_campaign + pass + + # Remove duplicates based on email + seen_emails = set() + unique_recipients = [] + for user in recipients: + if user.email not in seen_emails: + seen_emails.add(user.email) + unique_recipients.append(user) + + return unique_recipients @staticmethod def _apply_segment_criteria(db: Session, criteria: Dict[str, Any]) -> List[User]: @@ -105,9 +140,34 @@ class EmailCampaignService: if campaign.status not in [CampaignStatus.draft, CampaignStatus.scheduled]: raise ValueError(f"Cannot send campaign with status: {campaign.status}") - # Get recipients - recipients = EmailCampaignService.get_campaign_recipients(db, campaign) - campaign.total_recipients = len(recipients) + # Get recipients (users) + user_recipients = EmailCampaignService.get_campaign_recipients(db, campaign) + recipient_type = getattr(campaign, 'recipient_type', 'users') or 'users' + + # Get guest subscribers if recipient_type is 'subscribers' or 'both' + guest_subscribers = [] + if recipient_type in ['subscribers', 'both']: + guest_subscribers = db.query(NewsletterSubscriber).filter( + NewsletterSubscriber.is_active == True, + NewsletterSubscriber.user_id.is_(None) # Only guest subscribers + ).all() + + # Combine all recipient emails + all_recipient_emails = set() + recipient_data = {} # Store email -> (user_id, name) mapping + + # Add user recipients + for user in user_recipients: + all_recipient_emails.add(user.email) + recipient_data[user.email] = (user.id, user.full_name) + + # Add guest subscribers + for subscriber in guest_subscribers: + if subscriber.email not in all_recipient_emails: + all_recipient_emails.add(subscriber.email) + recipient_data[subscriber.email] = (None, subscriber.name) + + campaign.total_recipients = len(all_recipient_emails) # Update status campaign.status = CampaignStatus.sending @@ -116,17 +176,19 @@ class EmailCampaignService: sent_count = 0 failed_count = 0 - for user in recipients: - # Check if user unsubscribed - if EmailCampaignService._is_unsubscribed(db, user.email, campaign): + for email in all_recipient_emails: + # Check if email is unsubscribed + if EmailCampaignService._is_unsubscribed(db, email, campaign): continue + user_id, name = recipient_data[email] + try: # Create campaign email record campaign_email = CampaignEmail( campaign_id=campaign.id, - user_id=user.id, - email=user.email, + user_id=user_id, + email=email, status=EmailStatus.pending ) db.add(campaign_email) @@ -135,11 +197,13 @@ class EmailCampaignService: # Replace template variables html_content = EmailCampaignService._replace_variables( campaign.html_content or '', - user + name or 'Guest', + email ) subject = EmailCampaignService._replace_variables( campaign.subject, - user + name or 'Guest', + email ) # Send email (async function) @@ -151,7 +215,7 @@ class EmailCampaignService: asyncio.set_event_loop(loop) loop.run_until_complete(send_email( - to=user.email, + to=email, subject=subject, html=html_content, text=campaign.text_content @@ -162,7 +226,7 @@ class EmailCampaignService: sent_count += 1 except Exception as e: - logger.error(f"Failed to send email to {user.email}: {str(e)}") + logger.error(f"Failed to send email to {email}: {str(e)}") if 'campaign_email' in locals(): campaign_email.status = EmailStatus.failed campaign_email.error_message = str(e) @@ -177,16 +241,17 @@ class EmailCampaignService: return { "sent": sent_count, "failed": failed_count, - "total": len(recipients) + "total": len(all_recipient_emails) } @staticmethod - def _replace_variables(content: str, user: User) -> str: - """Replace template variables with user data""" + def _replace_variables(content: str, name: str, email: str) -> str: + """Replace template variables with user/subscriber data""" + first_name = name.split()[0] if name and ' ' in name else (name or 'Guest') replacements = { - '{{name}}': user.full_name or 'Guest', - '{{email}}': user.email, - '{{first_name}}': user.full_name.split()[0] if user.full_name else 'Guest', + '{{name}}': name or 'Guest', + '{{email}}': email, + '{{first_name}}': first_name, } for key, value in replacements.items(): diff --git a/Backend/src/shared/utils/__pycache__/sanitization.cpython-312.pyc b/Backend/src/shared/utils/__pycache__/sanitization.cpython-312.pyc index 422ecde6..c44bf741 100644 Binary files a/Backend/src/shared/utils/__pycache__/sanitization.cpython-312.pyc and b/Backend/src/shared/utils/__pycache__/sanitization.cpython-312.pyc differ diff --git a/Backend/src/shared/utils/html_sanitizer.py b/Backend/src/shared/utils/html_sanitizer.py deleted file mode 100644 index 05ab3bdc..00000000 --- a/Backend/src/shared/utils/html_sanitizer.py +++ /dev/null @@ -1,99 +0,0 @@ -""" -HTML sanitization utilities for backend content storage. -Prevents XSS attacks by sanitizing HTML before storing in database. -""" -import bleach -from typing import Optional - -# Allowed HTML tags for rich content -ALLOWED_TAGS = [ - 'p', 'br', 'strong', 'em', 'u', 'b', 'i', 'span', 'div', - 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', - 'ul', 'ol', 'li', - 'a', 'blockquote', 'pre', 'code', - 'table', 'thead', 'tbody', 'tr', 'th', 'td', - 'img', 'hr', 'section', 'article' -] - -# Allowed HTML attributes -ALLOWED_ATTRIBUTES = { - 'a': ['href', 'title', 'target', 'rel'], - 'img': ['src', 'alt', 'title', 'width', 'height', 'class'], - 'div': ['class', 'id', 'style'], - 'span': ['class', 'id', 'style'], - 'p': ['class', 'id', 'style'], - 'h1': ['class', 'id'], - 'h2': ['class', 'id'], - 'h3': ['class', 'id'], - 'h4': ['class', 'id'], - 'h5': ['class', 'id'], - 'h6': ['class', 'id'], - 'table': ['class', 'id'], - 'tr': ['class', 'id'], - 'th': ['class', 'id', 'colspan', 'rowspan'], - 'td': ['class', 'id', 'colspan', 'rowspan'], -} - -# Allowed URL schemes -ALLOWED_SCHEMES = ['http', 'https', 'mailto', 'tel'] - -def sanitize_html(html_content: Optional[str]) -> str: - """ - Sanitize HTML content to prevent XSS attacks. - - Args: - html_content: HTML string to sanitize (can be None) - - Returns: - Sanitized HTML string safe for storage - """ - if not html_content: - return '' - - # Clean HTML content - cleaned = bleach.clean( - html_content, - tags=ALLOWED_TAGS, - attributes=ALLOWED_ATTRIBUTES, - protocols=ALLOWED_SCHEMES, - strip=True, # Strip disallowed tags instead of escaping - strip_comments=True, # Remove HTML comments - ) - - # Additional link sanitization - ensure external links have rel="noopener" - if '' - elif 'noopener' not in tag and 'noreferrer' not in tag: - # Add to existing rel attribute - tag = tag.replace('rel="', 'rel="noopener noreferrer ') - tag = tag.replace("rel='", "rel='noopener noreferrer ") - return tag - return tag - - cleaned = re.sub(r']*>', add_rel, cleaned) - - return cleaned - -def sanitize_text_for_html(text: Optional[str]) -> str: - """ - Escape text content to be safely included in HTML. - Use this for plain text that should be displayed as-is. - - Args: - text: Plain text string to escape - - Returns: - HTML-escaped string - """ - if not text: - return '' - - return bleach.clean(text, tags=[], strip=True) - diff --git a/Backend/src/shared/utils/sanitization.py b/Backend/src/shared/utils/sanitization.py index 903f2590..414b4554 100644 --- a/Backend/src/shared/utils/sanitization.py +++ b/Backend/src/shared/utils/sanitization.py @@ -60,6 +60,25 @@ def sanitize_html(content: Optional[str], strip: bool = False) -> str: strip_comments=True ) + # Additional link sanitization - ensure external links have rel="noopener noreferrer" + if '' + elif 'noopener' not in tag and 'noreferrer' not in tag: + # Add to existing rel attribute + tag = tag.replace('rel="', 'rel="noopener noreferrer ') + tag = tag.replace("rel='", "rel='noopener noreferrer ") + return tag + return tag + + sanitized = re.sub(r']*>', add_rel, sanitized) + # Linkify URLs (convert plain URLs to links) # Only linkify if content doesn't already contain HTML links if ' str: """ Strip all HTML tags from content, leaving only plain text. Useful for fields that should not contain any HTML. + Alias for sanitize_text_for_html for backward compatibility. Args: content: The content to sanitize (can be None) @@ -93,6 +113,21 @@ def sanitize_text(content: Optional[str]) -> str: return bleach.clean(content, tags=[], strip=True) +def sanitize_text_for_html(text: Optional[str]) -> str: + """ + Escape text content to be safely included in HTML. + Use this for plain text that should be displayed as-is. + Alias for sanitize_text for consistency. + + Args: + text: Plain text string to escape + + Returns: + HTML-escaped string + """ + return sanitize_text(text) + + def sanitize_filename(filename: str) -> str: """ Sanitize filename to prevent path traversal and other attacks. diff --git a/Backend/src/tests/conftest.py b/Backend/src/tests/conftest.py index 7577961d..f6917c0c 100644 --- a/Backend/src/tests/conftest.py +++ b/Backend/src/tests/conftest.py @@ -121,6 +121,32 @@ def test_staff_role(db_session): return role +@pytest.fixture +def test_accountant_role(db_session): + """Create an accountant role.""" + role = Role( + name="accountant", + description="Accountant role" + ) + db_session.add(role) + db_session.commit() + db_session.refresh(role) + return role + + +@pytest.fixture +def test_housekeeping_role(db_session): + """Create a housekeeping role.""" + role = Role( + name="housekeeping", + description="Housekeeping role" + ) + db_session.add(role) + db_session.commit() + db_session.refresh(role) + return role + + @pytest.fixture def test_user(db_session, test_role): """Create a test user.""" @@ -175,6 +201,42 @@ def test_staff_user(db_session, test_staff_role): return user +@pytest.fixture +def test_accountant_user(db_session, test_accountant_role): + """Create a test accountant user.""" + hashed_password = bcrypt.hashpw("accountantpassword123".encode('utf-8'), bcrypt.gensalt()).decode('utf-8') + user = User( + email="accountant@example.com", + password=hashed_password, + full_name="Accountant User", + phone="1234567890", + role_id=test_accountant_role.id, + is_active=True + ) + db_session.add(user) + db_session.commit() + db_session.refresh(user) + return user + + +@pytest.fixture +def test_housekeeping_user(db_session, test_housekeeping_role): + """Create a test housekeeping user.""" + hashed_password = bcrypt.hashpw("housekeepingpassword123".encode('utf-8'), bcrypt.gensalt()).decode('utf-8') + user = User( + email="housekeeping@example.com", + password=hashed_password, + full_name="Housekeeping User", + phone="1234567890", + role_id=test_housekeeping_role.id, + is_active=True + ) + db_session.add(user) + db_session.commit() + db_session.refresh(user) + return user + + @pytest.fixture def auth_token(client, test_user): """Get authentication token for test user (from cookies).""" @@ -227,6 +289,38 @@ def staff_token(client, test_staff_user): return None +@pytest.fixture +def accountant_token(client, test_accountant_user): + """Get authentication token for accountant user (from cookies).""" + response = client.post( + "/api/auth/login", + json={ + "email": "accountant@example.com", + "password": "accountantpassword123" + } + ) + if response.status_code == 200: + cookie_token = response.cookies.get("accessToken") + return cookie_token + return None + + +@pytest.fixture +def housekeeping_token(client, test_housekeeping_user): + """Get authentication token for housekeeping user (from cookies).""" + response = client.post( + "/api/auth/login", + json={ + "email": "housekeeping@example.com", + "password": "housekeepingpassword123" + } + ) + if response.status_code == 200: + cookie_token = response.cookies.get("accessToken") + return cookie_token + return None + + @pytest.fixture def authenticated_client(client, test_user): """Create an authenticated test client (uses cookies).""" @@ -257,6 +351,32 @@ def admin_client(client, test_admin_user): return client +@pytest.fixture +def accountant_client(client, test_accountant_user): + """Create an authenticated accountant test client (uses cookies).""" + response = client.post( + "/api/auth/login", + json={ + "email": "accountant@example.com", + "password": "accountantpassword123" + } + ) + return client + + +@pytest.fixture +def housekeeping_client(client, test_housekeeping_user): + """Create an authenticated housekeeping test client (uses cookies).""" + response = client.post( + "/api/auth/login", + json={ + "email": "housekeeping@example.com", + "password": "housekeepingpassword123" + } + ) + return client + + @pytest.fixture def test_room_type(db_session): """Create a test room type.""" diff --git a/Backend/src/tests/test_role_permissions.py b/Backend/src/tests/test_role_permissions.py new file mode 100644 index 00000000..4fcc9c74 --- /dev/null +++ b/Backend/src/tests/test_role_permissions.py @@ -0,0 +1,241 @@ +""" +Comprehensive role-based permission tests. +Tests that each user role can only access authorized endpoints and features. +""" +import pytest +from fastapi import status + + +@pytest.mark.integration +class TestAdminPermissions: + """Test admin role permissions.""" + + def test_admin_can_access_user_management(self, admin_client): + """Admin should be able to access user management.""" + response = admin_client.get("/api/admin/users") + assert response.status_code in [200, 404] # 404 if endpoint not implemented + + def test_admin_can_create_user(self, admin_client): + """Admin should be able to create users.""" + response = admin_client.post( + "/api/admin/users", + json={ + "email": "newuser@test.com", + "password": "Test123!", + "full_name": "New User", + "role": "customer" + } + ) + assert response.status_code in [201, 400, 404] + + def test_admin_can_access_analytics(self, admin_client): + """Admin should be able to access analytics.""" + response = admin_client.get("/api/admin/analytics/dashboard") + assert response.status_code in [200, 404] + + def test_admin_can_manage_rooms(self, admin_client): + """Admin should be able to manage rooms.""" + response = admin_client.get("/api/admin/rooms") + assert response.status_code in [200, 404] + + def test_admin_can_manage_bookings(self, admin_client): + """Admin should be able to manage all bookings.""" + response = admin_client.get("/api/admin/bookings") + assert response.status_code in [200, 404] + + def test_admin_can_manage_payments(self, admin_client): + """Admin should be able to manage payments.""" + response = admin_client.get("/api/admin/payments") + assert response.status_code in [200, 404] + + def test_admin_can_manage_invoices(self, admin_client): + """Admin should be able to manage invoices.""" + response = admin_client.get("/api/admin/invoices") + assert response.status_code in [200, 404] + + +@pytest.mark.integration +class TestStaffPermissions: + """Test staff role permissions.""" + + def test_staff_can_view_bookings(self, staff_token, client): + """Staff should be able to view bookings.""" + response = client.get( + "/api/staff/bookings", + cookies={"accessToken": staff_token} if staff_token else {} + ) + assert response.status_code in [200, 401, 403, 404] + + def test_staff_can_update_booking_status(self, staff_token, client, test_booking): + """Staff should be able to update booking status.""" + response = client.put( + f"/api/staff/bookings/{test_booking.id}", + json={"status": "checked_in"}, + cookies={"accessToken": staff_token} if staff_token else {} + ) + assert response.status_code in [200, 401, 403, 404] + + def test_staff_cannot_delete_users(self, staff_token, client, test_user): + """Staff should NOT be able to delete users.""" + response = client.delete( + f"/api/admin/users/{test_user.id}", + cookies={"accessToken": staff_token} if staff_token else {} + ) + assert response.status_code in [401, 403, 404] + + def test_staff_cannot_access_system_settings(self, staff_token, client): + """Staff should NOT be able to access system settings.""" + response = client.get( + "/api/admin/settings", + cookies={"accessToken": staff_token} if staff_token else {} + ) + assert response.status_code in [401, 403, 404] + + +@pytest.mark.integration +class TestCustomerPermissions: + """Test customer role permissions.""" + + def test_customer_can_view_own_bookings(self, authenticated_client, test_user, test_booking): + """Customer should be able to view their own bookings.""" + response = authenticated_client.get("/api/bookings/me") + assert response.status_code in [200, 404] + + def test_customer_can_create_booking(self, authenticated_client, test_room): + """Customer should be able to create bookings.""" + from datetime import datetime, timedelta + check_in = datetime.utcnow() + timedelta(days=1) + check_out = datetime.utcnow() + timedelta(days=3) + + response = authenticated_client.post( + "/api/bookings", + json={ + "room_id": test_room.id, + "check_in_date": check_in.isoformat(), + "check_out_date": check_out.isoformat(), + "num_guests": 2 + } + ) + assert response.status_code in [201, 400, 404] + + def test_customer_cannot_view_other_bookings(self, authenticated_client, test_booking): + """Customer should NOT be able to view other users' bookings.""" + # Try to access booking that doesn't belong to them + response = authenticated_client.get(f"/api/bookings/{test_booking.id}") + # Should return 403 or 404, not 200 + assert response.status_code in [403, 404] + + def test_customer_cannot_manage_users(self, authenticated_client): + """Customer should NOT be able to manage users.""" + response = authenticated_client.get("/api/admin/users") + assert response.status_code in [401, 403, 404] + + def test_customer_can_view_rooms(self, client): + """Customer should be able to view available rooms.""" + response = client.get("/api/rooms") + assert response.status_code in [200, 404] + + def test_customer_can_view_own_invoices(self, authenticated_client): + """Customer should be able to view their own invoices.""" + response = authenticated_client.get("/api/invoices/me") + assert response.status_code in [200, 404] + + +@pytest.mark.integration +class TestAccountantPermissions: + """Test accountant role permissions.""" + + def test_accountant_can_view_payments(self, accountant_client): + """Accountant should be able to view payments.""" + response = accountant_client.get("/api/accountant/payments") + assert response.status_code in [200, 404] + + def test_accountant_can_view_invoices(self, accountant_client): + """Accountant should be able to view invoices.""" + response = accountant_client.get("/api/accountant/invoices") + assert response.status_code in [200, 404] + + def test_accountant_can_generate_reports(self, accountant_client): + """Accountant should be able to generate financial reports.""" + response = accountant_client.get("/api/accountant/reports") + assert response.status_code in [200, 404] + + def test_accountant_cannot_manage_rooms(self, accountant_client): + """Accountant should NOT be able to manage rooms.""" + response = accountant_client.get("/api/admin/rooms") + assert response.status_code in [401, 403, 404] + + def test_accountant_cannot_manage_bookings(self, accountant_client): + """Accountant should NOT be able to manage bookings.""" + response = accountant_client.put("/api/admin/bookings/1", json={"status": "confirmed"}) + assert response.status_code in [401, 403, 404] + + +@pytest.mark.integration +class TestHousekeepingPermissions: + """Test housekeeping role permissions.""" + + def test_housekeeping_can_view_tasks(self, housekeeping_client): + """Housekeeping should be able to view assigned tasks.""" + response = housekeeping_client.get("/api/housekeeping/tasks") + assert response.status_code in [200, 404] + + def test_housekeeping_can_update_task_status(self, housekeeping_client): + """Housekeeping should be able to update task status.""" + # This test would need a test task fixture + # For now, just test the endpoint exists + response = housekeeping_client.put("/api/housekeeping/tasks/1", json={"status": "completed"}) + assert response.status_code in [200, 404, 400] + + def test_housekeeping_can_update_room_status(self, housekeeping_client): + """Housekeeping should be able to update room status.""" + response = housekeeping_client.put("/api/housekeeping/rooms/1/status", json={"status": "clean"}) + assert response.status_code in [200, 404, 400] + + def test_housekeeping_cannot_manage_bookings(self, housekeeping_client): + """Housekeeping should NOT be able to manage bookings.""" + response = housekeeping_client.get("/api/admin/bookings") + assert response.status_code in [401, 403, 404] + + def test_housekeeping_cannot_access_payments(self, housekeeping_client): + """Housekeeping should NOT be able to access payments.""" + response = housekeeping_client.get("/api/admin/payments") + assert response.status_code in [401, 403, 404] + + +@pytest.mark.integration +class TestUnauthenticatedAccess: + """Test that unauthenticated users cannot access protected endpoints.""" + + def test_unauthenticated_cannot_access_admin_endpoints(self, client): + """Unauthenticated users should not access admin endpoints.""" + response = client.get("/api/admin/users") + assert response.status_code in [401, 403, 404] + + def test_unauthenticated_cannot_access_staff_endpoints(self, client): + """Unauthenticated users should not access staff endpoints.""" + response = client.get("/api/staff/bookings") + assert response.status_code in [401, 403, 404] + + def test_unauthenticated_can_view_public_rooms(self, client): + """Unauthenticated users should be able to view public room listings.""" + response = client.get("/api/rooms") + assert response.status_code in [200, 404] + + def test_unauthenticated_cannot_create_booking(self, client, test_room): + """Unauthenticated users should not be able to create bookings.""" + from datetime import datetime, timedelta + check_in = datetime.utcnow() + timedelta(days=1) + check_out = datetime.utcnow() + timedelta(days=3) + + response = client.post( + "/api/bookings", + json={ + "room_id": test_room.id, + "check_in_date": check_in.isoformat(), + "check_out_date": check_out.isoformat(), + "num_guests": 2 + } + ) + assert response.status_code in [401, 403] + diff --git a/Frontend/src/App.tsx b/Frontend/src/App.tsx index 3b7264ef..739aff7a 100644 --- a/Frontend/src/App.tsx +++ b/Frontend/src/App.tsx @@ -66,6 +66,7 @@ const ComplaintPage = lazy(() => import('./pages/customer/ComplaintPage')); const GuestRequestsPage = lazy(() => import('./pages/customer/GuestRequestsPage')); const GDPRPage = lazy(() => import('./pages/customer/GDPRPage')); const GDPRDeletionConfirmPage = lazy(() => import('./pages/customer/GDPRDeletionConfirmPage')); +const SessionManagementPage = lazy(() => import('./pages/customer/SessionManagementPage')); const AboutPage = lazy(() => import('./features/content/pages/AboutPage')); const ContactPage = lazy(() => import('./features/content/pages/ContactPage')); const PrivacyPolicyPage = lazy(() => import('./features/content/pages/PrivacyPolicyPage')); @@ -112,13 +113,18 @@ const WebhookManagementPage = lazy(() => import('./pages/admin/WebhookManagement const APIKeyManagementPage = lazy(() => import('./pages/admin/APIKeyManagementPage')); const BackupManagementPage = lazy(() => import('./pages/admin/BackupManagementPage')); const ServiceManagementPage = lazy(() => import('./pages/admin/ServiceManagementPage')); +const InventoryManagementPage = lazy(() => import('./pages/admin/InventoryManagementPage')); +const MaintenanceManagementPage = lazy(() => import('./pages/admin/MaintenanceManagementPage')); +const InspectionManagementPage = lazy(() => import('./pages/admin/InspectionManagementPage')); +const StaffShiftManagementPage = lazy(() => import('./pages/admin/StaffShiftManagementPage')); const StaffDashboardPage = lazy(() => import('./pages/staff/DashboardPage')); +const StaffInventoryViewPage = lazy(() => import('./pages/staff/InventoryViewPage')); +const StaffShiftViewPage = lazy(() => import('./pages/staff/ShiftViewPage')); const StaffBookingManagementPage = lazy(() => import('./pages/staff/BookingManagementPage')); const StaffReceptionDashboardPage = lazy(() => import('./pages/staff/ReceptionDashboardPage')); const StaffPaymentManagementPage = lazy(() => import('./pages/staff/PaymentManagementPage')); const StaffAnalyticsDashboardPage = lazy(() => import('./pages/staff/AnalyticsDashboardPage')); -const StaffLoyaltyManagementPage = lazy(() => import('./pages/staff/LoyaltyManagementPage')); const StaffGuestProfilePage = lazy(() => import('./pages/staff/GuestProfilePage')); const StaffAdvancedRoomManagementPage = lazy(() => import('./pages/staff/AdvancedRoomManagementPage')); const ChatManagementPage = lazy(() => import('./pages/staff/ChatManagementPage')); @@ -142,6 +148,7 @@ const AccountantLayout = lazy(() => import('./pages/AccountantLayout')); const HousekeepingDashboardPage = lazy(() => import('./pages/housekeeping/DashboardPage')); const HousekeepingTasksPage = lazy(() => import('./pages/housekeeping/TasksPage')); +const HousekeepingShiftViewPage = lazy(() => import('./pages/housekeeping/ShiftViewPage')); const HousekeepingLayout = lazy(() => import('./pages/HousekeepingLayout')); const AdminProfilePage = lazy(() => import('./pages/admin/ProfilePage')); @@ -502,6 +509,16 @@ function App() { } /> + + + + + + } + /> {/* Separate Login Pages for Each Role */} @@ -696,10 +713,30 @@ function App() { path="services" element={} /> + } + /> + } + /> + } + /> + } + /> } /> + } + /> {} @@ -738,10 +775,6 @@ function App() { path="chats" element={} /> - } - /> } @@ -774,6 +807,18 @@ function App() { path="profile" element={} /> + } + /> + } + /> + } + /> {/* Accountant Routes */} @@ -828,6 +873,10 @@ function App() { path="profile" element={} /> + } + /> } @@ -854,6 +903,9 @@ function App() { element={} /> } /> + } /> + } /> + } /> {} diff --git a/Frontend/src/features/content/pages/HomePage.tsx b/Frontend/src/features/content/pages/HomePage.tsx index f0136ebe..572017e9 100644 --- a/Frontend/src/features/content/pages/HomePage.tsx +++ b/Frontend/src/features/content/pages/HomePage.tsx @@ -21,6 +21,7 @@ import bannerService from '../services/bannerService'; import roomService from '../../rooms/services/roomService'; import pageContentService from '../services/pageContentService'; import serviceService from '../../hotel_services/services/serviceService'; +import blogService, { BlogPost } from '../services/blogService'; import { useFormatCurrency } from '../../payments/hooks/useFormatCurrency'; import type { Banner } from '../services/bannerService'; import type { Room } from '../../rooms/services/roomService'; @@ -34,12 +35,14 @@ const HomePage: React.FC = () => { const [newestRooms, setNewestRooms] = useState([]); const [pageContent, setPageContent] = useState(null); const [services, setServices] = useState([]); + const [blogPosts, setBlogPosts] = useState([]); const [isLoadingBanners, setIsLoadingBanners] = useState(true); const [isLoadingRooms, setIsLoadingRooms] = useState(true); const [isLoadingNewest, setIsLoadingNewest] = useState(true); const [, setIsLoadingContent] = useState(true); const [isLoadingServices, setIsLoadingServices] = useState(true); + const [isLoadingBlog, setIsLoadingBlog] = useState(false); const [error, setError] = useState(null); const [apiError, setApiError] = useState(false); const [apiErrorMessage, setApiErrorMessage] = useState(''); @@ -153,16 +156,6 @@ const HomePage: React.FC = () => { } else if (!Array.isArray(content.amenities)) { content.amenities = content.amenities || []; } - // Handle testimonials - can be string, array, or null/undefined - if (typeof content.testimonials === 'string') { - try { - content.testimonials = JSON.parse(content.testimonials); - } catch (e) { - content.testimonials = []; - } - } else if (!Array.isArray(content.testimonials)) { - content.testimonials = content.testimonials || []; - } // Handle gallery_images - can be string, array, or null/undefined if (typeof content.gallery_images === 'string') { try { @@ -258,6 +251,53 @@ const HomePage: React.FC = () => { } else if (!Array.isArray(content.partners)) { content.partners = content.partners || []; } + // Handle trust_badges - can be string, array, or null/undefined + if (typeof content.trust_badges === 'string') { + try { + content.trust_badges = JSON.parse(content.trust_badges); + } catch (e) { + content.trust_badges = []; + } + } else if (!Array.isArray(content.trust_badges)) { + content.trust_badges = content.trust_badges || []; + } + // Handle promotions - can be string, array, or null/undefined + if (typeof content.promotions === 'string') { + try { + content.promotions = JSON.parse(content.promotions); + } catch (e) { + content.promotions = []; + } + } else if (!Array.isArray(content.promotions)) { + content.promotions = content.promotions || []; + } + // Handle sections_enabled - can be string, object, or null/undefined + if (typeof content.sections_enabled === 'string') { + try { + content.sections_enabled = JSON.parse(content.sections_enabled); + } catch (e) { + content.sections_enabled = {}; + } + } else if (typeof content.sections_enabled !== 'object' || content.sections_enabled === null) { + content.sections_enabled = content.sections_enabled || {}; + } + + // Normalize boolean values (MySQL returns 1/0, convert to true/false) + if (content.newsletter_enabled !== undefined) { + content.newsletter_enabled = Boolean(content.newsletter_enabled); + } + if (content.trust_badges_enabled !== undefined) { + content.trust_badges_enabled = Boolean(content.trust_badges_enabled); + } + if (content.promotions_enabled !== undefined) { + content.promotions_enabled = Boolean(content.promotions_enabled); + } + if (content.blog_enabled !== undefined) { + content.blog_enabled = Boolean(content.blog_enabled); + } + if (content.rooms_section_enabled !== undefined) { + content.rooms_section_enabled = Boolean(content.rooms_section_enabled); + } setPageContent(content); @@ -290,27 +330,53 @@ const HomePage: React.FC = () => { fetchPageContent(); }, []); + useEffect(() => { + const fetchBlogPosts = async () => { + if (!pageContent || !pageContent.blog_enabled || (pageContent.sections_enabled?.blog === false)) { + return; + } + try { + setIsLoadingBlog(true); + const limit = pageContent.blog_posts_limit || 3; + const response = await blogService.getBlogPosts({ + published_only: true, + limit: limit, + page: 1, + }); + if (response.status === 'success' && response.data?.posts) { + setBlogPosts(response.data.posts); + } + } catch (error: any) { + console.error('Error fetching blog posts:', error); + } finally { + setIsLoadingBlog(false); + } + }; + if (pageContent) { + fetchBlogPosts(); + } + }, [pageContent?.blog_enabled, pageContent?.sections_enabled?.blog, pageContent?.blog_posts_limit]); + useEffect(() => { const fetchBanners = async () => { try { setIsLoadingBanners(true); - const response = await bannerService - .getBannersByPosition('home'); + const response = await bannerService.getBannersByPosition('home'); - - if ( - response.success || - response.status === 'success' - ) { - setBanners(response.data?.banners || []); + if (response.success || response.status === 'success') { + const fetchedBanners = response.data?.banners || []; + setBanners(fetchedBanners); + if (fetchedBanners.length === 0) { + console.log('No banners found for home position'); + } } else { + console.warn('Banner service returned unsuccessful response:', response); setBanners([]); } } catch (err: any) { console.error('Error fetching banners:', err); - setApiError(true); - setApiErrorMessage('Unable to connect to the server. Please check your internet connection and try again.'); + // Don't set API error for banners - it's not critical setBanners([]); } finally { setIsLoadingBanners(false); @@ -477,6 +543,69 @@ const HomePage: React.FC = () => { + ) : pageContent ? ( + (() => { + // Check for valid local video first + const videoUrl = pageContent.hero_video_url; + if (videoUrl && ( + videoUrl.startsWith('/') || + videoUrl.startsWith('http://localhost') || + videoUrl.startsWith('https://localhost') || + videoUrl.startsWith(window.location.origin) + )) { + return ( +
+ + {(pageContent.hero_video_poster || pageContent.hero_image) && ( + Hero background + )} +
+
+ +
+
+ ); + } + + // Check for hero image as fallback + if (pageContent.hero_image) { + return ( +
+ Hero background +
+
+ +
+
+ ); + } + + return null; + })() ) : null} @@ -486,6 +615,7 @@ const HomePage: React.FC = () => {
{} + {(pageContent?.sections_enabled?.rooms !== false) && (
{}
@@ -493,20 +623,20 @@ const HomePage: React.FC = () => {

- {pageContent?.hero_title || (apiError ? '' : 'Featured & Newest Rooms')} + {pageContent?.rooms_section_title || pageContent?.hero_title || (apiError ? '' : 'Featured & Newest Rooms')}

- {pageContent?.hero_subtitle || pageContent?.description || (apiError ? '' : 'Discover our most popular accommodations and latest additions')} + {pageContent?.rooms_section_subtitle || pageContent?.hero_subtitle || pageContent?.description || (apiError ? '' : 'Discover our most popular accommodations and latest additions')}

{}
- View All Rooms + {pageContent?.rooms_section_button_text || 'View All Rooms'}
@@ -571,9 +701,10 @@ const HomePage: React.FC = () => { )}
+ )} {} - {(() => { + {(pageContent?.sections_enabled?.features !== false) && (() => { const validFeatures = pageContent?.features?.filter( (f: any) => f && (f.title || f.description) @@ -590,6 +721,24 @@ const HomePage: React.FC = () => { {}
+ {(pageContent?.features_section_title || pageContent?.features_section_subtitle) && ( +
+
+
+
+ {pageContent.features_section_title && ( +

+ {pageContent.features_section_title} +

+ )} + {pageContent.features_section_subtitle && ( +

+ {pageContent.features_section_subtitle} +

+ )} +
+ )} +
{validFeatures.length > 0 ? ( validFeatures.map((feature: any, index: number) => ( @@ -638,7 +787,7 @@ const HomePage: React.FC = () => { })()} {} - {(pageContent?.luxury_section_title || (pageContent?.luxury_features && pageContent.luxury_features.length > 0)) && ( + {(pageContent?.sections_enabled?.luxury !== false) && (pageContent?.luxury_section_title || (pageContent?.luxury_features && pageContent.luxury_features.length > 0)) && (
@@ -693,7 +842,7 @@ const HomePage: React.FC = () => { )} {} - {pageContent?.luxury_gallery && Array.isArray(pageContent.luxury_gallery) && pageContent.luxury_gallery.length > 0 && ( + {(pageContent?.sections_enabled?.gallery !== false) && pageContent?.luxury_gallery && Array.isArray(pageContent.luxury_gallery) && pageContent.luxury_gallery.length > 0 && (
@@ -761,7 +910,7 @@ const HomePage: React.FC = () => { )} {} - {pageContent?.luxury_testimonials && pageContent.luxury_testimonials.length > 0 && ( + {(pageContent?.sections_enabled?.testimonials !== false) && pageContent?.luxury_testimonials && pageContent.luxury_testimonials.length > 0 && (
@@ -775,9 +924,6 @@ const HomePage: React.FC = () => { {pageContent.luxury_testimonials_section_subtitle}

)} -

- Hear from our valued guests about their luxury stay -

{pageContent.luxury_testimonials.map((testimonial, index) => ( @@ -812,13 +958,31 @@ const HomePage: React.FC = () => { )} {} - {pageContent?.stats && Array.isArray(pageContent.stats) && pageContent.stats.length > 0 && ( + {(pageContent?.sections_enabled?.stats !== false) && pageContent?.stats && Array.isArray(pageContent.stats) && pageContent.stats.length > 0 && (
{}
+ {(pageContent?.stats_section_title || pageContent?.stats_section_subtitle) && ( +
+
+
+
+ {pageContent.stats_section_title && ( +

+ {pageContent.stats_section_title} +

+ )} + {pageContent.stats_section_subtitle && ( +

+ {pageContent.stats_section_subtitle} +

+ )} +
+ )} +
{pageContent.stats.map((stat, index) => (
@@ -851,7 +1015,7 @@ const HomePage: React.FC = () => { )} {} - {pageContent?.amenities && pageContent.amenities.length > 0 && ( + {(pageContent?.sections_enabled?.amenities !== false) && pageContent?.amenities && pageContent.amenities.length > 0 && (
@@ -896,56 +1060,9 @@ const HomePage: React.FC = () => { )} {} - {pageContent?.testimonials && pageContent.testimonials.length > 0 && ( -
-
-
-
-
-

- {pageContent.testimonials_section_title || 'Guest Testimonials'} -

-

- {pageContent.testimonials_section_subtitle || 'See what our guests say about their experience'} -

-
-
- {pageContent.testimonials.map((testimonial, index) => ( -
-
-
- {testimonial.image ? ( -
- {testimonial.name} -
-
- ) : ( -
- {testimonial.name.charAt(0).toUpperCase()} -
- )} -
-

{testimonial.name}

-

{testimonial.role}

-
-
-
- {[...Array(5)].map((_, i) => ( - - ))} -
-
-
"
-

"{testimonial.comment}"

-
-
- ))} -
-
- )} {} - {(pageContent?.about_preview_title || pageContent?.about_preview_content) && ( + {(pageContent?.sections_enabled?.about_preview !== false) && (pageContent?.about_preview_title || pageContent?.about_preview_content) && (
{} @@ -995,7 +1112,7 @@ const HomePage: React.FC = () => { )} {} - {services.length > 0 && ( + {(pageContent?.sections_enabled?.services !== false) && services.length > 0 && (
@@ -1011,7 +1128,7 @@ const HomePage: React.FC = () => { )}
- {services.slice(0, 6).map((service, index: number) => { + {services.slice(0, pageContent?.services_section_limit || 6).map((service, index: number) => { const serviceSlug = service.slug || service.name.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''); return ( {
- View All Services + {pageContent?.services_section_button_text || 'View All Services'}
@@ -1058,7 +1175,7 @@ const HomePage: React.FC = () => { )} {} - {pageContent?.luxury_experiences && pageContent.luxury_experiences.length > 0 && ( + {(pageContent?.sections_enabled?.experiences !== false) && pageContent?.luxury_experiences && pageContent.luxury_experiences.length > 0 && (
@@ -1105,7 +1222,7 @@ const HomePage: React.FC = () => { )} {} - {pageContent?.awards && pageContent.awards.length > 0 && ( + {(pageContent?.sections_enabled?.awards !== false) && pageContent?.awards && pageContent.awards.length > 0 && (
@@ -1194,7 +1311,7 @@ const HomePage: React.FC = () => { )} {} - {pageContent?.partners && pageContent.partners.length > 0 && ( + {(pageContent?.sections_enabled?.partners !== false) && pageContent?.partners && pageContent.partners.length > 0 && (
@@ -1220,6 +1337,200 @@ const HomePage: React.FC = () => {
)} + {/* Trust Badges Section */} + {(pageContent?.sections_enabled?.trust_badges !== false) && pageContent?.trust_badges_enabled && pageContent?.trust_badges && Array.isArray(pageContent.trust_badges) && pageContent.trust_badges.length > 0 && ( +
+
+
+
+
+ {pageContent.trust_badges_section_title && ( +

+ {pageContent.trust_badges_section_title} +

+ )} + {pageContent.trust_badges_section_subtitle && ( +

+ {pageContent.trust_badges_section_subtitle} +

+ )} +
+
+ {pageContent.trust_badges.map((badge, index) => ( +
+ {badge.link ? ( + +
+ {badge.logo && ( + {badge.name} + )} +
+ {badge.name && ( +

{badge.name}

+ )} + {badge.description && ( +

{badge.description}

+ )} +
+ ) : ( + <> +
+ {badge.logo && ( + {badge.name} + )} +
+ {badge.name && ( +

{badge.name}

+ )} + {badge.description && ( +

{badge.description}

+ )} + + )} +
+ ))} +
+
+ )} + + {/* Promotions Section */} + {(pageContent?.sections_enabled?.promotions !== false) && pageContent?.promotions_enabled && pageContent?.promotions && Array.isArray(pageContent.promotions) && pageContent.promotions.length > 0 && ( +
+
+
+
+
+ {pageContent.promotions_section_title && ( +

+ {pageContent.promotions_section_title} +

+ )} + {pageContent.promotions_section_subtitle && ( +

+ {pageContent.promotions_section_subtitle} +

+ )} +
+
+ {pageContent.promotions.map((promo, index) => ( +
+ {promo.image && ( +
+ {promo.title} + {promo.discount && ( +
+ {promo.discount} +
+ )} +
+ )} +
+

{promo.title}

+ {promo.description && ( +

{promo.description}

+ )} + {promo.valid_until && ( +

Valid until: {new Date(promo.valid_until).toLocaleDateString()}

+ )} + {promo.link && ( + + {promo.button_text || 'Learn More'} + + + )} +
+
+ ))} +
+
+ )} + + {/* Blog Section */} + {(pageContent?.sections_enabled?.blog !== false) && pageContent?.blog_enabled && ( +
+
+
+
+
+ {pageContent.blog_section_title && ( +

+ {pageContent.blog_section_title} +

+ )} + {pageContent.blog_section_subtitle && ( +

+ {pageContent.blog_section_subtitle} +

+ )} +
+ {isLoadingBlog ? ( +
+ {[1, 2, 3].map((i) => ( +
+
+
+
+
+
+
+
+ ))} +
+ ) : blogPosts.length > 0 ? ( +
+ {blogPosts.map((post) => ( + + {post.featured_image && ( +
+ {post.title} +
+ )} +
+ {post.published_at && ( +

+ {new Date(post.published_at).toLocaleDateString()} +

+ )} +

+ {post.title} +

+ {post.excerpt && ( +

{post.excerpt}

+ )} +
+ Read More + +
+
+ + ))} +
+ ) : null} + {blogPosts.length > 0 && ( +
+ + View All Posts + + +
+ )} +
+ )} +
diff --git a/Frontend/src/features/content/services/pageContentService.ts b/Frontend/src/features/content/services/pageContentService.ts index ef9edf89..0ceefa4e 100644 --- a/Frontend/src/features/content/services/pageContentService.ts +++ b/Frontend/src/features/content/services/pageContentService.ts @@ -38,9 +38,13 @@ export interface PageContent { hero_title?: string; hero_subtitle?: string; hero_image?: string; + hero_video_url?: string; + hero_video_poster?: string; story_content?: string; values?: Array<{ icon?: string; title: string; description: string }>; features?: Array<{ icon?: string; title: string; description: string; image?: string }>; + features_section_title?: string; + features_section_subtitle?: string; about_hero_image?: string; mission?: string; vision?: string; @@ -72,8 +76,18 @@ export interface PageContent { about_preview_content?: string; about_preview_image?: string; stats?: Array<{ number: string; label: string; icon?: string }>; + stats_section_title?: string; + stats_section_subtitle?: string; + rooms_section_title?: string; + rooms_section_subtitle?: string; + rooms_section_button_text?: string; + rooms_section_button_link?: string; + rooms_section_enabled?: boolean; luxury_services_section_title?: string; luxury_services_section_subtitle?: string; + services_section_button_text?: string; + services_section_button_link?: string; + services_section_limit?: number; luxury_services?: Array<{ icon?: string; title: string; @@ -115,6 +129,50 @@ export interface PageContent { partners_section_title?: string; partners_section_subtitle?: string; partners?: Array<{ name: string; logo: string; link?: string }>; + sections_enabled?: { + features?: boolean; + luxury?: boolean; + gallery?: boolean; + testimonials?: boolean; + stats?: boolean; + amenities?: boolean; + about_preview?: boolean; + services?: boolean; + experiences?: boolean; + awards?: boolean; + cta?: boolean; + partners?: boolean; + rooms?: boolean; + newsletter?: boolean; + trust_badges?: boolean; + promotions?: boolean; + blog?: boolean; + }; + newsletter_section_title?: string; + newsletter_section_subtitle?: string; + newsletter_placeholder?: string; + newsletter_button_text?: string; + newsletter_enabled?: boolean; + trust_badges_section_title?: string; + trust_badges_section_subtitle?: string; + trust_badges?: Array<{ name: string; logo: string; description?: string; link?: string }>; + trust_badges_enabled?: boolean; + promotions_section_title?: string; + promotions_section_subtitle?: string; + promotions?: Array<{ + title: string; + description: string; + image?: string; + discount?: string; + valid_until?: string; + link?: string; + button_text?: string; + }>; + promotions_enabled?: boolean; + blog_section_title?: string; + blog_section_subtitle?: string; + blog_posts_limit?: number; + blog_enabled?: boolean; is_active?: boolean; created_at?: string; updated_at?: string; @@ -163,9 +221,13 @@ export interface UpdatePageContentData { hero_title?: string; hero_subtitle?: string; hero_image?: string; + hero_video_url?: string; + hero_video_poster?: string; story_content?: string; values?: Array<{ icon?: string; title: string; description: string }>; features?: Array<{ icon?: string; title: string; description: string; image?: string }>; + features_section_title?: string; + features_section_subtitle?: string; about_hero_image?: string; mission?: string; vision?: string; @@ -197,8 +259,18 @@ export interface UpdatePageContentData { about_preview_content?: string; about_preview_image?: string; stats?: Array<{ number: string; label: string; icon?: string }>; + stats_section_title?: string; + stats_section_subtitle?: string; + rooms_section_title?: string; + rooms_section_subtitle?: string; + rooms_section_button_text?: string; + rooms_section_button_link?: string; + rooms_section_enabled?: boolean; luxury_services_section_title?: string; luxury_services_section_subtitle?: string; + services_section_button_text?: string; + services_section_button_link?: string; + services_section_limit?: number; luxury_services?: Array<{ icon?: string; title: string; @@ -240,6 +312,50 @@ export interface UpdatePageContentData { partners_section_title?: string; partners_section_subtitle?: string; partners?: Array<{ name: string; logo: string; link?: string }>; + sections_enabled?: { + features?: boolean; + luxury?: boolean; + gallery?: boolean; + testimonials?: boolean; + stats?: boolean; + amenities?: boolean; + about_preview?: boolean; + services?: boolean; + experiences?: boolean; + awards?: boolean; + cta?: boolean; + partners?: boolean; + rooms?: boolean; + newsletter?: boolean; + trust_badges?: boolean; + promotions?: boolean; + blog?: boolean; + }; + newsletter_section_title?: string; + newsletter_section_subtitle?: string; + newsletter_placeholder?: string; + newsletter_button_text?: string; + newsletter_enabled?: boolean; + trust_badges_section_title?: string; + trust_badges_section_subtitle?: string; + trust_badges?: Array<{ name: string; logo: string; description?: string; link?: string }>; + trust_badges_enabled?: boolean; + promotions_section_title?: string; + promotions_section_subtitle?: string; + promotions?: Array<{ + title: string; + description: string; + image?: string; + discount?: string; + valid_until?: string; + link?: string; + button_text?: string; + }>; + promotions_enabled?: boolean; + blog_section_title?: string; + blog_section_subtitle?: string; + blog_posts_limit?: number; + blog_enabled?: boolean; is_active?: boolean; } @@ -404,6 +520,15 @@ const pageContentService = { if (data.achievements) { updateData.achievements = data.achievements; } + if (data.trust_badges) { + updateData.trust_badges = data.trust_badges; + } + if (data.promotions) { + updateData.promotions = data.promotions; + } + if (data.sections_enabled) { + updateData.sections_enabled = data.sections_enabled; + } const response = await apiClient.put( `/page-content/${pageType}`, diff --git a/Frontend/src/features/notifications/services/emailCampaignService.ts b/Frontend/src/features/notifications/services/emailCampaignService.ts index 5cc04246..294541cb 100644 --- a/Frontend/src/features/notifications/services/emailCampaignService.ts +++ b/Frontend/src/features/notifications/services/emailCampaignService.ts @@ -97,6 +97,7 @@ class EmailCampaignService { reply_to_email?: string; track_opens?: boolean; track_clicks?: boolean; + recipient_type?: 'users' | 'subscribers' | 'both'; }): Promise<{ campaign_id: number }> { const response = await apiClient.post('/email-campaigns', data); return response.data; @@ -165,6 +166,26 @@ class EmailCampaignService { return response.data; } + // Newsletter Subscribers + async getNewsletterSubscribers(params?: { + page?: number; + limit?: number; + }): Promise<{ + subscribers: Array<{ + email: string; + user_id: number | null; + name: string | null; + type: string; + }>; + total: number; + page: number; + limit: number; + total_pages: number; + }> { + const response = await apiClient.get('/email-campaigns/newsletter/subscribers', { params }); + return response.data.data; + } + async createDripSequence(data: { name: string; description?: string; diff --git a/Frontend/src/pages/admin/EmailCampaignManagementPage.tsx b/Frontend/src/pages/admin/EmailCampaignManagementPage.tsx index da00acdf..fcc5dd62 100644 --- a/Frontend/src/pages/admin/EmailCampaignManagementPage.tsx +++ b/Frontend/src/pages/admin/EmailCampaignManagementPage.tsx @@ -6,7 +6,9 @@ import { FileText, X, Layers, - Target + Target, + Users, + Search as SearchIcon } from 'lucide-react'; import { emailCampaignService, Campaign, CampaignSegment, EmailTemplate, DripSequence, CampaignAnalytics } from '../../features/notifications/services/emailCampaignService'; import { toast } from 'react-toastify'; @@ -54,7 +56,8 @@ const EmailCampaignManagementPage: React.FC = () => { from_name: '', from_email: '', track_opens: true, - track_clicks: true + track_clicks: true, + recipient_type: 'users' as 'users' | 'subscribers' | 'both' }); const [segmentForm, setSegmentForm] = useState({ @@ -557,30 +560,53 @@ const SegmentsTab: React.FC<{ segments: CampaignSegment[]; onRefresh: () => void; onCreate: () => void; -}> = ({ segments, onCreate }) => ( -
-
-

Segments

- -
-
- {segments.map((segment) => ( -
-

{segment.name}

-

{segment.description}

-

- Estimated: {segment.estimated_count || 0} users -

+}> = ({ segments, onCreate }) => { + const [showSubscribersModal, setShowSubscribersModal] = React.useState(false); + const newsletterSegment = segments.find(s => s.name === "Newsletter Subscribers"); + + return ( + <> +
+
+

Segments

+
- ))} -
-
-); +
+ {segments.map((segment) => ( +
+

{segment.name}

+

{segment.description}

+
+

+ Estimated: {segment.estimated_count || 0} users +

+ {segment.name === "Newsletter Subscribers" && ( + + )} +
+
+ ))} +
+
+ {showSubscribersModal && newsletterSegment && ( + setShowSubscribersModal(false)} + /> + )} + + ); +}; const TemplatesTab: React.FC<{ templates: EmailTemplate[]; @@ -726,6 +752,15 @@ const CampaignModal: React.FC<{ + setSearch(e.target.value)} + className="w-full pl-10 pr-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" + /> +
+
+ + {loading ? ( +
+
+
+ ) : filteredSubscribers.length === 0 ? ( +
+ No subscribers found +
+ ) : ( +
+ {filteredSubscribers.map((subscriber, index) => ( +
+
+
+ +
+
+

{subscriber.email}

+ {subscriber.name && ( +

{subscriber.name}

+ )} +
+
+ + {subscriber.type} + +
+ ))} +
+ )} +
+ + {totalPages > 1 && ( +
+ + + Page {currentPage} of {totalPages} + + +
+ )} +
+
+ ); +}; + export default EmailCampaignManagementPage; diff --git a/Frontend/src/pages/admin/InspectionManagementPage.tsx b/Frontend/src/pages/admin/InspectionManagementPage.tsx new file mode 100644 index 00000000..352283d9 --- /dev/null +++ b/Frontend/src/pages/admin/InspectionManagementPage.tsx @@ -0,0 +1,651 @@ +import React, { useEffect, useState } from 'react'; +import { Search, Plus, Edit, Eye, CheckCircle, Clock, X, Filter, FileCheck, AlertCircle } from 'lucide-react'; +import advancedRoomService, { RoomInspection } from '../../features/rooms/services/advancedRoomService'; +import roomService, { Room } from '../../features/rooms/services/roomService'; +import userService, { User } from '../../features/auth/services/userService'; +import { toast } from 'react-toastify'; +import Loading from '../../shared/components/Loading'; +import Pagination from '../../shared/components/Pagination'; +import { formatDate } from '../../shared/utils/format'; +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; + +const InspectionManagementPage: React.FC = () => { + const [inspections, setInspections] = useState([]); + const [loading, setLoading] = useState(true); + const [showModal, setShowModal] = useState(false); + const [editingInspection, setEditingInspection] = useState(null); + const [viewingInspection, setViewingInspection] = useState(null); + const [rooms, setRooms] = useState([]); + const [staffMembers, setStaffMembers] = useState([]); + + const [filters, setFilters] = useState({ + search: '', + status: '', + inspection_type: '', + room_id: '', + }); + + const [currentPage, setCurrentPage] = useState(1); + const [totalPages, setTotalPages] = useState(1); + const [totalItems, setTotalItems] = useState(0); + const itemsPerPage = 20; + + const [formData, setFormData] = useState({ + room_id: 0, + booking_id: 0, + inspection_type: 'routine', + scheduled_at: new Date(), + inspected_by: 0, + checklist_items: [] as any[], + }); + + const inspectionTypes = [ + { value: 'pre_checkin', label: 'Pre Check-in', color: 'bg-blue-100 text-blue-800' }, + { value: 'post_checkout', label: 'Post Check-out', color: 'bg-green-100 text-green-800' }, + { value: 'routine', label: 'Routine', color: 'bg-purple-100 text-purple-800' }, + { value: 'maintenance', label: 'Maintenance', color: 'bg-orange-100 text-orange-800' }, + { value: 'damage', label: 'Damage', color: 'bg-red-100 text-red-800' }, + ]; + + const statuses = [ + { value: 'pending', label: 'Pending', color: 'bg-yellow-100 text-yellow-800' }, + { value: 'in_progress', label: 'In Progress', color: 'bg-blue-100 text-blue-800' }, + { value: 'completed', label: 'Completed', color: 'bg-green-100 text-green-800' }, + { value: 'failed', label: 'Failed', color: 'bg-red-100 text-red-800' }, + { value: 'cancelled', label: 'Cancelled', color: 'bg-gray-100 text-gray-800' }, + ]; + + useEffect(() => { + setCurrentPage(1); + }, [filters]); + + useEffect(() => { + fetchInspections(); + fetchRooms(); + fetchStaffMembers(); + }, [filters, currentPage]); + + const fetchInspections = async () => { + try { + setLoading(true); + const params: any = { + page: currentPage, + limit: itemsPerPage, + }; + + if (filters.status) params.status = filters.status; + if (filters.inspection_type) params.inspection_type = filters.inspection_type; + if (filters.room_id) params.room_id = parseInt(filters.room_id); + + const response = await advancedRoomService.getRoomInspections(params); + + if (response.status === 'success' && response.data) { + let inspectionList = response.data.inspections || []; + + if (filters.search) { + inspectionList = inspectionList.filter((inspection: RoomInspection) => + inspection.room_number?.toLowerCase().includes(filters.search.toLowerCase()) || + inspection.inspector_name?.toLowerCase().includes(filters.search.toLowerCase()) + ); + } + + setInspections(inspectionList); + setTotalPages(response.data.pagination?.total_pages || 1); + setTotalItems(response.data.pagination?.total || 0); + } + } catch (error: any) { + toast.error(error.response?.data?.message || 'Unable to load inspections'); + } finally { + setLoading(false); + } + }; + + const fetchRooms = async () => { + try { + const response = await roomService.getRooms({ limit: 1000 }); + if (response.data && response.data.rooms) { + setRooms(response.data.rooms); + } + } catch (error) { + console.error('Error fetching rooms:', error); + } + }; + + const fetchStaffMembers = async () => { + try { + const response = await userService.getUsers({ role: 'staff', limit: 100 }); + if (response.data && response.data.users) { + setStaffMembers(response.data.users); + } + } catch (error) { + console.error('Error fetching staff members:', error); + } + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + if (!formData.room_id && !editingInspection) { + toast.error('Please select a room'); + return; + } + + try { + if (editingInspection) { + // Update existing inspection + const updateData: any = { + status: editingInspection.status, + }; + + if (formData.inspected_by && formData.inspected_by !== editingInspection.inspected_by) { + // Reassignment would need a different endpoint + } + + await advancedRoomService.updateRoomInspection(editingInspection.id, updateData); + toast.success('Inspection updated successfully'); + } else { + // Create new inspection + const dataToSubmit: any = { + room_id: formData.room_id, + inspection_type: formData.inspection_type, + scheduled_at: formData.scheduled_at.toISOString(), + checklist_items: formData.checklist_items, + }; + + if (formData.booking_id) { + dataToSubmit.booking_id = formData.booking_id; + } + + if (formData.inspected_by) { + dataToSubmit.inspected_by = formData.inspected_by; + } + + await advancedRoomService.createRoomInspection(dataToSubmit); + toast.success('Inspection created successfully'); + } + + setShowModal(false); + setEditingInspection(null); + resetForm(); + fetchInspections(); + } catch (error: any) { + toast.error(error.response?.data?.message || `Unable to ${editingInspection ? 'update' : 'create'} inspection`); + } + }; + + const handleStatusUpdate = async (inspectionId: number, newStatus: string) => { + try { + await advancedRoomService.updateRoomInspection(inspectionId, { + status: newStatus, + }); + toast.success('Inspection status updated successfully'); + fetchInspections(); + } catch (error: any) { + toast.error(error.response?.data?.message || 'Unable to update status'); + } + }; + + const resetForm = () => { + setFormData({ + room_id: 0, + booking_id: 0, + inspection_type: 'routine', + scheduled_at: new Date(), + inspected_by: 0, + checklist_items: [], + }); + }; + + const getStatusBadge = (status: string) => { + const statusObj = statuses.find((s) => s.value === status); + return statusObj || statuses[0]; + }; + + const getTypeBadge = (type: string) => { + const typeObj = inspectionTypes.find((t) => t.value === type); + return typeObj || inspectionTypes[2]; + }; + + const getPendingInspections = () => inspections.filter((i) => i.status === 'pending').length; + const getCompletedInspections = () => inspections.filter((i) => i.status === 'completed').length; + const getFailedInspections = () => inspections.filter((i) => i.status === 'failed').length; + + if (loading && inspections.length === 0) { + return ; + } + + return ( +
+ {/* Header */} +
+
+
+
+

+ Inspection Management +

+
+

Manage room inspections and quality control

+
+ +
+ + {/* Filters */} +
+
+
+ + setFilters({ ...filters, search: e.target.value })} + className="w-full pl-12 pr-4 py-3.5 bg-white border-2 border-slate-200 rounded-xl focus:border-amber-400 focus:ring-4 focus:ring-amber-100 transition-all duration-200 text-slate-700 placeholder-slate-400 font-medium shadow-sm hover:shadow-md" + /> +
+ + + +
+
+ + {/* Stats */} +
+
+
+
+

Total Inspections

+

{totalItems}

+
+ +
+
+
+
+
+

Pending

+

{getPendingInspections()}

+
+ +
+
+
+
+
+

Completed

+

{getCompletedInspections()}

+
+ +
+
+
+
+
+

Failed

+

{getFailedInspections()}

+
+ +
+
+
+ + {/* Inspections Table */} +
+
+ + + + + + + + + + + + + + + {inspections.map((inspection) => { + const statusBadge = getStatusBadge(inspection.status); + const typeBadge = getTypeBadge(inspection.inspection_type); + return ( + + + + + + + + + + + ); + })} + +
+ Inspection + + Room + + Type + + Scheduled + + Status + + Inspector + + Score + + Actions +
+
+ {inspectionTypes.find((t) => t.value === inspection.inspection_type)?.label || 'Inspection'} +
+ {inspection.overall_notes && ( +
{inspection.overall_notes}
+ )} +
+
+ Room {inspection.room_number || inspection.room_id} +
+
+ + {typeBadge.label} + + +
+ {formatDate(inspection.scheduled_at)} +
+ {inspection.completed_at && ( +
+ Completed: {formatDate(inspection.completed_at)} +
+ )} +
+ + {statusBadge.label} + + + {inspection.inspector_name || 'Unassigned'} + + {inspection.overall_score !== null && inspection.overall_score !== undefined ? ( +
+ {inspection.overall_score} + / 5 +
+ ) : ( + + )} +
+
+ + + {inspection.status !== 'completed' && inspection.status !== 'cancelled' && ( + + )} +
+
+
+ {inspections.length === 0 && !loading && ( +
+ +

No inspections found

+
+ )} +
+ + {/* Pagination */} + {totalPages > 1 && ( + + )} + + {/* Create/Edit Modal */} + {showModal && ( +
+
+
+

+ {editingInspection ? 'Edit Inspection' : 'Create Inspection'} +

+ +
+
+
+
+ + +
+
+ + +
+
+ +
+
+ + setFormData({ ...formData, scheduled_at: date })} + showTimeSelect + dateFormat="MMMM d, yyyy h:mm aa" + className="w-full px-4 py-2 border-2 border-slate-200 rounded-xl focus:border-amber-400" + required + /> +
+
+ + +
+
+ +
+ + +
+
+
+
+ )} + + {/* View Details Modal - Simplified */} + {viewingInspection && ( +
+
+
+

Inspection Details

+ +
+
+
+
+

Room

+

Room {viewingInspection.room_number || viewingInspection.room_id}

+
+
+

Type

+ + {getTypeBadge(viewingInspection.inspection_type).label} + +
+
+

Status

+ + {getStatusBadge(viewingInspection.status).label} + +
+
+

Inspector

+

{viewingInspection.inspector_name || 'Unassigned'}

+
+
+ {viewingInspection.overall_score !== null && ( +
+

Overall Score

+

{viewingInspection.overall_score} / 5

+
+ )} + {viewingInspection.overall_notes && ( +
+

Notes

+

{viewingInspection.overall_notes}

+
+ )} +
+
+
+ )} +
+ ); + + const handleEdit = (inspection: RoomInspection) => { + setEditingInspection(inspection); + setFormData({ + room_id: inspection.room_id, + booking_id: inspection.booking_id || 0, + inspection_type: inspection.inspection_type, + scheduled_at: new Date(inspection.scheduled_at), + inspected_by: inspection.inspected_by || 0, + checklist_items: inspection.checklist_items || [], + }); + setShowModal(true); + }; +}; + +export default InspectionManagementPage; + diff --git a/Frontend/src/pages/admin/InventoryManagementPage.tsx b/Frontend/src/pages/admin/InventoryManagementPage.tsx new file mode 100644 index 00000000..273ec56d --- /dev/null +++ b/Frontend/src/pages/admin/InventoryManagementPage.tsx @@ -0,0 +1,808 @@ +import React, { useEffect, useState } from 'react'; +import { Search, Plus, Edit, Trash2, Package, AlertTriangle, TrendingDown, Filter, X } from 'lucide-react'; +import inventoryService, { InventoryItem, ReorderRequest } from '../../features/inventory/services/inventoryService'; +import { toast } from 'react-toastify'; +import Loading from '../../shared/components/Loading'; +import Pagination from '../../shared/components/Pagination'; +import { useFormatCurrency } from '../../features/payments/hooks/useFormatCurrency'; +import { formatDate } from '../../shared/utils/format'; + +const InventoryManagementPage: React.FC = () => { + const { formatCurrency } = useFormatCurrency(); + const [items, setItems] = useState([]); + const [loading, setLoading] = useState(true); + const [showModal, setShowModal] = useState(false); + const [editingItem, setEditingItem] = useState(null); + const [showReorderModal, setShowReorderModal] = useState(false); + const [selectedItem, setSelectedItem] = useState(null); + const [reorderRequests, setReorderRequests] = useState([]); + const [lowStockItems, setLowStockItems] = useState([]); + + const [filters, setFilters] = useState({ + search: '', + category: '', + low_stock: false, + is_active: '', + }); + + const [currentPage, setCurrentPage] = useState(1); + const [totalPages, setTotalPages] = useState(1); + const [totalItems, setTotalItems] = useState(0); + const itemsPerPage = 20; + + const [formData, setFormData] = useState({ + name: '', + description: '', + category: 'cleaning_supplies', + unit: 'piece', + minimum_quantity: 0, + maximum_quantity: 0, + reorder_quantity: 0, + unit_cost: 0, + supplier: '', + supplier_contact: '', + storage_location: '', + barcode: '', + sku: '', + notes: '', + is_active: true, + is_tracked: true, + }); + + const categories = [ + { value: 'cleaning_supplies', label: 'Cleaning Supplies' }, + { value: 'linens', label: 'Linens' }, + { value: 'toiletries', label: 'Toiletries' }, + { value: 'amenities', label: 'Amenities' }, + { value: 'maintenance', label: 'Maintenance' }, + { value: 'food_beverage', label: 'Food & Beverage' }, + { value: 'other', label: 'Other' }, + ]; + + const units = [ + { value: 'piece', label: 'Piece' }, + { value: 'box', label: 'Box' }, + { value: 'bottle', label: 'Bottle' }, + { value: 'roll', label: 'Roll' }, + { value: 'pack', label: 'Pack' }, + { value: 'liter', label: 'Liter' }, + { value: 'kilogram', label: 'Kilogram' }, + { value: 'meter', label: 'Meter' }, + { value: 'other', label: 'Other' }, + ]; + + useEffect(() => { + setCurrentPage(1); + }, [filters]); + + useEffect(() => { + fetchItems(); + fetchLowStockItems(); + fetchReorderRequests(); + }, [filters, currentPage]); + + const fetchItems = async () => { + try { + setLoading(true); + const params: any = { + page: currentPage, + limit: itemsPerPage, + }; + + if (filters.category) params.category = filters.category; + if (filters.low_stock) params.low_stock = true; + if (filters.is_active !== '') params.is_active = filters.is_active === 'true'; + + const response = await inventoryService.getInventoryItems(params); + + if (response.status === 'success' && response.data) { + let itemList = response.data.items || []; + + if (filters.search) { + itemList = itemList.filter((item: InventoryItem) => + item.name.toLowerCase().includes(filters.search.toLowerCase()) || + item.description?.toLowerCase().includes(filters.search.toLowerCase()) || + item.sku?.toLowerCase().includes(filters.search.toLowerCase()) || + item.barcode?.toLowerCase().includes(filters.search.toLowerCase()) + ); + } + + setItems(itemList); + setTotalPages(response.data.pagination?.total_pages || 1); + setTotalItems(response.data.pagination?.total || 0); + } + } catch (error: any) { + toast.error(error.response?.data?.message || 'Unable to load inventory items'); + } finally { + setLoading(false); + } + }; + + const fetchLowStockItems = async () => { + try { + const response = await inventoryService.getLowStockItems(); + if (response.status === 'success' && response.data) { + setLowStockItems(response.data.items || []); + } + } catch (error) { + // Silently fail - not critical + } + }; + + const fetchReorderRequests = async () => { + try { + const response = await inventoryService.getReorderRequests({ status: 'pending' }); + if (response.status === 'success' && response.data) { + setReorderRequests(response.data.requests || []); + } + } catch (error) { + // Silently fail - not critical + } + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + try { + if (editingItem) { + await inventoryService.updateInventoryItem(editingItem.id, formData); + toast.success('Inventory item updated successfully'); + } else { + await inventoryService.createInventoryItem(formData); + toast.success('Inventory item created successfully'); + } + + setShowModal(false); + resetForm(); + fetchItems(); + fetchLowStockItems(); + } catch (error: any) { + toast.error(error.response?.data?.message || 'Unable to save inventory item'); + } + }; + + const handleEdit = (item: InventoryItem) => { + setEditingItem(item); + setFormData({ + name: item.name, + description: item.description || '', + category: item.category, + unit: item.unit, + minimum_quantity: item.minimum_quantity, + maximum_quantity: item.maximum_quantity || 0, + reorder_quantity: item.reorder_quantity || 0, + unit_cost: item.unit_cost || 0, + supplier: item.supplier || '', + supplier_contact: '', + storage_location: item.storage_location || '', + barcode: item.barcode || '', + sku: item.sku || '', + notes: '', + is_active: item.is_active, + is_tracked: item.is_tracked, + }); + setShowModal(true); + }; + + const handleDelete = async (id: number) => { + if (!window.confirm('Are you sure you want to delete this inventory item?')) { + return; + } + + try { + await inventoryService.updateInventoryItem(id, { is_active: false }); + toast.success('Inventory item deactivated successfully'); + fetchItems(); + } catch (error: any) { + toast.error(error.response?.data?.message || 'Unable to delete inventory item'); + } + }; + + const resetForm = () => { + setEditingItem(null); + setFormData({ + name: '', + description: '', + category: 'cleaning_supplies', + unit: 'piece', + minimum_quantity: 0, + maximum_quantity: 0, + reorder_quantity: 0, + unit_cost: 0, + supplier: '', + supplier_contact: '', + storage_location: '', + barcode: '', + sku: '', + notes: '', + is_active: true, + is_tracked: true, + }); + }; + + const openReorderModal = (item: InventoryItem) => { + setSelectedItem(item); + setShowReorderModal(true); + }; + + const handleCreateReorder = async (quantity: number, priority: string, notes: string) => { + if (!selectedItem) return; + + try { + await inventoryService.createReorderRequest({ + item_id: selectedItem.id, + requested_quantity: quantity, + priority, + notes, + }); + toast.success('Reorder request created successfully'); + setShowReorderModal(false); + setSelectedItem(null); + fetchReorderRequests(); + } catch (error: any) { + toast.error(error.response?.data?.message || 'Unable to create reorder request'); + } + }; + + const getStockStatus = (item: InventoryItem) => { + if (!item.is_tracked) return { color: 'bg-slate-100 text-slate-700', label: 'Not Tracked' }; + if (item.is_low_stock) return { color: 'bg-red-100 text-red-800', label: 'Low Stock' }; + if (item.maximum_quantity && item.current_quantity >= item.maximum_quantity) { + return { color: 'bg-blue-100 text-blue-800', label: 'Max Stock' }; + } + return { color: 'bg-green-100 text-green-800', label: 'In Stock' }; + }; + + if (loading && items.length === 0) { + return ; + } + + return ( +
+ {/* Header */} +
+
+
+
+

+ Inventory Management +

+
+

Manage hotel inventory and supplies

+
+ +
+ + {/* Alerts */} + {lowStockItems.length > 0 && ( +
+
+ +
+

Low Stock Alert

+

+ {lowStockItems.length} item{lowStockItems.length > 1 ? 's' : ''} below minimum quantity +

+
+
+
+ )} + + {/* Filters */} +
+
+
+ + setFilters({ ...filters, search: e.target.value })} + className="w-full pl-12 pr-4 py-3.5 bg-white border-2 border-slate-200 rounded-xl focus:border-amber-400 focus:ring-4 focus:ring-amber-100 transition-all duration-200 text-slate-700 placeholder-slate-400 font-medium shadow-sm hover:shadow-md" + /> +
+ + + +
+
+ + {/* Stats */} +
+
+
+
+

Total Items

+

{totalItems}

+
+ +
+
+
+
+
+

Low Stock

+

{lowStockItems.length}

+
+ +
+
+
+
+
+

Pending Orders

+

{reorderRequests.length}

+
+ +
+
+
+
+
+

Active Items

+

+ {items.filter((i) => i.is_active).length} +

+
+ +
+
+
+ + {/* Items Table */} +
+
+ + + + + + + + + + + + + + {items.map((item) => { + const stockStatus = getStockStatus(item); + return ( + + + + + + + + + + ); + })} + +
+ Item + + Category + + Quantity + + Status + + Location + + Cost + + Actions +
+
+
{item.name}
+ {item.description && ( +
{item.description}
+ )} + {item.sku && ( +
SKU: {item.sku}
+ )} +
+
+ + {categories.find((c) => c.value === item.category)?.label || item.category} + + +
+ {item.current_quantity} {units.find((u) => u.value === item.unit)?.label || item.unit} +
+ {item.is_tracked && ( +
+ Min: {item.minimum_quantity} +
+ )} +
+ + {stockStatus.label} + + + {item.storage_location || '—'} + + {item.unit_cost ? formatCurrency(item.unit_cost) : '—'} + +
+ {item.is_low_stock && ( + + )} + + +
+
+
+ {items.length === 0 && !loading && ( +
+ +

No inventory items found

+
+ )} +
+ + {/* Pagination */} + {totalPages > 1 && ( + + )} + + {/* Create/Edit Modal */} + {showModal && ( +
+
+
+

+ {editingItem ? 'Edit Inventory Item' : 'Add Inventory Item'} +

+ +
+
+
+
+ + setFormData({ ...formData, name: e.target.value })} + className="w-full px-4 py-2 border-2 border-slate-200 rounded-xl focus:border-amber-400 focus:ring-4 focus:ring-amber-100" + required + /> +
+
+ + +
+
+ +
+ +