# FirstPay Egypt — ملف التسليم والتشغيل على cPanel

**المشروع:** FirstPay Egypt
**الدومين المستهدف:** `firstpayeg.com`
**نوع التطبيق:** React/Vite + Node.js/Express + MySQL/Drizzle
**بيئة التشغيل المطلوبة:** cPanel يدعم Node.js Applications وMySQL
**جهة البريد الوظيفي:** `hr.opportunity@firstpayeg.com`
**بريد الشركة:** `info@firstpayeg.com`
**WhatsApp:** `01212000061` — الرابط الدولي: `https://wa.me/201212000061`

---

## 1. الهدف ونطاق العمل

الغرض من هذا الملف هو تشغيل النسخة الجديدة بدل الموقع الحالي على نفس الدومين، مع الحفاظ على نسخة رجوع كاملة. الموقع يحتوي على الموقع العام، العربية/الإنجليزية، الخدمات، الأخبار، الوظائف، نموذج التوظيف ورفع CV، AI Chat، لوحة الإدارة، رسائل التواصل، صفحات الخصوصية والشروط، صفحات تفاصيل الأخبار والوظائف، وزر WhatsApp.

لا يتم حذف الموقع القديم قبل اجتياز اختبارات القبول النهائية. يجب الاحتفاظ بنسخة ملفات الموقع القديم ونسخة SQL من قاعدة بياناته.

---

## 2. متطلبات الاستضافة

يجب أن تتوفر في حساب cPanel:

- Node.js 22 أو أقرب إصدار متاح.
- `Setup Node.js App` أو `Node.js Selector`.
- MySQL/MariaDB وقاعدة بيانات قابلة للاتصال من Node.js.
- Terminal أو SSH.
- SSL/AutoSSL.
- مساحة تخزين كافية لملفات CV والـlogs.
- إمكانية ضبط Environment Variables داخل تطبيق Node.
- Passenger أو Node Application Manager.

إذا لم توجد أداة Node.js Applications، فلن يعمل الموقع كاملًا على Shared Hosting PHP-only. يجب تفعيل Node.js من شركة الاستضافة أو نقل التطبيق إلى VPS/Cloud Hosting يدعم Node.js.

---

## 3. ملفات التسليم

ارفع ملف `firstpay-delivery.zip`، ثم فك الضغط داخل مجلد مستقل مثل:

```text
/home2/CPANEL_USER/firstpay-app
```

يجب أن تكون ملفات المشروع مباشرة داخل `firstpay-app`، وليس داخل مجلد فرعي إضافي:

```text
firstpay-app/package.json
firstpay-app/client/
firstpay-app/server/
firstpay-app/drizzle/
firstpay-app/vite.config.ts
```

بعد البناء يجب أن يظهر:

```text
firstpay-app/dist/index.js
firstpay-app/dist/public/
```

لا ترفع `node_modules` من جهاز آخر. يتم تثبيتها على الخادم من `package.json` و`pnpm-lock.yaml`.

---

## 4. خطة النسخ الاحتياطي قبل الاستبدال

### ملفات الموقع القديم

من File Manager:

1. ادخل إلى مجلد الدومين الحالي، غالبًا:
   `public_html/firstpayeg.com`.
2. اضغط المجلد واختر Compress → ZIP.
3. سمّ النسخة:
   `firstpayeg-old-site-BACKUP-DATE.zip`.
4. لا تحذف النسخة القديمة.

### قاعدة البيانات القديمة

من phpMyAdmin:

1. اختر قاعدة بيانات الموقع القديم.
2. اختر Export → Quick → SQL.
3. احفظ الملف خارج public_html.

### قاعدة بيانات الموقع الجديد

أنشئ قاعدة منفصلة للموقع الجديد، ولا تستخدم قاعدة الموقع القديم إلا بعد مراجعة الجداول والتوافق. اسم مقترح:

```text
CPANEL_USER_firstpay
```

---

## 5. إنشاء قاعدة MySQL الجديدة

من cPanel → MySQL Databases:

1. أنشئ Database باسم `firstpay`.
2. أنشئ User باسم `firstpay_app`.
3. اربط المستخدم بالقاعدة.
4. فعّل `ALL PRIVILEGES`.
5. احتفظ باسم القاعدة والمستخدم وكلمة المرور.

في أغلب الاستضافات تكون الأسماء النهائية مسبوقة باسم حساب cPanel:

```text
Database: CPANEL_USER_firstpay
User: CPANEL_USER_firstpay_app
Host: localhost
Port: 3306
```

---

## 6. إنشاء Node.js Application

من cPanel → Setup Node.js App → Create Application:

```text
Node.js version: 22.22.2 أو أعلى إصدار 22 متاح
Application mode: Production
Application root: firstpay-app
Application URL: https://firstpayeg.com
Application startup file: dist/index.js
```

اترك مسار URL فارغًا حتى يعمل الموقع من الجذر، وليس من `/firstpay-app`.

