Files
SS/AGENTS.md
T

304 lines
13 KiB
Markdown

# AGENTS.md — SMM Panel Project
> ملف تعليمات للوكيل البرمجي (AI Agent). اقرأه بالكامل قبل كتابة أي كود.
> الهدف: بناء موقع SMM Panel لبيع خدمات السوشال ميديا عبر API مزوّد خارجي،
> مع محفظة رصيد (Wallet) ونظام مستخدمين ولوحة أدمن.
>
> ⚠️ راجع أيضاً `WALLET.md` — فيه تفاصيل إلزامية عن نظام تسجيل الدخول وصحة المحفظة،
> و`TASKS.md` — فيه خطة تنفيذ مرحلية بالترتيب.
---
## 1. نظرة عامة على المشروع (Project Overview)
منصة ويب تبيع خدمات سوشال ميديا (متابعين، لايكات، مشاهدات … إلخ).
المستخدم:
1. يسجّل حساب ويسجّل دخول.
2. يشحن محفظته (Wallet) برصيد.
3. يتصفّح الخدمات المتاحة.
4. ينشئ طلب (Order): يختار خدمة + يحط الرابط/الـ ID + الكمية.
5. النظام يخصم من رصيده ويرسل الطلب لمزوّد الخدمة عبر API، ثم يتابع حالته.
الموقع **وسيط**: يشتري من مزوّد بسعر منخفض ويبيع للمستخدم بسعر أعلى (هامش ربح يحدده الأدمن).
---
## 2. المصطلحات (Glossary)
- **Provider / المزوّد**: الجهة الخارجية اللي تملك الـ API الحقيقي وتنفّذ الخدمات.
- **Service / الخدمة**: عنصر قابل للبيع (مثال: "1000 متابع انستقرام")، له `service_id` وسعر وحد أدنى وأقصى.
- **Wallet / المحفظة**: رصيد المستخدم داخل الموقع.
- **Order / الطلب**: عملية شراء خدمة من قبل المستخدم.
- **Transaction / المعاملة**: أي حركة على الرصيد (شحن، خصم، استرجاع).
- **Markup / الهامش**: نسبة أو مبلغ يُضاف على سعر المزوّد ليصير سعر البيع.
---
## 3. التقنيات (Tech Stack)
> ⚠️ هذه افتراضات قابلة للتغيير — راجع "قرارات مفتوحة" في الأسفل.
- **Backend**: Node.js + Express
- **Database**: MySQL (أو MariaDB)
- **Auth**: JWT + bcrypt لتشفير كلمات المرور
- **Frontend**: (اختر واحد) React / EJS templates بسيطة للبداية
- **HTTP client** للتواصل مع المزوّد: `axios`
- **Validation**: `zod` أو `express-validator`
- **Env config**: `dotenv`
هيكل المجلدات المقترح:
```
/src
/config (اتصال قاعدة البيانات، متغيرات البيئة)
/models (استعلامات قاعدة البيانات)
/services (منطق العمل: wallet, orders, provider API)
/controllers (معالجة الطلبات)
/routes (المسارات)
/middleware (auth, admin-check, error handler)
/utils
/public (الواجهة)
```
---
## 4. مخطط قاعدة البيانات (Database Schema)
### جدول users
| العمود | النوع | ملاحظات |
|---|---|---|
| id | BIGINT PK AUTO_INCREMENT | |
| username | VARCHAR(50) UNIQUE | |
| email | VARCHAR(120) UNIQUE | |
| password_hash | VARCHAR(255) | bcrypt |
| balance | DECIMAL(12,4) DEFAULT 0 | رصيد المحفظة |
| role | ENUM('user','admin') DEFAULT 'user' | |
| status | ENUM('active','banned') DEFAULT 'active' | |
| created_at | TIMESTAMP | |
### جدول services
| العمود | النوع | ملاحظات |
|---|---|---|
| id | BIGINT PK | |
| provider_service_id | VARCHAR(50) | الـ ID عند المزوّد |
| name | VARCHAR(255) | |
| category | VARCHAR(100) | |
| provider_price | DECIMAL(12,4) | سعر المزوّد لكل 1000 |
| sell_price | DECIMAL(12,4) | سعر البيع لكل 1000 (بعد الهامش) |
| min | INT | أقل كمية |
| max | INT | أكبر كمية |
| is_active | BOOLEAN DEFAULT true | |
| updated_at | TIMESTAMP | |
### جدول orders
| العمود | النوع | ملاحظات |
|---|---|---|
| id | BIGINT PK | |
| user_id | BIGINT FK → users.id | |
| service_id | BIGINT FK → services.id | |
| link | VARCHAR(500) | الرابط/الـ ID المستهدف |
| quantity | INT | |
| charge | DECIMAL(12,4) | المبلغ المخصوم من المستخدم |
| provider_order_id | VARCHAR(80) | رقم الطلب عند المزوّد |
| status | ENUM('pending','processing','in_progress','completed','partial','canceled','failed') DEFAULT 'pending' | |
| created_at | TIMESTAMP | |
### جدول transactions
| العمود | النوع | ملاحظات |
|---|---|---|
| id | BIGINT PK | |
| user_id | BIGINT FK | |
| type | ENUM('deposit','order','refund') | |
| amount | DECIMAL(12,4) | موجب = إضافة، سالب = خصم |
| balance_after | DECIMAL(12,4) | الرصيد بعد العملية (للتدقيق) |
| reference | VARCHAR(120) | مرجع (رقم الطلب / رقم الإيداع) |
| note | VARCHAR(255) | |
| created_at | TIMESTAMP | |
### جدول deposits (طلبات الشحن اليدوي)
| العمود | النوع | ملاحظات |
|---|---|---|
| id | BIGINT PK | |
| user_id | BIGINT FK | |
| amount | DECIMAL(12,4) | |
| method | VARCHAR(50) | usdt / manual … |
| tx_ref | VARCHAR(200) | إثبات التحويل (hash / رقم عملية) |
| status | ENUM('pending','approved','rejected') DEFAULT 'pending' | |
| reviewed_by | BIGINT NULL | id الأدمن |
| created_at | TIMESTAMP | |
---
## 5. تكامل API المزوّد (Provider Integration)
معظم مزوّدي SMM يتبعون نفس المعيار (Perfect Panel standard). كل الطلبات
عبارة عن POST إلى نقطة نهاية واحدة مع `key` و `action`.
**متغيرات البيئة المطلوبة:**
```
PROVIDER_API_URL=https://provider.example/api/v2
PROVIDER_API_KEY=xxxxxxxx
```
**العمليات:**
```
# جلب كل الخدمات
POST { key, action: "services" }
# إنشاء طلب
POST { key, action: "add", service, link, quantity }
→ يرجّع { order: <provider_order_id> }
# متابعة حالة طلب
POST { key, action: "status", order: <provider_order_id> }
→ يرجّع { charge, start_count, status, remains }
# رصيدك أنت عند المزوّد
POST { key, action: "balance" }
```
> ⚠️ تحقّق من توثيق المزوّد الفعلي: بعض الحقول قد تختلف بالتسمية.
> اجعل طبقة `provider.service.js` قابلة للتعديل من مكان واحد.
---
## 6. المنطق الحرج: المحفظة والطلبات (Critical Logic)
> التفاصيل الكاملة (race conditions، idempotency، تسوية دورية) موجودة في `WALLET.md`. هذا ملخص سريع فقط.
### قاعدة ذهبية: كل عملية على الرصيد داخل Transaction من قاعدة البيانات (atomic)
لا تسمح أبداً بخصم الرصيد وإرسال الطلب في خطوات منفصلة غير محمية.
**تدفق إنشاء الطلب (order flow):**
```
1. تحقّق أن المستخدم مسجّل دخول ونشِط.
2. تحقّق أن الخدمة موجودة و is_active.
3. تحقّق quantity ضمن [min, max].
4. احسب charge = (sell_price / 1000) * quantity.
5. ابدأ DB Transaction:
a. اقفل صف المستخدم (SELECT ... FOR UPDATE).
b. تحقّق balance >= charge، وإلا ارفض (رصيد غير كافٍ).
c. اخصم: balance -= charge.
d. أنشئ صف order بحالة pending.
e. أنشئ صف transaction (type=order, amount=-charge).
f. Commit.
6. أرسل الطلب لـ API المزوّد.
7. إذا نجح: خزّن provider_order_id وحدّث status=processing.
8. إذا فشل الإرسال: أعِد الرصيد (refund) وحدّث status=failed.
```
**تدفق الشحن اليدوي:**
```
1. المستخدم يقدّم طلب إيداع (amount + tx_ref) → deposits(status=pending).
2. الأدمن يراجع ويوافق.
3. عند الموافقة (داخل DB Transaction):
- balance += amount
- transaction (type=deposit)
- deposit.status = approved
```
**متابعة الحالات (cron/job):**
مهمة دورية تمرّ على الطلبات غير المكتملة وتستعلم عن حالتها من المزوّد وتحدّثها.
---
## 7. المسارات (API Routes)
### عامة / مصادقة
```
POST /auth/register
POST /auth/login
POST /auth/logout
POST /auth/forgot-password
```
### المستخدم (يتطلب تسجيل دخول)
```
GET /me → بيانات الحساب + الرصيد
GET /services → قائمة الخدمات النشطة (بسعر البيع)
POST /orders → إنشاء طلب
GET /orders → طلباتي
GET /orders/:id → تفاصيل طلب
GET /transactions → كشف حساب المحفظة
POST /deposits → طلب شحن يدوي
GET /deposits → طلبات الشحن الخاصة بي
```
### الأدمن (يتطلب role=admin)
```
GET /admin/users
PATCH /admin/users/:id → حظر/رفع حظر، تعديل رصيد يدوي
GET /admin/deposits → طلبات الشحن المعلّقة
PATCH /admin/deposits/:id → موافقة/رفض
GET /admin/orders → كل الطلبات
POST /admin/services/sync → سحب الخدمات من المزوّد
PATCH /admin/services/:id → تعديل السعر/الهامش/التفعيل
GET /admin/stats → إحصائيات (أرباح، مبيعات)
```
---
## 8. متطلبات الأمان (Security — إلزامي)
- تشفير كلمات المرور بـ **bcrypt** (لا تخزّنها نصّاً أبداً).
- مفتاح API المزوّد في **متغيرات البيئة فقط**، لا يُرسل للواجهة إطلاقاً.
- كل حسابات المال بـ `DECIMAL` وليس `FLOAT`.
- التحقق من صحة كل المدخلات (server-side validation).
- حماية من SQL Injection عبر prepared statements / ORM.
- Rate limiting على مسارات auth و orders.
- التحقق من الصلاحيات (middleware) على كل مسار أدمن.
- **السعر يُحسب دائماً في الخادم** — لا تثق بأي سعر قادم من الواجهة.
---
## 9. متغيرات البيئة (.env)
```
PORT=3000
DATABASE_URL=mysql://user:pass@localhost:3306/smm
JWT_SECRET=change_me_long_random
PROVIDER_API_URL=https://provider.example/api/v2
PROVIDER_API_KEY=your_provider_key
DEFAULT_MARKUP_PERCENT=25
```
---
## 10. ترتيب البناء (Build Order / Milestones)
1. **الإعداد**: مشروع Node + Express + اتصال MySQL + الهجرات (migrations).
2. **المصادقة**: register / login / JWT / middleware.
3. **المحفظة**: جداول transactions + عرض الرصيد + كشف حساب.
4. **الشحن اليدوي**: deposits + موافقة الأدمن.
5. **الخدمات**: سحب من المزوّد + عرضها بسعر البيع + إدارة الأدمن.
6. **الطلبات**: تدفق الطلب الكامل (atomic) + الإرسال للمزوّد.
7. **متابعة الحالات**: مهمة دورية لتحديث حالات الطلبات.
8. **لوحة الأدمن**: الإحصائيات والإدارة.
9. **الواجهة**: ربط كل شيء بواجهة نظيفة.
سلّم كل مرحلة قابلة للتشغيل والاختبار قبل الانتقال للتالية.
> 📋 للتنفيذ الفعلي خطوة بخطوة، اتّبع `TASKS.md`.
---
## 11. قرارات مفتوحة (Open Decisions — املأها)
هذه القرارات محسومة للنسخة الحالية، ومفصلة في `DECISIONS.md`:
- [x] **طريقة الشحن**: شحن يدوي عبر قنوات قابلة للإدارة، مع PayPal وشام كاش وUSDT كبداية.
- [x] **اللغة/التقنية**: Node.js + Express + MySQL/MariaDB.
- [x] **الواجهة**: HTML/CSS/JavaScript ثابتة داخل `public/` وتخدمها Express.
- [x] **العملة المعتمدة**: USD بأربع خانات عشرية.
- [x] **الهامش**: هامش افتراضي من `DEFAULT_MARKUP_PERCENT` مع تخزين `markup_percent` لكل خدمة ودعم تعديل الأدمن.
- [x] **رابط ومفتاح API المزوّد الفعلي**: عبر `PROVIDER_API_URL` و`PROVIDER_API_KEY` في متغيرات البيئة فقط.
- [x] **دعم متعدد اللغات**: الواجهة والرسائل عربية حالياً، وتعليقات الكود والداخليات بالإنجليزية.
---
## 12. ملاحظات للوكيل (Agent Notes)
- اطلب توثيق المزوّد الحقيقي قبل كتابة طبقة `provider.service.js`.
- لا تفترض تفاصيل الدفع؛ إن كانت غير محسومة اسأل المالك.
- اكتب اختبارات لمنطق المحفظة (أهم جزء حسّاس) — راجع `WALLET.md` قسم 4.
- علّق الكود بالإنجليزية، والرسائل للمستخدم بالعربية (أو حسب إعداد اللغة).