Skip to content

Commit

Permalink
feat/Ls-22: 회고 생성 API 구현 (#29)
Browse files Browse the repository at this point in the history
* chore: 엔티티 수정

* chore: 예약어 사용으로 인한 수정

* add: dto 추가

* feat: 회고 생성 로직 수정 및 구현

* chore: h2 설정을 위한 수정

* refactor: 리뷰 내용 반영

* chore: 내 회고폼 자동 추가로 변경

---------

Co-authored-by: Raymond <[email protected]>
  • Loading branch information
mikekks and raymondanythings authored Jul 14, 2024
1 parent 912dca4 commit 41435c8
Show file tree
Hide file tree
Showing 13 changed files with 100 additions and 41 deletions.
7 changes: 6 additions & 1 deletion layer-api/src/main/java/org/layer/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
Expand Down Expand Up @@ -50,8 +51,12 @@ private void setHttp(HttpSecurity http) throws Exception {
.requestMatchers(new AntPathRequestMatcher("/api/test")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/auth/oauth2/kakao")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/auth/test")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/h2-console/**")).permitAll()
.anyRequest().authenticated()
);
)
.headers(headers -> headers
.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)
);
}

// swagger
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
import java.util.List;

import org.layer.common.annotation.MemberId;
import org.layer.domain.retrospect.controller.dto.request.RetrospectCreateRequest;
import org.layer.domain.retrospect.controller.dto.response.RetrospectGetResponse;
import org.layer.domain.retrospect.controller.dto.response.RetrospectListGetResponse;
import org.layer.domain.retrospect.service.RetrospectService;
import org.layer.domain.retrospect.controller.dto.request.RetrospectCreateRequest;
import org.layer.domain.retrospect.service.dto.request.RetrospectCreateServiceRequest;
import org.layer.domain.retrospect.service.dto.response.RetrospectListGetServiceResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
Expand Down Expand Up @@ -35,8 +36,10 @@ public ResponseEntity<Void> createRetrospect(
@RequestBody @Valid RetrospectCreateRequest request,
@MemberId Long memberId) {

retrospectService.create(spaceId, request.formId(), request.title(), request.introduction());
return ResponseEntity.ok(null);
retrospectService.createRetrospect(
RetrospectCreateServiceRequest.of(request.title(), request.introduction(), spaceId, request.questions()), memberId);

return ResponseEntity.ok().build();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package org.layer.domain.retrospect.controller.dto.request;

import java.util.List;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

@Schema(name = "RetrospectCreateRequest", description = "회고 생성 요청 Dto")
public record RetrospectCreateRequest(
@Schema(description = "회고 폼 id", example = "1")
@NotNull
Long formId,
@Schema(description = "회고 제목", example = "중간 발표 이후 회고")
@Size(min = 3)
String title,
@Schema(description = "회고 한줄 설명", example = "우리만의 KPT 회고")
@NotNull
String introduction

String introduction,
@Schema(description = "회고 질문 목록(리스트)", example = "이번에 가장 어려웠던 점은 무엇인가요?")
@NotNull
@Size(min = 3, max = 15)
List<String> questions
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@

import org.layer.domain.answer.entity.Answers;
import org.layer.domain.answer.repository.AnswerRepository;
import org.layer.domain.form.entity.Form;
import org.layer.domain.form.repository.FormRepository;
import org.layer.domain.question.entity.Question;
import org.layer.domain.question.enums.QuestionOwner;
import org.layer.domain.question.enums.QuestionType;
import org.layer.domain.question.repository.QuestionRepository;
import org.layer.domain.retrospect.entity.Retrospect;
import org.layer.domain.retrospect.entity.RetrospectStatus;
import org.layer.domain.retrospect.repository.RetrospectRepository;
import org.layer.domain.retrospect.service.dto.request.RetrospectCreateServiceRequest;
import org.layer.domain.retrospect.service.dto.response.RetrospectGetServiceResponse;
import org.layer.domain.retrospect.service.dto.response.RetrospectListGetServiceResponse;
import org.layer.domain.space.entity.MemberSpaceRelation;
Expand All @@ -27,27 +34,45 @@ public class RetrospectService {

private final RetrospectRepository retrospectRepository;
private final MemberSpaceRelationRepository memberSpaceRelationRepository;
private final QuestionRepository questionRepository;
private final AnswerRepository answerRepository;
private final FormRepository formRepository;

@Transactional
public void create(Long spaceId, Long formId, String title, String introduction) {
Retrospect retrospect = Retrospect.builder()
.title(title)
.formId(formId)
.spaceId(spaceId)
.introduction(introduction)
public void createRetrospect(RetrospectCreateServiceRequest request, Long memberId) {
// 해당 스페이스 팀원인지 검증
validateTeamMember(request.spaceId(), memberId);

Retrospect retrospect = getRetrospect(request);
Retrospect savedRetrospect = retrospectRepository.save(retrospect);

List<Question> questions = request.questions().stream()
.map(q -> new Question(savedRetrospect.getId(), q, QuestionOwner.TEAM, QuestionType.PLAIN_TEXT))
.toList();
questionRepository.saveAll(questions);

// 내 회고 폼에 추가
Form form = new Form(memberId, request.title(), request.introduction());
Form savedForm = formRepository.save(form);

List<Question> myQuestions = request.questions().stream()
.map(q -> new Question(savedForm.getId(), q, QuestionOwner.INDIVIDUAL, QuestionType.PLAIN_TEXT))
.toList();
questionRepository.saveAll(myQuestions);
}

private Retrospect getRetrospect(RetrospectCreateServiceRequest request) {
return Retrospect.builder()
.title(request.title())
.spaceId(request.spaceId())
.introduction(request.introduction())
.retrospectStatus(RetrospectStatus.PROCEEDING)
.build();

retrospectRepository.save(retrospect);
}

public RetrospectListGetServiceResponse getRetrospects(Long spaceId, Long memberId) {
Optional<MemberSpaceRelation> team = memberSpaceRelationRepository.findBySpaceIdAndMemberId(
spaceId, memberId);
if (team.isEmpty()) { // 해당 멤버가 요청한 스페이스 소속 여부 확인
throw new MemberSpaceRelationException(NOT_FOUND_MEMBER_SPACE_RELATION);
}
// 해당 스페이스 팀원인지 검증
validateTeamMember(spaceId, memberId);

List<Retrospect> retrospects = retrospectRepository.findAllBySpaceId(spaceId);
List<Long> retrospectIds = retrospects.stream().map(Retrospect::getId).toList();
Expand All @@ -60,4 +85,12 @@ public RetrospectListGetServiceResponse getRetrospects(Long spaceId, Long member

return RetrospectListGetServiceResponse.of(retrospects.size(), retrospectDtos);
}

private void validateTeamMember(Long request, Long memberId) {
Optional<MemberSpaceRelation> team = memberSpaceRelationRepository.findBySpaceIdAndMemberId(
request, memberId);
if (team.isEmpty()) {
throw new MemberSpaceRelationException(NOT_FOUND_MEMBER_SPACE_RELATION);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@

public record RetrospectCreateServiceRequest(
String title,
String introduction,
Long spaceId,
List<String> questions,
boolean isMyForm
List<String> questions
) {
public static RetrospectCreateServiceRequest of(String title, String introduction, Long spaceId, List<String> questions) {

return new RetrospectCreateServiceRequest(title, introduction, spaceId, questions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,13 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Form extends BaseEntity {

@NotNull
private Long memberId;

@NotNull
private String title;

@Column(length = 10)
@ColumnDefault("1")
@Convert(converter = FormPublishedByConverter.class)
@NotNull
private FormPublishedBy formPublishedBy;

private String introduction;

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import org.layer.domain.question.entity.QuestionType;
import org.layer.domain.question.enums.QuestionType;

import java.util.stream.Stream;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import lombok.NoArgsConstructor;
import org.layer.domain.BaseEntity;
import org.layer.domain.question.converter.QuestionTypeConverter;
import org.layer.domain.question.enums.QuestionOwner;
import org.layer.domain.question.enums.QuestionType;
import org.layer.domain.questionOption.entity.QuestionOption;

import java.util.HashSet;
Expand All @@ -18,11 +20,15 @@
public class Question extends BaseEntity {

@NotNull
private Long formId;
private Long questionOwnerId;

@NotNull
private String content;

@NotNull
@Enumerated(EnumType.STRING)
private QuestionOwner questionOwner;

@Column(length = 20)
@NotNull
@Convert(converter = QuestionTypeConverter.class)
Expand All @@ -31,4 +37,10 @@ public class Question extends BaseEntity {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "question", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<QuestionOption> options = new HashSet<>();

public Question(Long questionOwnerId, String content, QuestionOwner questionOwner, QuestionType questionType) {
this.questionOwnerId = questionOwnerId;
this.content = content;
this.questionOwner = questionOwner;
this.questionType = questionType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.layer.domain.question.enums;

public enum QuestionOwner {
INDIVIDUAL, TEAM
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.layer.domain.question.entity;
package org.layer.domain.question.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@

@Entity
@Table(name = "question_option", uniqueConstraints = {
@UniqueConstraint(columnNames = {"question_id", "value"})
@UniqueConstraint(columnNames = {"question_id", "option_value"})
})
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class QuestionOption extends BaseEntity {

private String label;
private String optionLabel;

@NotNull
private String value;
private String optionValue;

@ManyToOne
@JoinColumn(name = "question_id")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ public class Retrospect extends BaseTimeEntity {
@NotNull
private Long spaceId;

@NotNull
private Long formId;

@NotNull
private String title;

Expand All @@ -39,9 +36,8 @@ public class Retrospect extends BaseTimeEntity {
private RetrospectStatus retrospectStatus;

@Builder
public Retrospect(Long spaceId, Long formId, String title, String introduction, RetrospectStatus retrospectStatus) {
public Retrospect(Long spaceId, String title, String introduction, RetrospectStatus retrospectStatus) {
this.spaceId = spaceId;
this.formId = formId;
this.title = title;
this.introduction = introduction;
this.retrospectStatus = retrospectStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.layer.domain.space.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import lombok.experimental.SuperBuilder;
Expand All @@ -15,9 +17,11 @@
public class Space extends BaseEntity {

@NotNull
@Enumerated(EnumType.STRING)
private SpaceCategory category;

@NotNull
@Enumerated(EnumType.STRING)
private SpaceField field;

@NotNull
Expand Down

0 comments on commit 41435c8

Please sign in to comment.