Skip to content

مخطط قاعدة البيانات

يولّد FORGE مخطط قاعدة بيانات PostgreSQL كامل مع مفاتيح UUID أساسية، وفهرسة مناسبة، وحذف ناعم، وترجمات قائمة على JSONB. هذه الصفحة هي المرجع الكامل لكل جدول وعمود وعلاقة في التطبيق المولّد.

نظرة عامة على المخطط

كل تطبيق FORGE يأتي مع 19 جدولاً منظمة في خمس فئات:

┌─────────────────────────────────────────────────────────────────────┐
│                      بنية قاعدة البيانات                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  الجداول الأساسية (المصادقة والصلاحيات)                            │
│  users, roles, permissions, role_user, permission_role,            │
│  password_resets, otp_codes                                        │
│                                                                     │
│  جداول النظام (الإعدادات والتدقيق)                                 │
│  settings, languages, translations, api_keys, audit_logs, sessions │
│                                                                     │
│  جداول المحتوى (CMS والتنقل)                                       │
│  contents, menus                                                   │
│                                                                     │
│  التخزين والمراجع                                                   │
│  media (polymorphic), lookups (hierarchical)                       │
│                                                                     │
│  المدفوعات (عند تفعيل مزود الدفع)                                   │
│  invoices, invoice_items                                           │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

جميع الجداول تتبع هذه الاتفاقيات

  • مفاتيح UUID أساسية عبر gen_random_uuid()
  • الطوابع الزمنية created_at و updated_at في كل جدول
  • الحذف الناعم عبر عمود deleted_at القابل للقيمة الفارغة حيث ينطبق
  • أعمدة JSONB للترجمات والبيانات الوصفية المرنة

مخطط العلاقات

                           +-------------+
                           |    users    |
                           +------+------+
                                  |
           +----------------------+---------------------+
           |                      |                     |
           v                      v                     v
   +---------------+      +-------------+      +-----------------+
   |   role_user   |      | audit_logs  |      | password_resets |
   +-------+-------+      +-------------+      +-----------------+
           |
           v
   +---------------+      +--------------------+
   |    roles      |<-----| permission_role    |
   +---------------+      +----------+---------+
                                     |
                                     v
                           +-----------------+
                           |  permissions    |
                           +-----------------+

   +----------+  +----------+  +--------------+  +----------+
   | settings |  | languages|  | translations |  | api_keys |
   +----------+  +----------+  +--------------+  +----------+

   +----------+   +----------+   +----------+   +----------+
   | contents |   |  menus   |   |  media   |   | lookups  |
   +----------+   +----------+   +----------+   +----------+

الجداول الأساسية

users

جدول حسابات المستخدمين الرئيسي. يدعم المصادقة عبر البريد الإلكتروني والهاتف المحمول، مع حذف ناعم لإلغاء تفعيل الحسابات بأمان.

العمودالنوعالقيودالوصف
idUUIDPK, default gen_random_uuid()المعرف الفريد
emailVARCHAR(255)UNIQUE, nullableالبريد الإلكتروني
mobileVARCHAR(20)UNIQUE, nullableرقم الهاتف
passwordVARCHAR(255)nullableتجزئة Argon2id
remember_tokenVARCHAR(100)nullableرمز استمرار الجلسة
nameVARCHAR(255)NOT NULLاسم العرض
avatarVARCHAR(500)nullableرابط أو مسار الصورة الرمزية
is_activeBOOLEANdefault trueعلامة تفعيل الحساب
email_verified_atTIMESTAMPnullableتاريخ تأكيد البريد
mobile_verified_atTIMESTAMPnullableتاريخ تأكيد الهاتف
last_login_atTIMESTAMPnullableآخر تسجيل دخول
last_login_ipVARCHAR(45)nullableIP متوافق مع IPv6
deleted_atTIMESTAMPnullableعلامة الحذف الناعم
created_atTIMESTAMPdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPdefault NOW()تاريخ التحديث
sql
-- At least one identifier required
CONSTRAINT users_email_or_mobile CHECK (
    email IS NOT NULL OR mobile IS NOT NULL
);

-- Partial indexes (exclude deleted rows)
CREATE INDEX idx_users_email ON users(email) WHERE deleted_at IS NULL;
CREATE INDEX idx_users_mobile ON users(mobile) WHERE deleted_at IS NULL;
CREATE INDEX idx_users_is_active ON users(is_active) WHERE deleted_at IS NULL;

