81 lines
5.6 KiB
SQL
81 lines
5.6 KiB
SQL
-- ============================================================
|
||
-- طلب رحلة بلا إنترنت — عبر SMS (بند 3.1 من دراسة الفرص)
|
||
--
|
||
-- المسار: الراكب يرسل رسالة نصية لرقمنا الثابت ← تطبيق أندرويد على
|
||
-- ذلك الهاتف يوجّهها إلى webhook_sms/webhook.php ← نحلّلها وننشئ رحلة
|
||
-- ← نرد عليه برسالة، وحين يقبل سائق نرد برسالة ثانية فيها اسمه ولوحته.
|
||
--
|
||
-- لا مشغّل اتصالات ولا ترخيص ولا رقم قصير — شريحة عادية في هاتف عادي.
|
||
-- ============================================================
|
||
|
||
-- ── ١) الوارد الخام ─────────────────────────────────────────
|
||
-- نحفظ كل رسالة تصل كما وصلت، قبل أي تحليل. السبب: المحلّل سيخطئ في
|
||
-- البداية حتماً (اللهجات، الأخطاء الإملائية، صيغ لم نتوقّعها)، وبلا
|
||
-- الخام لن نعرف *لماذا* أخطأ ولا كيف نحسّنه.
|
||
CREATE TABLE IF NOT EXISTS `sms_inbox` (
|
||
`id` INT NOT NULL AUTO_INCREMENT,
|
||
`sender` VARCHAR(32) NOT NULL COMMENT 'رقم المرسل كما وصل من الهاتف',
|
||
`sender_norm` VARCHAR(32) NOT NULL COMMENT 'الرقم بعد التوحيد (بلا رموز، بمقدمة دولية)',
|
||
`body` TEXT NOT NULL,
|
||
`intent` ENUM('ride','payment','unknown') NOT NULL DEFAULT 'unknown',
|
||
`received_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_sender_norm` (`sender_norm`),
|
||
KEY `idx_received` (`received_at`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
|
||
-- ── ٢) طلبات الرحلة المستخرجة ───────────────────────────────
|
||
-- جدول وسيط بين الرسالة والرحلة، لا اختصار له. وظيفته الأمنية أساساً:
|
||
-- add_ride.php يفتح مساراً داخلياً بمفتاح S2S لهذه الطلبات، وشرط المرور
|
||
-- وجود صف هنا بحالة 'dispatching' يطابق الراكب ونقطة الانطلاق — تماماً
|
||
-- كما فعلنا مع الحجز المسبق. مفتاح مسرّب وحده لا يخلق رحلة.
|
||
CREATE TABLE IF NOT EXISTS `sms_ride_requests` (
|
||
`id` INT NOT NULL AUTO_INCREMENT,
|
||
`inbox_id` INT DEFAULT NULL,
|
||
`sender_norm` VARCHAR(32) NOT NULL,
|
||
`passenger_id` VARCHAR(100) DEFAULT NULL COMMENT 'يُملأ بعد إيجاد/إنشاء الحساب',
|
||
`raw_start` VARCHAR(255) DEFAULT NULL COMMENT 'النص كما كتبه الراكب',
|
||
`raw_end` VARCHAR(255) DEFAULT NULL,
|
||
`start_location` VARCHAR(100) DEFAULT NULL COMMENT '"lat,lng"',
|
||
`end_location` VARCHAR(100) DEFAULT NULL,
|
||
`start_name` VARCHAR(255) DEFAULT NULL COMMENT 'اسم المعلم المطابَق',
|
||
`end_name` VARCHAR(255) DEFAULT NULL,
|
||
`distance` DOUBLE DEFAULT 0,
|
||
`duration` INT DEFAULT 0,
|
||
`status` ENUM('pending','dispatching','dispatched','failed','unparsed')
|
||
NOT NULL DEFAULT 'pending',
|
||
`ride_id` VARCHAR(100) DEFAULT NULL,
|
||
`attempts` TINYINT NOT NULL DEFAULT 0,
|
||
`fail_reason` VARCHAR(255) 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_status_created` (`status`, `created_at`),
|
||
KEY `idx_ride` (`ride_id`),
|
||
KEY `idx_sender` (`sender_norm`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
|
||
-- ── ٣) الصادر ───────────────────────────────────────────────
|
||
-- طابور لا إرسال مباشر. مزوّدونا الحاليون (Kazumi / Nabeh / Intaleq)
|
||
-- مسارات OTP لا رسائل حرة، فالمُرسِل اليوم هو نفس الهاتف المستقبِل:
|
||
-- يسحب من هنا كل بضع ثوانٍ ويرسل عبر شريحته. الطابور يجعل استبدال
|
||
-- المُرسِل لاحقاً (مشغّل، أو بوابة تجارية) تغييراً في طرف واحد.
|
||
CREATE TABLE IF NOT EXISTS `sms_outbox` (
|
||
`id` INT NOT NULL AUTO_INCREMENT,
|
||
`recipient` VARCHAR(32) NOT NULL,
|
||
`body` TEXT NOT NULL,
|
||
`context` VARCHAR(64) DEFAULT NULL COMMENT 'ride_created / driver_found / error ...',
|
||
`ref_id` VARCHAR(100) DEFAULT NULL COMMENT 'رقم الرحلة أو الطلب المرتبط',
|
||
`status` ENUM('pending','sending','sent','failed') NOT NULL DEFAULT 'pending',
|
||
`attempts` TINYINT NOT NULL DEFAULT 0,
|
||
`claimed_by` VARCHAR(64) DEFAULT NULL COMMENT 'معرّف الهاتف الذي سحب الرسالة',
|
||
`claimed_at` DATETIME DEFAULT NULL,
|
||
`sent_at` DATETIME DEFAULT NULL,
|
||
`last_error` VARCHAR(255) DEFAULT NULL,
|
||
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
-- الفهرس على (status, id) هو ما يجعل السحب رخيصاً مهما كبر الجدول.
|
||
KEY `idx_status_id` (`status`, `id`),
|
||
KEY `idx_claimed` (`status`, `claimed_at`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|