لا تضغط Remove Domain ولا تغيّر Document Root قبل أخذ النسخة الاحتياطية.

إذا كان cPanel يطلب منفذًا، استخدم المنفذ الذي يحدده Passenger ولا تثبت منفذًا عشوائيًا. التطبيق يقرأ `PORT` من بيئة التشغيل.

---

## 7. تثبيت الاعتمادات والبناء

من Terminal/SSH:

```bash
cd ~/firstpay-app
npm install
npm run build
```

إذا كان pnpm متاحًا، يفضّل استخدام النسخة المثبتة في المشروع:

```bash
corepack enable
corepack prepare pnpm@10.18.0 --activate
pnpm install --frozen-lockfile
pnpm build
```

أوامر المشروع الرسمية:

```text
pnpm check       فحص TypeScript
pnpm build       بناء الواجهة والخادم
pnpm db:migrate  تطبيق migrations قاعدة البيانات
pnpm start       تشغيل الإنتاج محليًا/من مدير العملية
```

لا تستخدم `pnpm dev` في الإنتاج.

---

## 8. Environment Variables

تضاف المتغيرات من cPanel → Setup Node.js App → التطبيق → Environment Variables. لا تضع كلمات المرور داخل الكود أو ZIP أو Git.

### أساسية

```text
NODE_ENV=production
DATABASE_URL=mysql://DB_USER:DB_PASSWORD@localhost:3306/DB_NAME
```

استبدل القيم ببيانات قاعدة cPanel. إذا كانت كلمة المرور تحتوي رموزًا خاصة، يجب URL-encode لها داخل `DATABASE_URL`.

### متغيرات تشغيل Manus/AI/Auth/Storage

المشروع الحالي يعتمد على قيم المشروع التالية إذا كانت الخدمات المدارة ستستمر:

```text
MANUS_PROJECT_ID=قيمة المشروع
MANUS_JWT_SECRET=قيمة سرية طويلة
MANUS_OAUTH_API_URL=رابط OAuth المعتمد
MANUS_API_URL=رابط Manus API المعتمد
MANUS_API_KEY=مفتاح Manus API
OWNER_OPEN_ID=معرف مالك المشروع إن كان مطلوبًا
```

لا يتم تخمين هذه القيم. يجب أن يوفرها مسؤول البنية أو يتم استبدال تكامل Manus بتكامل مستقل قبل التشغيل خارج بيئة Manus. غيابها قد يؤثر على تسجيل دخول لوحة الإدارة وAI Chat والتخزين والإشعارات.

### SMTP

بعد إنشاء حساب البريد في cPanel، افتح Email Accounts → Connect Devices للحساب `info@firstpayeg.com` وانسخ بيانات Outgoing/SMTP التي يعرضها مزود الاستضافة.

القيم المتوقعة:

```text
SMTP_HOST=mail.firstpayeg.com
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=info@firstpayeg.com
SMTP_PASSWORD=كلمة مرور صندوق البريد
SMTP_FROM=info@firstpayeg.com
HR_EMAIL=hr.opportunity@firstpayeg.com
INFO_EMAIL=info@firstpayeg.com
```

إذا كانت بيانات الاستضافة تستخدم STARTTLS على 587:

```text
SMTP_PORT=587
SMTP_SECURE=false
```

لا تفترض أن `mail.firstpayeg.com` صحيح؛ استخدم قيمة Connect Devices الفعلية.

---

## 9. تطبيق قاعدة البيانات

بعد ضبط `DATABASE_URL`:

```bash
cd ~/firstpay-app
pnpm db:migrate
```

أو:

```bash
npm run db:migrate
```

يجب أن تظهر جداول الموقع مثل الخدمات والأخبار والوظائف وطلبات التوظيف والرسائل وFAQ وإعدادات الموقع. لا تطبق migration على قاعدة الموقع القديم دون نسخة SQL ومراجعة.

---

## 10. تشغيل التطبيق وربط الدومين

1. من Setup Node.js App اضغط Restart Application.
2. راجع Passenger/Application Logs.
3. اختبر:

```text
https://firstpayeg.com/api/health
```

النتيجة المطلوبة:

```json
{"status":"ok"}
```

4. افتح:

```text
https://firstpayeg.com
https://firstpayeg.com/admin
```

إذا كان الدومين بالفعل داخل نفس cPanel، فلا تغيّر DNS عادةً؛ المطلوب هو أن يوجه Document Root/Node Application إلى التطبيق الجديد. لا تحذف الدومين.

---

## 11. SSL وwww

من cPanel → SSL/TLS Status شغّل AutoSSL للدومينين:

```text
firstpayeg.com
www.firstpayeg.com
```

اختبر:

```text
https://firstpayeg.com
https://www.firstpayeg.com
```

يفضل اختيار نسخة أساسية واحدة، مثل `https://firstpayeg.com`، وتحويل `www` إليها من إعدادات الاستضافة بعد التأكد من عمل الاثنين.

