# 🗺️ خطة الترحيل التفصيلية

**التاريخ:** 2025-10-25  
**النوع:** Auto Migration - Idempotent  
**الحالة:** 📋 جاهز للتنفيذ

---

## 🎯 الأهداف

1. ✅ نقل جميع البيانات الحيوية من القديمة إلى الجديدة
2. ✅ ربط البوتات والحسابات بالمجموعة الافتراضية
3. ✅ الحفاظ على العلاقات والقيود
4. ✅ إمكانية إعادة التشغيل بأمان (Idempotent)
5. ✅ سجل كامل لكل عملية

---

## 📊 مراحل الترحيل

### المرحلة 0️⃣: التحضير (Pre-Migration)

```
┌─────────────────────────────────────────┐
│ 0.1 التحقق من الاتصال بالقاعدتين      │
│ 0.2 إنشاء نسخة احتياطية من الجديدة   │
│ 0.3 التحقق من وجود المجموعة id=1      │
│ 0.4 تعطيل Foreign Keys مؤقتاً          │
│ 0.5 تهيئة ملف السجل                    │
└─────────────────────────────────────────┘
```

**الوقت المتوقع:** 1-2 دقيقة

---

### المرحلة 1️⃣: البيانات الأساسية (Core Data)

#### 1.1 ترحيل البوتات الفرعية (`sub_bots`)

**الاستعلام:**
```sql
INSERT IGNORE INTO supehgku_test0.sub_bots 
(id, label, bot_token, channel_id, max_users, current_users, paused, welcome_message, created_at)
SELECT 
    id, label, bot_token, channel_id, max_users, current_users, paused, welcome_message, created_at
FROM supehgku_Packagemaker.sub_bots;
```

**التحقق:**
```sql
SELECT COUNT(*) FROM supehgku_test0.sub_bots;
-- يجب أن يساوي عدد البوتات في القديمة
```

**الوقت المتوقع:** < 1 ثانية  
**السجلات المتوقعة:** 10-20

---

#### 1.2 ترحيل حسابات Steam (`steam_accounts`)

**الاستعلام:**
```sql
INSERT IGNORE INTO supehgku_test0.steam_accounts 
(id, account_name, shared_secret, active, created_at)
SELECT 
    id, account_name, shared_secret, active, created_at
FROM supehgku_Packagemaker.steam_accounts;
```

**التحقق:**
```sql
SELECT COUNT(*) FROM supehgku_test0.steam_accounts;
```

**الوقت المتوقع:** < 1 ثانية  
**السجلات المتوقعة:** 50-100

---

#### 1.3 ترحيل المستخدمين (`allowed_users`)

**الاستعلام:**
```sql
INSERT IGNORE INTO supehgku_test0.allowed_users 
(id, bot_token, user_id, banned, created_at)
SELECT 
    id, bot_token, user_id, banned, created_at
FROM supehgku_Packagemaker.allowed_users;
```

**ملاحظة:** حقل `daily_attempts` سيأخذ القيمة الافتراضية 0

**التحقق:**
```sql
SELECT COUNT(*) FROM supehgku_test0.allowed_users;
```

**الوقت المتوقع:** 1-2 ثانية  
**السجلات المتوقعة:** 200-500

---

#### 1.4 ترحيل قوالب الرسائل (`message_templates`)

**الاستعلام:**
```sql
INSERT INTO supehgku_test0.message_templates (`key`, text)
SELECT `key`, text
FROM supehgku_Packagemaker.message_templates
ON DUPLICATE KEY UPDATE text = VALUES(text);
```

**ملاحظة:** سيتم دمج القوالب (تحديث الموجود)

**التحقق:**
```sql
SELECT COUNT(*) FROM supehgku_test0.message_templates;
-- يجب أن يكون >= العدد في القديمة
```

**الوقت المتوقع:** < 1 ثانية  
**السجلات المتوقعة:** 10-20

---

### المرحلة 2️⃣: ربط العلاقات (Relationship Linking)

#### 2.1 ربط الحسابات بالمجموعة الافتراضية

**الاستعلام:**
```sql
INSERT IGNORE INTO supehgku_test0.group_accounts (group_id, account_id)
SELECT 1, id 
FROM supehgku_test0.steam_accounts;
```

**المنطق:**
- كل حساب يُربط بالمجموعة `default` (id=1)
- هذا يجعل جميع الحسابات متاحة فوراً

**التحقق:**
```sql
SELECT COUNT(*) FROM supehgku_test0.group_accounts WHERE group_id = 1;
-- يجب أن يساوي عدد steam_accounts
```

**الوقت المتوقع:** < 1 ثانية

---

#### 2.2 ربط البوتات بالمجموعة الافتراضية

