using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Fitness_core_BE.Models { /// A physical area of the club (e.g. "Pool Area", "Indoor Gym", "Court 1") that can /// both be booked (Booking/FacilitySession below) and fitted with its own fingerprint/face /// terminal for membership-plan access scoping (AccessDevice.FKFacilityId, /// CustomerPlanFacility). Merged from the formerly-separate Facility (bookable capacity) and /// Place (access zone) concepts -- see the booking redesign plan for the migration that /// carried Place's rows over reusing this table's original PlaceId values as FacilityId. public class Facility { [Key] public Guid FacilityId { get; set; } public Guid FKClientId { get; set; } [ForeignKey(nameof(FKClientId))] public Client Client { get; set; } [MaxLength(128)] public string Name { get; set; } = string.Empty; /// "Scheduled" | "AdHoc". Scheduled: staff pre-creates fixed-time /// FacilitySessions that many bookings share one capacity pool against (classes). /// AdHoc: a booking claims one of NumberOfUnits identical units directly for an /// arbitrary time window, no pre-created session needed (courts/pool). public string BookingMode { get; set; } = "Scheduled"; [MaxLength(500)] public string? Description { get; set; } /// Default per-session headcount limit when BookingMode == "Scheduled"; a /// specific FacilitySession can override. public int DefaultCapacity { get; set; } = 1; /// Number of identical, independently-bookable units when BookingMode == /// "AdHoc" (e.g. 3 for "3 courts") -- availability is this minus overlapping /// non-cancelled/non-completed AdHoc bookings in the requested window. public int NumberOfUnits { get; set; } = 1; /// Hourly rate used to compute a guest AdHoc booking's suggested AmountCharged /// (PricePerHour * duration-in-hours) at creation time. public decimal PricePerHour { get; set; } = 0m; public bool IsActive { get; set; } = true; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; } }