كيف يمنع النظام تعارض الحجوزات؟ وأين يتم ذلك في الشيفرة؟
عن المشروع: حجز القاعات- أنت
كيف يمنع النظام تعارض الحجوزات؟ وأين يتم ذلك في الشيفرة؟
- النموذج
يمنع النظام تعارض الحجوزات من خلال تطبيق قاعدة واضحة: لا يمكن حجز القاعة نفسها في فترة زمنية تتداخل مع حجز آخر مؤكد أو قيد الاعتماد. يتم ذلك عبر دالة تحقق اسمها
validate_no_overlapالتي تُستدعى في نقاط حرجة من دورة حياة الحجز.1. منطق المنع (كيف يعمل؟)
يعتمد المنع على مقارنة الفترات الزمنية باستخدام قاعدة رياضية بسيطة: تتداخل فترتان
[start1, end1)و[start2, end2)إذا كان:start1 < end2وstart2 < end1إذا وُجد حجز موجود (بالحالة
CONFIRMEDأوPENDING_APPROVAL) يطابق هذه الشروط لنفس القاعة، يرفض النظام العملية ويرمي استثناءValidationErrorبرسالة:- بالعربية: "توجد حجزات متعارضة في نفس الفترة الزمنية لهذه القاعة"
- بالإنجليزية: "There is an overlapping booking for this room in the same time slot"
2. أين يتم ذلك في الشيفرة؟
يتم تنفيذ المنع في ثلاثة أماكن رئيسية:
أ. دالة التحقق الأساسية
توجد في ملف [backend/models/validation.py]، وهي الدالة التي تستعلم عن قاعدة البيانات للتحقق من التعارض:
def validate_no_overlap( db: Session, room_id: str, start_time: datetime.datetime, end_time: datetime.datetime, exclude_booking_id: Optional[str] = None ) -> None: """ Validate that no existing confirmed or pending bookings overlap with the proposed time slot for the same room (FR-01). """ query = db.query(Booking).filter( Booking.room_id == room_id, Booking.status.in_([BookingStatus.CONFIRMED, BookingStatus.PENDING_APPROVAL]), Booking.start_time < end_time, Booking.end_time > start_time ) if exclude_booking_id: query = query.filter(Booking.id != exclude_booking_id) overlapping_booking = query.first() if overlapping_booking: raise ValidationError( message_ar="توجد حجزات متعارضة في نفس الفترة الزمنية لهذه القاعة", message_en="There is an overlapping booking for this room in the same time slot" )ب. عند إنشاء حجز جديد
في ملف [backend/services/bookings/service.py]، داخل دالة
create_booking، يتم استدعاءvalidate_no_overlapقبل حفظ الحجز في قاعدة البيانات. إذا فشل التحقق، لن يُنشأ الحجز.ج. عند تعديل حجز قائم
في نفس الملف [backend/services/bookings/service.py]، داخل دالة
modify_booking، يتم استدعاءvalidate_no_overlapمع تمريرexclude_booking_id(معرف الحجز الحالي) لضمان عدم اعتبار الحجز نفسه متعارضاً مع نفسه عند تغيير موعده.د. عند البحث عن القاعات المتاحة
في ملف [backend/services/availability/service.py]، تستخدم دالة
search_available_roomsمنطقاً مشابهاً (عبرfilter_rooms_by_availabilityوvalidate_no_overlap) لاستبعاد القاعات التي لديها تعارض من نتائج البحث، مما يضمن أن المستخدم لا يرى قاعات غير متاحة أصلاً.ملاحظة تقنية
تُستبعد الحجوزات الملغاة (
CANCELLED) تلقائياً من فحص التعارض لأنها لا تحتجز الموارد فعلياً، مما يتيح إعادة استخدام نفس الفترة الزمنية بعد الإلغاء (متوافق مع [FR-08]). - أنت
وما الاختبارات التي تغطي ذلك؟
- النموذج
تغطي الاختبارات منع تعارض الحجوزات على مستويين: مستوى دالة التحقق المباشرة (
validate_no_overlap)، ومستوى خدمة الحجوزات (BookingService)، ومستوى خدمة التوفر (AvailabilityService).1. اختبارات دالة التحقق المباشرة
توجد في [backend/tests/test_validation.py] وتختبر منطق
validate_no_overlapبشكل معزول:-
test_validate_no_overlap_no_conflict:- الهدف: التحقق من نجاح التحقق عندما لا توجد حجوزات متداخلة.
- السيناريو: إنشاء قاعة، ثم استدعاء
validate_no_overlapلفترة زمنية لا يوجد فيها أي حجز. - النتيجة المتوقعة:
is_valid is Trueوerror is None.
-
test_validate_no_overlap_with_conflict:- الهدف: التحقق من رفض التحقق عند وجود حجز متداخل.
- السيناريو:
- إنشاء حجز مؤكد (
CONFIRMED) من الساعة 1 إلى الساعة 3. - محاولة التحقق من حجز جديد من الساعة 2 إلى الساعة 4 (تداخل واضح).
- إنشاء حجز مؤكد (
- النتيجة المتوقعة:
is_valid is Falseوerrorتحتوي على كلمة "تعارض" أو "overlap".
2. اختبارات خدمة الحجوزات (
BookingService)توجد في [backend/tests/test_bookings_service.py] وتختبر سلوك الخدمة الكاملة عند إنشاء حجز:
-
test_create_booking_conflict:- الهدف: التحقق من أن خدمة
create_bookingترفض إنشاء حجز متعارض. - السيناريو:
- وجود حجز مؤكد (
EMP002) من الساعة 1 إلى الساعة 3. - محاولة
EMP003إنشاء حجز لنفس القاعة من الساعة 2 إلى الساعة 4.
- وجود حجز مؤكد (
- النتيجة المتوقعة: رمي استثناء
ValidationErrorمع رسالة تحتوي على "تعارض" أو "overlap".
- الهدف: التحقق من أن خدمة
-
test_modify_booking_success(غير مباشر):- رغم أن الاسم يشير إلى النجاح، إلا أن الكود يتحقق من أن التعديل إلى وقت غير متعارض ينجح. لو كان الوقت متعارضا، لرمى
ValidationError(كما هو مضمن في منطقmodify_booking).
- رغم أن الاسم يشير إلى النجاح، إلا أن الكود يتحقق من أن التعديل إلى وقت غير متعارض ينجح. لو كان الوقت متعارضا، لرمى
-
test_cancel_booking_resource_release:- الهدف: التحقق من أن إلغاء الحجز يحرر الفترة الزمنية.
- السيناريو:
- إنشاء حجز.
- إلغاءه.
- محاولة إنشاء حجز جديد لنفس الفترة الزمنية بالضبط.
- النتيجة المتوقعة: نجاح الحجز الجديد (
status == CONFIRMED)، مما يؤكد أن الحجز الملغي لم يعد سبباً في التعارض.
3. اختبارات خدمة التوفر (
AvailabilityService)توجد في [backend/tests/test_availability_service.py] وتختبر كيف يتعامل البحث عن القاعات مع التعارضات:
-
test_search_available_rooms_excludes_booked_rooms:- الهدف: التحقق من استبعاد القاعات المحجوزة من نتائج البحث.
- السيناريو:
- وجود حجز مؤكد من الساعة 1 إلى الساعة 2.
- البحث عن قاعات متاحة من الساعة 1 إلى الساعة 2.
- النتيجة المتوقعة: قائمة فارغة (
len(results) == 0).
-
test_search_available_rooms_includes_non_overlapping_bookings:- الهدف: التحقق من تضمين القاعات التي لديها حجوزات غير متداخلة.
- السيناريو:
- وجود حجز من الساعة 1 إلى الساعة 2.
- البحث عن قاعات متاحة من الساعة 3 إلى الساعة 4.
- النتيجة المتوقعة: القاعة تظهر في النتائج (
len(results) == 1).
-
test_check_room_availability_with_conflict:- الهدف: التحقق من أن فحص توفر قاعة محددة يعيد "غير متاحة" عند وجود تعارض.
- السيناريو:
- وجود حجز من الساعة 1 إلى الساعة 3.
- فحص التوفر من الساعة 2 إلى الساعة 4.
- النتيجة المتوقعة:
is_available is Falseوerrorتحتوي على "تعارض".
-
test_check_room_availability_pending_booking_conflict:- الهدف: التحقق من أن الحجوزات "قيد الاعتماد" (
PENDING_APPROVAL) تُعتبر تعارضاً أيضاً. - السيناريو: وجود حجز بحالة
PENDING_APPROVALوفحص فترة متداخلة. - النتيجة المتوقعة:
is_available is False.
- الهدف: التحقق من أن الحجوزات "قيد الاعتماد" (
-
test_check_room_availability_cancelled_booking_no_conflict:- الهدف: التحقق من أن الحجوزات الملغاة لا تُعتبر تعارضاً.
- السيناريو: وجود حجز بحالة
CANCELLEDوفحص فترة متداخلة. - النتيجة المتوقعة:
is_available is True.
التتبع مع متطلبات النظام
هذه الاختبارات تغطي بشكل مباشر [FR-01] (منع تعارض الحجوزات) و [FR-08] (تحرير القاعة بعد الإلغاء)، وتتوافق مع سيناريو الاختبار الوظيفي [TC-02].
-