**الاستعلام:**
```sql
INSERT IGNORE INTO supehgku_test0.bot_groups (bot_id, group_id)
SELECT id, 1 
FROM supehgku_test0.sub_bots;
```

**المنطق:**
- كل بوت يُربط بالمجموعة `default` (id=1)
- هذا يتيح لكل بوت الوصول لجميع الحسابات

**التحقق:**
```sql
SELECT COUNT(*) FROM supehgku_test0.bot_groups WHERE group_id = 1;
-- يجب أن يساوي عدد sub_bots
```

**الوقت المتوقع:** < 1 ثانية

---

### المرحلة 3️⃣: البيانات الاختيارية (Optional Data)

#### 3.1 ترحيل سجل الطلبات (`steam_requests`)

⚠️ **تحذير:** قد يحتوي على آلاف/ملايين السجلات!

**الاستعلام (بالدفعات):**
```sql
-- دفعة 1
INSERT IGNORE INTO supehgku_test0.steam_requests
SELECT * FROM supehgku_Packagemaker.steam_requests
LIMIT 0, 10000;

-- دفعة 2
INSERT IGNORE INTO supehgku_test0.steam_requests
SELECT * FROM supehgku_Packagemaker.steam_requests
LIMIT 10000, 10000;

-- ... الخ
```

**التحقق:**
```sql
SELECT COUNT(*) FROM supehgku_test0.steam_requests;
```

**الوقت المتوقع:** 5-30 دقيقة (حسب الحجم)  
**الخيار:** يمكن تعطيله في الإعدادات

---

#### 3.2 توليد عدادات الحدود (`limit_counters`)

**الخيار A: من الصفر (الأسرع)**
```sql
-- سيتم إنشاؤها تلقائياً عند الاستخدام
-- لا حاجة لفعل شيء
```

**الخيار B: من السجل التاريخي (الأدق)**
```sql
INSERT IGNORE INTO supehgku_test0.limit_counters 
(user_id, account_id, day_used, week_used, month_used, day_reset_at, week_reset_at, month_reset_at)
SELECT 
    sr.user_id,
    sa.id as account_id,
    COUNT(CASE WHEN DATE(sr.created_at) = CURDATE() THEN 1 END) as day_used,
    COUNT(CASE WHEN YEARWEEK(sr.created_at) = YEARWEEK(NOW()) THEN 1 END) as week_used,
    COUNT(CASE WHEN YEAR(sr.created_at) = YEAR(NOW()) AND MONTH(sr.created_at) = MONTH(NOW()) THEN 1 END) as month_used,
    DATE_ADD(CURDATE(), INTERVAL 1 DAY) as day_reset_at,
    DATE_ADD(DATE_ADD(CURDATE(), INTERVAL (7 - WEEKDAY(CURDATE())) DAY), INTERVAL 1 WEEK) as week_reset_at,
    DATE_ADD(LAST_DAY(CURDATE()), INTERVAL 1 DAY) as month_reset_at
FROM supehgku_Packagemaker.steam_requests sr
JOIN supehgku_test0.steam_accounts sa ON sa.account_name = sr.account_name
GROUP BY sr.user_id, sa.id;
```

**الوقت المتوقع:** 1-10 دقيقة

---

### المرحلة 4️⃣: التنظيف والتحقق (Cleanup & Verification)

```
┌─────────────────────────────────────────┐
│ 4.1 إعادة تفعيل Foreign Keys           │
│ 4.2 تحديث Auto Increment Counters      │
│ 4.3 إعادة بناء الفهارس                 │
│ 4.4 تحليل الجداول (ANALYZE)            │
│ 4.5 التحقق من سلامة البيانات           │
└─────────────────────────────────────────┘
```

#### 4.1 إعادة تفعيل Foreign Keys
```sql
SET FOREIGN_KEY_CHECKS=1;
```

#### 4.2 تحديث Auto Increment
```sql
ALTER TABLE sub_bots AUTO_INCREMENT = (SELECT MAX(id) + 1 FROM sub_bots);
ALTER TABLE steam_accounts AUTO_INCREMENT = (SELECT MAX(id) + 1 FROM steam_accounts);
ALTER TABLE allowed_users AUTO_INCREMENT = (SELECT MAX(id) + 1 FROM allowed_users);
```

#### 4.3 التحقق من العلاقات
```sql
-- التحقق من أن كل حساب له مجموعة
SELECT COUNT(*) as orphaned_accounts
FROM steam_accounts sa
LEFT JOIN group_accounts ga ON ga.account_id = sa.id
WHERE ga.account_id IS NULL;
-- يجب أن يكون 0

-- التحقق من أن كل بوت له مجموعة
SELECT COUNT(*) as orphaned_bots
FROM sub_bots sb
LEFT JOIN bot_groups bg ON bg.bot_id = sb.id
WHERE bg.bot_id IS NULL;
-- يجب أن يكون 0
```

