نظام نقطة البيع الذي يتطلب اتصالاً مستقراً بالإنترنت ليس نظاماً - بل هو عبء. إليك كيفية بناء معمارية POS تعمل أولاً بدون إنترنت وتتزامن بشكل موثوق عند عودة الاتصال.
نظام نقطة البيع الذي يتطلب اتصالاً ثابتاً بالإنترنت ليس نظام نقطة بيع، بل هو عبء. تعمل المطاعم اللبنانية في ظل انقطاعات متكررة للكهرباء، وبيانات جوال متقطعة، وانقطاعات أحياناً لمزود الإنترنت تمتد لساعات. معمارية نظام POS احترافي للبنان تبدأ بالعمل دون إنترنت وتتعامل مع الاتصال كمكافأة، لا كشرط أساسي.
لماذا تفشل أنظمة POS التي تعتمد على الإنترنت في السياق اللبناني؟
معظم أنظمة POS التجارية مصممة لأسواق ذات بنية تحتية موثوقة. تخزن بيانات الجلسة على الخادم، وتوجه كل معاملة عبر API مركزي، وتعتمد على اتصال حي للتحقق من المخزون والخصومات وإنشاء الإيصالات.
في لبنان، هذا الافتراض يفشل بانتظام. أسباب فشله المحددة:
انقطاعات مزود الإنترنت. البنية التحتية للإنترنت في لبنان لها مشاكل موثقة في الموثوقية. مطعم لا يستطيع معالجة الطلبات لساعتين في ليلة الجمعة تعرض لإخفاق تجاري بالغ الأهمية.
تقنين الكهرباء والانتقال للمولد. انقطاعات الكهرباء تسبب اضطرابات قصيرة في الشبكة حتى عندما يكون الراوتر والمودم على UPS. هذه الانقطاعات القصيرة تحدث خلال ساعات الخدمة ولا يمكنها إيقاف خدمة الطاولات.
تدهور بيانات الجوال. كثير من المطاعم الصغيرة تستخدم نقاط اتصال جوال بدلاً من الإنترنت الثابت. بيانات الجوال تتدهور خلال ساعات الذروة في المناطق الكثيفة.
الحل ليس تحسين الشبكة - ذلك خارج سيطرة نظام POS. الحل هو تصميم POS بحيث حالة الشبكة لا صلة لها بالتشغيل الأساسي لاستقبال الطلبات ومعالجة المعاملات.
معمارية المزامنة: محلي أولاً مع Go و SQLite
معمارية local-first تخزن جميع البيانات التشغيلية على الجهاز. SQLite هو الخيار الصحيح لقاعدة البيانات المدمجة في الطرفية. إنه موثوق، مدعوم جيداً، ونموذج قاعدة البيانات بملف واحد يجعل النسخ الاحتياطي والاسترداد مباشراً.
الـ backend بـ Go يعمل كخدمة محلية على جهاز الطرفية. في نشر نموذجي، ملف Go ثنائي صغير يعمل كخدمة نظام. يكشف عن HTTP API يتواصل معه الواجهة الأمامية.
نموذج البيانات له طبقتان: قاعدة بيانات SQLite المحلية التي تحتفظ بجميع الحالات الحالية، وطابور مزامنة يسجل كل عملية كتابة بالترتيب.
طابور المزامنة هو المكون الحرج. كل عملية تغيير الحالة - طلب جديد، تعديل طلب، دفع، إلغاء، تطبيق خصم - تُكتب في قاعدة بيانات SQLite المحلية وفي نفس الوقت تُلحق بطابور المزامنة كحدث منظم.
عند توفر الاتصال بالشبكة، goroutine خلفية في خدمة Go تستنزف طابور المزامنة بإرسال الأحداث إلى API المركزي. API المركزي يطبق الأحداث على قاعدة البيانات الرئيسية PostgreSQL ويعيد تأكيدات. الأحداث المؤكدة بنجاح تُحذف من الطابور المحلي.
عندما لا تكون الشبكة متاحة، يستمر قبول الكتابات في قاعدة البيانات المحلية ويتراكم طابور المزامنة. يستمر المطعم في العمل. عند عودة الاتصال، يتفرغ الطابور تلقائياً.
التعامل مع التعارضات عند دمج طوابير الطرفيات المنفصلة
في مطعم متعدد الطرفيات - POS رئيسي في البار، طرفية ثانوية في قاعة الطعام، لوحة للطلبات الجدولية - كل طرفية تحافظ على طابور مزامنتها الخاص.
استراتيجيات حل التعارضات التي تنجح في سياق POS المطاعم:
أحداث غير قابلة للتغيير مع ترتيب على جانب الخادم. بدلاً من إرسال الحالة الحالية للمزامنة، أرسل أحداثاً غير قابلة للتغيير مع أرقام تسلسلية. عندما تعدل طرفيتان نفس الطلب، يطبق الخادم الأحداث بترتيب الأرقام التسلسلية والنتيجة حتمية.
قفل متشائم للمدفوعات. عمليات الدفع هي الحالة الوحيدة التي يكون فيها حل التعارض التفاؤلي خطيراً. طاولة تم الدفع عنها من طرفية يجب ألا تكون قابلة للدفع من طرفية ثانية. عمليات الدفع تمر عبر قفل موزع يوقف عمله عند الانفصال عن الشبكة.
دروس من الإنتاج
صمم للعمل دون إنترنت أولاً، لا كفكرة لاحقة. الأنظمة المصممة مع الاتصال كميزة اختيارية أكثر متانة من الأنظمة التي أُضيف لها وضع عدم الاتصال بعد النشر الأولي.
موثوقية SQLite كقاعدة بيانات مدمجة لخدمات Go في الإنتاج ممتازة. نموذج الملف الواحد يجعل النسخ الاحتياطي مباشراً.
nموذج أحداث طابور المزامنة أكثر متانة من مزامنة الحالة. الأحداث غير قابلة للتغيير ومرتبة. مزامنة الحالة تتطلب منطق حل تعارضات يصبح معقداً بسرعة.
عمليات الدفع تحتاج معالجة خاصة. خطر الدفع المزدوج يبرر القفل المتشائم حتى في الأنظمة محلية الأولوية.
هل تحتاج مساعدة في بناء نظامك؟
Voxire تبني أنظمة POS والأنظمة التشغيلية للمطاعم والمحلات التجارية في لبنان ومنطقة الشرق الأوسط. إذا كنت تخطط لنشر POS أو استبدال نظام غير موثوق يعتمد على الإنترنت فقط، يمكننا مساعدتك في تصميم المعمارية التي تعمل فعلاً في سياق البنية التحتية المحلية.
https://voxire.com/get-a-quote/


