diff --git a/db/1.0.0/17. createRaidInstance.sql b/db/1.0.0/17. createRaidInstance.sql new file mode 100644 index 0000000..575fd26 --- /dev/null +++ b/db/1.0.0/17. createRaidInstance.sql @@ -0,0 +1,23 @@ +CREATE TABLE raid_builder.raid_instance ( + raid_instance_id uuid PRIMARY KEY, + raid_group_id uuid REFERENCES raid_builder.raid_group(raid_group_id), + raid_layout_id uuid REFERENCES raid_builder.raid_layout(raid_layout_id), + raid_instance_name text, + raid_size int, + number_runs int NOT NULL, + raid_start_date timestamptz NOT NULL, + raid_end_date timestamptz NOT NULL, + + --Auditing + modified_by uuid, + modified_date timestamptz, + created_by uuid NOT NULL, + created_date timestamptz NOT NULL +); + +CREATE INDEX idx_raid_instance_raid_group_id ON raid_builder.raid_instance(raid_group_id); +CREATE INDEX idx_raid_instance_raid_layout_id ON raid_builder.raid_instance(raid_layout_id); +CREATE INDEX idx_raid_instance_raid_instance_name ON raid_builder.raid_instance(raid_instance_name); +CREATE INDEX idx_raid_instance_raid_start_date ON raid_builder.raid_instance(raid_start_date); + +GRANT ALL ON TABLE raid_builder.raid_instance TO raid_builder; diff --git a/src/main/java/com/mattrixwv/raidbuilder/controller/RaidInstanceController.java b/src/main/java/com/mattrixwv/raidbuilder/controller/RaidInstanceController.java new file mode 100644 index 0000000..c718d86 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/controller/RaidInstanceController.java @@ -0,0 +1,130 @@ +package com.mattrixwv.raidbuilder.controller; + + +import java.time.ZonedDateTime; +import java.util.List; +import java.util.UUID; + +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.mattrixwv.raidbuilder.annotation.AccountAuthorization; +import com.mattrixwv.raidbuilder.annotation.RaidGroupAuthorization; +import com.mattrixwv.raidbuilder.entity.RaidInstance; +import com.mattrixwv.raidbuilder.service.RaidInstanceService; +import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountPermissionType; +import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.RaidGroupPermissionType; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +@RestController +@RequestMapping("/raidGroup/{raidGroupId}/raidInstance") +@RequiredArgsConstructor +public class RaidInstanceController{ + private final ObjectMapper mapper; + private final RaidInstanceService raidInstanceService; + + + @GetMapping + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN, RaidGroupPermissionType.LEADER, RaidGroupPermissionType.RAIDER}) + public List getRaidInstances(@PathVariable("raidGroupId") UUID raidGroupId, @RequestParam("page") int page, @RequestParam("pageSize") int pageSize, @RequestParam(name = "searchTerm", required = false) String searchTerm){ + log.info("Getting future raid instance for raid group {} on page {} of size {} with search term {}", raidGroupId, page, pageSize, searchTerm); + + + List raidInstances; + if(searchTerm == null || searchTerm.isEmpty()){ + raidInstances = raidInstanceService.findAllByRaidGroupIdAndEndDate(raidGroupId, ZonedDateTime.now(), page, pageSize); + } + else{ + raidInstances = raidInstanceService.findAllByRaidGroupIdAndEndDate(raidGroupId, ZonedDateTime.now(), page, pageSize, searchTerm); + } + log.debug("Found {} raid instances", raidInstances.size()); + + + return raidInstances; + } + + @GetMapping("/count") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN, RaidGroupPermissionType.LEADER, RaidGroupPermissionType.RAIDER}) + public ObjectNode getRaidInstanceCount(@PathVariable("raidGroupId") UUID raidGroupId, @RequestParam(name = "searchTerm", required = false) String searchTerm){ + log.info("Getting raid instance count for raid group {} with search term {}", raidGroupId, searchTerm); + + + long count; + if(searchTerm == null || searchTerm.isEmpty()){ + count = raidInstanceService.countByRaidGroupIdAndEndDate(raidGroupId, ZonedDateTime.now()); + } + else{ + count = raidInstanceService.countByRaidGroupIdAndEndDate(raidGroupId, ZonedDateTime.now(), searchTerm); + } + log.debug("Found count {}", count); + ObjectNode returnNode = mapper.createObjectNode(); + returnNode.put("count", count); + returnNode.put("status", "success"); + + + return returnNode; + } + + + @PostMapping + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN, RaidGroupPermissionType.LEADER}) + public RaidInstance createRaidInstance(@PathVariable("raidGroupId") UUID raidGroupId, @RequestBody RaidInstance raidInstance){ + log.info("Creating raid instance for raid group {}", raidGroupId); + + + raidInstance.setRaidGroupId(raidGroupId); + RaidInstance createdRaidInstance = raidInstanceService.createRaidInstance(raidInstance); + log.debug("Created raid instance {}", createdRaidInstance); + + + return createdRaidInstance; + } + + @PutMapping("/{raidInstanceId}") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN, RaidGroupPermissionType.LEADER}) + public RaidInstance updateRaidInstance(@PathVariable("raidGroupId") UUID raidGroupId, @PathVariable("raidInstanceId") UUID raidInstanceId, @RequestBody RaidInstance raidInstance){ + log.info("Updating raid instance {} for raid group {}", raidInstanceId, raidGroupId); + + + raidInstance.setRaidInstanceId(raidInstanceId); + raidInstance.setRaidGroupId(raidGroupId); + RaidInstance updatedRaidInstance = raidInstanceService.updateRaidInstance(raidInstance); + log.debug("Updated raid instance {}", updatedRaidInstance); + + + return updatedRaidInstance; + } + + @DeleteMapping("/{raidInstanceId}") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN, RaidGroupPermissionType.LEADER}) + public ObjectNode deleteRaidInstance(@PathVariable("raidGroupId") UUID raidGroupId, @PathVariable("raidInstanceId") UUID raidInstanceId){ + log.info("Deleting raid instance {} for raid group {}", raidInstanceId, raidGroupId); + + + raidInstanceService.deleteById(raidInstanceId); + + ObjectNode returnNode = mapper.createObjectNode(); + returnNode.put("status", "success"); + + + return returnNode; + } +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/RaidInstance.java b/src/main/java/com/mattrixwv/raidbuilder/entity/RaidInstance.java new file mode 100644 index 0000000..4505e2a --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/entity/RaidInstance.java @@ -0,0 +1,42 @@ +package com.mattrixwv.raidbuilder.entity; + + +import java.time.ZonedDateTime; +import java.util.UUID; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + + +@Entity +@Table(name = "raid_instance", schema = "raid_builder") +@Data +@EqualsAndHashCode(callSuper = false) +@NoArgsConstructor +public class RaidInstance extends AuditableEntity{ + @Id + @Column(name = "raid_instance_id") + @GeneratedValue(strategy = GenerationType.UUID) + private UUID raidInstanceId; + @Column(name = "raid_group_id") + private UUID raidGroupId; + @Column(name = "raid_layout_id") + private UUID raidLayoutId; + @Column(name = "raid_instance_name") + private String raidInstanceName; + @Column(name = "raid_size") + private Integer raidSize; + @Column(name = "number_runs") + private Integer numberRuns; + @Column(name = "raid_start_date") + private ZonedDateTime raidStartDate; + @Column(name = "raid_end_date") + private ZonedDateTime raidEndDate; +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_instance/RaidInstanceCustomRepository.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_instance/RaidInstanceCustomRepository.java new file mode 100644 index 0000000..94a60f6 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_instance/RaidInstanceCustomRepository.java @@ -0,0 +1,5 @@ +package com.mattrixwv.raidbuilder.repository.raid_instance; + + +public interface RaidInstanceCustomRepository{ +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_instance/RaidInstanceRepository.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_instance/RaidInstanceRepository.java new file mode 100644 index 0000000..a73f45c --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_instance/RaidInstanceRepository.java @@ -0,0 +1,30 @@ +package com.mattrixwv.raidbuilder.repository.raid_instance; + + +import java.time.ZonedDateTime; +import java.util.List; +import java.util.UUID; + +import org.springframework.data.domain.PageRequest; +import org.springframework.data.jpa.repository.JpaRepository; + +import com.mattrixwv.raidbuilder.entity.RaidInstance; + + +public interface RaidInstanceRepository extends RaidInstanceCustomRepository, JpaRepository{ + public void deleteAllByRaidGroupId(UUID raidGroupId); + public void deleteAllByRaidGroupIdIn(Iterable raidGroupIds); + public void deleteAllByRaidLayoutId(UUID raidLayoutId); + public void deleteAllByRaidLayoutIdIn(Iterable raidLayoutIds); + + + public List findAllByRaidGroupId(UUID raidGroupId, PageRequest pageRequest); + public List findAllByRaidGroupIdAndRaidInstanceNameContainingIgnoreCase(UUID raidGroupId, String searchTerm, PageRequest pageRequest); + public List findAllByRaidGroupIdAndRaidEndDateAfter(UUID raidGroupId, ZonedDateTime raidEndDate, PageRequest pageRequest); + public List findAllByRaidGroupIdAndRaidEndDateAfterAndRaidInstanceNameContainingIgnoreCase(UUID raidGroupId, ZonedDateTime raidEndDate, String searchTerm, PageRequest pageRequest); + + public long countByRaidGroupId(UUID raidGroupId); + public long countByRaidGroupIdAndRaidInstanceNameContainingIgnoreCase(UUID raidGroupId, String searchTerm); + public long countByRaidGroupIdAndRaidEndDateAfter(UUID raidGroupId, ZonedDateTime raidEndDate); + public long countByRaidGroupIdAndRaidEndDateAfterAndRaidInstanceNameContainingIgnoreCase(UUID raidGroupId, ZonedDateTime raidEndDate, String searchTerm); +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_instance/RaidInstanceRepositoryImpl.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_instance/RaidInstanceRepositoryImpl.java new file mode 100644 index 0000000..21906a2 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_instance/RaidInstanceRepositoryImpl.java @@ -0,0 +1,9 @@ +package com.mattrixwv.raidbuilder.repository.raid_instance; + + +import org.springframework.stereotype.Repository; + + +@Repository +public class RaidInstanceRepositoryImpl implements RaidInstanceCustomRepository{ +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/service/RaidInstanceService.java b/src/main/java/com/mattrixwv/raidbuilder/service/RaidInstanceService.java new file mode 100644 index 0000000..2e70ead --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/service/RaidInstanceService.java @@ -0,0 +1,92 @@ +package com.mattrixwv.raidbuilder.service; + + +import java.time.ZonedDateTime; +import java.util.List; +import java.util.UUID; + +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.mattrixwv.raidbuilder.entity.RaidInstance; +import com.mattrixwv.raidbuilder.repository.raid_instance.RaidInstanceRepository; + +import lombok.RequiredArgsConstructor; + + +@Service +@Transactional(rollbackFor = Exception.class) +@RequiredArgsConstructor +public class RaidInstanceService{ + private final RaidInstanceRepository raidInstanceRepository; + + + //Write + public RaidInstance createRaidInstance(RaidInstance raidInstance){ + return raidInstanceRepository.save(raidInstance); + } + + public RaidInstance updateRaidInstance(RaidInstance raidInstance){ + return raidInstanceRepository.save(raidInstance); + } + + public void deleteById(UUID raidInstanceId){ + raidInstanceRepository.deleteById(raidInstanceId); + } + + public void deleteByRaidGroupId(UUID raidGroupId){ + raidInstanceRepository.deleteAllByRaidGroupId(raidGroupId); + } + + public void deleteByRaidGroupIds(Iterable raidGroupIds){ + raidInstanceRepository.deleteAllByRaidGroupIdIn(raidGroupIds); + } + + public void deleteByRaidLayoutId(UUID raidLayoutId){ + raidInstanceRepository.deleteAllByRaidLayoutId(raidLayoutId); + } + + public void deleteByRaidLayoutIds(Iterable raidLayoutIds){ + raidInstanceRepository.deleteAllByRaidLayoutIdIn(raidLayoutIds); + } + + + //Read + public RaidInstance findById(UUID raidInstanceId){ + return raidInstanceRepository.findById(raidInstanceId).orElse(null); + } + + public List findAllByRaidGroupId(UUID raidGroupId, int page, int pageSize){ + return raidInstanceRepository.findAllByRaidGroupId(raidGroupId, PageRequest.of(page, pageSize, Sort.by("raidInstanceName").ascending())); + } + + public List findAllByRaidGroupId(UUID raidGroupId, int page, int pageSize, String searchTerm){ + return raidInstanceRepository.findAllByRaidGroupIdAndRaidInstanceNameContainingIgnoreCase(raidGroupId, searchTerm, PageRequest.of(page, pageSize, Sort.by("raidInstanceName").ascending())); + } + + public List findAllByRaidGroupIdAndEndDate(UUID raidGroupId, ZonedDateTime endDate, int page, int pageSize){ + return raidInstanceRepository.findAllByRaidGroupIdAndRaidEndDateAfter(raidGroupId, endDate, PageRequest.of(page, pageSize, Sort.by("raidInstanceName").ascending())); + } + + public List findAllByRaidGroupIdAndEndDate(UUID raidGroupId, ZonedDateTime endDate, int page, int pageSize, String searchTerm){ + return raidInstanceRepository.findAllByRaidGroupIdAndRaidEndDateAfterAndRaidInstanceNameContainingIgnoreCase(raidGroupId, endDate, searchTerm, PageRequest.of(page, pageSize, Sort.by("raidInstanceName").ascending())); + } + + public long countByRaidGroupId(UUID raidGroupId){ + return raidInstanceRepository.countByRaidGroupId(raidGroupId); + } + + public long countByRaidGroupId(UUID raidGroupId, String searchTerm){ + return raidInstanceRepository.countByRaidGroupIdAndRaidInstanceNameContainingIgnoreCase(raidGroupId, searchTerm); + } + + public long countByRaidGroupIdAndEndDate(UUID raidGroupId, ZonedDateTime endDate){ + return raidInstanceRepository.countByRaidGroupIdAndRaidEndDateAfter(raidGroupId, endDate); + } + + public long countByRaidGroupIdAndEndDate(UUID raidGroupId, ZonedDateTime endDate, String searchTerm){ + return raidInstanceRepository.countByRaidGroupIdAndRaidEndDateAfterAndRaidInstanceNameContainingIgnoreCase(raidGroupId, endDate, searchTerm); + } +}