WARNING

عمودا email و mobile كلاهما قابلان للقيمة الفارغة بشكل فردي، لكن قيد CHECK يضمن وجود واحد منهما على الأقل دائماً. أي حقل مطلوب يعتمد على auth_method المختارة أثناء forge new.

roles

يحدد أدوار المستخدمين لنظام RBAC. أدوار النظام (admin، user) لا يمكن حذفها.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
nameVARCHAR(100)NOT NULL, UNIQUEالاسم الآلي (admin)
display_nameVARCHAR(255)NOT NULLالتسمية البشرية (Administrator)
descriptionTEXTnullableوصف الدور
is_systemBOOLEANdefault falseيمنع الحذف
created_atTIMESTAMPdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPdefault NOW()تاريخ التحديث

permissions

سجلات الصلاحيات الدقيقة مجمعة حسب المورد.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
nameVARCHAR(100)NOT NULL, UNIQUEمفتاح التنقيط (users.create)
display_nameVARCHAR(255)NOT NULLالتسمية البشرية (Create Users)
descriptionTEXTnullableوصف الصلاحية
group_nameVARCHAR(100)NOT NULLمفتاح التجميع (users, roles)
is_systemBOOLEANdefault trueيمنع الحذف
created_atTIMESTAMPdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPdefault NOW()تاريخ التحديث

role_user (جدول الربط)

علاقة متعدد-لمتعدد بين المستخدمين والأدوار.

sql
CREATE TABLE role_user (
    user_id     UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    role_id     UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
    assigned_at TIMESTAMP DEFAULT NOW(),
    assigned_by UUID REFERENCES users(id),

    PRIMARY KEY (user_id, role_id)
);

permission_role (جدول الربط)

علاقة متعدد-لمتعدد بين الصلاحيات والأدوار.

sql
CREATE TABLE permission_role (
    permission_id UUID NOT NULL REFERENCES permissions(id) ON DELETE CASCADE,
    role_id       UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,

    PRIMARY KEY (permission_id, role_id)
);

جداول المصادقة

password_resets

يخزن رموز إعادة تعيين كلمة المرور المجزأة مع تاريخ انتهاء الصلاحية.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
emailVARCHAR(255)NOT NULLالبريد المستهدف
tokenVARCHAR(255)NOT NULLرمز SHA-256 مجزأ
expires_atTIMESTAMPNOT NULLوقت انتهاء الصلاحية
used_atTIMESTAMPnullableمتى تم استخدام الرمز
created_atTIMESTAMPdefault NOW()تاريخ الإنشاء

otp_codes

رموز كلمة المرور لمرة واحدة للمصادقة عبر الهاتف وتدفقات التحقق.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
identifierVARCHAR(255)NOT NULLالبريد أو رقم الهاتف
codeVARCHAR(10)NOT NULLرمز OTP من 6 أرقام
typeVARCHAR(50)NOT NULLlogin, verify, أو reset
attemptsINTdefault 0عدد محاولات التحقق الفاشلة
max_attemptsINTdefault 3الحد الأقصى للمحاولات
expires_atTIMESTAMPNOT NULLوقت انتهاء الصلاحية
verified_atTIMESTAMPnullableوقت التحقق الناجح
created_atTIMESTAMPdefault NOW()تاريخ الإنشاء

DANGER

رموز OTP لها حد صارم لـ max_attempts. بعد 3 محاولات فاشلة يتم إبطال الرمز. أنشئ دائماً OTP جديد بعد استنفاد المحاولات -- لا تقم بإعادة تعيين العداد.

جداول النظام

settings

إعدادات التطبيق بنمط مفتاح-قيمة مع معرفة النوع والتشفير الاختياري.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
group_nameVARCHAR(100)NOT NULLالمجموعة المنطقية (general, email, sms)
keyVARCHAR(255)NOT NULLمفتاح الإعداد (app_name)
valueTEXTnullableنص عادي أو قيمة مشفرة
typeVARCHAR(50)default stringstring, boolean, number, json, encrypted
is_publicBOOLEANdefault falseمعروض لواجهة API
is_sensitiveBOOLEANdefault falseمخفي في واجهة الإدارة
created_atTIMESTAMPdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPdefault NOW()تاريخ التحديث

