Skip to content

التصميم بالعقود أولاً

يتبنى FORGE نهج العقود أولاً في توليد التطبيقات. كل تطبيق يُنتجه FORGE يلتزم بعقود صارمة تُحدد نقاط نهاية API ومخطط قاعدة البيانات والصلاحيات وصفحات الواجهة الأمامية. تعمل هذه العقود كطبقة المواصفات بين الخلفيات والواجهات الأمامية، مما يضمن أن أي خلفية مدعومة يمكنها تشغيل أي واجهة أمامية مدعومة بدون تعديل.

يُحدد العقد ما يجب أن يوجد. يُحدد التنفيذ كيف يعمل.

لماذا العقود؟

عند توليد تطبيقات متكاملة عبر أُطر خلفية متعددة (Rust، Laravel، FastAPI، Node.js) وأُطر واجهة أمامية متعددة (Next.js، Nuxt.js، Angular)، الاتساق غير قابل للتفاوض. بدون عقود، ستُنفذ كل خلفية أشكال API مختلفة قليلاً، وستتوقع كل واجهة أمامية تنسيقات استجابة مختلفة، واستبدال تقنية بأخرى سيتطلب إعادة كتابة كود التكامل.

نصيحة

فكر في العقود كمخطط بناء. سواء بُني المنزل بالطوب أو الخشب أو الفولاذ، يبقى مخطط الأرضية كما هو. الغرف في نفس الأماكن، والأبواب تُفتح بنفس الطريقة، والسباكة تتصل بشكل متطابق.

                         FORGE CLI

              ┌─────────────┼─────────────┐
              │             │             │
              ▼             ▼             ▼
        ┌───────────┐ ┌───────────┐ ┌───────────┐
        │  عقود     │ │  عقود     │ │  عقود     │
        │ المزودين  │ │ الخلفية   │ │ الواجهة   │
        └─────┬─────┘ └─────┬─────┘ └─────┬─────┘
              │             │             │
     ┌────┬──┴──┐    ┌─────┼─────┐  ┌────┼────┐
     ▼    ▼     ▼    ▼     ▼     ▼  ▼    ▼    ▼
   Twilio Uni  أخرى Rust Laravel  … Next Nuxt Angular

عقود API

تُحدد عقود API مسارات نقاط النهاية بالضبط وطرق HTTP وأجسام الطلبات وأشكال الاستجابة التي يجب أن تُنفذها كل خلفية مُولّدة. المصدر الموثوق هو مواصفات OpenAPI التي تلتزم بها جميع الخلفيات.

تعريفات نقاط النهاية

كل تطبيق FORGE يكشف نفس سطح API بغض النظر عن الخلفية:

المصادقة (AUTH)
├── POST /api/v1/auth/register    → { data: { user, token } }
├── POST /api/v1/auth/login       → { data: { user, token } }
├── POST /api/v1/auth/logout      → { message }
├── POST /api/v1/auth/refresh     → { data: { token } }
└── GET  /api/v1/auth/me          → { data: { user } }

الإدارة (ADMIN) (تتطلب مصادقة + صلاحيات)
├── GET    /api/v1/admin/users        → { data: [...], meta: {...} }
├── POST   /api/v1/admin/users        → { data: user }
├── GET    /api/v1/admin/users/:id    → { data: user }
├── PUT    /api/v1/admin/users/:id    → { data: user }
├── DELETE /api/v1/admin/users/:id    → { message }
├── ... (نفس النمط للأدوار، المحتويات، القوائم، الإعدادات، إلخ.)

العامة (PUBLIC) (لا تتطلب مصادقة)
├── GET /api/v1/contents/:slug   → { data: content }
└── GET /api/v1/menus            → { data: [...] }

تنسيق الاستجابة

جميع الخلفيات تُرجع استجابات في مُغلّف متسق:

json
// Success (single resource)
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "name": "Ahmed"
  }
}

// Success (list with pagination)
{
  "data": [{ ... }, { ... }],
  "meta": {
    "total": 42,
    "page": 1,
    "per_page": 15
  }
}

// Error
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": {
      "email": ["The email field is required"]
    }
  }
}

رموز الأخطاء القياسية

كل خلفية تستخدم نفس مجموعة رموز الأخطاء:

الرمزحالة HTTPالمعنى
VALIDATION_ERROR422فشل التحقق من جسم الطلب
UNAUTHORIZED401مصادقة مفقودة أو غير صالحة
FORBIDDEN403مُصادق لكن يفتقر للصلاحية
NOT_FOUND404المورد غير موجود
RATE_LIMITED429عدد طلبات كثير جداً
INTERNAL_ERROR500خطأ خادم غير متوقع

تحذير

يجب ألا تُرجع الخلفيات أخطاء الإطار الخام أبداً. يجب تغليف جميع الأخطاء في مُغلّف الخطأ القياسي. هذا يضمن أن الواجهات الأمامية يمكنها تحليل كل استجابة بمعالج أخطاء واحد.

OpenAPI كمصدر موثوق

عقد API مُعرّف رسمياً كمواصفات OpenAPI 3.0:

