Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into feat/#166
Browse files Browse the repository at this point in the history
  • Loading branch information
cruelladevil committed Aug 3, 2023
2 parents 1215b89 + 75dc7f3 commit 34a9f69
Show file tree
Hide file tree
Showing 51 changed files with 1,525 additions and 319 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/backend-dev-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Backend Develop Deploy (CD)

on:
workflow_dispatch:
inputs:
branch:
description: 'Branch Name'
required: true

jobs:
build:
name: Backend Deploy
runs-on: shook-runner

steps:
- name: Log pwd
shell: bash
run: pwd
- name: Log Branch Name
shell: bash
run: echo "${{ github.event.inputs.branch }}"
- name: Deploy
shell: bash
run: bash /home/ubuntu/deploy.sh ${{ github.event.inputs.branch }}
3 changes: 3 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'

//swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'

compileOnly 'org.projectlombok:lombok'

runtimeOnly 'com.h2database:h2'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package shook.shook.part.application;

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shook.shook.part.application.dto.PartCommentRegisterRequest;
import shook.shook.part.application.dto.PartCommentResponse;
import shook.shook.part.domain.Part;
import shook.shook.part.domain.PartComment;
import shook.shook.part.domain.repository.PartCommentRepository;
import shook.shook.part.domain.repository.PartRepository;
import shook.shook.part.exception.PartException;

