-- ============================================================================== -- Uruk International Prize Platform - Database Schema (MySQL 8.0) -- Engine: InnoDB | Collation: utf8mb4_unicode_ci -- Designed for High Security, Fingerprint Verification, and Audit Compliance -- ============================================================================== SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- 1. جدول المستخدمين الأساسي (Users) CREATE TABLE IF NOT EXISTS `users` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `phone` VARCHAR(20) NOT NULL UNIQUE, `email` VARCHAR(191) NULL UNIQUE, `full_name` VARCHAR(191) NOT NULL, `country` VARCHAR(64) NOT NULL DEFAULT 'Iraq', `city` VARCHAR(64) NULL, `national_id_hash` VARCHAR(64) NULL COMMENT 'Encrypted or hashed national ID', `avatar_url` VARCHAR(255) NULL, `role` ENUM('MEMBER', 'PARTNER_STAFF', 'ADMIN', 'SUPER_ADMIN') NOT NULL DEFAULT 'MEMBER', `status` ENUM('PENDING_VERIFICATION', 'ACTIVE', 'SUSPENDED', 'BANNED') NOT NULL DEFAULT 'PENDING_VERIFICATION', `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_users_phone` (`phone`), INDEX `idx_users_status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 2. جدول أمان الجهاز والبصمة والترويسات (User Security & Fingerprint) CREATE TABLE IF NOT EXISTS `user_security` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `user_id` BIGINT UNSIGNED NOT NULL, `device_fingerprint` VARCHAR(64) NOT NULL COMMENT 'SHA-256 derived from hardware & SecureStorage', `device_secret` VARCHAR(64) NOT NULL COMMENT 'HMAC secret key unique to this device', `device_model` VARCHAR(128) NULL, `os_version` VARCHAR(64) NULL, `last_token` VARCHAR(255) NULL, `last_ip` VARCHAR(45) NULL, `last_active_at` TIMESTAMP NULL, `failed_attempts` INT UNSIGNED NOT NULL DEFAULT 0, `is_locked` TINYINT(1) NOT NULL DEFAULT 0, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT `fk_security_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, UNIQUE KEY `uk_user_device` (`user_id`, `device_fingerprint`), INDEX `idx_fingerprint` (`device_fingerprint`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 3. جدول العضويات والاشتراكات (Memberships / Subscriptions) CREATE TABLE IF NOT EXISTS `subscriptions` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `user_id` BIGINT UNSIGNED NOT NULL, `membership_number` VARCHAR(32) NOT NULL UNIQUE COMMENT 'e.g. URUK-2026-XXXXX', `plan_name` VARCHAR(64) NOT NULL DEFAULT '2-Year Executive Membership', `price_usd` DECIMAL(10, 2) NOT NULL DEFAULT 100.00, `price_local` DECIMAL(14, 2) NOT NULL DEFAULT 132000.00, `currency` VARCHAR(8) NOT NULL DEFAULT 'IQD', `starts_at` DATE NOT NULL, `expires_at` DATE NOT NULL, `status` ENUM('PENDING_PAYMENT', 'ACTIVE', 'EXPIRED', 'REVOKED') NOT NULL DEFAULT 'PENDING_PAYMENT', `qr_seed` VARCHAR(64) NOT NULL COMMENT 'Cryptographic salt for dynamic rotating QR', `activated_by` BIGINT UNSIGNED NULL COMMENT 'Admin user ID if activated manually', `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT `fk_subscription_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, INDEX `idx_membership_number` (`membership_number`), INDEX `idx_status_expiry` (`status`, `expires_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 4. جدول المعاملات والمدفوعات (Financial Transactions) CREATE TABLE IF NOT EXISTS `transactions` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `subscription_id` BIGINT UNSIGNED NOT NULL, `user_id` BIGINT UNSIGNED NOT NULL, `method` ENUM('SUPER_QI', 'ZAIN_CASH', 'SWIFTPAY_IQ', 'RAFIDAIN_CARD', 'CLIQ_JORDAN', 'CASH_DIRECT') NOT NULL, `reference_number` VARCHAR(128) NOT NULL UNIQUE COMMENT 'Transaction ID / Movement ID from SuperQi, ZainCash, etc.', `sender_account_or_phone` VARCHAR(64) NULL, `recipient_account` VARCHAR(64) NULL, `amount` DECIMAL(14, 2) NOT NULL, `currency` VARCHAR(8) NOT NULL DEFAULT 'IQD', `status` ENUM('SUBMITTED', 'VERIFIED_AUTO', 'VERIFIED_ADMIN', 'REJECTED') NOT NULL DEFAULT 'SUBMITTED', `receipt_image_url` VARCHAR(255) NULL, `raw_webhook_payload` JSON NULL, `verified_at` TIMESTAMP NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT `fk_transaction_sub` FOREIGN KEY (`subscription_id`) REFERENCES `subscriptions` (`id`) ON DELETE CASCADE, CONSTRAINT `fk_transaction_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, INDEX `idx_ref_number` (`reference_number`), INDEX `idx_status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 5. جدول الشركاء (المستشفيات والفنادق والمراكز) CREATE TABLE IF NOT EXISTS `partners` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `type` ENUM('HOSPITAL', 'HOTEL', 'TRAINING_CENTER', 'OTHER') NOT NULL, `name_ar` VARCHAR(191) NOT NULL, `name_en` VARCHAR(191) NULL, `category` VARCHAR(64) NOT NULL COMMENT 'Eyes, Cancer, Heart, General, 5-Star Hotel...', `country` VARCHAR(64) NOT NULL DEFAULT 'Iraq', `city` VARCHAR(64) NOT NULL, `discount_percentage` DECIMAL(5, 2) NOT NULL COMMENT 'e.g. 50.00 for hospitals, 40-60 for hotels', `address` TEXT NULL, `phone` VARCHAR(64) NULL, `email` VARCHAR(128) NULL, `latitude` DECIMAL(10, 8) NULL, `longitude` DECIMAL(11, 8) NULL, `contract_starts_at` DATE NULL, `contract_ends_at` DATE NULL, `is_active` TINYINT(1) NOT NULL DEFAULT 1, `added_by_admin` BIGINT UNSIGNED NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_type_country_city` (`type`, `country`, `city`), INDEX `idx_is_active` (`is_active`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 6. جدول الدورات التدريبية المعتمدة (Academy & Workshops) CREATE TABLE IF NOT EXISTS `courses` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `title` VARCHAR(191) NOT NULL, `specialty` VARCHAR(64) NOT NULL COMMENT 'Medical, Languages, Engineering, Management...', `instructor_name` VARCHAR(128) NOT NULL, `delivery_format` ENUM('IN_PERSON_HOTEL', 'ONLINE_STREAM', 'HYBRID') NOT NULL DEFAULT 'HYBRID', `hotel_partner_id` BIGINT UNSIGNED NULL, `scheduled_start` DATETIME NOT NULL, `scheduled_end` DATETIME NULL, `broadcast_url` VARCHAR(255) NULL, `max_seats` INT UNSIGNED NULL, `is_published` TINYINT(1) NOT NULL DEFAULT 1, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT `fk_course_hotel` FOREIGN KEY (`hotel_partner_id`) REFERENCES `partners` (`id`) ON DELETE SET NULL, INDEX `idx_specialty` (`specialty`), INDEX `idx_scheduled_start` (`scheduled_start`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 7. جدول تسجيل المتدربين والشهادات (Course Enrollments & Certificates) CREATE TABLE IF NOT EXISTS `course_enrollments` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `user_id` BIGINT UNSIGNED NOT NULL, `course_id` BIGINT UNSIGNED NOT NULL, `status` ENUM('REGISTERED', 'ATTENDED', 'COMPLETED', 'CERTIFICATE_ISSUED') NOT NULL DEFAULT 'REGISTERED', `certificate_serial` VARCHAR(64) NULL UNIQUE COMMENT 'Accredited certificate tracking number', `certificate_url` VARCHAR(255) NULL, `issued_at` DATETIME NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT `fk_enrollment_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, CONSTRAINT `fk_enrollment_course` FOREIGN KEY (`course_id`) REFERENCES `courses` (`id`) ON DELETE CASCADE, UNIQUE KEY `uk_user_course` (`user_id`, `course_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 8. سجل التحقق والزيارات الميدانية (Verification Logs at Partners) CREATE TABLE IF NOT EXISTS `verification_logs` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `subscription_id` BIGINT UNSIGNED NOT NULL, `partner_id` BIGINT UNSIGNED NOT NULL, `verifier_staff_name` VARCHAR(128) NULL, `applied_discount` DECIMAL(5, 2) NOT NULL, `service_type` VARCHAR(128) NULL, `scanned_token_signature` VARCHAR(64) NOT NULL, `verified_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT `fk_verif_sub` FOREIGN KEY (`subscription_id`) REFERENCES `subscriptions` (`id`) ON DELETE CASCADE, CONSTRAINT `fk_verif_partner` FOREIGN KEY (`partner_id`) REFERENCES `partners` (`id`) ON DELETE CASCADE, INDEX `idx_partner_verified_at` (`partner_id`, `verified_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 9. جدول التدقيق الأمني ومراقبة الترويسات (Audit & Header Logs) CREATE TABLE IF NOT EXISTS `audit_logs` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `user_id` BIGINT UNSIGNED NULL, `action` VARCHAR(64) NOT NULL, `endpoint` VARCHAR(128) NOT NULL, `method` VARCHAR(10) NOT NULL, `ip_address` VARCHAR(45) NOT NULL, `device_fingerprint` VARCHAR(64) NULL, `nonce_used` VARCHAR(64) NULL, `response_code` SMALLINT UNSIGNED NOT NULL, `payload_snippet` TEXT NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX `idx_user_action` (`user_id`, `action`), INDEX `idx_created_at` (`created_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 10. جدول أجهزة بوابات الاتصال الثلاثة (Gateway Caller Devices - Zain, Asiacell, Korek) CREATE TABLE IF NOT EXISTS `gateway_devices` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `device_id` VARCHAR(64) NOT NULL UNIQUE COMMENT 'e.g. zain-node-1, asiacell-node-2, korek-node-3', `operator` ENUM('ZAIN', 'ASIACELL', 'KOREK', 'UNKNOWN') NOT NULL DEFAULT 'UNKNOWN', `phone_number` VARCHAR(32) NULL, `sim_slot` TINYINT UNSIGNED NOT NULL DEFAULT 1, `status` ENUM('ACTIVE', 'OFFLINE', 'BUSY') NOT NULL DEFAULT 'ACTIVE', `last_heartbeat` TIMESTAMP NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_gw_status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 11. جدول مهام الاتصال الفلاش والرسائل النصية (Gateway Tasks Queue) CREATE TABLE IF NOT EXISTS `gateway_tasks` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `task_type` ENUM('FLASH_CALL', 'SMS') NOT NULL DEFAULT 'FLASH_CALL', `target_phone` VARCHAR(32) NOT NULL, `otp_code` VARCHAR(16) NOT NULL, `assigned_device_id` VARCHAR(64) NULL, `status` ENUM('PENDING', 'PROCESSING', 'COMPLETED', 'FAILED', 'EXPIRED') NOT NULL DEFAULT 'PENDING', `timeout_seconds` INT UNSIGNED NOT NULL DEFAULT 25, `completed_at` TIMESTAMP NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX `idx_task_status_type` (`status`, `task_type`, `created_at`), INDEX `idx_assigned_device` (`assigned_device_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; SET FOREIGN_KEY_CHECKS = 1;