215 lines
12 KiB
SQL
215 lines
12 KiB
SQL
-- ==============================================================================
|
|
-- 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;
|
|
|