@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class PartCommentService {

private final PartRepository partRepository;
private final PartCommentRepository partCommentRepository;

@Transactional
public void register(final Long partId, final PartCommentRegisterRequest request) {
final Part part = partRepository.findById(partId)
.orElseThrow(PartException.PartNotExistException::new);
final PartComment partComment = PartComment.forSave(part, request.getContent());

part.addComment(partComment);
partCommentRepository.save(partComment);
}

public List<PartCommentResponse> findPartReplies(final Long partId) {
final Part part = partRepository.findById(partId)
.orElseThrow(PartException.PartNotExistException::new);

return PartCommentResponse.getList(part.getCommentsInRecentOrder());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package shook.shook.part.application.dto;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor
@Getter
public class PartCommentRegisterRequest {

private String content;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package shook.shook.part.application.dto;

import java.time.LocalDateTime;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import shook.shook.part.domain.PartComment;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public class PartCommentResponse {

private final Long id;
private final String content;
private final LocalDateTime createdAt;

public static PartCommentResponse from(final PartComment partComment) {
return new PartCommentResponse(
partComment.getId(),
partComment.getContent(),
partComment.getCreatedAt()
);
}

public static List<PartCommentResponse> getList(final List<PartComment> partComments) {
return partComments.stream()
.map(PartCommentResponse::from)
.toList();
}
}
20 changes: 20 additions & 0 deletions backend/src/main/java/shook/shook/part/domain/Part.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package shook.shook.part.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
Expand All @@ -22,6 +23,7 @@
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import shook.shook.part.exception.PartCommentException;
import shook.shook.part.exception.PartException;
import shook.shook.part.exception.VoteException;
import shook.shook.song.domain.Song;
Expand Down Expand Up @@ -54,6 +56,9 @@ public class Part {
@OneToMany(mappedBy = "part")
private final List<Vote> votes = new ArrayList<>();

@Embedded
private final PartComments comments = new PartComments();

@Column(nullable = false, updatable = false)
private LocalDateTime createdAt = LocalDateTime.now();

Expand Down Expand Up @@ -118,6 +123,13 @@ private void validateVote(final Vote vote) {
}
}

public void addComment(final PartComment comment) {
if (comment.isBelongToOtherPart(this)) {
throw new PartCommentException.CommentForOtherPartException();
}
comments.addComment(comment);
}

public boolean hasEqualStartAndLength(final Part other) {
return this.startSecond == other.startSecond && this.length.equals(other.length);
}
Expand All @@ -143,6 +155,14 @@ public int getVoteCount() {
return votes.size();
}

public List<PartComment> getComments() {
return comments.getComments();
}

public List<PartComment> getCommentsInRecentOrder() {
return comments.getCommentsInRecentOrder();
}

@Override
public boolean equals(final Object o) {
if (this == o) {
Expand Down
89 changes: 89 additions & 0 deletions backend/src/main/java/shook/shook/part/domain/PartComment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package shook.shook.part.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Objects;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Table(name = "part_comment")
@Entity
public class PartComment {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Embedded
private PartCommentContent content;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "part_id", foreignKey = @ForeignKey(name = "none"), nullable = false, updatable = false)
@Getter(AccessLevel.NONE)
private Part part;

@Column(nullable = false, updatable = false)
private LocalDateTime createdAt = LocalDateTime.now();

@PrePersist
private void prePersist() {
createdAt = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
}

private PartComment(final Long id, final Part part, final String content) {
this.id = id;
this.part = part;
this.content = new PartCommentContent(content);
}

public static PartComment saved(final Long id, final Part part, final String content) {
return new PartComment(id, part, content);
}

public static PartComment forSave(final Part part, final String content) {
return new PartComment(null, part, content);
}

public boolean isBelongToOtherPart(final Part part) {
return !this.part.equals(part);
}

public String getContent() {
return content.getValue();
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final PartComment partComment = (PartComment) o;
if (Objects.isNull(partComment.id) || Objects.isNull(this.id)) {
return false;
}
return Objects.equals(id, partComment.id);
}

@Override
public int hashCode() {
return Objects.hash(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package shook.shook.part.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import shook.shook.part.exception.PartCommentException;
import shook.shook.util.StringChecker;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Embeddable
public class PartCommentContent {

private static final int MAXIMUM_LENGTH = 200;

@Column(name = "content", length = 200, nullable = false)
private String value;

public PartCommentContent(final String value) {
validate(value);
this.value = value;
}

private void validate(final String value) {
if (StringChecker.isNullOrBlank(value)) {
throw new PartCommentException.NullOrEmptyPartCommentException();
}
if (value.length() > MAXIMUM_LENGTH) {
throw new PartCommentException.TooLongPartCommentException();
}
}
}
41 changes: 41 additions & 0 deletions backend/src/main/java/shook/shook/part/domain/PartComments.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package shook.shook.part.domain;

import jakarta.persistence.Embeddable;
import jakarta.persistence.OneToMany;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import shook.shook.part.exception.PartCommentException;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Embeddable
public class PartComments {

@OneToMany(mappedBy = "part")
private final List<PartComment> comments = new ArrayList<>();

public void addComment(final PartComment comment) {
validateComment(comment);
comments.add(comment);
}

private void validateComment(final PartComment comment) {
if (comments.contains(comment)) {
throw new PartCommentException.DuplicateCommentExistException();
}
}

public List<PartComment> getComments() {
return new ArrayList<>(comments);
}

public List<PartComment> getCommentsInRecentOrder() {
return comments.stream()
.sorted(Comparator.comparing(PartComment::getCreatedAt).reversed())
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package shook.shook.part.domain.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import shook.shook.part.domain.PartComment;

@Repository
public interface PartCommentRepository extends JpaRepository<PartComment, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package shook.shook.part.exception;

public class PartCommentException extends RuntimeException {

public static class NullOrEmptyPartCommentException extends PartCommentException {

public NullOrEmptyPartCommentException() {
super();
}
}

public static class TooLongPartCommentException extends PartCommentException {

public TooLongPartCommentException() {
super();
}
}

public static class CommentForOtherPartException extends PartCommentException {

public CommentForOtherPartException() {
super();
}
}

public static class DuplicateCommentExistException extends PartCommentException {

public DuplicateCommentExistException() {
super();
}
}
}
Loading

0 comments on commit 34a9f69

Please sign in to comment.