using Fitness_core_BE.Models; namespace Fitness_core_BE.Interfaces { public interface IFacilityRepository { Task> GetAllFacilities(Guid clientId, bool includeInactive = false); Task GetFacilityById(Guid facilityId); Task CreateFacility(Facility facility); Task UpdateFacility(Facility facility); Task SetFacilityActive(Guid facilityId, Guid clientId, bool isActive); Task CreateFacilitySession(FacilitySession session); Task GetFacilitySessionById(Guid facilitySessionId); Task> GetSessions(Guid clientId, Guid? facilityId, DateTime fromUtc, DateTime toUtc, bool includeCancelled = false); Task GetActiveBookingCount(Guid facilitySessionId); Task> GetOverlappingActiveSessionsAsync(Guid facilityId, DateTime startUtc, DateTime endUtc); /// "Mark not held" -- see FacilityService.CancelFacilitySession for the full /// cascade this backs. Returns the session with its Bookings included so the caller can /// cancel+refund each Confirmed one. Task MarkFacilitySessionNotHeldAsync(Guid facilitySessionId, Guid clientId, string? reason); // Device binding (absorbed from the old IPlaceRepo -- one AccessDevice per Facility). Task GetDeviceByIdForClientAsync(Guid deviceId, Guid clientId); Task> GetDevicesByFacilityIdsAsync(List facilityIds); Task IsDeviceAssignedToAnotherFacilityAsync(Guid deviceId, Guid facilityId); Task AssignDeviceAsync(Guid facilityId, Guid deviceId); Task UnassignDeviceAsync(Guid facilityId); // CustomerPlan <-> Facility access-scoping (many-to-many). Replace-all semantics, like a // tags field. Absorbed from the old IPlaceRepo. Task SetPlanFacilitiesAsync(Guid customerPlanId, List facilityIds); Task> GetFacilityIdsForPlanAsync(Guid customerPlanId); Task>> GetFacilityIdsByPlanIdsAsync(List customerPlanIds); Task> GetFacilityNamesByIdsAsync(List facilityIds); // WalkIn booking support (new). See TenantDbContext's Booking (FKFacilityId, StartTime, // EndTime) index comment -- overlap is checked here rather than by a DB constraint. /// Counts non-cancelled/non-completed WalkIn bookings on this facility whose /// [StartTime, EndTime) overlaps the given window. Pass excludeBookingId when /// re-checking a booking being rescheduled, so it doesn't count against itself. Task GetOverlappingWalkInBookingCountAsync(Guid facilityId, DateTime startTime, DateTime endTime, Guid? excludeBookingId = null); /// Issues a row lock on the facility (SELECT ... FOR UPDATE) inside the caller's /// already-open unit-of-work transaction, serializing concurrent WalkIn-slot claims on the /// same facility so two overlapping bookings can't both pass the overlap-count check. Task LockFacilityForUpdateAsync(Guid facilityId); } }