Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
Expand All @@ -13,6 +15,7 @@
import project.flipnote.common.security.dto.AuthPrinciple;
import project.flipnote.group.model.GroupCreateRequest;
import project.flipnote.group.model.GroupCreateResponse;
import project.flipnote.group.model.GroupDetailResponse;
import project.flipnote.group.service.GroupService;

@RequiredArgsConstructor
Expand All @@ -28,4 +31,13 @@ public ResponseEntity<GroupCreateResponse> create(
GroupCreateResponse res = groupService.create(authPrinciple, req);
return ResponseEntity.status(HttpStatus.CREATED).body(res);
}

@GetMapping("/{groupId}")
public ResponseEntity<GroupDetailResponse> findGroupDetail(
@AuthenticationPrincipal AuthPrinciple authPrinciple,
@PathVariable("groupId") Long groupId) {
GroupDetailResponse res = groupService.findGroupDetail(authPrinciple, groupId);

return ResponseEntity.ok(res);
}
}
11 changes: 11 additions & 0 deletions src/main/java/project/flipnote/group/entity/Group.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package project.flipnote.group.entity;

import java.time.LocalDateTime;

import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLRestriction;
import org.hibernate.annotations.Where;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
Expand All @@ -23,6 +29,8 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "app_groups")
@Entity
@SQLDelete(sql = "UPDATE app_groups SET deleted_at = now() WHERE id = ?")
@SQLRestriction("deleted_at IS NULL")
public class Group extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down Expand Up @@ -51,6 +59,9 @@ public class Group extends BaseEntity {

private String imageUrl;

@Column(name = "deleted_at")
private LocalDateTime deletedAt;

@Builder
private Group(
String name,
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/project/flipnote/group/entity/GroupMember.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package project.flipnote.group.entity;

import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLRestriction;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
Expand All @@ -21,6 +24,8 @@
@Entity
@Table(name = "group_members")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@SQLDelete(sql = "UPDATE group_members SET deleted_at = CURRENT_TIMESTAMP WHERE id = ?")
@SQLRestriction("deleted_at IS NULL")
public class GroupMember extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package project.flipnote.group.model;

import java.time.LocalDateTime;

import project.flipnote.group.entity.Category;
import project.flipnote.group.entity.Group;

public record GroupDetailResponse(

String name,

Category category,

String description,

Boolean applicationRequired,

Boolean publicVisible,

Integer maxMember,

String imageUrl,

LocalDateTime createdAt,

LocalDateTime modifiedAt
) {
public static GroupDetailResponse from(Group group) {
return new GroupDetailResponse(
group.getName(),
group.getCategory(),
group.getDescription(),
group.getApplicationRequired(),
group.getPublicVisible(),
group.getMaxMember(),
group.getImageUrl(),
group.getCreatedAt(),
group.getModifiedAt()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

@Repository
public interface GroupRepository extends JpaRepository<Group, Long> {
Optional<Group> findById(Long groupId);
Optional<Group> findByIdAndDeletedAtIsNull(Long groupId);

@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select g from Group g where g.id = :id")
Expand Down
59 changes: 53 additions & 6 deletions src/main/java/project/flipnote/group/service/GroupService.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
import project.flipnote.group.exception.GroupErrorCode;
import project.flipnote.group.model.GroupCreateRequest;
import project.flipnote.group.model.GroupCreateResponse;
import project.flipnote.group.model.GroupDetailResponse;
import project.flipnote.group.repository.GroupMemberRepository;
import project.flipnote.group.repository.GroupPermissionRepository;
import project.flipnote.group.repository.GroupRepository;
import project.flipnote.group.repository.GroupRolePermissionRepository;
import project.flipnote.groupjoin.exception.GroupJoinErrorCode;
import project.flipnote.user.entity.UserProfile;
import project.flipnote.user.entity.UserStatus;
import project.flipnote.user.exception.UserErrorCode;
Expand All @@ -40,19 +42,40 @@ public class GroupService {
private final GroupRolePermissionRepository groupRolePermissionRepository;
private final UserProfileRepository userProfileRepository;

//유저 정보 조회
public UserProfile findUser(AuthPrinciple authPrinciple) {
/*
유저 정보 조회
*/
public UserProfile validateUser(AuthPrinciple authPrinciple) {
return userProfileRepository.findByIdAndStatus(authPrinciple.userId(), UserStatus.ACTIVE).orElseThrow(
() -> new BizException(UserErrorCode.USER_NOT_FOUND)
);
}

/*
그룹 내 유저 조회
*/
public boolean validateGroupInUser(UserProfile user, Long groupId) {
return groupMemberRepository.existsByGroup_idAndUser_id(groupId, user.getId());
}

/*
그룹 조회
*/
public Group validateGroup(Long groupId) {
return groupRepository.findByIdAndDeletedAtIsNull(groupId).orElseThrow(
() -> new BizException(GroupErrorCode.GROUP_NOT_FOUND)
);
}


//그룹 생성
/*
그룹 생성
*/
@Transactional
public GroupCreateResponse create(AuthPrinciple authPrinciple, GroupCreateRequest req) {

//1. 유저 조회
UserProfile userProfile = findUser(authPrinciple);
UserProfile user = validateUser(authPrinciple);

//2. 인원수 검증
validateMaxMember(req.maxMember());
Expand All @@ -61,7 +84,7 @@ public GroupCreateResponse create(AuthPrinciple authPrinciple, GroupCreateReques
Group group = createGroup(req);

//4. 그룹 회원 정보 생성
saveGroupOwner(group, userProfile);
saveGroupOwner(group, user);

//5. 그룹 내의 모든 권한 조회
initializeGroupPermissions(group);
Expand Down Expand Up @@ -135,11 +158,35 @@ private void saveGroupOwner(Group group, UserProfile user) {
groupMemberRepository.save(groupMember);
}

//인원수 검증
/*
인원수 검증
*/
private void validateMaxMember(int maxMember) {
if (maxMember < 1 || maxMember > 100) {
throw new BizException(GroupErrorCode.INVALID_MAX_MEMBER);
}
}

/*
그룹 상세 정보 조회
*/
public GroupDetailResponse findGroupDetail(AuthPrinciple authPrinciple, Long groupId) {

//1. 그룹 조회
Group group = validateGroup(groupId);

//2. 유저 조회
UserProfile user = validateUser(authPrinciple);

//3. 그룹 내 유저 조회
if (!validateGroupInUser(user, groupId)) {
throw new BizException(GroupJoinErrorCode.USER_NOT_IN_GROUP);
}

return GroupDetailResponse.from(group);
}

public void deleteGroup(AuthPrinciple authPrinciple, Long groupId) {

}
}
Loading
Loading