
نظام نقاط البيع
نظام نقاط بيع متكامل وعصري مبني باستخدام React و NestJS و Prisma. يتميز بإدارة المخزون في الوقت الفعلي، والتحكم في الوصول القائم على الأدوار، وواجهة مستخدم سريعة وموثوقة.
دراسة حالة: نظام نقاط البيع (POS System)
الدور: مطور واجهات متكاملة (Full Stack Developer)
التقنيات المستخدمة: React 18, Vite, NestJS, Prisma, PostgreSQL, Docker, Tailwind CSS
معاينة حية: رابط المشروع (يستبدل بالرابط الفعلي)
🚀 السياق والتطور
يحتل هذا المشروع مكانة خاصة في مسيرتي المهنية. بدأ كواحد من أوائل تطبيقاتي المتكاملة (Full Stack)، التي بنيتها لإتقان أساسيات تطوير الويب. في البداية، كان مجرد إثبات للمفهوم لفهم كيفية تدفق البيانات المعقدة بين واجهة React وخلفية Node.js.
ومع ذلك، البرمجيات (والمطورون) يجب أن تتطور. مؤخرًا، قررت تحديث وإحياء هذا الكود بدلاً من تركه يجمع الغبار. لم يكن مجرد تحديث للصيانة؛ بل كان إعادة بناء شاملة:
- الأداء: الانتقال من Create React App إلى Vite لضمان تشغيل فوري للخادم وتحسين عمليات البناء.
- قاعدة البيانات: الترقية إلى أحدث إصدار من Prisma للاستفادة من أمان النوع (Type Safety) والأداء المحسن.
- واجهة المستخدم (UI/UX): إعادة تصميم الواجهة بالكامل باستخدام HEROUI ومبادئ التصميم الحديث، لنتقل من مظهر "تقليدي" إلى جمالية مصقولة واحترافية.
- الدقة: فرض تكوينات TypeScript أكثر صرامة للتخلص من أنواع "any" القديمة وتحسين الموثوقية.
🎯 التحدي
تحتاج شركات التجزئة إلى السرعة والدقة والموثوقية. حالات الاستخدام مثل معالجة الكاشير لطابور من العملاء أو فحص المدير لمستويات المخزون لا تتحمل التأخير أو عدم تناسق البيانات.
كان هدفي بناء نظام يحل هذه المشاكل الأساسية وفي نفس الوقت يكون ملعبًا لتطبيق أنماط معمارية متقدمة. التحدي التقني كان مزدوجًا:
- منطق الأعمال: التعامل مع العلاقات المعقدة بين المنتجات، الفئات، الوحدات، والطلبات مع الحفاظ على سلامة البيانات.
- التحديث: إعادة هيكلة الكود القديم إلى بنية Monorepo نظيفة ومعيارية دون كسر الوظائف الموجودة.
🏗 البنية التحتية التقنية
اعتمدت هيكلية Monorepo للحفاظ على توافق وثيق بين العميل (Client) والخادم (Server).
الواجهة الخلفية (العمود الفقري)
- NestJS: تم اختياره لهيكليته القابلة للتوسع والمعيارية. يفرض عادات جيدة مثل حقن التبعيات (Dependency Injection) وفصل الاهتمامات.
- Prisma ORM: نقلة نوعية للعمل مع PostgreSQL. عميله المولد آمن النوع يعني أن استعلامات قاعدة البيانات يتم التحقق منها وقت التجميع، مما يقلل بشكل كبير من أخطاء وقت التشغيل.
- المصادقة: تنفيذ قوي لـ JWT مع Refresh Tokens. يضمن بقاء المستخدمين مسجلين دخول بأمان دون الحاجة لإعادة إدخال البيانات باستمرار، وهي ميزة حيوية لمحطات نقاط البيع.
الواجهة الأمامية (التجربة)
- React 18 & Vite: الاستفادة من الميزات المتزامنة (Concurrent Features) والتحديث السريع للوحدات (HMR).
- Redux Toolkit: يستخدم لإدارة الحالة العامة المعقدة، وتحديداً إدارة عربة التسوق (Cart). عندما يضيف الكاشير عناصر، أو يطبق خصومات، أو يعلق طلبًا، يضمن Redux أن تكون هذه الحالة متوقعة ومستمرة.
- نظام التصميم: بني باستخدام Tailwind CSS وأساسيات Radix UI (عبر Shadcn)، لضمان سهولة الوصول والاستجابة.
💡 حل مشاكل واقعية
1. مشكلة "تضارب المخزون" (إدارة المخزون)
- المشكلة: في متجر مزدحم، قد يبيع اثنان من الكاشير آخر قطعة في نفس اللحظة، مما يؤدي إلى مخزون بالسالب.
- الحل: القدرة على التعامل مع التزامن العالي. استخدمت معاملات قاعدة البيانات الصحيحة عبر Prisma. عندما يتم تقديم طلب، يحدث خصم المخزون وإنشاء الطلب داخل معاملة ذرية واحدة (Atomic Transaction). إذا فشل أحدهما، يتم التراجع عن كليهما.
2. التحكم الآمن في الوصول
- المشكلة: لا ينبغي أن يكون للكاشير القدرة على حذف المنتجات أو الاطلاع على تحليلات الإدارة الحساسة.
- الحل: قمت بتطبيق نظام تحكم في الوصول قائم على الأدوار (RBAC) قوي. باستخدام NestJS Guards (
@Roles('ADMIN')), قمت بتأمين نقاط النهاية بحيث لا يمكن إلا للموظفين المصرح لهم تنفيذ إجراءات حساسة، بينما يمتلك الكاشيرات واجهة مبسطة ومقيدة للمبيعات فقط.
✨ الميزات الرئيسية
- واجهة POS حديثة: واجهة سريعة وصديقة للوحة المفاتيح لمعالجة المبيعات بكفاءة.
- لوحة تحكم تفاعلية: تصور فوري لاتجاهات المبيعات باستخدام Recharts، مما يساعد المالكين على اتخاذ قرارات مبنية على البيانات.
- دعم متعدد الوحدات: إدارة مرنة للمنتجات تتعامل مع وحدات مختلفة (قطعة، كجم، إلخ) وفئات متعددة.
- نشر مع Docker: يتم تشغيل المجموعة الكاملة (الواجهة الأمامية، الخلفية، قاعدة البيانات) باستخدام أمر
docker-compose upواحد، مما يقضي على مشاكل "إنه يعمل على جهازي".
🧠 ماذا تعلمت
إعادة زيارة هذا المشروع علمتني أن الكود كائن حي. الفرق بين تنفيذي الأولي والنسخة الحالية هو كالفرق بين الليل والنهار.
- أمان النوع هو الملك: الانتقال إلى TypeScript الصارم أنقذني من أخطاء لا حصر لها كانت ستظهر فقط في الإنتاج.
- تجربة المستخدم تهم: الخلفية القوية عديمة الفائدة إذا كانت الواجهة الأمامية صعبة الاستخدام. استثمار الوقت في نظام تصميم مناسب آتى ثماره في سهولة الاستخدام.