diff --git a/book-my-show/backend/java/bms-monolith/pom.xml b/book-my-show/backend/java/bms-monolith/pom.xml
index 2583367..76f9214 100644
--- a/book-my-show/backend/java/bms-monolith/pom.xml
+++ b/book-my-show/backend/java/bms-monolith/pom.xml
@@ -50,6 +50,11 @@
mysql-connector-j
runtime
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
org.projectlombok
lombok
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/config/JpaConfig.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/config/JpaConfig.java
new file mode 100644
index 0000000..ca00d90
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/config/JpaConfig.java
@@ -0,0 +1,16 @@
+package org.lbcc.bms.bms_monolith.common.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.domain.AuditorAware;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+
+import java.util.Optional;
+
+@EnableJpaAuditing
+public class JpaConfig {
+
+ @Bean
+ public AuditorAware auditorProvider() {
+ return () -> Optional.of("system"); // TODO: Replace with code to fetch username when spring-security is implemented.
+ }
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/constants/BMSConstants.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/constants/BMSConstants.java
new file mode 100644
index 0000000..c479131
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/constants/BMSConstants.java
@@ -0,0 +1,15 @@
+package org.lbcc.bms.bms_monolith.common.constants;
+
+public final class BMSConstants {
+
+ private BMSConstants() {
+ }
+
+ public static final String STATUS_200 = "200";
+ public static final String MESSAGE_200 = "Request processed successfully";
+ public static final String EVENT_SUCCESS_MESSAGE = "Events fetched successfully";
+ public static final String UNEXPECTED_ERROR_MESSAGE = "An unexpected error occurred";
+ public static final String UNEXPECTED_ERROR_CODE = "UNEXPECTED_ERROR";
+ public static final String EVENT_SERVICE_ERROR = "EVENT_SERVICE_ERROR";
+ public static final String INVALID_PAGINATION_PARAMETER = "INVALID_PAGINATION_PARAMETER";
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/entity/BaseAuditingEntity.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/entity/BaseAuditingEntity.java
index f02e651..8c7f0f6 100644
--- a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/entity/BaseAuditingEntity.java
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/entity/BaseAuditingEntity.java
@@ -1,12 +1,21 @@
package org.lbcc.bms.bms_monolith.common.entity;
-import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.Column;
+import jakarta.persistence.EntityListeners;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.time.Instant;
import java.util.UUID;
@@ -17,14 +26,27 @@
@NoArgsConstructor
@Setter
@SuperBuilder
+@EntityListeners(AuditingEntityListener.class)
public abstract class BaseAuditingEntity {
@Id
+ @GeneratedValue(strategy = GenerationType.UUID)
+ @Column(columnDefinition = "CHAR(36)")
private UUID id;
+ @CreatedDate
+ @Column(updatable = false)
private Instant createdDate;
+
+ @LastModifiedDate
+ @Column(insertable = false)
private Instant lastModifiedDate;
+ @CreatedBy
+ @Column(updatable = false)
private String createdBy;
+
+ @LastModifiedBy
+ @Column(insertable = false)
private String lastModifiedBy;
}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/response/ApiErrorResponse.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/response/ApiErrorResponse.java
index eb5cfa5..14d2369 100644
--- a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/response/ApiErrorResponse.java
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/common/response/ApiErrorResponse.java
@@ -14,7 +14,8 @@
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
public class ApiErrorResponse {
- private boolean success;
+ @Builder.Default
+ private boolean success = false;
private String message;
private String code;
@Builder.Default
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/controller/EventController.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/controller/EventController.java
new file mode 100644
index 0000000..8c9b5f1
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/controller/EventController.java
@@ -0,0 +1,41 @@
+package org.lbcc.bms.bms_monolith.controller;
+
+import org.lbcc.bms.bms_monolith.common.constants.BMSConstants;
+import org.lbcc.bms.bms_monolith.common.response.ApiListResponse;
+import org.lbcc.bms.bms_monolith.entity.Event;
+import org.lbcc.bms.bms_monolith.service.IEventService;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.web.PageableDefault;
+import org.springframework.data.web.SortDefault;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(path="/events")
+public class EventController {
+
+ private final IEventService iEventService;
+
+ public EventController(IEventService iEventService) {
+ this.iEventService = iEventService;
+ }
+
+ @GetMapping
+ public ResponseEntity> getAllEvents(
+ @PageableDefault(page = 0, size = 10)
+ @SortDefault(sort = "startDate", direction = Sort.Direction.DESC) Pageable pageable) {
+
+ Page eventsPage = iEventService.getAllEvents(pageable);
+
+ ApiListResponse response = ApiListResponse.builder()
+ .success(true)
+ .message(BMSConstants.EVENT_SUCCESS_MESSAGE)
+ .setPage(eventsPage)
+ .build();
+
+ return ResponseEntity.ok(response);
+ }
+
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/Event.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/Event.java
new file mode 100644
index 0000000..5e5f6ab
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/Event.java
@@ -0,0 +1,56 @@
+package org.lbcc.bms.bms_monolith.entity;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.Column;
+import jakarta.validation.constraints.Size;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;
+
+import java.time.Instant;
+import java.util.List;
+
+@Entity
+@Getter @Setter
+@AllArgsConstructor @NoArgsConstructor
+public class Event extends BaseAuditingEntity {
+
+ @Size(min=10, max=50, message = "Title must be between 10 and 50 characters.")
+ @Column(nullable = false, length = 50)
+ private String title;
+
+ @Column(length = 1000)
+ private String description;
+
+ @ManyToOne(fetch = FetchType.EAGER)
+ @JoinColumn(name = "vendor_id")
+ private Vendor vendor;
+
+ @ManyToOne(fetch = FetchType.EAGER)
+ @JoinColumn(name = "venue_id")
+ private Venue venue;
+
+ @OneToMany(mappedBy = "event", cascade = CascadeType.ALL)
+ private List show;
+
+ @ManyToOne(fetch = FetchType.EAGER)
+ @JoinColumn(name = "event_type_id")
+ private EventType eventType;
+
+ @Column(nullable = false)
+ private Instant startDate;
+
+ @Column(length = 255)
+ private String thumbnailUrl;
+
+ @Column(nullable = false)
+ private Instant endDate;
+
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/EventShow.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/EventShow.java
new file mode 100644
index 0000000..23ad904
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/EventShow.java
@@ -0,0 +1,50 @@
+package org.lbcc.bms.bms_monolith.entity;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.ElementCollection;
+import jakarta.persistence.CollectionTable;
+import jakarta.persistence.Column;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.FetchType;
+import jakarta.validation.constraints.NotNull;
+import lombok.Builder;
+
+import lombok.experimental.SuperBuilder;
+import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;
+import org.lbcc.bms.bms_monolith.entity.enums.Genre;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+
+@Entity
+@SuperBuilder
+public class EventShow extends BaseAuditingEntity {
+
+ @ElementCollection(targetClass = Genre.class)
+ @CollectionTable(name = "show_genre", joinColumns = @JoinColumn(name = "show_id"))
+ @Column(name = "genre")
+ @Enumerated(EnumType.STRING)
+ private List genres;
+
+ @NotNull
+ private Instant startDate;
+
+ @NotNull
+ private Instant endDate;
+
+ @ManyToOne
+ @JoinColumn(name = "event_id", nullable = false)
+ private Event event;
+
+ @OneToMany(mappedBy = "show", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
+ private List seatInShows;
+
+ @OneToMany(mappedBy = "show", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
+ private List seatTypeInShows;
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/EventType.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/EventType.java
new file mode 100644
index 0000000..181321b
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/EventType.java
@@ -0,0 +1,18 @@
+package org.lbcc.bms.bms_monolith.entity;
+
+import jakarta.persistence.Entity;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;
+
+@Entity
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class EventType extends BaseAuditingEntity {
+
+ private String label;
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/Seat.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/Seat.java
new file mode 100644
index 0000000..e80426e
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/Seat.java
@@ -0,0 +1,34 @@
+package org.lbcc.bms.bms_monolith.entity;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.EnumType;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;
+import org.lbcc.bms.bms_monolith.entity.enums.OperationalStatus;
+
+@Entity
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class Seat extends BaseAuditingEntity {
+
+ @ManyToOne
+ @JoinColumn(name = "seat_type_id")
+ private SeatType seatType;
+
+ @ManyToOne
+ @JoinColumn(name = "venue_id")
+ private Venue venue;
+
+ @Enumerated(EnumType.STRING)
+ private OperationalStatus operationalStatus;
+
+ private String label;
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/SeatInShow.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/SeatInShow.java
new file mode 100644
index 0000000..80aef33
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/SeatInShow.java
@@ -0,0 +1,32 @@
+package org.lbcc.bms.bms_monolith.entity;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.EnumType;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;
+import org.lbcc.bms.bms_monolith.entity.enums.BookingStatus;
+
+@Entity
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class SeatInShow extends BaseAuditingEntity {
+
+ @ManyToOne
+ @JoinColumn(name = "seat_type_in_show_id")
+ private SeatTypeInShow seatTypeInShow;
+
+ @ManyToOne
+ @JoinColumn(name = "show_id")
+ private EventShow show;
+
+ @Enumerated(EnumType.STRING)
+ private BookingStatus bookingStatus;
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/SeatType.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/SeatType.java
new file mode 100644
index 0000000..3975c2b
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/SeatType.java
@@ -0,0 +1,25 @@
+package org.lbcc.bms.bms_monolith.entity;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;
+
+import java.math.BigDecimal;
+
+@Entity
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class SeatType extends BaseAuditingEntity {
+
+ private String label;
+
+ @Column(precision = 10, scale = 2)
+ private BigDecimal price;
+
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/SeatTypeInShow.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/SeatTypeInShow.java
new file mode 100644
index 0000000..c56bf6a
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/SeatTypeInShow.java
@@ -0,0 +1,26 @@
+package org.lbcc.bms.bms_monolith.entity;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.Column;
+import lombok.experimental.SuperBuilder;
+import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;
+
+import java.math.BigDecimal;
+
+@Entity
+@SuperBuilder
+public class SeatTypeInShow extends BaseAuditingEntity {
+
+ @ManyToOne
+ @JoinColumn(name = "seat_type_id")
+ private SeatType seatType;
+
+ @ManyToOne
+ @JoinColumn(name = "show_id")
+ private EventShow show;
+
+ @Column(precision = 10, scale = 2)
+ private BigDecimal price;
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/Vendor.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/Vendor.java
new file mode 100644
index 0000000..0b7ec1f
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/Vendor.java
@@ -0,0 +1,38 @@
+package org.lbcc.bms.bms_monolith.entity;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Column;
+import jakarta.validation.constraints.Size;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;
+import org.lbcc.bms.bms_monolith.entity.enums.VendorStatus;
+
+@Entity
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class Vendor extends BaseAuditingEntity {
+
+ private String name;
+ private String contactNumber;
+ private String email;
+ private String address;
+ private String website;
+
+ @Enumerated(EnumType.STRING)
+ private VendorStatus status;
+
+ @Column(nullable = true, length = 100)
+ @Size(min = 10, max = 100, message = "Registration date must be between 10 and 100 characters.")
+ private String registrationDate;
+
+ @Column(nullable = false, length = 255)
+ @Size(min = 25, max = 255, message = "Logo URL must be between 25 and 255 characters.")
+ private String logoUrl;
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/Venue.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/Venue.java
new file mode 100644
index 0000000..2c49496
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/Venue.java
@@ -0,0 +1,44 @@
+package org.lbcc.bms.bms_monolith.entity;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.OneToMany;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;
+import org.lbcc.bms.bms_monolith.entity.enums.OperationalStatus;
+import org.lbcc.bms.bms_monolith.entity.enums.VenueType;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Entity
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class Venue extends BaseAuditingEntity {
+
+ private String address;
+ private BigDecimal latitude;
+ private BigDecimal longitude;
+ private Integer totalSeatingCapacity;
+
+ @Enumerated(EnumType.STRING)
+ private VenueType venueType;
+
+ @Enumerated(EnumType.STRING)
+ private OperationalStatus operationalStatus;
+
+ @OneToMany(mappedBy = "venue", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
+ @NotNull(message = "Seats list cannot be null.")
+ @Size(min = 1, max = 100, message = "Seats list must contain between 1 and 100 seats.")
+ private List seats;
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/BookingStatus.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/BookingStatus.java
new file mode 100644
index 0000000..c8e3c16
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/BookingStatus.java
@@ -0,0 +1,7 @@
+package org.lbcc.bms.bms_monolith.entity.enums;
+
+public enum BookingStatus {
+ BOOKED,
+ AVAILABLE,
+ NOT_AVAILABLE;
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/Genre.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/Genre.java
new file mode 100644
index 0000000..61853ef
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/Genre.java
@@ -0,0 +1,9 @@
+package org.lbcc.bms.bms_monolith.entity.enums;
+
+public enum Genre {
+ COMEDY,
+ DRAMA,
+ ACTION,
+ THRILLER,
+ HORROR;
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/OperationalStatus.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/OperationalStatus.java
new file mode 100644
index 0000000..e98f001
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/OperationalStatus.java
@@ -0,0 +1,6 @@
+package org.lbcc.bms.bms_monolith.entity.enums;
+
+public enum OperationalStatus {
+ OPERATIONAL,
+ NON_OPERATIONAL;
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/VendorStatus.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/VendorStatus.java
new file mode 100644
index 0000000..1543c19
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/VendorStatus.java
@@ -0,0 +1,7 @@
+package org.lbcc.bms.bms_monolith.entity.enums;
+
+public enum VendorStatus {
+ ACTIVE,
+ INACTIVE,
+ SUSPENDED;
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/VenueType.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/VenueType.java
new file mode 100644
index 0000000..bcc5056
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/entity/enums/VenueType.java
@@ -0,0 +1,6 @@
+package org.lbcc.bms.bms_monolith.entity.enums;
+
+public enum VenueType {
+ AUDITORIUM,
+ STADIUM;
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/exception/EventServiceException.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/exception/EventServiceException.java
new file mode 100644
index 0000000..1c1b7d5
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/exception/EventServiceException.java
@@ -0,0 +1,8 @@
+package org.lbcc.bms.bms_monolith.exception;
+
+public class EventServiceException extends RuntimeException {
+
+ public EventServiceException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/exception/GlobalExceptionHandler.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/exception/GlobalExceptionHandler.java
new file mode 100644
index 0000000..bc90f06
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/exception/GlobalExceptionHandler.java
@@ -0,0 +1,44 @@
+package org.lbcc.bms.bms_monolith.exception;
+
+import org.lbcc.bms.bms_monolith.common.constants.BMSConstants;
+import org.lbcc.bms.bms_monolith.common.response.ApiErrorResponse;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+import java.time.Instant;
+
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+ @ExceptionHandler(EventServiceException.class)
+ public ResponseEntity handleEventServiceException(EventServiceException ex) {
+ return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, ex.getMessage(), BMSConstants.EVENT_SERVICE_ERROR);
+ }
+
+ @ExceptionHandler(InvalidPaginationParameterException.class)
+ public ResponseEntity handleInvalidPaginationParameter(InvalidPaginationParameterException ex) {
+ ApiErrorResponse errorResponse = ApiErrorResponse.builder()
+ .success(false)
+ .message(ex.getMessage())
+ .code(BMSConstants.INVALID_PAGINATION_PARAMETER)
+ .timestamp(Instant.now())
+ .build();
+
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
+ }
+
+ @ExceptionHandler(Exception.class)
+ public ResponseEntity handleGlobalException(Exception ex) {
+ return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, BMSConstants.UNEXPECTED_ERROR_MESSAGE, BMSConstants.UNEXPECTED_ERROR_CODE);
+ }
+
+ private ResponseEntity buildErrorResponse(HttpStatus status, String message, String code) {
+ ApiErrorResponse errorResponse = ApiErrorResponse.builder()
+ .message(message)
+ .code(code)
+ .build();
+ return ResponseEntity.status(status).body(errorResponse);
+ }
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/exception/InvalidPaginationParameterException.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/exception/InvalidPaginationParameterException.java
new file mode 100644
index 0000000..4a3d3cc
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/exception/InvalidPaginationParameterException.java
@@ -0,0 +1,8 @@
+package org.lbcc.bms.bms_monolith.exception;
+
+public class InvalidPaginationParameterException extends RuntimeException {
+
+ public InvalidPaginationParameterException(String message) {
+ super(message);
+ }
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/repository/IEventRepository.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/repository/IEventRepository.java
new file mode 100644
index 0000000..efa9979
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/repository/IEventRepository.java
@@ -0,0 +1,17 @@
+package org.lbcc.bms.bms_monolith.repository;
+
+import org.lbcc.bms.bms_monolith.entity.Event;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.util.UUID;
+
+@Repository
+public interface IEventRepository extends JpaRepository {
+
+ @Query("SELECT e FROM Event e JOIN FETCH e.vendor JOIN FETCH e.venue JOIN FETCH e.eventType ORDER BY e.startDate DESC")
+ Page findAllWithDetails(Pageable pageable);
+}
\ No newline at end of file
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/service/IEventService.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/service/IEventService.java
new file mode 100644
index 0000000..f3c62c7
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/service/IEventService.java
@@ -0,0 +1,10 @@
+package org.lbcc.bms.bms_monolith.service;
+
+import org.lbcc.bms.bms_monolith.entity.Event;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+public interface IEventService {
+
+ Page getAllEvents(Pageable pageable);
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/service/impl/EventServiceImpl.java b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/service/impl/EventServiceImpl.java
new file mode 100644
index 0000000..ce8e843
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/java/org/lbcc/bms/bms_monolith/service/impl/EventServiceImpl.java
@@ -0,0 +1,36 @@
+package org.lbcc.bms.bms_monolith.service.impl;
+
+import lombok.extern.slf4j.Slf4j;
+import org.lbcc.bms.bms_monolith.entity.Event;
+import org.lbcc.bms.bms_monolith.exception.EventServiceException;
+import org.lbcc.bms.bms_monolith.repository.IEventRepository;
+import org.lbcc.bms.bms_monolith.service.IEventService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+@Service
+@Slf4j
+public class EventServiceImpl implements IEventService {
+
+ private final IEventRepository IEventRepository;
+
+ @Autowired
+ public EventServiceImpl(IEventRepository IEventRepository) {
+ this.IEventRepository = IEventRepository;
+ }
+
+ @Override
+ public Page getAllEvents(Pageable pageable) {
+ try {
+ Page eventsPage = IEventRepository.findAllWithDetails(pageable);
+ log.info("Fetched {} events with pageable {}", eventsPage.getTotalElements(), pageable);
+
+ return eventsPage;
+ } catch (Exception e) {
+ log.error("Error fetching events: {}", e.getMessage());
+ throw new EventServiceException("Failed to fetch events", e);
+ }
+ }
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/main/resources/application.properties b/book-my-show/backend/java/bms-monolith/src/main/resources/application.properties
deleted file mode 100644
index c41048a..0000000
--- a/book-my-show/backend/java/bms-monolith/src/main/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-spring.application.name=BMS Monolith
diff --git a/book-my-show/backend/java/bms-monolith/src/main/resources/application.yaml b/book-my-show/backend/java/bms-monolith/src/main/resources/application.yaml
new file mode 100644
index 0000000..5ac2e86
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/main/resources/application.yaml
@@ -0,0 +1,19 @@
+spring:
+ application:
+ name: BMS Monolith
+ datasource:
+ url: jdbc:mysql://localhost:3306/bms
+ username: ${DB_USERNAME:root}
+ password: ${DB_PASSWORD:root}
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ jpa:
+ show-sql: true
+ hibernate:
+ ddl-auto: update
+ sql:
+ init:
+ mode: always
+
+server:
+ servlet:
+ context-path: /api/v1
\ No newline at end of file
diff --git a/book-my-show/backend/java/bms-monolith/src/test/java/org/lbcc/bms/bms_monolith/controller/EventControllerTest.java b/book-my-show/backend/java/bms-monolith/src/test/java/org/lbcc/bms/bms_monolith/controller/EventControllerTest.java
new file mode 100644
index 0000000..e528b5e
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/test/java/org/lbcc/bms/bms_monolith/controller/EventControllerTest.java
@@ -0,0 +1,107 @@
+package org.lbcc.bms.bms_monolith.controller;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.lbcc.bms.bms_monolith.common.response.ApiListResponse;
+import org.lbcc.bms.bms_monolith.entity.Event;
+import org.lbcc.bms.bms_monolith.exception.EventServiceException;
+import org.lbcc.bms.bms_monolith.service.IEventService;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.PageRequest;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import org.springframework.data.domain.Pageable;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.HttpStatus;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+import java.util.UUID;
+import static org.mockito.Mockito.when;
+
+public class EventControllerTest {
+
+ @Mock
+ private IEventService eventService;
+
+ @InjectMocks
+ private EventController eventController;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ }
+
+ @Test
+ void testGetAllEventsSuccess() {
+ Event event = new Event();
+ event.setId(UUID.randomUUID());
+ event.setTitle("Sample Event");
+
+ Page eventPage = new PageImpl<>(List.of(event), PageRequest.of(0, 10), 1);
+
+ when(eventService.getAllEvents(any(Pageable.class))).thenReturn(eventPage);
+
+ ResponseEntity> response = eventController.getAllEvents(PageRequest.of(0, 10));
+
+ ApiListResponse expectedResponse = ApiListResponse.builder()
+ .success(true)
+ .message("Events fetched successfully")
+ .data(eventPage.getContent())
+ .totalItems((int) eventPage.getTotalElements())
+ .totalPages(eventPage.getTotalPages())
+ .currentPage(eventPage.getNumber())
+ .pageSize(eventPage.getSize())
+ .hasNextPage(eventPage.hasNext())
+ .hasPreviousPage(eventPage.hasPrevious())
+ .build();
+
+ // Assertions to verify response
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ assertEquals(expectedResponse.getMessage(), response.getBody().getMessage());
+ assertEquals(expectedResponse.isSuccess(), response.getBody().isSuccess());
+ assertEquals(1, response.getBody().getTotalItems());
+ }
+
+ @Test
+ void testGetAllEventsInvalidPageParameters() {
+ Page emptyPage = Page.empty(PageRequest.of(0, 10));
+
+ when(eventService.getAllEvents(PageRequest.of(0, 10))).thenReturn(emptyPage);
+
+ ResponseEntity> response = eventController.getAllEvents(PageRequest.of(0, 10));
+
+ ApiListResponse expectedResponse = ApiListResponse.builder()
+ .success(false)
+ .message("Invalid page or size parameters")
+ .data(emptyPage.getContent())
+ .totalItems((int) emptyPage.getTotalElements())
+ .totalPages(emptyPage.getTotalPages())
+ .currentPage(0)
+ .pageSize(emptyPage.getSize())
+ .hasNextPage(emptyPage.hasNext())
+ .hasPreviousPage(emptyPage.hasPrevious())
+ .build();
+
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ assertEquals("Events fetched successfully", response.getBody().getMessage());
+ assertEquals(true, response.getBody().isSuccess());
+ }
+
+ @Test
+ void testGetAllEventsExceptionHandling() {
+ when(eventService.getAllEvents(any(Pageable.class)))
+ .thenThrow(new EventServiceException("Failed to fetch events", new RuntimeException()));
+
+ EventServiceException exception = assertThrows(EventServiceException.class, () -> {
+ eventController.getAllEvents(PageRequest.of(0, 10));
+ });
+
+ assertEquals("Failed to fetch events", exception.getMessage());
+ }
+
+}
diff --git a/book-my-show/backend/java/bms-monolith/src/test/java/org/lbcc/bms/bms_monolith/service/EventServiceImplTest.java b/book-my-show/backend/java/bms-monolith/src/test/java/org/lbcc/bms/bms_monolith/service/EventServiceImplTest.java
new file mode 100644
index 0000000..606ae21
--- /dev/null
+++ b/book-my-show/backend/java/bms-monolith/src/test/java/org/lbcc/bms/bms_monolith/service/EventServiceImplTest.java
@@ -0,0 +1,68 @@
+package org.lbcc.bms.bms_monolith.service;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.lbcc.bms.bms_monolith.entity.Event;
+import org.lbcc.bms.bms_monolith.exception.EventServiceException;
+import org.lbcc.bms.bms_monolith.repository.IEventRepository;
+import org.lbcc.bms.bms_monolith.service.impl.EventServiceImpl;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+
+import java.util.Collections;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+public class EventServiceImplTest {
+
+ @Mock
+ private IEventRepository IEventRepository;
+
+ @InjectMocks
+ private EventServiceImpl eventService;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ }
+
+ @Test
+ void testGetAllEventsSuccess() {
+ Event event = new Event();
+ event.setTitle("Sample Event");
+ event.setDescription("Sample Description");
+
+ Pageable pageable = PageRequest.of(0, 10);
+ Page eventPage = new PageImpl<>(Collections.singletonList(event), pageable, 1);
+
+ when(IEventRepository.findAllWithDetails(pageable)).thenReturn(eventPage);
+
+ Page response = eventService.getAllEvents(pageable);
+
+ assertNotNull(response);
+ assertEquals(1, response.getTotalElements());
+ assertEquals("Sample Event", response.getContent().get(0).getTitle());
+ assertEquals("Sample Description", response.getContent().get(0).getDescription());
+ }
+
+ @Test
+ void testGetAllEventsExceptionHandling() {
+ when(IEventRepository.findAllWithDetails(any(Pageable.class))).thenThrow(new RuntimeException("Database error"));
+
+ EventServiceException exception = assertThrows(EventServiceException.class, () -> {
+ eventService.getAllEvents(PageRequest.of(0, 10));
+ });
+
+ assertEquals("Failed to fetch events", exception.getMessage());
+ }
+}