---

## 12. اختبار SMTP

بعد ضبط SMTP وتشغيل التطبيق:

1. افتح نموذج التوظيف.
2. أرسل طلبًا تجريبيًا مع CV صغير PDF.
3. تحقق من وصول الرسالة إلى:
   `hr.opportunity@firstpayeg.com` و`info@firstpayeg.com`.
4. افتح نموذج التواصل وأرسل رسالة تجريبية.
5. افحص Spam/Junk وPassenger Logs.
6. تأكد من حفظ الطلب والـCV في لوحة الإدارة حتى لو تعطل SMTP.

موضوع رسالة التوظيف المتوقع يبدأ بـ:

```text
New FirstPay job application:
```

موضوع رسالة التواصل المتوقع يبدأ بـ:

```text
FirstPay contact message from
```

إذا ظهر `SMTP is not configured`، راجع أسماء المتغيرات حرفيًا. إذا ظهر Authentication failed، راجع كلمة مرور صندوق البريد وSMTP Host/Port/Secure.

---

## 13. اختبار الوظائف ولوحة الإدارة

يجب اختبار الآتي:

- الصفحة الرئيسية تعمل بالعربية والإنجليزية.
- الشعار واضح على الهاتف والكمبيوتر.
- الخدمات لا تعرض ميزة دفع بالفيزا.
- الوظائف الثلاثة تظهر: مندوب مبيعات، مشرف مبيعات، مدير حسابات.
- نموذج الوظيفة يقبل PDF/Word حتى 8MB ويرفض الملفات غير المسموحة.
- الطلب يظهر في لوحة الإدارة.
- تغيير حالة الطلب يعمل: New، Reviewing، Shortlisted، Rejected، Hired.
- تنزيل CV يعمل للمستخدم الإداري فقط.
- الأخبار والوظائف لها صفحات تفاصيل.
- WhatsApp يفتح الرقم `01212000061`.
- صفحات `/privacy` و`/terms` تعمل.
- `/api/health` يعيد status ok.
- `/manus-routes.json` يعيد JSON صحيحًا.
- الحساب العادي لا يصل إلى APIs الإدارة.

---

## 14. صلاحيات لوحة الإدارة

افتح:

```text
https://firstpayeg.com/admin
```

يجب الدخول بحساب مصرح له. في قاعدة البيانات يكون دور المستخدم الإداري:

```text
role = admin
```

لا تمنح صلاحية admin لأي حساب إلا بعد موافقة إدارة الشركة. لا تشارك كلمات مرور أو مفاتيح API في البريد أو WhatsApp.

---

## 15. النسخ الاحتياطي والمراقبة

أنشئ نسخة يومية من MySQL ونسخة دورية من تخزين CV. احتفظ بثلاث نسخ على الأقل في أماكن منفصلة. راقب:

- Passenger Logs.
- مساحة التخزين.
- فشل SMTP.
- أخطاء `/api/health`.
- محاولات الدخول الفاشلة.

لا تحفظ ملفات CV داخل `public_html` مباشرة. يجب أن تبقى خلف التخزين/صلاحيات التطبيق.

---

## 16. خطة الرجوع للموقع القديم

إذا فشل الإطلاق:

1. أوقف Node Application الجديد.
2. أعد Document Root للمجلد القديم أو أعد تشغيل تطبيق الموقع القديم.
3. استرجع قاعدة البيانات القديمة فقط إذا تم تعديلها، وبعد الاحتفاظ بنسخة من قاعدة الموقع الجديد.
4. احتفظ بسجلات الخطأ.
5. لا تحذف ملفات النسخة الجديدة قبل معرفة سبب الفشل.

---

## 17. بيانات يجب أن يسلمها فريق IT بعد التنفيذ

يجب أن يرسل الفريق تقريرًا يتضمن:

- رابط الموقع النهائي.
- Node.js version.
- Application root وstartup file.
- حالة `/api/health`.
- اسم قاعدة البيانات فقط، وليس كلمة المرور.
- تأكيد نجاح `pnpm db:migrate`.
- تأكيد نجاح اختبار إرسال البريد.
- تأكيد نجاح رفع وتنزيل CV.
- تاريخ آخر نسخة احتياطية.
- مكان حفظ بيانات الدخول بشكل آمن.

لا يتم إرسال كلمات المرور أو `MANUS_API_KEY` في تقرير عادي؛ تحفظ في مدير أسرار أو Password Manager.

---

## 18. قبول الإطلاق

يُعتبر الموقع جاهزًا للإطلاق عندما تنجح كل الاختبارات السابقة، وتعمل الواجهة على `https://firstpayeg.com`، ويصل بريد تجريبي إلى العنوانين، وتعمل لوحة الإدارة، وتوجد نسخة احتياطية قابلة للاسترجاع، ويؤكد فريق IT أن خطة الرجوع جاهزة.
