koprogo_api/application/ports/
resource_booking_repository.rs

1use crate::application::dto::BookingStatisticsDto;
2use crate::domain::entities::{BookingStatus, ResourceBooking, ResourceType};
3use async_trait::async_trait;
4use chrono::{DateTime, Utc};
5use uuid::Uuid;
6
7/// Repository trait for ResourceBooking persistence operations
8///
9/// Defines the contract for storing and retrieving resource bookings.
10/// Implementations must handle conflict detection, statistics, and filtering.
11#[async_trait]
12pub trait ResourceBookingRepository: Send + Sync {
13    /// Create a new booking
14    async fn create(&self, booking: &ResourceBooking) -> Result<ResourceBooking, String>;
15
16    /// Find booking by ID
17    async fn find_by_id(&self, id: Uuid) -> Result<Option<ResourceBooking>, String>;
18
19    /// Find all bookings for a building
20    async fn find_by_building(&self, building_id: Uuid) -> Result<Vec<ResourceBooking>, String>;
21
22    /// Find all bookings for a building with a specific resource type
23    async fn find_by_building_and_resource_type(
24        &self,
25        building_id: Uuid,
26        resource_type: ResourceType,
27    ) -> Result<Vec<ResourceBooking>, String>;
28
29    /// Find all bookings for a specific resource (building_id, resource_type, resource_name)
30    async fn find_by_resource(
31        &self,
32        building_id: Uuid,
33        resource_type: ResourceType,
34        resource_name: &str,
35    ) -> Result<Vec<ResourceBooking>, String>;
36
37    /// Find bookings by user (owner who made the booking)
38    async fn find_by_user(&self, user_id: Uuid) -> Result<Vec<ResourceBooking>, String>;
39
40    /// Find bookings by user and status
41    async fn find_by_user_and_status(
42        &self,
43        user_id: Uuid,
44        status: BookingStatus,
45    ) -> Result<Vec<ResourceBooking>, String>;
46
47    /// Find bookings by building and status
48    async fn find_by_building_and_status(
49        &self,
50        building_id: Uuid,
51        status: BookingStatus,
52    ) -> Result<Vec<ResourceBooking>, String>;
53
54    /// Find upcoming bookings (start_time in the future, status Confirmed or Pending)
55    async fn find_upcoming(
56        &self,
57        building_id: Uuid,
58        limit: Option<i64>,
59    ) -> Result<Vec<ResourceBooking>, String>;
60
61    /// Find active bookings (currently in progress: now >= start_time AND now < end_time)
62    async fn find_active(&self, building_id: Uuid) -> Result<Vec<ResourceBooking>, String>;
63
64    /// Find past bookings (end_time < now)
65    async fn find_past(
66        &self,
67        building_id: Uuid,
68        limit: Option<i64>,
69    ) -> Result<Vec<ResourceBooking>, String>;
70
71    /// Find conflicting bookings for a time range and resource
72    ///
73    /// Returns bookings that overlap with the given time range for the same resource.
74    /// Excludes cancelled, completed, and no-show bookings.
75    /// Excludes the booking with exclude_booking_id (useful for update conflict checks).
76    ///
77    /// Conflict logic: start1 < end2 AND start2 < end1
78    async fn find_conflicts(
79        &self,
80        building_id: Uuid,
81        resource_type: ResourceType,
82        resource_name: &str,
83        start_time: DateTime<Utc>,
84        end_time: DateTime<Utc>,
85        exclude_booking_id: Option<Uuid>,
86    ) -> Result<Vec<ResourceBooking>, String>;
87
88    /// Update booking
89    async fn update(&self, booking: &ResourceBooking) -> Result<ResourceBooking, String>;
90
91    /// Delete booking
92    async fn delete(&self, id: Uuid) -> Result<(), String>;
93
94    /// Count total bookings for a building
95    async fn count_by_building(&self, building_id: Uuid) -> Result<i64, String>;
96
97    /// Count bookings by building and status
98    async fn count_by_building_and_status(
99        &self,
100        building_id: Uuid,
101        status: BookingStatus,
102    ) -> Result<i64, String>;
103
104    /// Count bookings by resource
105    async fn count_by_resource(
106        &self,
107        building_id: Uuid,
108        resource_type: ResourceType,
109        resource_name: &str,
110    ) -> Result<i64, String>;
111
112    /// Get booking statistics for a building
113    async fn get_statistics(&self, building_id: Uuid) -> Result<BookingStatisticsDto, String>;
114}