# turfslot-utils report

## Purpose

`turfslot-utils` encapsulates the full booking domain for badminton, table tennis, and tennis slots. By extracting these rules from any specific web framework we ensure clean separation of concerns, easier reuse across channels, and simpler testing.

## Domain model

- **SportSlot** – validated time-boxed reservation request for one court and sport. Carries computed duration to drive pricing.
- **Court** – metadata for a playable surface including name and hourly rate.
- Supported sports are fixed to `BADMINTON`, `TABLE_TENNIS`, and `TENNIS` to enforce consistent downstream reporting.

## Core components

| Module | Responsibility |
| --- | --- |
| `slots.SlotRangeValidator` | Ensures slot inputs are sane (start before end, duration within 0.5–4 hours, supported sport). Returns a `SportSlot`. |
| `availability.SportAvailabilityChecker` | Detects overlaps with existing bookings for the same court and sport. Raises `CourtNotAvailableError` when conflicts exist. |
| `pricing.SlotPriceCalculator` | Multiplies duration and hourly rate, adding a configurable weekend multiplier. Raises `InvalidSlotRangeError` for mismatches or invalid rates. |
| `exceptions` | Provides domain-specific errors. |

The modules are intentionally small so they can be orchestrated in any environment (CLI, APIs, or the TurfEase Django app).

## Validation, availability, pricing flow

1. Incoming payload is normalized through `SlotRangeValidator`.
2. The resulting `SportSlot` is compared against stored bookings by `SportAvailabilityChecker`.
3. Once free, `SlotPriceCalculator` uses the associated `Court` to compute a rounded price with weekend surcharges.

This triad mirrors the StayEase/accomm_utils_lib separation while reflecting sports-specific nomenclature.

## Integration with TurfEase

The forthcoming Django app uses the same validator/checker/pricer before persisting bookings. Because the utilities are framework-agnostic the Django layer only orchestrates data fetching (Postgres/DynamoDB), messaging (SQS/SNS), and presentation. Any future mobile or CLI channel can reuse the package unchanged.

## Design decisions

- **Time zones** – the library expects timezone-aware datetimes but does not enforce a specific zone, leaving responsibility to the caller.
- **Weekend handling** – Saturday/Sunday multiplier defaults to 1.2 but can be overridden.
- **Extensibility** – Supported sports are a tuple constant to allow fast membership checks and guardrails.
- **Zero dependencies** – relies solely on the standard library, simplifying packaging and deployment to constrained environments.