الإعدادات المشفرة

عندما يكون type = 'encrypted'، تُخزن القيم كـ enc:v1:nonce:ciphertext:tag باستخدام AES-256-GCM. يُقرأ مفتاح التشفير من متغير البيئة FORGE_ENCRYPTION_KEY ولا يُخزن أبداً في قاعدة البيانات.

languages

اللغات المدعومة مع دعم اتجاه RTL.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
codeVARCHAR(10)NOT NULL, UNIQUEكود ISO (en, ar)
nameVARCHAR(100)NOT NULLالاسم الإنجليزي (Arabic)
native_nameVARCHAR(100)nullableالاسم الأصلي (العربية)
directionVARCHAR(3)default ltrltr أو rtl
is_defaultBOOLEANdefault falseعلامة اللغة الافتراضية
is_activeBOOLEANdefault trueعلامة التوفر
sort_orderINTdefault 0ترتيب العرض
created_atTIMESTAMPdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPdefault NOW()تاريخ التحديث

translations

سلاسل ترجمة واجهة المستخدم المخزنة كـ JSONB مع جميع قيم اللغات في صف واحد.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
group_nameVARCHAR(100)NOT NULLالمجموعة المنطقية (common, auth, admin)
keyVARCHAR(255)NOT NULLمفتاح الترجمة (login_title)
translationsJSONBNOT NULL{"en": "Sign In", "ar": "تسجيل الدخول"}
created_atTIMESTAMPdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPdefault NOW()تاريخ التحديث

مجموعات الترجمة الافتراضية:

المجموعةالغرضأمثلة المفاتيح
commonسلاسل UI المشتركةSave, Cancel, Delete, Confirm
authصفحات المصادقةlogin_title, register_title
adminلوحة التحكمdashboard_title, تسميات الشريط الجانبي
validationرسائل النماذجrequired, min_length
web.homeالصفحة الرئيسيةWelcome_to, App_Description
web.headerرأس الموقعSign_In, Get_Started
web.footerتذييل الموقعAll_rights_reserved, Privacy

api_keys

إدارة مفاتيح API للأطراف الثالثة مع تحديد المعدل والإلغاء.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
nameVARCHAR(255)NOT NULLاسم وصفي
key_hashVARCHAR(255)NOT NULLتجزئة SHA-256 للمفتاح
key_prefixVARCHAR(12)NOT NULLأول 8 أحرف للتعريف
permissionsJSONBdefault []أسماء الصلاحيات المسموحة
rate_limitINTdefault 1000الحد الأقصى للطلبات في الساعة
last_used_atTIMESTAMPnullableتاريخ آخر استخدام
last_used_ipVARCHAR(45)nullableIP آخر استخدام
request_countBIGINTdefault 0إجمالي عدد الطلبات
expires_atTIMESTAMPnullableانتهاء الصلاحية (NULL = أبداً)
revoked_atTIMESTAMPnullableتاريخ الإلغاء
revoked_byUUIDFK to usersمن ألغى المفتاح
revoked_reasonTEXTnullableسبب الإلغاء
created_byUUIDNOT NULL, FK to usersمنشئ المفتاح
created_atTIMESTAMPdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPdefault NOW()تاريخ التحديث

audit_logs

سجل تدقيق النشاط غير القابل للتغيير. سجلات التدقيق لا تحتوي على عمود updated_at -- فهي للإضافة فقط.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
user_idUUIDFK to users, nullableالمستخدم المنفذ (NULL للنظام)
user_emailVARCHAR(255)nullableالبريد للتاريخ
api_key_idUUIDFK to api_keys, nullableإذا كان الإجراء عبر مفتاح API
actionVARCHAR(50)NOT NULLcreated, updated, deleted, login
resource_typeVARCHAR(100)NOT NULLuser, role, setting
resource_idUUIDnullableمعرف المورد المتأثر
old_valuesJSONBnullableالحالة السابقة
new_valuesJSONBnullableالحالة الجديدة
ip_addressVARCHAR(45)nullableIP العميل
user_agentTEXTnullableوكيل مستخدم العميل
urlVARCHAR(500)nullableرابط الطلب
created_atTIMESTAMPdefault NOW()تاريخ الحدث

