مشروع عميلنشط

نظام خلفي لنقاط البيع متعدد المستأجرين

نظام خلفي لنقاط البيع قابل للتوسع يدعم عدة مؤسسات وأكثر من ١٠٠ فرع وكتالوجات المنتجات والباركود والمجموعات الضريبية ومزامنة المبيعات الفورية.

Node.jsTypeScriptPrismaPostgreSQLRedisAzure DevOpsDocker

نظرة عامة

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

البنية المعمارية

ينقسم النظام إلى خدمات متخصصة:

  • خدمة المنتجات — الكتالوج والخصائص والباركود وقواعد التسعير.
  • خدمة المبيعات — استقبال المعاملات وإنشاء الإيصالات وقواعد استرداد المدفوعات.
  • خدمة المزامنة — مزامنة ثنائية الاتجاه مع أجهزة نقاط البيع القادرة على العمل دون اتصال.
  • خدمة التقارير — تحليلات مبيعات مجمعة حسب الموقع والفترة والمنتج.

مزامنة الأجهزة غير المتصلة

يجب أن تعمل أجهزة نقاط البيع دون اتصال وتزامن بياناتها عند عودته. نفّذت نهجًا مبسطًا من الاعتماد على سجل الأحداث (Event Sourcing):

// Each terminal action is logged as an event
interface SalesEvent {
  terminalId: string;
  tenantId: string;
  sequence: number; // monotonic, per terminal
  type: "SALE" | "REFUND" | "VOID";
  payload: SalePayload;
  createdAt: Date;
}

تستقبل خدمة المزامنة الأحداث بالترتيب، وتزيل التكرار باستخدام (terminalId, sequence)، وتطبقها على السجل المركزي. توضع الأحداث الخارجة عن الترتيب في قائمة انتظار بدل رفضها.

استراتيجية تعدد المستأجرين

يستخدم كل جدول عزلًا على مستوى الصف عبر عمود tenantId وفهرس مقابل. تمر جميع الاستعلامات عبر دوال المستودع التي تضيف سياق المستأجر من الجلسة التي جرى التحقق من هوية صاحبها دائمًا، وتتجاهل معرّفات المستأجر التي يرسلها العميل.

مسار التكامل المستمر والنشر المستمر

يُجرى النشر عبر مسارات Azure DevOps بصيغة YAML مع ثلاث بيئات:

stages:
  - stage: Build
    jobs:
      - job: Test
        steps:
          - script: npm test
      - job: BuildImage
        steps:
          - task: Docker@2

  - stage: DeployStaging
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/develop'))

  - stage: DeployProduction
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))

المؤشرات الرئيسية

  • يدعم أكثر من ١٠٠ جهاز نقاط بيع موزعة على مواقع متعددة.
  • زمن استجابة أقل من ١٠٠ مللي ثانية للبحث عن المنتجات باستخدام ذاكرة Redis المؤقتة.
  • لم تُسجل حوادث تسرب بيانات بين المستأجرين، وفق اختبار الاختراق.
  • توافر بنسبة ٩٩٫٩٪ خلال ١٢ شهرًا.