yaml
# contracts/api/openapi.yaml
openapi: 3.0.3
info:
  title: FORGE Application API
  version: 1.0.0

paths:
  /api/v1/auth/login:
    post:
      summary: تسجيل دخول المستخدم
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, password]
              properties:
                email:
                  type: string
                  format: email
                password:
                  type: string
                  minLength: 8
      responses:
        '200':
          description: تم تسجيل الدخول بنجاح
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'

تُولّد أنواع TypeScript للواجهة الأمامية مباشرة من مواصفات OpenAPI هذه، مما يضمن استهلاك API آمن للأنواع.

عقود قاعدة البيانات

تُحدد عقود قاعدة البيانات الجداول المطلوبة والأعمدة والأنواع والفهارس التي يجب أن يحتويها كل تطبيق مُولّد. بينما قد تختلف تسمية الأعمدة قليلاً حسب اتفاقية الخلفية (snake_case مقابل camelCase)، المخطط المنطقي متطابق.

الجداول المطلوبة

كل تطبيق FORGE يتضمن هذه الجداول الأساسية:

الجدولالغرض
languagesلغات التطبيق المدعومة
usersحسابات المستخدمين
rolesتعريفات الأدوار المُسماة
permissionsإدخالات الصلاحيات التفصيلية
role_userعلاقة متعدد-لمتعدد: تعيين مستخدم-دور
permission_roleعلاقة متعدد-لمتعدد: تعيين دور-صلاحية
password_resetsرموز إعادة تعيين كلمة المرور
otp_codesرموز كلمة المرور لمرة واحدة (إذا كان OTP مُفعّلاً)
settingsإعدادات التطبيق مفتاح-قيمة
translationsسلاسل UI قابلة للترجمة
api_keysإدارة مفاتيح API الخارجية
audit_logsسجل تتبع الإجراءات
mediaمرفقات الملفات متعددة الأشكال
contentsصفحات محتوى CMS
menusهياكل قوائم التنقل

عقود الأعمدة

كل جدول له أعمدة مطلوبة. على سبيل المثال، users:

