Files
Salon/docs/execplans/booking-integrity.md
mohd 411180e312 Created and activated the booking integrity ExecPlan, then implemented staff availability, overlap prevention, and duration validation with backend tests.
Added a staff availability model and migration, a booking validation service, and serializer enforcement.
2026-02-28 12:05:57 +03:00

8.0 KiB
Raw Permalink Blame History

Booking Integrity (Availability, Schedules, Overlap Prevention)

This ExecPlan is a living document. The sections Progress, Surprises & Discoveries, Decision Log, and Outcomes & Retrospective must be kept up to date as work proceeds.

The requirements for ExecPlans live in PLANS.md at the repository root. This document must be maintained in accordance with that file.

Purpose / Big Picture

After this change, bookings cannot be created in invalid time windows or in ways that double-book staff. A manager can rely on the system to prevent overlapping appointments and to enforce staff working hours. You can see it working by attempting to create a booking outside a staff members availability window or that overlaps an existing confirmed booking and receiving a clear validation error; creating a booking that fits availability and does not overlap should succeed.

Progress

  • (2026-02-28 13:05Z) Created ExecPlan for booking integrity (availability, schedules, overlap prevention).
  • (2026-02-28 13:25Z) Added staff availability model, admin registration, and manual migration.
  • (2026-02-28 13:30Z) Introduced booking validation service for duration, schedule, and overlap checks.
  • (2026-02-28 13:32Z) Updated booking create serializer to require staff and enforce validation rules.
  • (2026-02-28 13:45Z) Added backend tests covering overlap prevention, availability windows, and duration validation.
  • (2026-02-28 13:50Z) Updated docs/risks.md to reflect closed booking-integrity gaps.

Surprises & Discoveries

  • Observation: Django is not installed in the environment, so makemigrations could not run. Evidence: ImportError: Couldn't import Django when running python3 backend/manage.py makemigrations salons.

Decision Log

  • Decision: Require staff on booking creation to enforce schedule and overlap rules deterministically. Rationale: Without an assigned staff member, the system cannot guarantee schedule integrity. Date/Author: 2026-02-28, Codex
  • Decision: Treat staff availability as open-ended if no availability records exist for that staff member. Rationale: This avoids breaking existing workflows while enabling explicit schedule enforcement when configured. Date/Author: 2026-02-28, Codex
  • Decision: Enforce that end_time - start_time matches the service duration in minutes. Rationale: Prevents inconsistent bookings and ensures predictable slot lengths. Date/Author: 2026-02-28, Codex
  • Decision: Add the StaffAvailability migration manually instead of using makemigrations. Rationale: Django was unavailable in the environment; a manual migration keeps schema changes explicit and reviewable. Date/Author: 2026-02-28, Codex

Outcomes & Retrospective

Booking integrity is now enforced via staff availability checks, duration validation, and overlap prevention, with test coverage for each rule. This closes the highest-risk booking integrity gap in docs/risks.md, while timezone and business-hours enforcement remain future work.

Context and Orientation

Booking creation is implemented in backend/apps/bookings/serializers.py (BookingCreateSerializer) and routed via backend/apps/bookings/views.py in a DRF ModelViewSet. The booking model lives in backend/apps/bookings/models.py, while staff information is in backend/apps/salons/models.py as StaffProfile. There is no current scheduling model and no overlap validation. This plan introduces a staff availability model and a dedicated booking validation service to keep business logic out of views, in line with project standards.

Plan of Work

First, add a staff availability model in backend/apps/salons/models.py. Create a StaffAvailability model with a foreign key to StaffProfile, a day-of-week integer (0-6), and start/end times (as TimeField). Use an is_active boolean to allow disabling entries without deleting them. Register the model in backend/apps/salons/admin.py for basic management. Create and apply a migration in the salons app.

Next, add a booking validation service in backend/apps/bookings/services.py. The service should expose a function like validate_booking_request(service, staff, start_time, end_time) that raises serializers.ValidationError or a custom domain error translated into DRF validation errors. It should check:

  • staff is required and belongs to the same salon as the service.
  • start_time < end_time and duration matches service.duration_minutes.
  • Staff availability: if availability records exist for the staff and day-of-week, ensure the booking window is fully inside one availability window with is_active=True.
  • Overlap: prevent any booking for the same staff with status in pending or confirmed that overlaps the requested window; cancelled and completed bookings should not block.

Then, update BookingCreateSerializer in backend/apps/bookings/serializers.py to call the validation service and to require staff. Keep create unchanged beyond relying on validated data.

Finally, add tests in backend/apps/bookings/tests/test_booking_integrity.py. Cover these cases:

  • Reject bookings with no staff assigned.
  • Reject bookings where end_time precedes start_time.
  • Reject bookings where duration does not match service.duration_minutes.
  • Reject bookings outside staff availability when availability records exist.
  • Allow bookings when no availability records exist.
  • Reject overlapping bookings for the same staff with pending or confirmed status; allow overlaps with cancelled or completed bookings.

Update docs/risks.md to mark booking integrity gaps as addressed once tests pass.

Concrete Steps

Run these commands from the repository root (/home/m7md/kshkool/Salon).

  1. Add staff availability model and migration.

    • Edit backend/apps/salons/models.py and backend/apps/salons/admin.py.
    • Run: python3 backend/manage.py makemigrations salons
  2. Add booking validation service and update serializer.

    • Create backend/apps/bookings/services.py and update backend/apps/bookings/serializers.py.
  3. Add tests.

    • Create backend/apps/bookings/tests/test_booking_integrity.py.
  4. Run tests.

    • Backend: python3 -m pytest

Validation and Acceptance

  • Attempting to create a booking without a staff member returns HTTP 400 with a clear validation error.
  • Creating a booking outside availability returns HTTP 400 with a clear validation error.
  • Creating a booking overlapping an existing pending/confirmed booking for the same staff returns HTTP 400.
  • Creating a booking within an availability window and without overlap returns HTTP 201.
  • Running python3 -m pytest passes, and the new booking-integrity tests fail before the changes and pass after.

Idempotence and Recovery

Model and serializer changes are additive and safe to reapply. If a migration needs to be re-run, it can be rolled back using standard Django migration rollback and re-applied. The validation service is pure and can be iterated without impacting data. If availability rules are too strict, disabling availability entries will effectively remove the constraint without deleting data.

Artifacts and Notes

Example overlap query used in validation:

Booking.objects.filter(
    staff=staff,
    status__in=[BookingStatus.PENDING, BookingStatus.CONFIRMED],
    start_time__lt=end_time,
    end_time__gt=start_time,
)

Interfaces and Dependencies

  • backend/apps/salons/models.py must define a new StaffAvailability model with fields: staff (FK), day_of_week (0-6), start_time, end_time, is_active.
  • backend/apps/bookings/services.py must define validate_booking_request(service, staff, start_time, end_time).
  • backend/apps/bookings/serializers.py must call the validation service and require staff on create.

Plan Maintenance Note: Created on 2026-02-28 to implement booking integrity (availability, schedules, overlap prevention) as the next Phase 1 reliability step. Plan Maintenance Note (Update): Marked milestones complete and recorded the manual migration decision after implementing booking integrity and tests on 2026-02-28.