المفاهيم الأساسية
الكيانات (Entities)
المسارات داخل المشروع:
/src/modules/credit/
credit-account.entity.ts
credit-request.entity.ts
credit-ledger-entry.entity.ts
CreditAccount
يمثّل حساب الآجل (لـ User أو Company) ويحتوي على الحد المستخدم والمتاح وحالة الحساب والمدة.
limitSar / limitPoints
usedSar / usedPoints
platformFeePointsPerKg (اختياري)
termStartAt / termDueAt
status: active | frozen | disabled
reachedFullLimitInTerm: boolean
CreditRequest
طلب تقديم آجل يتم مراجعته من الإدارة (قبول/رفض) مع تخزين القرار والحد والمدة.
CreditLedgerEntry
سجل حركات الآجل: purchase / repayment / freeze / unfreeze
تدفقات الاستخدام (Flows)
1) تدفق طلب الآجل + المراجعة
مستخدم/شركة
|
| POST /credit/requests
v
CreditRequest: pending
|
| (Admin)
| POST /credit/admin/requests/:id/approve أو /reject
v
CreditAccount: active + حد + مدة
2) الشراء بالآجل (Orders)
Buyer
|
| POST /orders/:id/checkout/credit
| - تحقق من CreditAccount (active + limit)
| - احتساب عمولة المنصة لكل KG (platformFeePointsPerKg إن وُجد)
| - زيادة usedPoints/usedSar + ledger purchase
| - Mint نقاط للبائع فورًا
| - تسجيل رسوم المنصة (fees)
v
Order: awaiting_fulfillment (paymentMethod=credit)
3) الشراء بالآجل (Service Orders)
Buyer
|
| POST /service-orders/:id/pay-credit
| - تحقق من CreditAccount (active + limit)
| - زيادة usedPoints/usedSar + ledger purchase
| - Mint basePoints للمقدّم فورًا
| - تسجيل ربح المنصة (profit)
v
ServiceOrder: paid
4) السداد التلقائي (من المبيعات)
عند اكتمال الطلب (Order COMPLETED)
|
| net = total - (buyerFee + sellerFee)
| ملاحظة: عند الدفع بالآجل يتم احتساب صافي السداد بناءً على الرسوم الفعلية التي تم خصمها وقت الشراء
| (باستخدام order.totalPoints لضمان التطابق حتى لو تغيّرت إعدادات العمولة لاحقًا)
| applyRepaymentFromSale(net)
v
CreditAccount.usedPoints ينقص + ledger repayment
ملاحظة: السداد هنا idempotent (لن يتكرر لنفس orderId).
5) التجميد عند نهاية المدة (Scheduler)
كل ساعة (Cron)
|
| إذا termDueAt انتهت و reachedFullLimitInTerm=false و usedPoints<limitPoints
v
CreditAccount.status = frozen
أمثلة الحالات (كما طلبت)
النتيجة: يعود له رصيد متاح 4000 فورًا، ويتم تمديد المدة لشهر جديد من تاريخ السداد، ولا يتم إيقاف الحساب.
النتيجة: عند نهاية المدة يتم تجميد حسابه الآجل ويحتاج طلب آجل جديد لإعادة تقييم احتياجه.
الإشعارات (Notifications)
النظام يرسل إشعارات إلى كل الـAdmins وإلى صاحب الطلب/الحساب لكل الأحداث المتعلقة بالآجل.
NotificationType:
credit_request_created
credit_request_approved
credit_request_rejected
credit_account_frozen
credit_account_unfrozen
يتم الإرسال عبر جدول notifications + Push Notification (Firebase topic لكل مستخدم) + WhatsApp إن كان مفعّل.
نقاط النهاية (API)
جميع المسارات التالية تتطلب إرسال هيدر: Authorization: Bearer <token> ما لم يُذكر خلاف ذلك.
Customer APIs
إنشاء طلب آجل (User أو Company). يتم إرسال إشعارات للـAdmins ولصاحب الطلب.
{
"ownerType": "user", // "user" | "company"
"ownerCompanyId": null, // مطلوب فقط عند ownerType=company
"requestedLimitSar": "5000",
"companyName": "",
"phone": "+9665...",
"email": "customer@example.com",
"commercialRegisterNumber": "",
"notes": "احتاج حد للشراء الشهري"
}
عرض حساب/حسابات الآجل للمستخدم (قد يعيد حساب مستخدم + حساب شركة إن كان مالك شركة).
Admin APIs
جلب طلبات الآجل حسب الحالة: pending/approved/rejected.
قبول الطلب وتحديد الحد والمدة. يقوم النظام بإنشاء/تحديث CreditAccount.
{
"limitSar": "5000",
"termDueAtIso": "2026-05-02T00:00:00.000Z",
"platformFeePointsPerKg": 1
}
رفض الطلب مع سبب اختياري.
{
"reason": "لا يوجد سجل مشتريات كافي"
}
تجميد حساب الآجل يدويًا (مع سبب اختياري).
{
"reason": "مطلوب تحديث بيانات العميل"
}
فك تجميد حساب الآجل يدويًا.
{
"reason": "تم تحديث البيانات"
}
Checkout with Credit
دفع طلب منتجات بالآجل. يقوم النظام بالتالي داخل Transaction: زيادة استخدام الآجل + إنشاء Ledger purchase + Mint للبائع + تسجيل رسوم المنصة.
{
"ownerType": "user", // اختياري
"ownerCompanyId": null // اختياري
}
دفع طلب خدمة بالآجل. يقوم النظام بزيادة استخدام الآجل + Mint للمقدّم + تسجيل ربح المنصة.