From c58df66e758fcd116b1741015c87d021f63421f0 Mon Sep 17 00:00:00 2001 From: Mattrixwv Date: Mon, 10 Mar 2025 19:19:53 -0400 Subject: [PATCH] Requests tab working --- db/1.0.0/16. createRaidGroupRequest.sql | 17 ++ .../controller/AccountController.java | 16 ++ .../RaidGroupRequestController.java | 145 ++++++++++++++++++ .../raidbuilder/entity/RaidGroupRequest.java | 39 +++++ .../RaidGroupPermissionRepository.java | 1 + .../RaidGroupRequestCustomRepository.java | 16 ++ .../RaidGroupRequestRepository.java | 21 +++ .../RaidGroupRequestRepositoryImpl.java | 55 +++++++ .../service/RaidGroupPermissionService.java | 4 + .../service/RaidGroupRequestService.java | 79 ++++++++++ .../raidbuilder/service/RaidGroupService.java | 3 + 11 files changed, 396 insertions(+) create mode 100644 db/1.0.0/16. createRaidGroupRequest.sql create mode 100644 src/main/java/com/mattrixwv/raidbuilder/controller/RaidGroupRequestController.java create mode 100644 src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroupRequest.java create mode 100644 src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_request/RaidGroupRequestCustomRepository.java create mode 100644 src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_request/RaidGroupRequestRepository.java create mode 100644 src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_request/RaidGroupRequestRepositoryImpl.java create mode 100644 src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupRequestService.java diff --git a/db/1.0.0/16. createRaidGroupRequest.sql b/db/1.0.0/16. createRaidGroupRequest.sql new file mode 100644 index 0000000..969e202 --- /dev/null +++ b/db/1.0.0/16. createRaidGroupRequest.sql @@ -0,0 +1,17 @@ +CREATE TABLE raid_builder.raid_group_request( + raid_group_request_id uuid PRIMARY KEY, + raid_group_id uuid REFERENCES raid_builder.raid_group(raid_group_id) NOT NULL, + account_id uuid REFERENCES raid_builder.account(account_id) NOT NULL, + request_message text, + + --Auditing + modified_by uuid, + modified_date timestamptz, + created_by uuid NOT NULL, + created_date timestamptz NOT NULL +); + +CREATE INDEX idx_raid_group_request_raid_group_id ON raid_builder.raid_group_request(raid_group_id); +CREATE INDEX idx_raid_group_request_account_id ON raid_builder.raid_group_request(account_id); + +GRANT ALL ON TABLE raid_builder.raid_group_request TO raid_builder; \ No newline at end of file diff --git a/src/main/java/com/mattrixwv/raidbuilder/controller/AccountController.java b/src/main/java/com/mattrixwv/raidbuilder/controller/AccountController.java index ec3ff52..3edb8a5 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/controller/AccountController.java +++ b/src/main/java/com/mattrixwv/raidbuilder/controller/AccountController.java @@ -121,6 +121,22 @@ public class AccountController{ return returnNode; } + @DeleteMapping("/{accountId}/raidGroup/{raidGroupId}/permission") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN}) + public ObjectNode deleteAccountPermission(@PathVariable("accountId") UUID accountId, @PathVariable("raidGroupId") UUID raidGroupId){ + log.info("Deleting account permission for account {} and raid group {}", accountId, raidGroupId); + + + rgpService.deleteByAccountIdAndRaidGroupId(accountId, raidGroupId); + + ObjectNode returnNode = mapper.createObjectNode(); + returnNode.put("status", "success"); + + + return returnNode; + } + @PostMapping @AccountAuthorization(permissions = {AccountPermissionType.ADMIN}) public ObjectNode createAccount(@RequestBody Account account){ diff --git a/src/main/java/com/mattrixwv/raidbuilder/controller/RaidGroupRequestController.java b/src/main/java/com/mattrixwv/raidbuilder/controller/RaidGroupRequestController.java new file mode 100644 index 0000000..d2e57c7 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/controller/RaidGroupRequestController.java @@ -0,0 +1,145 @@ +package com.mattrixwv.raidbuilder.controller; + + +import java.util.List; +import java.util.UUID; + +import org.springframework.security.core.Authentication; +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.Account; +import com.mattrixwv.raidbuilder.entity.RaidGroupRequest; +import com.mattrixwv.raidbuilder.service.AccountService; +import com.mattrixwv.raidbuilder.service.RaidGroupRequestService; +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}/raidGroupRequest") +@RequiredArgsConstructor +public class RaidGroupRequestController{ + private final ObjectMapper mapper; + private final AccountService accountService; + private final RaidGroupRequestService rgrService; + + + @GetMapping + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN}) + public List getRaidGroupRequests(@PathVariable("raidGroupId") UUID raidGroupId, @RequestParam("page") int page, @RequestParam("pageSize") int pageSize, @RequestParam(name = "searchTerm", required = false) String searchTerm){ + log.info("Getting raid group requests for raid group id: {}", raidGroupId); + + + List raidGroupRequests = searchTerm == null ? + rgrService.getByRaidGroupId(raidGroupId, page, pageSize) : + rgrService.getByRaidGroupId(raidGroupId, page, pageSize, searchTerm); + + + return raidGroupRequests; + } + + @GetMapping("/count") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + public ObjectNode getRaidGroupRequestCount(@PathVariable("raidGroupId") UUID raidGroupId, @RequestParam(name = "searchTerm", required = false) String searchTerm){ + log.info("Getting Raid Group Request Count for Raid Group {} with search {}", raidGroupId, searchTerm); + + + long count = searchTerm == null ? + rgrService.getCountByRaidGroupId(raidGroupId) : + rgrService.getCountByRaidGroupId(raidGroupId, searchTerm); + + ObjectNode returnNode = mapper.createObjectNode(); + returnNode.put("count", count); + returnNode.put("status", "success"); + + return returnNode; + } + + @PutMapping("/{raidGroupRequestId}/resolve") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN}) + public ObjectNode resolveRaidGroupRequest(@PathVariable("raidGroupId") UUID raidGroupId, @PathVariable("raidGroupRequestId") UUID raidGroupRequestId, @RequestBody ObjectNode bodyNode){ + log.info("Resolving raid group request for raid group id: {}", raidGroupId); + + + String resolution = bodyNode.get("resolution").asText(); + if(resolution.equals("denied")){ + rgrService.deleteRaidGroupRequest(raidGroupRequestId); + } + else{ + RaidGroupPermissionType permissionType = RaidGroupPermissionType.valueOf(resolution); + rgrService.resolveRaidGroupRequest(raidGroupRequestId, permissionType); + } + + ObjectNode returnNode = mapper.createObjectNode(); + returnNode.put("status", "success"); + + + return returnNode; + } + + + @PostMapping + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + public RaidGroupRequest createRaidGroupRequest(@PathVariable("raidGroupId") UUID raidGroupId, @RequestBody RaidGroupRequest raidGroupRequest, Authentication authentication){ + log.info("Creating raid group request for raid group id: {}", raidGroupId); + + + Account account = accountService.getByUsername(authentication.getName()); + raidGroupRequest.setAccountId(account.getAccountId()); + raidGroupRequest.setRaidGroupId(raidGroupId); + raidGroupRequest = rgrService.createRaidGroupRequest(raidGroupRequest); + + + return raidGroupRequest; + } + + @PutMapping("/{raidGroupRequestId}") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + public ObjectNode updateRaidGroupRequest(@PathVariable("raidGroupId") UUID raidGroupId, @PathVariable("raidGroupRequestId") UUID raidGroupRequestId, @RequestBody RaidGroupRequest raidGroupRequest){ + log.info("Updating raid group request for raid group id: {}", raidGroupId); + + + raidGroupRequest.setRaidGroupRequestId(raidGroupRequestId); + raidGroupRequest.setRaidGroupId(raidGroupId); + raidGroupRequest = rgrService.updateRaidGroupRequest(raidGroupRequest); + + ObjectNode returnNode = mapper.createObjectNode(); + returnNode.put("status", "success"); + + + return returnNode; + } + + @DeleteMapping("/{raidGroupRequestId}") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + public ObjectNode deleteRaidGroupRequest(@PathVariable("raidGroupId") UUID raidGroupId, @PathVariable("raidGroupRequestId") UUID raidGroupRequestId){ + log.info("Deleting raid group request for raid group id: {}", raidGroupId); + + + rgrService.deleteRaidGroupRequest(raidGroupRequestId); + + ObjectNode returnNode = mapper.createObjectNode(); + returnNode.put("status", "success"); + + + return returnNode; + } +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroupRequest.java b/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroupRequest.java new file mode 100644 index 0000000..29374fa --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroupRequest.java @@ -0,0 +1,39 @@ +package com.mattrixwv.raidbuilder.entity; + + +import java.util.UUID; + +import org.hibernate.annotations.Formula; + +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_group_request", schema = "raid_builder") +@Data +@EqualsAndHashCode(callSuper = false) +@NoArgsConstructor +public class RaidGroupRequest extends AuditableEntity{ + @Id + @Column(name = "raid_group_request_id") + @GeneratedValue(strategy = GenerationType.UUID) + private UUID raidGroupRequestId; + @Column(name = "raid_group_id") + private UUID raidGroupId; + @Column(name = "account_id") + private UUID accountId; + @Column(name = "request_message") + private String requestMessage; + + + @Formula("(SELECT a.username FROM raid_builder.account a WHERE a.account_id = account_id)") + private String username; +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionRepository.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionRepository.java index b17181b..7283c74 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionRepository.java +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionRepository.java @@ -12,6 +12,7 @@ import com.mattrixwv.raidbuilder.entity.RaidGroupPermission; public interface RaidGroupPermissionRepository extends RaidGroupPermissionCustomRepository, JpaRepository{ public void deleteAllByAccountId(UUID accountId); public void deleteAllByRaidGroupId(UUID raidGroupId); + public void deleteByAccountIdAndRaidGroupId(UUID accountId, UUID raidGroupId); public void deleteAllByRaidGroupIdIn(Iterable raidGroupIds); diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_request/RaidGroupRequestCustomRepository.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_request/RaidGroupRequestCustomRepository.java new file mode 100644 index 0000000..fed96f0 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_request/RaidGroupRequestCustomRepository.java @@ -0,0 +1,16 @@ +package com.mattrixwv.raidbuilder.repository.raid_group_request; + + +import java.util.List; +import java.util.UUID; + +import org.springframework.data.domain.PageRequest; + +import com.mattrixwv.raidbuilder.entity.RaidGroupRequest; + + +public interface RaidGroupRequestCustomRepository{ + public List findAllByRaidGroupIdAndAccountNameContainingIgnoreCase(UUID raidGroupId, String searchTerm, PageRequest pageRequest); + + public long countByRaidGroupIdAndAccountNameContainingIgnoreCase(UUID raidGroupId, String searchTerm); +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_request/RaidGroupRequestRepository.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_request/RaidGroupRequestRepository.java new file mode 100644 index 0000000..7c37729 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_request/RaidGroupRequestRepository.java @@ -0,0 +1,21 @@ +package com.mattrixwv.raidbuilder.repository.raid_group_request; + + +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.RaidGroupRequest; + + +public interface RaidGroupRequestRepository extends RaidGroupRequestCustomRepository, JpaRepository{ + public void deleteAllByRaidGroupId(UUID raidGroupId); + public void deleteAllByRaidGroupIdIn(Iterable raidGroupIds); + + + public List findByRaidGroupId(UUID raidGroupId, PageRequest pageRequest); + + public long countByRaidGroupId(UUID raidGroupId); +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_request/RaidGroupRequestRepositoryImpl.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_request/RaidGroupRequestRepositoryImpl.java new file mode 100644 index 0000000..f951225 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_request/RaidGroupRequestRepositoryImpl.java @@ -0,0 +1,55 @@ +package com.mattrixwv.raidbuilder.repository.raid_group_request; + + +import java.util.List; +import java.util.UUID; + +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort.Order; +import org.springframework.stereotype.Repository; + +import com.mattrixwv.raidbuilder.entity.RaidGroupRequest; + +import jakarta.persistence.EntityManager; +import lombok.RequiredArgsConstructor; + + +@Repository +@RequiredArgsConstructor +public class RaidGroupRequestRepositoryImpl implements RaidGroupRequestCustomRepository{ + private final EntityManager entityManager; + + + @Override + public List findAllByRaidGroupIdAndAccountNameContainingIgnoreCase(UUID raidGroupId, String searchTerm, PageRequest pageRequest){ + Order order = pageRequest.getSort().toList().get(0); + + return entityManager.createQuery(""" + SELECT rgr FROM RaidGroupRequest rgr + INNER JOIN Account a ON rgr.accountId = a.accountId + WHERE rgr.raidGroupId = :raidGroupId + AND LOWER(a.username) LIKE LOWER(:searchTerm) + ORDER BY :orderBy + """, RaidGroupRequest.class) + .setParameter("raidGroupId", raidGroupId) + .setParameter("searchTerm", "%" + searchTerm + "%") + .setParameter("orderBy", order.getProperty() + " " + order.getDirection()) + .setFirstResult(pageRequest.getPageNumber() * pageRequest.getPageSize()) + .setMaxResults(pageRequest.getPageSize()) + .getResultList(); + } + + + @Override + public long countByRaidGroupIdAndAccountNameContainingIgnoreCase(UUID raidGroupId, String searchTerm){ + return entityManager.createQuery(""" + SELECT COUNT(rgr) FROM RaidGroupRequest rgr + INNER JOIN Account a ON rgr.accountId = a.accountId + WHERE rgr.raidGroupId = :raidGroupId + AND LOWER(a.username) LIKE LOWER(:searchTerm) + """, Long.class) + .setParameter("raidGroupId", raidGroupId) + .setParameter("searchTerm", "%" + searchTerm + "%") + .getSingleResult(); + } +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupPermissionService.java b/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupPermissionService.java index 57092ad..fdf223a 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupPermissionService.java +++ b/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupPermissionService.java @@ -29,6 +29,10 @@ public class RaidGroupPermissionService{ raidGroupPermissionRepository.deleteAllByRaidGroupId(raidGroupId); } + public void deleteByAccountIdAndRaidGroupId(UUID accountId, UUID raidGroupId){ + raidGroupPermissionRepository.deleteByAccountIdAndRaidGroupId(accountId, raidGroupId); + } + public void deleteByRaidGroupIds(Iterable raidGroupIds){ raidGroupPermissionRepository.deleteAllByRaidGroupIdIn(raidGroupIds); } diff --git a/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupRequestService.java b/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupRequestService.java new file mode 100644 index 0000000..e530bcc --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupRequestService.java @@ -0,0 +1,79 @@ +package com.mattrixwv.raidbuilder.service; + + +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.RaidGroupPermission; +import com.mattrixwv.raidbuilder.entity.RaidGroupRequest; +import com.mattrixwv.raidbuilder.repository.raid_group_request.RaidGroupRequestRepository; +import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.RaidGroupPermissionType; + +import lombok.RequiredArgsConstructor; + + +@Service +@Transactional(rollbackFor = Exception.class) +@RequiredArgsConstructor +public class RaidGroupRequestService{ + private final RaidGroupRequestRepository rgrRepository; + //Related services + private final RaidGroupPermissionService rgpService; + + + //Write + public RaidGroupRequest createRaidGroupRequest(RaidGroupRequest raidGroupRequest){ + return rgrRepository.save(raidGroupRequest); + } + + public RaidGroupRequest updateRaidGroupRequest(RaidGroupRequest raidGroupRequest){ + return rgrRepository.save(raidGroupRequest); + } + + public void deleteRaidGroupRequest(UUID raidGroupRequestId){ + rgrRepository.deleteById(raidGroupRequestId); + } + + public void deleteByRaidGroupId(UUID raidGroupId){ + rgrRepository.deleteAllByRaidGroupId(raidGroupId); + } + + public void deleteByRaidGroupIds(Iterable raidGroupIds){ + rgrRepository.deleteAllByRaidGroupIdIn(raidGroupIds); + } + + public void resolveRaidGroupRequest(UUID raidGroupRequestId, RaidGroupPermissionType permission){ + RaidGroupRequest raidGroupRequest = rgrRepository.findById(raidGroupRequestId).orElseThrow(); + + RaidGroupPermission newPermission = new RaidGroupPermission(); + newPermission.setAccountId(raidGroupRequest.getAccountId()); + newPermission.setRaidGroupId(raidGroupRequest.getRaidGroupId()); + newPermission.setPermission(permission); + rgpService.createRaidGroupPermission(newPermission); + + rgrRepository.deleteById(raidGroupRequestId); + } + + + //Read + public List getByRaidGroupId(UUID raidGroupId, int page, int pageSize){ + return rgrRepository.findByRaidGroupId(raidGroupId, PageRequest.of(page, pageSize, Sort.by("createdBy").ascending())); + } + + public List getByRaidGroupId(UUID raidGroupId, int page, int pageSize, String searchTerm){ + return rgrRepository.findAllByRaidGroupIdAndAccountNameContainingIgnoreCase(raidGroupId, searchTerm, PageRequest.of(page, pageSize, Sort.by("createdBy").ascending())); + } + + public long getCountByRaidGroupId(UUID raidGroupId){ + return rgrRepository.countByRaidGroupId(raidGroupId); + } + + public long getCountByRaidGroupId(UUID raidGroupId, String searchTerm){ + return rgrRepository.countByRaidGroupIdAndAccountNameContainingIgnoreCase(raidGroupId, searchTerm); + } +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupService.java b/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupService.java index 2148265..1e71f7b 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupService.java +++ b/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupService.java @@ -35,6 +35,7 @@ public class RaidGroupService{ private final PersonService personService; private final RaidGroupCalendarEventService raidGroupCalendarEventService; private final RaidGroupPermissionService raidGroupPermissionService; + private final RaidGroupRequestService raidGroupRequestService; //Values @Value("${uploadFileDirectory}") private String uploadFileDirectory; @@ -113,6 +114,7 @@ public class RaidGroupService{ personService.deleteByRaidGroupId(raidGroupId); raidGroupCalendarEventService.deleteByRaidGroupId(raidGroupId); raidGroupPermissionService.deleteByRaidGroupId(raidGroupId); + raidGroupRequestService.deleteByRaidGroupId(raidGroupId); raidGroupRepository.flush(); raidGroupRepository.deleteById(raidGroupId); @@ -133,6 +135,7 @@ public class RaidGroupService{ personService.deleteByRaidGroupIds(raidGroupIds); raidGroupCalendarEventService.deleteByRaidGroupIds(raidGroupIds); raidGroupPermissionService.deleteByRaidGroupIds(raidGroupIds); + raidGroupRequestService.deleteByRaidGroupIds(raidGroupIds); raidGroupRepository.flush(); raidGroupRepository.deleteAll(raidGroups);