diff --git a/src/main/java/com/slotline/reservation/WaitlistEntry.java b/src/main/java/com/slotline/reservation/WaitlistEntry.java new file mode 100644 index 0000000..55cb482 --- /dev/null +++ b/src/main/java/com/slotline/reservation/WaitlistEntry.java @@ -0,0 +1,101 @@ +package com.slotline.reservation; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +import java.time.Instant; + +@Entity +@Table(name = "waitlist_entry") +public class WaitlistEntry { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "resource_id", nullable = false) + private Long resourceId; + + @Column(name = "organization_id", nullable = false) + private Long organizationId; + + @Column(name = "user_id", nullable = false) + private Long userId; + + @Column(name = "start_time", nullable = false) + private Instant startTime; + + @Column(name = "end_time", nullable = false) + private Instant endTime; + + @Enumerated(EnumType.STRING) + @Column(nullable = false, length = 16) + private WaitlistStatus status; + + @Column(name = "created_at", nullable = false) + private Instant createdAt; + + @Column(name = "promoted_reservation_id") + private Long promotedReservationId; + + protected WaitlistEntry() { + } + + public WaitlistEntry(Long resourceId, Long organizationId, Long userId, Instant startTime, Instant endTime, + Instant createdAt) { + this.resourceId = resourceId; + this.organizationId = organizationId; + this.userId = userId; + this.startTime = startTime; + this.endTime = endTime; + this.status = WaitlistStatus.WAITING; + this.createdAt = createdAt; + } + + public void promote(Long reservationId) { + this.status = WaitlistStatus.PROMOTED; + this.promotedReservationId = reservationId; + } + + public Long getId() { + return id; + } + + public Long getResourceId() { + return resourceId; + } + + public Long getOrganizationId() { + return organizationId; + } + + public Long getUserId() { + return userId; + } + + public Instant getStartTime() { + return startTime; + } + + public Instant getEndTime() { + return endTime; + } + + public WaitlistStatus getStatus() { + return status; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public Long getPromotedReservationId() { + return promotedReservationId; + } +} diff --git a/src/main/java/com/slotline/reservation/WaitlistRepository.java b/src/main/java/com/slotline/reservation/WaitlistRepository.java new file mode 100644 index 0000000..2d52d33 --- /dev/null +++ b/src/main/java/com/slotline/reservation/WaitlistRepository.java @@ -0,0 +1,25 @@ +package com.slotline.reservation; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.time.Instant; +import java.util.List; + +public interface WaitlistRepository extends JpaRepository { + + List findByUserIdOrderByCreatedAtDesc(Long userId); + + @Query(""" + select w from WaitlistEntry w + where w.resourceId = :resourceId + and w.status = com.slotline.reservation.WaitlistStatus.WAITING + and w.startTime < :end + and w.endTime > :start + order by w.createdAt asc + """) + List findWaitingOverlaps(@Param("resourceId") Long resourceId, + @Param("start") Instant start, + @Param("end") Instant end); +} diff --git a/src/main/java/com/slotline/reservation/WaitlistStatus.java b/src/main/java/com/slotline/reservation/WaitlistStatus.java new file mode 100644 index 0000000..99c8e91 --- /dev/null +++ b/src/main/java/com/slotline/reservation/WaitlistStatus.java @@ -0,0 +1,7 @@ +package com.slotline.reservation; + +public enum WaitlistStatus { + WAITING, + PROMOTED, + CANCELLED +}