sql
CREATE TABLE users (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name        VARCHAR(255) NOT NULL,
    email       VARCHAR(255) UNIQUE NOT NULL,
    phone       VARCHAR(50) UNIQUE,
    password    VARCHAR(255) NOT NULL,
    avatar      VARCHAR(500),
    is_active   BOOLEAN NOT NULL DEFAULT true,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at  TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

نصيحة

جميع الجداول تستخدم مفاتيح أساسية UUID وتتضمن طوابع created_at / updated_at. هذه الاتفاقية مُفروضة عبر كل مولّد خلفية.

عقود الفهارس

الفهارس الحرجة للأداء هي جزء من العقد:

sql
-- Users
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_phone ON users(phone);

-- Contents
CREATE INDEX idx_contents_slug ON contents(slug);
CREATE INDEX idx_contents_type ON contents(type);
CREATE INDEX idx_contents_status ON contents(status);

-- Audit logs
CREATE INDEX idx_audit_logs_user ON audit_logs(user_id);
CREATE INDEX idx_audit_logs_action ON audit_logs(action);
CREATE INDEX idx_audit_logs_created ON audit_logs(created_at);

عقود الصلاحيات

يستخدم FORGE نظام التحكم في الوصول المبني على الأدوار (RBAC). يُحدد عقد الصلاحيات أي صلاحيات يجب أن توجد لكل وحدة وكيف ترتبط بنقاط نهاية API.

اتفاقية تسمية الصلاحيات

تتبع الصلاحيات النمط {module}.{action}:

users.view        users.create        users.edit        users.delete
roles.view        roles.create        roles.edit        roles.delete
permissions.view
contents.view     contents.create     contents.edit     contents.delete
menus.view        menus.create        menus.edit        menus.delete
settings.view     settings.edit
translations.view translations.edit
api_keys.view     api_keys.create     api_keys.edit     api_keys.delete
audit.view

ربط الصلاحيات بنقاط النهاية

كل نقطة نهاية إدارية تتطلب صلاحية محددة:

نقطة النهايةالصلاحية المطلوبة
GET /api/v1/admin/usersusers.view
POST /api/v1/admin/usersusers.create
PUT /api/v1/admin/users/:idusers.edit
DELETE /api/v1/admin/users/:idusers.delete
GET /api/v1/admin/contentscontents.view
POST /api/v1/admin/contentscontents.create
PUT /api/v1/admin/contents/:idcontents.edit
DELETE /api/v1/admin/contents/:idcontents.delete

الأدوار الافتراضية

كل تطبيق مُولّد يزرع دورين:

الدورالصلاحيات
super_adminجميع الصلاحيات (wildcard)
adminجميع الصلاحيات ما عدا permissions.view، api_keys.*، audit.view

تحذير

يجب تعيين دور super_admin بحذر. في الإنتاج، معظم المديرين يجب أن يستخدموا دور admin أو أدوار مخصصة بصلاحيات محددة.

عقود الصفحات

تُحدد عقود الصفحات أي صفحات واجهة أمامية يجب أن توجد في كل تطبيق مُولّد. هذا يضمن أنه بغض النظر عن إطار الواجهة الأمامية، التطبيق الموجه للمستخدم له تغطية كاملة.

الصفحات العامة المطلوبة

/                          الصفحة الرئيسية
/login                     تسجيل الدخول
/register                  التسجيل
/password/forgot           نسيت كلمة المرور
/password/reset            إعادة تعيين كلمة المرور برمز
/:slug                     صفحة محتوى CMS ديناميكية

الصفحات المحمية المطلوبة

/profile                   عرض الملف الشخصي (تتطلب مصادقة)
/profile/edit              تعديل الملف الشخصي (تتطلب مصادقة)
/profile/password          تغيير كلمة المرور (تتطلب مصادقة)

صفحات الإدارة المطلوبة

/admin                     لوحة التحكم
/admin/users               قائمة المستخدمين          (users.view)
/admin/users/create        إنشاء مستخدم              (users.create)
/admin/users/:id/edit      تعديل مستخدم              (users.edit)
/admin/roles               قائمة الأدوار             (roles.view)
/admin/roles/create        إنشاء دور                 (roles.create)
/admin/roles/:id/edit      تعديل دور                 (roles.edit)
/admin/permissions         قائمة الصلاحيات          (permissions.view)
/admin/contents            قائمة المحتوى            (contents.view)
/admin/contents/create     إنشاء محتوى              (contents.create)
/admin/contents/:id        عرض المحتوى              (contents.view)
/admin/contents/:id/edit   تعديل المحتوى            (contents.edit)
/admin/menus               قائمة القوائم            (menus.view)
/admin/menus/create        إنشاء قائمة              (menus.create)
/admin/menus/:id/edit      تعديل قائمة              (menus.edit)
/admin/settings            إعدادات التطبيق          (settings.view)
/admin/translations        إدارة الترجمات          (translations.view)
/admin/api-keys            إدارة مفاتيح API        (api_keys.view)
/admin/audit               سجلات التدقيق           (audit.view)

كل صفحة إدارة تُفرض الصلاحية المطلوبة لها. إذا انتقل مستخدم إلى صفحة يفتقر لصلاحيتها، تعرض الواجهة الأمامية عرض "الوصول مرفوض" بدون إجراء استدعاء API.

التحقق من العقود

يوفر FORGE أوامر CLI للتحقق من أن التطبيق المُولّد يلتزم بعقوده.

التحقق من API

bash
# Verify all required endpoints exist and return correct shapes
forge validate:api

# Verify specific backend
forge validate:api --backend=rust

يُشغّل المُحقق خادم الخلفية، ويُرسل طلبات إلى كل نقطة نهاية مُتعاقد عليها، ويتحقق من:

  • نقطة النهاية موجودة ولا تُرجع 404
  • الاستجابة تُطابق مخطط JSON المتوقع
  • استجابات الأخطاء تستخدم مُغلّف الخطأ القياسي
  • فحوصات المصادقة والصلاحيات مُفروضة

التحقق من الصفحات

bash
# Verify all required pages exist in frontend
forge validate:pages

# Verify specific frontend
forge validate:pages --frontend=nextjs

مُحقق الصفحات يتحقق من:

  • كل ملف مسار مطلوب موجود في المشروع
  • الصفحات المحمية تتضمن حراسات المصادقة
  • صفحات الإدارة تتضمن فحوصات الصلاحيات
  • الصفحات العامة قابلة للوصول بدون مصادقة

مجموعة اختبارات العقود الكاملة

bash
# Run the full contract test suite
forge test:contracts

هذا يُشغّل اختبارات التكامل التي تُمارس الحزمة الكاملة: الخلفية تخدم API، والاختبارات الآلية تتحقق من كل سلوك مُتعاقد عليه من النهاية إلى النهاية.

نصيحة

شغّل forge test:contracts قبل النشر للإنتاج. يلتقط انتهاكات العقود التي قد تفوتها اختبارات الوحدات، مثل فحص صلاحية مفقود على نقطة نهاية إدارية.

الفوائد

الفائدةالوصف
خلفيات قابلة للتبديلابدأ بـ Rust، انتقل إلى Laravel لاحقاً -- نفس API، نفس الواجهة الأمامية
واجهات أمامية قابلة للتبديلابدأ بـ Next.js، أضف Nuxt.js لاحقاً -- نفس API، نفس السلوك
مزودون قابلون للتبديلانتقل من Twilio إلى Unifonic بتغيير إعداد
قابلية الاختبارمحاكاة أي مزود أو خلفية خلف واجهة العقد
توثيق مُولّد تلقائياًمواصفات OpenAPI تُنتج توثيق API تلقائياً
أمان الأنواعأنواع TypeScript مُولّدة من OpenAPI للاستهلاك في الواجهة الأمامية
أمان الترقيةاختبارات العقود تلتقط التغييرات الكاسرة قبل وصولها للإنتاج

Released under the MIT License.