-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: 사용자는 링크 허브를 생성할 수 있다.
- Loading branch information
Showing
21 changed files
with
631 additions
and
5 deletions.
There are no files selected for viewing
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
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,50 @@ | ||
package com.seong.shoutlink.domain.hub; | ||
|
||
import com.seong.shoutlink.domain.exception.ErrorCode; | ||
import com.seong.shoutlink.domain.exception.ShoutLinkException; | ||
import java.text.MessageFormat; | ||
import java.util.Objects; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
public class Hub { | ||
|
||
private static final int NAME_MAX_SIZE = 30; | ||
private static final String DESCRIPTION_DEFAULT = ""; | ||
private static final int DESCRIPTION_MAX_SIZE = 200; | ||
|
||
private Long hubId; | ||
private String name; | ||
private String description; | ||
private boolean isPrivate; | ||
|
||
public Hub(String name, String description, boolean isPrivate) { | ||
this.name = validateName(name); | ||
this.description = validateDescription(description); | ||
this.isPrivate = isPrivate; | ||
} | ||
|
||
private String validateName(String name) { | ||
if (Objects.isNull(name)) { | ||
throw new ShoutLinkException("허브 이름은 필수입니다.", ErrorCode.ILLEGAL_ARGUMENT); | ||
} | ||
if(name.isEmpty() || name.length() > NAME_MAX_SIZE) { | ||
throw new ShoutLinkException( | ||
MessageFormat.format("허브 이름은 1자 이상, {0}자 이하여야 합니다.", NAME_MAX_SIZE), | ||
ErrorCode.ILLEGAL_ARGUMENT); | ||
} | ||
return name; | ||
} | ||
|
||
private String validateDescription(String description) { | ||
if(Objects.isNull(description)) { | ||
return DESCRIPTION_DEFAULT; | ||
} | ||
if(description.length() > DESCRIPTION_MAX_SIZE) { | ||
throw new ShoutLinkException( | ||
MessageFormat.format("허브 설명은 {0}자 이하여야 합니다.", DESCRIPTION_MAX_SIZE), | ||
ErrorCode.ILLEGAL_ARGUMENT); | ||
} | ||
return description; | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/seong/shoutlink/domain/hub/HubWithMembers.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,16 @@ | ||
package com.seong.shoutlink.domain.hub; | ||
|
||
import com.seong.shoutlink.domain.member.Member; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
public class HubWithMembers { | ||
|
||
private final Hub hub; | ||
private final Member member; | ||
|
||
public HubWithMembers(Hub hub, Member member) { | ||
this.hub = hub; | ||
this.member = member; | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
src/main/java/com/seong/shoutlink/domain/hub/controller/HubController.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,35 @@ | ||
package com.seong.shoutlink.domain.hub.controller; | ||
|
||
import com.seong.shoutlink.domain.auth.LoginUser; | ||
import com.seong.shoutlink.domain.hub.controller.request.CreateHubRequest; | ||
import com.seong.shoutlink.domain.hub.service.HubService; | ||
import com.seong.shoutlink.domain.hub.service.request.CreateHubCommand; | ||
import com.seong.shoutlink.domain.hub.service.response.CreateHubResponse; | ||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
|
||
@Controller | ||
@RequiredArgsConstructor | ||
@RequestMapping("/api") | ||
public class HubController { | ||
|
||
private final HubService hubService; | ||
|
||
@PostMapping("/hubs") | ||
public ResponseEntity<CreateHubResponse> createHub( | ||
@RequestBody @Valid CreateHubRequest request, | ||
@LoginUser Long memberId) { | ||
CreateHubResponse response = hubService.createHub(new CreateHubCommand( | ||
memberId, | ||
request.name(), | ||
request.description(), | ||
request.isPrivate())); | ||
return ResponseEntity.status(HttpStatus.CREATED).body(response); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/com/seong/shoutlink/domain/hub/controller/request/CreateHubRequest.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,13 @@ | ||
package com.seong.shoutlink.domain.hub.controller.request; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotNull; | ||
|
||
public record CreateHubRequest( | ||
@NotBlank(message = "허브 이름은 공백일 수 없습니다.") | ||
String name, | ||
String description, | ||
@NotNull(message = "허브 공개 여부는 필수입니다.") | ||
Boolean isPrivate) { | ||
|
||
} |
40 changes: 40 additions & 0 deletions
40
src/main/java/com/seong/shoutlink/domain/hub/repository/HubEntity.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.seong.shoutlink.domain.hub.repository; | ||
|
||
import com.seong.shoutlink.domain.hub.Hub; | ||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Entity | ||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class HubEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long hubId; | ||
|
||
@Column(nullable = false) | ||
private String name; | ||
|
||
@Column(nullable = false) | ||
private String description; | ||
|
||
@Column(nullable = false) | ||
private boolean isPrivate; | ||
|
||
private HubEntity(String name, String description, boolean isPrivate) { | ||
this.name = name; | ||
this.description = description; | ||
this.isPrivate = isPrivate; | ||
} | ||
|
||
public static HubEntity create(Hub hub) { | ||
return new HubEntity(hub.getName(), hub.getDescription(), hub.isPrivate()); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/java/com/seong/shoutlink/domain/hub/repository/HubJpaRepository.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,7 @@ | ||
package com.seong.shoutlink.domain.hub.repository; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface HubJpaRepository extends JpaRepository<HubEntity, Long> { | ||
|
||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/com/seong/shoutlink/domain/hub/repository/HubRepositoryImpl.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,26 @@ | ||
package com.seong.shoutlink.domain.hub.repository; | ||
|
||
import com.seong.shoutlink.domain.hub.HubWithMembers; | ||
import com.seong.shoutlink.domain.hub.service.HubRepository; | ||
import com.seong.shoutlink.domain.hubMember.repository.HubMemberEntity; | ||
import com.seong.shoutlink.domain.hubMember.repository.HubMemberJpaRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
@RequiredArgsConstructor | ||
public class HubRepositoryImpl implements HubRepository { | ||
|
||
private final HubJpaRepository hubJpaRepository; | ||
private final HubMemberJpaRepository hubMemberJpaRepository; | ||
|
||
@Override | ||
public Long save(HubWithMembers hubWithMembers) { | ||
HubEntity hubEntity = HubEntity.create(hubWithMembers.getHub()); | ||
hubJpaRepository.save(hubEntity); | ||
HubMemberEntity hubMemberEntity | ||
= HubMemberEntity.create(hubWithMembers.getHub(), hubWithMembers.getMember()); | ||
hubMemberJpaRepository.save(hubMemberEntity); | ||
return hubEntity.getHubId(); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/com/seong/shoutlink/domain/hub/service/HubRepository.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,8 @@ | ||
package com.seong.shoutlink.domain.hub.service; | ||
|
||
import com.seong.shoutlink.domain.hub.HubWithMembers; | ||
|
||
public interface HubRepository { | ||
|
||
Long save(HubWithMembers hubWithMembers); | ||
} |
36 changes: 36 additions & 0 deletions
36
src/main/java/com/seong/shoutlink/domain/hub/service/HubService.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,36 @@ | ||
package com.seong.shoutlink.domain.hub.service; | ||
|
||
import com.seong.shoutlink.domain.common.EventPublisher; | ||
import com.seong.shoutlink.domain.exception.ErrorCode; | ||
import com.seong.shoutlink.domain.exception.ShoutLinkException; | ||
import com.seong.shoutlink.domain.hub.Hub; | ||
import com.seong.shoutlink.domain.hub.HubWithMembers; | ||
import com.seong.shoutlink.domain.hub.service.event.CreateHubEvent; | ||
import com.seong.shoutlink.domain.hub.service.request.CreateHubCommand; | ||
import com.seong.shoutlink.domain.hub.service.response.CreateHubResponse; | ||
import com.seong.shoutlink.domain.member.Member; | ||
import com.seong.shoutlink.domain.member.service.MemberRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class HubService { | ||
|
||
private final MemberRepository memberRepository; | ||
private final HubRepository hubRepository; | ||
private final EventPublisher eventPublisher; | ||
|
||
public CreateHubResponse createHub(CreateHubCommand command) { | ||
Member member = getMember(command.memberId()); | ||
Hub hub = new Hub(command.name(), command.description(), command.isPrivate()); | ||
Long hubId = hubRepository.save(new HubWithMembers(hub, member)); | ||
eventPublisher.publishEvent(new CreateHubEvent(hubId)); | ||
return new CreateHubResponse(hubId); | ||
} | ||
|
||
private Member getMember(Long memberId) { | ||
return memberRepository.findById(memberId) | ||
.orElseThrow(() -> new ShoutLinkException("존재하지 않는 사용자입니다.", ErrorCode.NOT_FOUND)); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/java/com/seong/shoutlink/domain/hub/service/event/CreateHubEvent.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,7 @@ | ||
package com.seong.shoutlink.domain.hub.service.event; | ||
|
||
import com.seong.shoutlink.domain.common.Event; | ||
|
||
public record CreateHubEvent(Long hubId) implements Event { | ||
|
||
} |
5 changes: 5 additions & 0 deletions
5
src/main/java/com/seong/shoutlink/domain/hub/service/request/CreateHubCommand.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,5 @@ | ||
package com.seong.shoutlink.domain.hub.service.request; | ||
|
||
public record CreateHubCommand(Long memberId, String name, String description, boolean isPrivate) { | ||
|
||
} |
5 changes: 5 additions & 0 deletions
5
src/main/java/com/seong/shoutlink/domain/hub/service/response/CreateHubResponse.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,5 @@ | ||
package com.seong.shoutlink.domain.hub.service.response; | ||
|
||
public record CreateHubResponse(Long hubId) { | ||
|
||
} |
5 changes: 5 additions & 0 deletions
5
src/main/java/com/seong/shoutlink/domain/hubMember/HubMemberRole.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,5 @@ | ||
package com.seong.shoutlink.domain.hubMember; | ||
|
||
public enum HubMemberRole { | ||
MASTER, PARTICIPANTS | ||
} |
45 changes: 45 additions & 0 deletions
45
src/main/java/com/seong/shoutlink/domain/hubMember/repository/HubMemberEntity.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,45 @@ | ||
package com.seong.shoutlink.domain.hubMember.repository; | ||
|
||
import com.seong.shoutlink.domain.hub.Hub; | ||
import com.seong.shoutlink.domain.hubMember.HubMemberRole; | ||
import com.seong.shoutlink.domain.member.Member; | ||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.EnumType; | ||
import jakarta.persistence.Enumerated; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Entity | ||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class HubMemberEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long hubMemberId; | ||
|
||
@Column(nullable = false) | ||
private Long memberId; | ||
|
||
@Column(nullable = false) | ||
private Long hubId; | ||
|
||
@Column(nullable = false) | ||
@Enumerated(EnumType.STRING) | ||
private HubMemberRole hubMemberRole; | ||
|
||
public HubMemberEntity(Long memberId, Long hubId, HubMemberRole hubMemberRole) { | ||
this.memberId = memberId; | ||
this.hubId = hubId; | ||
this.hubMemberRole = hubMemberRole; | ||
} | ||
|
||
public static HubMemberEntity create(Hub hub, Member member) { | ||
return new HubMemberEntity(member.getMemberId(), hub.getHubId(), HubMemberRole.MASTER); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/java/com/seong/shoutlink/domain/hubMember/repository/HubMemberJpaRepository.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,7 @@ | ||
package com.seong.shoutlink.domain.hubMember.repository; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface HubMemberJpaRepository extends JpaRepository<HubMemberEntity, Long> { | ||
|
||
} |
Oops, something went wrong.