جداول المحتوى

contents

صفحات محتوى CMS مع دعم كامل للترجمة وبيانات SEO والنشر المجدول.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
titleVARCHAR(255)NOT NULLعنوان اللغة الافتراضية
slugVARCHAR(255)NOT NULL, UNIQUEمعرف صديق للرابط
summaryTEXTnullableوصف قصير
detailsTEXTnullableمحتوى HTML غني
button_textVARCHAR(100)nullableزر CTA اختياري
seoJSONBdefault {}{title, description, keywords, robots, canonical}
translationsJSONBdefault {}تجاوزات لكل لغة لجميع الحقول النصية
is_activeBOOLEANdefault trueعلامة النشر
publish_atTIMESTAMPTZnullableتاريخ النشر المجدول
expire_atTIMESTAMPTZnullableتاريخ إلغاء النشر التلقائي
sort_orderINTdefault 0ترتيب العرض
created_byUUIDFK to usersالمؤلف
updated_byUUIDFK to usersآخر محرر
created_atTIMESTAMPTZdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPTZdefault NOW()تاريخ التحديث
deleted_atTIMESTAMPTZnullableعلامة الحذف الناعم

هيكل JSONB للترجمات:

json
{
  "ar": {
    "title": "من نحن",
    "summary": "نبذة عن الشركة",
    "details": "<p>محتوى الصفحة...</p>",
    "button_text": "اقرأ المزيد",
    "seo": {
      "title": "من نحن | الموقع",
      "description": "وصف الصفحة"
    }
  }
}

الصور المميزة

صور المحتوى لا تُخزن كعمود في جدول contents. بدلاً من ذلك، تستخدم جدول media متعدد الأشكال مع model_type='Content' و collection='featured_image'. استخدم MediaService.attach() و MediaService.get_first_for_model() لإدارتها.

عناصر قائمة التنقل مع هيكل هرمي (أب/ابن)، وتحكم بالرؤية، والترجمات.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
titleVARCHAR(255)NOT NULLعنوان اللغة الافتراضية
urlVARCHAR(500)nullableرابط URL
iconVARCHAR(100)nullableمعرف الأيقونة
targetVARCHAR(20)default _self_self أو _blank
visibilityVARCHAR(20)default publicpublic, auth, أو guest
translationsJSONBdefault {}{"ar": {"title": "الرئيسية"}}
parent_idUUIDFK to menus(id), nullableعنصر القائمة الأب
is_activeBOOLEANdefault trueعلامة التفعيل
sort_orderINTdefault 0ترتيب العرض
created_atTIMESTAMPTZdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPTZdefault NOW()تاريخ التحديث
deleted_atTIMESTAMPTZnullableعلامة الحذف الناعم

خيارات الرؤية:

القيمةمن يراها
publicالجميع (افتراضي)
authالمستخدمون المسجلون فقط
guestالمستخدمون غير المسجلين فقط

جدول التخزين

media

رفع الملفات متعدد الأشكال يدعم أي نوع نموذج. يتبع نمط Spatie حيث model_type + model_id + collection يحددون المالك.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
diskVARCHAR(50)default locallocal أو s3
pathVARCHAR(500)NOT NULLمسار الملف النسبي
filenameVARCHAR(255)NOT NULLاسم الملف الأصلي
mime_typeVARCHAR(100)nullableنوع MIME
sizeBIGINTnullableحجم الملف بالبايت
widthINTnullableعرض الصورة (بكسل)
heightINTnullableارتفاع الصورة (بكسل)
variantsJSONBdefault {}{"thumb": "path/thumb.jpg"}
alt_textVARCHAR(500)nullableنص إمكانية الوصول
captionTEXTnullableتعليق العرض
metadataJSONBdefault {}بيانات EXIF، بيانات وصفية مخصصة
model_typeVARCHAR(100)nullableنموذج المالك (Content, User)
model_idUUIDnullableمعرف سجل المالك
collectionVARCHAR(100)default defaultfeatured_image, avatars
uploaded_byUUIDFK to usersالرافع
created_atTIMESTAMPdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPdefault NOW()تاريخ التحديث

جدول البحث

