-- 2026_08_07_scheduled_rides.sql — الحجز المسبق -- -- ‏شريحة مفقودة بالكامل: رحلات المطار، المواعيد الطبية، الدوام اليومي، -- ‏رحلات الفجر. أعلى الشرائح استعداداً للدفع وأقلها حساسية للسعر. -- -- ‏والزاوية الأهم: الحجز ليس ميزة راكب فقط — هو **مصدر توقّع طلب مؤكد**. -- ‏رحلة محجوزة لبعد ست ساعات معلومة يقينية تُغذّي cron_predictive_demand -- ‏والخريطة الحرارية بشيء أدق من أي تنبؤ إحصائي، وتسمح بتوجيه السائقين -- ‏قبل الذروة لا بعدها. -- -- ⚠️ ‏يُنفَّذ على قاعدة primary (jorSiroDB) وحدها: الكرون والتنبؤ يقرآن -- ‏من primary، والرحلة الفعلية تُنشأ عبر add_ride.php الذي يكتب للاثنتين. CREATE TABLE IF NOT EXISTS `scheduled_rides` ( `id` INT NOT NULL AUTO_INCREMENT, `passenger_id` VARCHAR(100) NOT NULL, -- ‏نقاط الرحلة — نفس صيغة ride.start_location ("lat,lng") `start_location` VARCHAR(255) NOT NULL, `end_location` VARCHAR(255) NOT NULL, `start_name` VARCHAR(255) NULL DEFAULT NULL, `end_name` VARCHAR(255) NULL DEFAULT NULL, `car_type` VARCHAR(20) NOT NULL DEFAULT 'Speed', `distance` FLOAT NOT NULL DEFAULT 0, `duration` INT NOT NULL DEFAULT 0 COMMENT 'ثوانٍ', -- ‏السعر التقديري وقت الحجز. ليس ملزماً: التسعير النهائي يحدث لحظة -- ‏إنشاء الرحلة الفعلية، فسعر ما قبل ست ساعات لا يعرف الذروة ولا الطقس. `estimated_price` DECIMAL(10,2) NOT NULL DEFAULT 0, `scheduled_at` DATETIME NOT NULL COMMENT 'موعد انطلاق الرحلة كما طلبه الراكب', -- ‏كم دقيقة قبل الموعد نبدأ البحث عن سائق. رحلة مطار تحتاج هامشاً أطول -- ‏من رحلة داخل الحي، والراكب لا يُطلب منه ضبطها — نشتقها من المسافة. `lead_minutes` SMALLINT UNSIGNED NOT NULL DEFAULT 15, `status` VARCHAR(20) NOT NULL DEFAULT 'scheduled' COMMENT 'scheduled = بانتظار موعده | dispatching = قفل مؤقت أثناء الإنشاء (يمنع الإطلاق المزدوج) | dispatched = أُنشئت رحلته | cancelled | expired = فات موعده بلا إسناد', -- ‏الرحلة الفعلية التي وُلدت من هذا الحجز. `ride_id` VARCHAR(20) NULL DEFAULT NULL, -- ‏أختام التذكيرات: يُكتب الختم مرة واحدة فيمنع تكرار الإشعار على كل -- ‏مرور للكرون. راكب يصله «رحلتك بعد ساعة» ستين مرة يُلغي الحجز ويحذف -- ‏التطبيق. `reminded_60_at` DATETIME NULL DEFAULT NULL, `reminded_15_at` DATETIME NULL DEFAULT NULL, `note` VARCHAR(255) NULL DEFAULT NULL, `cancelled_reason` VARCHAR(255) NULL DEFAULT NULL, `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), -- ‏المفتاح الذي يعتمد عليه الكرون: يمسح المستحق دون قراءة الجدول كله. KEY `idx_due` (`status`, `scheduled_at`), KEY `idx_passenger` (`passenger_id`, `status`), KEY `idx_ride` (`ride_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='الحجوزات المسبقة — ومصدر توقّع الطلب المؤكد'; -- ‏للتراجع: -- DROP TABLE `scheduled_rides`;