-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #740 from bounswe/backend/group-implementation
group implementation (get-all, get, create)
- Loading branch information
Showing
12 changed files
with
404 additions
and
2 deletions.
There are no files selected for viewing
70 changes: 70 additions & 0 deletions
70
app/backend/src/main/java/com/app/gamereview/controller/GroupController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package com.app.gamereview.controller; | ||
|
||
import com.app.gamereview.dto.request.group.CreateGroupRequestDto; | ||
import com.app.gamereview.dto.request.group.GetAllGroupsFilterRequestDto; | ||
import com.app.gamereview.dto.request.review.CreateReviewRequestDto; | ||
import com.app.gamereview.dto.request.review.GetAllReviewsFilterRequestDto; | ||
import com.app.gamereview.dto.request.review.UpdateReviewRequestDto; | ||
import com.app.gamereview.dto.response.review.GetAllReviewsResponseDto; | ||
import com.app.gamereview.model.Group; | ||
import com.app.gamereview.model.Review; | ||
import com.app.gamereview.model.User; | ||
import com.app.gamereview.repository.GroupRepository; | ||
import com.app.gamereview.service.GroupService; | ||
import com.app.gamereview.service.ReviewService; | ||
import com.app.gamereview.util.validation.annotation.AuthorizationRequired; | ||
import io.jsonwebtoken.*; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.validation.Valid; | ||
import org.springdoc.core.annotations.ParameterObject; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.validation.annotation.Validated; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.util.Date; | ||
import java.util.List; | ||
|
||
@RestController | ||
@RequestMapping("/api/group") | ||
@Validated | ||
public class GroupController { | ||
|
||
@Value("${SECRET_KEY}") | ||
private String secret_key = "${SECRET_KEY}"; | ||
|
||
private final GroupService groupService; | ||
|
||
@Autowired | ||
public GroupController( | ||
GroupService groupService | ||
) { | ||
this.groupService = groupService; | ||
} | ||
|
||
@GetMapping("/get-all") | ||
public ResponseEntity<List<Group>> getReviews( | ||
@ParameterObject GetAllGroupsFilterRequestDto filter) { | ||
List<Group> groups = groupService.getAllGroups(filter); | ||
return ResponseEntity.ok(groups); | ||
} | ||
|
||
@GetMapping("/get") | ||
public ResponseEntity<Group> getGroup(@RequestParam String id) { | ||
Group group = groupService.getGroupById(id); | ||
|
||
return ResponseEntity.ok(group); | ||
} | ||
|
||
@AuthorizationRequired | ||
@PostMapping("/create") | ||
public ResponseEntity<Group> createGroup(@Valid @RequestBody CreateGroupRequestDto createGroupRequestDto, | ||
@RequestHeader String Authorization, HttpServletRequest request) { | ||
User user = (User) request.getAttribute("authenticatedUser"); | ||
Group groupToCreate = groupService.createGroup(createGroupRequestDto, user); | ||
return ResponseEntity.ok(groupToCreate); | ||
} | ||
|
||
} |
40 changes: 40 additions & 0 deletions
40
app/backend/src/main/java/com/app/gamereview/dto/request/group/CreateGroupRequestDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.app.gamereview.dto.request.group; | ||
|
||
import com.app.gamereview.enums.MembershipPolicy; | ||
import com.app.gamereview.enums.TagType; | ||
import com.app.gamereview.util.validation.annotation.ValidMemberPolicy; | ||
import jakarta.validation.constraints.*; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
@Getter | ||
@Setter | ||
public class CreateGroupRequestDto { | ||
|
||
@NotEmpty(message = "Title field cannot be null or empty") | ||
@Size(min = 3, message = "Title must be at least 3 characters long") | ||
@Size(max = 25, message = "Title must be at most 25 characters long") | ||
private String title; | ||
|
||
@NotNull(message = "Description field cannot be null") | ||
@Size(max = 600, message = "Description must be at most 600 characters long") | ||
private String description; | ||
|
||
@ValidMemberPolicy(allowedValues = {MembershipPolicy.PUBLIC, MembershipPolicy.PRIVATE}) | ||
private String membershipPolicy; | ||
|
||
private List<String> tags = new ArrayList<>(); // list of tag ids | ||
|
||
@NotEmpty(message = "Game Id must be provided") | ||
@Pattern(regexp = "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$", | ||
message = "Game has Invalid Id (UUID) format") | ||
private String gameId; // id of related game | ||
|
||
@Positive(message = "Quota cannot be negative or zero") | ||
private int quota; | ||
|
||
private Boolean avatarOnly = false; | ||
} |
29 changes: 29 additions & 0 deletions
29
...kend/src/main/java/com/app/gamereview/dto/request/group/GetAllGroupsFilterRequestDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.app.gamereview.dto.request.group; | ||
|
||
import com.app.gamereview.enums.SortDirection; | ||
import com.app.gamereview.enums.SortType; | ||
import com.app.gamereview.util.validation.annotation.ValidSortDirection; | ||
import com.app.gamereview.util.validation.annotation.ValidSortType; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
@Getter | ||
@Setter | ||
public class GetAllGroupsFilterRequestDto { | ||
private String title; | ||
|
||
private String membershipPolicy; | ||
|
||
private List<String> tags = new ArrayList<>(); // list of tag ids | ||
|
||
private String gameName; // id of related game | ||
|
||
@ValidSortType(allowedValues = {SortType.QUOTA, SortType.CREATION_DATE}) | ||
private String sortBy = SortType.CREATION_DATE.name(); | ||
|
||
@ValidSortDirection(allowedValues = {SortDirection.ASCENDING, SortDirection.DESCENDING}) | ||
private String sortDirection = SortDirection.DESCENDING.name(); | ||
} |
6 changes: 6 additions & 0 deletions
6
app/backend/src/main/java/com/app/gamereview/enums/MembershipPolicy.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.app.gamereview.enums; | ||
|
||
public enum MembershipPolicy { | ||
PUBLIC, | ||
PRIVATE | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,5 +4,6 @@ public enum SortType { | |
CREATION_DATE, | ||
EDIT_DATE, | ||
OVERALL_VOTE, | ||
VOTE_COUNT | ||
VOTE_COUNT, | ||
QUOTA | ||
} |
40 changes: 40 additions & 0 deletions
40
app/backend/src/main/java/com/app/gamereview/model/Group.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.app.gamereview.model; | ||
|
||
import com.app.gamereview.enums.MembershipPolicy; | ||
import com.app.gamereview.model.common.BaseModel; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
import org.springframework.data.annotation.TypeAlias; | ||
import org.springframework.data.mongodb.core.mapping.Document; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
@Document(collection = "Group") | ||
@TypeAlias("Group") | ||
@Getter | ||
@Setter | ||
public class Group extends BaseModel { | ||
private String title; | ||
|
||
private String description; | ||
|
||
private MembershipPolicy membershipPolicy; | ||
|
||
private List<String> tags = new ArrayList<>(); // list of tag ids | ||
|
||
private String gameId; // id of related game | ||
|
||
private String forumId; // id of the forum of the group | ||
|
||
private int quota; | ||
|
||
private List<String> moderators = new ArrayList<>(); // userIds of the moderators | ||
|
||
private List<String> members = new ArrayList<>(); // userIds of the members | ||
|
||
private List<String> bannedMembers = new ArrayList<>(); // userIds of the banned members | ||
|
||
private Boolean avatarOnly; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
app/backend/src/main/java/com/app/gamereview/repository/GroupRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.app.gamereview.repository; | ||
|
||
import com.app.gamereview.model.Group; | ||
import org.springframework.data.mongodb.repository.MongoRepository; | ||
|
||
import java.util.Optional; | ||
|
||
public interface GroupRepository extends MongoRepository<Group, String> { | ||
Optional<Group> findByIdAndIsDeletedFalse(String id); | ||
|
||
Optional<Group> findByTitleAndIsDeletedFalse(String title); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
155 changes: 155 additions & 0 deletions
155
app/backend/src/main/java/com/app/gamereview/service/GroupService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
package com.app.gamereview.service; | ||
|
||
import com.app.gamereview.dto.request.group.CreateGroupRequestDto; | ||
import com.app.gamereview.dto.request.group.GetAllGroupsFilterRequestDto; | ||
import com.app.gamereview.dto.request.tag.AddGameTagRequestDto; | ||
import com.app.gamereview.enums.ForumType; | ||
import com.app.gamereview.enums.SortDirection; | ||
import com.app.gamereview.enums.SortType; | ||
import com.app.gamereview.exception.BadRequestException; | ||
import com.app.gamereview.exception.ResourceNotFoundException; | ||
import com.app.gamereview.model.*; | ||
import com.app.gamereview.repository.*; | ||
import org.modelmapper.ModelMapper; | ||
import org.modelmapper.PropertyMap; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.data.domain.Sort; | ||
import org.springframework.data.mongodb.core.MongoTemplate; | ||
import org.springframework.data.mongodb.core.query.Criteria; | ||
import org.springframework.data.mongodb.core.query.Query; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.*; | ||
|
||
@Service | ||
public class GroupService { | ||
|
||
private final GroupRepository groupRepository; | ||
|
||
private final GameRepository gameRepository; | ||
|
||
private final ForumRepository forumRepository; | ||
|
||
private final TagRepository tagRepository; | ||
|
||
private final MongoTemplate mongoTemplate; | ||
|
||
private final ModelMapper modelMapper; | ||
|
||
@Autowired | ||
public GroupService( | ||
GroupRepository groupRepository, | ||
GameRepository gameRepository, | ||
ForumRepository forumRepository, | ||
TagRepository tagRepository, | ||
MongoTemplate mongoTemplate, | ||
ModelMapper modelMapper | ||
) { | ||
this.groupRepository = groupRepository; | ||
this.gameRepository = gameRepository; | ||
this.forumRepository = forumRepository; | ||
this.tagRepository = tagRepository; | ||
this.mongoTemplate = mongoTemplate; | ||
this.modelMapper = modelMapper; | ||
|
||
modelMapper.addMappings(new PropertyMap<CreateGroupRequestDto, Group>() { | ||
@Override | ||
protected void configure() { | ||
map().setGameId(source.getGameId()); | ||
skip().setId(null); // Exclude id from mapping | ||
} | ||
}); | ||
} | ||
|
||
public List<Group> getAllGroups(GetAllGroupsFilterRequestDto filter){ | ||
Query query = new Query(); | ||
|
||
// search for title | ||
if(filter.getTitle() != null && !filter.getTitle().isBlank()){ | ||
String regexPattern = ".*" + filter.getTitle() + ".*"; | ||
query.addCriteria(Criteria.where("title").regex(regexPattern, "i")); | ||
} | ||
if (filter.getMembershipPolicy() != null) { | ||
query.addCriteria(Criteria.where("membershipPolicy").is(filter.getMembershipPolicy())); | ||
} | ||
if (filter.getTags() != null && !filter.getTags().isEmpty()) { | ||
query.addCriteria(Criteria.where("tags").in(filter.getTags())); | ||
} | ||
if (filter.getGameName() != null && !filter.getGameName().isBlank()) { | ||
String gameName = filter.getGameName(); | ||
Optional<Game> game = gameRepository.findByGameNameAndIsDeletedFalse(gameName); | ||
if(game.isEmpty()){ | ||
return new ArrayList<>(); | ||
} | ||
query.addCriteria(Criteria.where("gameId").is(game.get().getId())); | ||
} | ||
if (filter.getSortBy() != null) { | ||
Sort.Direction sortDirection = Sort.Direction.DESC; | ||
if (filter.getSortDirection() != null) { | ||
sortDirection = filter.getSortDirection().equals(SortDirection.ASCENDING.name()) ? Sort.Direction.ASC | ||
: Sort.Direction.DESC; | ||
} | ||
if (filter.getSortBy().equals(SortType.CREATION_DATE.name())) { | ||
query.with(Sort.by(sortDirection, "createdAt")); | ||
} | ||
else if (filter.getSortBy().equals(SortType.QUOTA.name())) { | ||
query.with(Sort.by(sortDirection, "quota")); | ||
} | ||
} | ||
|
||
return mongoTemplate.find(query,Group.class); | ||
} | ||
|
||
public Group getGroupById(String groupId){ | ||
Optional<Group> isGroupExists = groupRepository.findByIdAndIsDeletedFalse(groupId); | ||
|
||
if(isGroupExists.isEmpty()){ | ||
throw new ResourceNotFoundException("Group not found"); | ||
} | ||
|
||
return isGroupExists.get(); | ||
} | ||
|
||
public Group createGroup(CreateGroupRequestDto request, User user){ | ||
|
||
Optional<Group> sameTitle = groupRepository.findByTitleAndIsDeletedFalse(request.getTitle()); | ||
|
||
if(sameTitle.isPresent()){ | ||
throw new BadRequestException("Group with same title already exists, please pick a new title"); | ||
} | ||
|
||
if(request.getTags() != null){ | ||
for(String tagId : request.getTags()){ | ||
Optional<Tag> tag = tagRepository.findByIdAndIsDeletedFalse(tagId); | ||
if(tag.isEmpty()){ | ||
throw new ResourceNotFoundException("One of the added tag is not found"); | ||
} | ||
} | ||
} | ||
|
||
if(request.getGameId() != null){ | ||
Optional<Game> game = gameRepository.findByIdAndIsDeletedFalse(request.getGameId()); | ||
if(game.isEmpty()){ | ||
throw new ResourceNotFoundException("Game is not found"); | ||
} | ||
} | ||
|
||
Group groupToCreate = modelMapper.map(request, Group.class); | ||
|
||
Forum correspondingForum = new Forum(groupToCreate.getTitle(), ForumType.GROUP, | ||
groupToCreate.getId(), new ArrayList<>(), new ArrayList<>()); | ||
forumRepository.save(correspondingForum); | ||
groupToCreate.setForumId(correspondingForum.getId()); | ||
|
||
List<String> moderators = new ArrayList<>(); | ||
moderators.add(user.getId()); | ||
List<String> members = new ArrayList<>(); | ||
members.add(user.getId()); | ||
|
||
groupToCreate.setModerators(moderators); | ||
groupToCreate.setMembers(members); | ||
|
||
return groupRepository.save(groupToCreate); | ||
} | ||
|
||
} |
Oops, something went wrong.