# SKANDER servertelegram v3.9.0 — حفظ دائم + تسريع لوحة التحكم

التحديث مبني فوق **servertelegram v3.8.2** ويحافظ على إصلاح **Cancel → Replace** الخاص بتعديل توصيات Telegram.

## المشاكل التي تم تشخيصها

### 1. الإعدادات كانت تعتمد على `data/state.json` فقط
في v3.8.2 كان ملف `state.json` يجمع معاً:
- إعدادات لوحة التحكم.
- حالة الأجهزة.
- التوصيات.
- الأوامر.
- نتائج التنفيذ.
- بيانات Telegram runtime.

ومع cPanel / Passenger يمكن أن توجد أكثر من عملية Node في أوقات مختلفة. إذا كانت عملية قديمة تحمل إعدادات قديمة في الذاكرة ثم حفظت Runtime state، فمن الممكن أن تعيد كتابة نسخة قديمة من الإعدادات داخل `state.json`.

### 2. الحفظ كان ثقيل جداً على event loop
الحفظ القديم كان في كل مرة يقوم بـ:
1. تحويل كامل state إلى JSON منسق.
2. كتابة الملف.
3. `fsync`.
4. إعادة قراءة الملف كاملاً.
5. `JSON.parse` للتحقق.
6. نسخ كامل الملف إلى `.bak`.

وفوق ذلك كان Telegram live polling يستطيع طلب حفظ كل ثانية، وكانت بعض عمليات الأجهزة تحفظ الحالة بشكل متكرر. على shared hosting هذا يسبب توقفات ملحوظة للـ Node event loop وبطء في `/dashboard`.

### 3. لوحة التحكم كانت تعيد رسم كل شيء مع كل WebSocket update
حتى لو كنت داخل صفحة الإعدادات فقط، كانت الصفحة تعيد بناء:
- القنوات.
- التوصيات.
- جميع بطاقات الأجهزة.
- جدول الوقت.
- سجل الأوامر.
- الإشعارات.

مع مئات أو أكثر من 1000 جهاز يصبح هذا مكلفاً جداً في المتصفح.

## الإصلاحات في v3.9.0

### Canonical settings file
تم إضافة:

```text
data/settings.json
data/settings.json.bak
```

هذه الملفات أصبحت المرجع الدائم لإعدادات السيرفر العامة.

عند الضغط على **حفظ**:
1. يتم حفظ `settings.json` بحفظ ذري ودائم.
2. يتم التحقق من الملف.
3. يتم إنشاء Backup.
4. تتم مزامنته مع `state.json`.
5. كل Passenger worker يراجع ملف الإعدادات تلقائياً كل ثانية.

وبذلك لا يستطيع Runtime save من Worker قديم إعادة الإعدادات القديمة.

### Fast state persistence
- `state.json` أصبح Compact JSON بدلاً من pretty-print.
- Runtime writes تستخدم Fast Atomic Save.
- `fsync + verify + backup` الكامل محجوز للعمليات الحرجة.
- Runtime saves المتكررة يتم دمجها `coalescing` بدلاً من الكتابة مئات المرات.
- Backup للحالة يتم بصورة دورية بدلاً من نسخه في كل ping/poll.
- Telegram polling لا يقوم Durable Write كل ثانية.
- فحص offline للأجهزة لا يحفظ الملف إلا إذا تغيرت حالة جهاز فعلاً.

### تسريع Dashboard
- `/api/dashboard/state` يدعم **gzip level 1** تلقائياً للمتصفحات.
- لا يتم إرسال كل حقول `device_meta` الخام إلى المتصفح؛ فقط الحقول المطلوبة للوحة.
- تقليل سجلات العرض إلى أحدث:
  - 120 توصية.
  - 120 أمر تحكم.
  - 80 إشعار.
- الصفحة تعيد رسم **التبويب المفتوح فقط** بدلاً من جميع التبويبات.
- صفحة الأجهزة تعرض أحدث 120 جهاز افتراضياً، والبحث يصل لأي جهاز من كامل القائمة فوراً.
- أوامر Bulk لم تعد تعيد آلاف كائنات التحكم في HTTP response؛ يتم إرجاع العدد وعينة IDs فقط.
- Dashboard WebSocket updates تم تخفيف معدل إعادة بناء الحالة.

## نتائج التحقق داخل بيئة الاختبار

Fixture يحتوي تقريباً على:
- 1000 جهاز.
- 1200 توصية.
- 6000 أمر تحكم.

نتيجة Fast state save في الاختبار المحلي:

```text
v3.8.2 average: ~29.6 ms
v3.9.0 average: ~6 ms إلى ~8 ms
```

أي تحسن يقارب **4–5 مرات** في عملية حفظ نفس حجم الحالة داخل بيئة الاختبار. الأداء على الاستضافة الفعلية يعتمد على سرعة قرص cPanel والتحميل.

Dashboard fixture بحوالي 1000 جهاز:

```text
JSON before HTTP compression: ~1.53 MB
Gzip wire payload: ~42 KB
Local endpoint response: ~0.05 sec
```

هذه أرقام اختبار وليست ضماناً لزمن الاستجابة على الاستضافة.

## طريقة التحديث على cPanel

المسار:

```text
public_html/servertelegram
```

احتفظ قبل الاستبدال بـ:

```text
.env
data/state.json
data/state.json.bak
```

إذا كان `data/settings.json` موجوداً من v3.9.0 أو أحدث احتفظ أيضاً بـ:

```text
data/settings.json
data/settings.json.bak
```

في أول تشغيل v3.9.0، إذا لم يوجد `settings.json` فسوف ينشئه السيرفر تلقائياً من الإعدادات الحالية الموجودة داخل `state.json`.

بعد رفع الملفات:
1. من **Setup Node.js App** اختر التطبيق `/servertelegram`.
2. شغل **Run NPM Install** إذا كانت `node_modules` غير موجودة أو بعد تغيير بيئة Node.
3. اضغط **Restart Application**.
4. افتح:

```text
https://scorpiion.ae/servertelegram/health
```

وتأكد أن `persistence` يحتوي:

```text
memoryOnly: false
writable: true
settingsLoadSource: settings_primary
```

ثم افتح:

```text
https://scorpiion.ae/servertelegram/dashboard
```

غيّر إعداداً واضغط حفظ. يجب أن يظهر تنبيه يحتوي على رقم `Revision` جديد.

## مهم جداً
لا تستخدم صلاحية `777`. مجلد `data` يجب أن يكون مملوكاً لنفس مستخدم cPanel وقابلاً للكتابة بواسطة تطبيق Node.