lookups

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

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
typeVARCHAR(100)NOT NULLفئة البحث (country, status)
parent_idUUIDFK to lookups(id), nullableالأب للتسلسل الهرمي
nameVARCHAR(255)NOT NULLاسم اللغة الافتراضية
valueVARCHAR(255)nullableقيمة قابلة للقراءة آلياً
translationsJSONBdefault {}{"ar": {"name": "الكويت"}}
is_activeBOOLEANdefault trueعلامة التفعيل
sort_orderINTdefault 0ترتيب العرض
metadataJSONBdefault {}بيانات إضافية (مثل أكواد الدول)
created_atTIMESTAMPTZdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPTZdefault NOW()تاريخ التحديث

استخدم lookups للبيانات المرجعية القابلة لإعادة الاستخدام

بدلاً من إنشاء جدول جديد لكل قائمة منسدلة (الدول، الحالات، الفئات)، خزنها كلها في lookups بقيم type مختلفة. عمود parent_id يتيح البيانات الهرمية مثل منطقة > دولة > مدينة.

جداول المدفوعات

يتم توليد هذه الجداول عند تفعيل مزود الدفع عبر forge provider:add payment stripe.

invoices

سجلات الفواتير لتتبع المدفوعات مع أرقام فواتير مولدة تلقائياً.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
invoice_numberVARCHAR(50)NOT NULL, UNIQUEمولد تلقائياً: INV-YYYYMM-XXXX
customer_idUUIDFK to users, nullableحساب العميل
customer_nameVARCHAR(255)nullableاسم العميل (للسجل)
customer_emailVARCHAR(255)nullableبريد العميل (للسجل)
subtotalDECIMAL(12,2)default 0مجموع البنود
tax_amountDECIMAL(12,2)default 0مبلغ الضريبة
discount_amountDECIMAL(12,2)default 0الخصم المطبق
total_amountDECIMAL(12,2)NOT NULLالمبلغ النهائي
currencyVARCHAR(3)default USDكود العملة ISO
statusVARCHAR(20)default pendingحالة الدفع
payment_providerVARCHAR(50)nullablestripe, hyperpay, إلخ.
payment_intent_idVARCHAR(255)nullableمعرف الدفع من المزود
payment_methodVARCHAR(50)nullablecard, apple_pay, إلخ.
card_last4VARCHAR(4)nullableآخر 4 أرقام
card_brandVARCHAR(20)nullablevisa, mastercard, إلخ.
descriptionTEXTnullableوصف الفاتورة
notesTEXTnullableملاحظات داخلية
metadataJSONBdefault {}بيانات وصفية مخصصة
due_dateTIMESTAMPTZnullableتاريخ استحقاق الدفع
paid_atTIMESTAMPTZnullableتاريخ الدفع
refunded_atTIMESTAMPTZnullableتاريخ الاسترداد
created_atTIMESTAMPTZdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPTZdefault NOW()تاريخ التحديث

تدفق حالة الفاتورة:

pending → processing → paid → refunded
    ↓         ↓          ↓
 cancelled  failed   partially_refunded
الحالةالوصف
pendingتم إنشاء الفاتورة، بانتظار الدفع
processingالدفع قيد التنفيذ
paidتم الدفع بنجاح
failedفشل الدفع
cancelledتم إلغاء الفاتورة قبل الدفع
refundedتمت معالجة استرداد كامل
partially_refundedتمت معالجة استرداد جزئي

invoice_items

بنود الفواتير مع حساب المجموع التلقائي.

العمودالنوعالقيودالوصف
idUUIDPKالمعرف الفريد
invoice_idUUIDNOT NULL, FK to invoicesالفاتورة الأم
descriptionVARCHAR(500)NOT NULLوصف البند
quantityINTEGERdefault 1كمية البند
unit_priceDECIMAL(12,2)NOT NULLسعر الوحدة
amountDECIMAL(12,2)NOT NULLquantity * unit_price
product_idUUIDnullableمرجع منتج اختياري
product_typeVARCHAR(100)nullableنوع نموذج المنتج
created_atTIMESTAMPTZdefault NOW()تاريخ الإنشاء
updated_atTIMESTAMPTZdefault NOW()تاريخ التحديث

المجاميع المتتالية

عند إضافة أو تحديث أو حذف بنود الفاتورة، تقوم المشغلات تلقائياً بإعادة حساب subtotal و total_amount للفاتورة. لا تحتاج لتحديث هذه القيم يدوياً.