---

## 📊 جدول زمني متوقع

| المرحلة | الوقت | التراكمي |
|---------|-------|----------|
| 0️⃣ التحضير | 1-2 دقيقة | 2 دقيقة |
| 1️⃣ البيانات الأساسية | 2-5 ثانية | 2 دقيقة |
| 2️⃣ الربط | 1 ثانية | 2 دقيقة |
| 3️⃣ الاختياري | 0-30 دقيقة | 2-32 دقيقة |
| 4️⃣ التحقق | 1-2 دقيقة | 3-34 دقيقة |

**الإجمالي:** 3-35 دقيقة (حسب حجم البيانات)

---

## ⚠️ نقاط الانتباه

### 1. تعارض المعرفات (ID Conflicts)
**المشكلة:** قد تتعارض IDs القديمة مع الموجودة

**الحل:**
```sql
-- استخدام INSERT IGNORE
-- سيتخطى السجلات المكررة
INSERT IGNORE INTO ...
```

### 2. بيانات معطوبة
**المشكلة:** قد تحتوي القديمة على بيانات غير صحيحة

**الحل:**
```sql
-- التحقق قبل النقل
SELECT * FROM old.steam_accounts WHERE account_name = '' OR shared_secret = '';
-- حذف أو تصحيح قبل الترحيل
```

### 3. الذاكرة والوقت
**المشكلة:** جداول كبيرة قد تفشل

**الحل:**
- الترحيل بالدفعات (batches)
- زيادة `memory_limit` و `max_execution_time`

---

## ✅ معايير النجاح

| المعيار | الهدف | كيفية التحقق |
|---------|--------|--------------|
| **عدد البوتات** | متطابق | `COUNT(*)` |
| **عدد الحسابات** | متطابق | `COUNT(*)` |
| **عدد المستخدمين** | متطابق | `COUNT(*)` |
| **الربط - حسابات** | 100% | `COUNT(group_accounts)` = `COUNT(steam_accounts)` |
| **الربط - بوتات** | 100% | `COUNT(bot_groups)` = `COUNT(sub_bots)` |
| **FK سليمة** | 0 أخطاء | تشغيل `FOREIGN_KEY_CHECKS=1` |
| **لا يتامى** | 0 | استعلامات LEFT JOIN |

---

## 🔄 إمكانية إعادة التشغيل (Idempotency)

النظام مصمم ليكون **idempotent** - يمكن إعادة تشغيله بأمان:

```
✅ INSERT IGNORE - يتخطى المكرر
✅ ON DUPLICATE KEY UPDATE - يحدّث الموجود
✅ التحقق قبل الإدراج
✅ Transactions - rollback عند الفشل
```

**مثال:**
```bash
# التشغيل الأول
php migrate.php  # ينقل كل شيء

# التشغيل الثاني (بعد إضافة بوت جديد في القديمة)
php migrate.php  # ينقل الجديد فقط، يتخطى الموجود
```

---

## 📝 السجلات (Logs)

سيتم تسجيل كل عملية في:
```
migration_system/logs/migration_YYYYMMDD_HHMMSS.log
```

**محتوى السجل:**
```
[2025-10-25 03:45:00] INFO: بدء الترحيل
[2025-10-25 03:45:01] INFO: تعطيل Foreign Keys
[2025-10-25 03:45:02] SUCCESS: sub_bots - 15 سجل
[2025-10-25 03:45:03] SUCCESS: steam_accounts - 73 سجل
[2025-10-25 03:45:04] SUCCESS: allowed_users - 412 سجل
[2025-10-25 03:45:05] SUCCESS: group_accounts - 73 سجل
[2025-10-25 03:45:06] SUCCESS: bot_groups - 15 سجل
[2025-10-25 03:45:10] INFO: إعادة تفعيل Foreign Keys
[2025-10-25 03:45:11] SUCCESS: اكتمل الترحيل بنجاح!
```

---

## 🚀 التنفيذ

```bash
# 1. تعديل الإعدادات
nano config/migration_config.ini

# 2. اختبار (dry-run)
php scripts/migrate.php --dry-run

# 3. التنفيذ الفعلي
php scripts/migrate.php

# 4. التحقق
php scripts/verify.php
```

---

## 🆘 استعادة النسخة الاحتياطية

إذا حدث خطأ:
```bash
mysql -u user -p supehgku_test0 < backups/backup_YYYYMMDD_HHMMSS.sql
```

---

*آخر تحديث: 2025-10-25 03:45 UTC+03*
