GoalKick
دراسة حالة
متاح على goalkick.ritmodev.com

GoalKick: إدارة ملعب كرة قدم، من الحجز إلى الصندوق

GoalKick منصة لإدارة ملاعب كرة القدم والملاعب الخماسية، صمّمتها وطوّرتها لسوق الدار البيضاء: لوحة تحكم للمالك، وتطبيق حجز للاعبين، وكتالوج عام للملاعب — بالأسعار بالدرهم، ومع اعتبار الدفع عند الوصول وسيلة دفع حقيقية.

المشكلة

ما زالت أغلب الملاعب تتلقى الحجوزات عبر الهاتف وواتساب وتدوّنها في دفتر: حجوزات مزدوجة، وغيابات لا يمكن تتبّعها، ولا رؤية واضحة للأوقات المربحة فعلًا.

ما قمت ببنائه

  • لوحة تحكم المالك — الملاعب ومواعيد العمل وقواعد الأسعار؛ الحجوزات وأوقات الإغلاق؛ العملاء وبرنامج الولاء؛ البطولات وحصص الأكاديمية؛ الاشتراكات ونقطة البيع والمصاريف والرواتب؛ تقارير الإشغال والإيرادات.
  • تطبيق اللاعب — iOS وAndroid والويب من قاعدة Expo واحدة: العثور على ملعب، ورؤية الأوقات المتاحة فعلًا، والحجز، وتقسيم التكلفة، والانضمام إلى المباريات.
  • الموقع العام — صفحات تعريفية وكتالوج للملاعب يُعرض من الخادم باستخدام Angular SSR، لتتمكن محركات البحث من قراءته.

القرارات التقنية

قاعدة البيانات تمنع الحجز المزدوج. قيد استبعاد (exclusion constraint) في PostgreSQL يغطي كل ملعب وكل فترة زمنية. تحاول خدمة الحجز الإدراج مباشرة وتنتقل إلى الملعب التالي إذا رفضه القيد؛ ويطلق اختبار 12 حجزًا متزامنًا على وقت فيه 3 ملاعب ويتحقق من نجاح 3 فقط.

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

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

متعدد الملاعب منذ البداية. لا تقبل أي نقطة وصول خاصة بالمالك معرّف الملعب: فهو يأتي من الرمز الموقّع، فلا يوجد مُعامل يمكن التلاعب به.

المدفوعات عبر واجهة واحدة. الدفع عند الوصول مزوّد قائم بذاته، ويمكن إضافة مقتني بطاقات مغربي (CMI أو Payzone) دون المساس بمنطق الحجز.

التقنيات المستخدمة

  • Java 25
  • Spring Boot 4.1
  • PostgreSQL 17
  • Liquibase
  • Angular 22 SSR
  • Expo · React Native
  • Testcontainers
  • Docker
  • GitHub Actions

تعمل اختبارات التكامل على PostgreSQL حقيقي عبر Testcontainers، وكل دمج يُنشر تلقائيًا خلف Caddy.

شاهد المشروع

هل يعتمد نشاطك على الجداول وواتساب؟ أخبرني كيف يعمل اليوم.