استراتيجية الفهرسة

يطبق FORGE عدة أنماط فهرسة لتحسين أداء الاستعلام:

النمطمثالالغرض
فهارس جزئيةWHERE deleted_at IS NULLتخطي الصفوف المحذوفة
فهارس مركبة(resource_type, action, created_at)مرشحات متعددة الأعمدة
فهارس GINUSING GIN (translations)استعلامات احتواء JSONB
فريد جزئيWHERE is_default = trueفرض افتراضي واحد
تنازليcreated_at DESCترتيب الأحدث أولاً

أنماط JSONB

يستخدم FORGE أعمدة JSONB في ثلاثة أنماط مميزة:

1. الترجمات المضمنة

تستخدمها contents و menus و lookups لتخزين النص لكل لغة مضمناً:

sql
-- Get Arabic title
SELECT translations->'ar'->>'title' FROM contents WHERE slug = 'about';

2. حزم الترجمة

يستخدمها جدول translations لتخزين سلاسل UI:

sql
-- Get all Arabic auth translations
SELECT key, translations->>'ar' AS value
FROM translations
WHERE group_name = 'auth';

3. البيانات الوصفية المهيكلة

تستخدمها contents.seo و media.metadata و api_keys.permissions:

sql
-- Find content with specific SEO robots setting
SELECT * FROM contents
WHERE seo->>'robots' = 'noindex';

ترتيب الترحيلات

تعمل الترحيلات بترتيب التبعية. يولد FORGE ملفات ترحيل مرقمة:

00001  create_languages_table
00002  create_users_table
00003  create_roles_table
00004  create_permissions_table
00005  create_role_user_table
00006  create_permission_role_table
00007  create_password_resets_table
00008  create_otp_codes_table
00009  create_settings_table
00010  create_translations_table
00011  create_api_keys_table
00012  create_audit_logs_table
00013  create_media_table
00014  create_contents_table
00015  create_menus_table
00016  migrate_media_polymorphic
00017  create_lookups_table
00018  create_invoices_table      (عند تفعيل المدفوعات)
00019  create_invoice_items_table (عند تفعيل المدفوعات)

بعد الترحيلات، تملأ البيانات الأولية البيانات الافتراضية بهذا الترتيب:

01  seed_permissions (جميع مجموعات الصلاحيات)
02  seed_roles (admin, user)
03  seed_users (admin@{app}.test, user@{app}.test)
04  seed_languages (en, ar)
05  seed_settings (general, auth, email, storage)
06  seed_translations (common, auth, admin, web.*)

استعلامات مفيدة

الحصول على مستخدم مع الأدوار والصلاحيات

sql
SELECT
    u.id, u.email, u.name,
    array_agg(DISTINCT r.name) AS roles,
    array_agg(DISTINCT p.name) AS permissions
FROM users u
LEFT JOIN role_user ru ON u.id = ru.user_id
LEFT JOIN roles r ON ru.role_id = r.id
LEFT JOIN permission_role pr ON r.id = pr.role_id
LEFT JOIN permissions p ON pr.permission_id = p.id
WHERE u.id = $1
GROUP BY u.id, u.email, u.name;

التحقق من امتلاك المستخدم لصلاحية محددة

sql
SELECT EXISTS (
    SELECT 1
    FROM users u
    JOIN role_user ru ON u.id = ru.user_id
    JOIN permission_role pr ON ru.role_id = pr.role_id
    JOIN permissions p ON pr.permission_id = p.id
    WHERE u.id = $1 AND p.name = $2
) AS has_permission;

الحصول على جميع الترجمات للغة

sql
SELECT group_name, key, translations->>$1 AS value
FROM translations
WHERE translations ? $1;
-- $1 = language code, e.g. 'ar'

ملخص سجل التدقيق (آخر 7 أيام)

sql
SELECT
    u.email, al.action, al.resource_type,
    COUNT(*) AS event_count
FROM audit_logs al
JOIN users u ON al.user_id = u.id
WHERE al.created_at > NOW() - INTERVAL '7 days'
GROUP BY u.email, al.action, al.resource_type
ORDER BY event_count DESC;

انظر أيضاً

Released under the MIT License.