Skip to content

Commit

Permalink
Merge pull request #59 from Cafegory/feature-58
Browse files Browse the repository at this point in the history
[BUILD SUCCESS] [BUILD SUCCESS] [BUILD FAIL] [BUILD FAIL] 카공 Q&A 질문 생성,수정,삭제 기능구현
  • Loading branch information
donghyun0304 authored Mar 24, 2024
2 parents 848233b + 6562dac commit 6e5f2d5
Show file tree
Hide file tree
Showing 19 changed files with 634 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/main/java/com/example/demo/config/MapperConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import com.example.demo.mapper.BusinessHourMapper;
import com.example.demo.mapper.CafeMapper;
import com.example.demo.mapper.MemberMapper;
import com.example.demo.mapper.ReviewMapper;
import com.example.demo.mapper.SnsDetailMapper;
import com.example.demo.mapper.StudyMemberMapper;
Expand Down Expand Up @@ -38,6 +39,11 @@ public StudyOnceMapper studyOnceMapper() {
return new StudyOnceMapper();
}

@Bean
public MemberMapper memberMapper() {
return new MemberMapper();
}

@Bean
public StudyMemberMapper studyMemberMapper() {
return new StudyMemberMapper();
Expand Down
42 changes: 40 additions & 2 deletions src/main/java/com/example/demo/controller/StudyOnceController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.time.LocalDateTime;

import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
Expand All @@ -22,13 +23,17 @@
import com.example.demo.dto.StudyMembersResponse;
import com.example.demo.dto.StudyOnceCreateRequest;
import com.example.demo.dto.StudyOnceJoinResult;
import com.example.demo.dto.StudyOnceQuestionRequest;
import com.example.demo.dto.StudyOnceQuestionResponse;
import com.example.demo.dto.StudyOnceQuestionUpdateRequest;
import com.example.demo.dto.StudyOnceSearchRequest;
import com.example.demo.dto.StudyOnceSearchResponse;
import com.example.demo.dto.UpdateAttendanceRequest;
import com.example.demo.dto.UpdateAttendanceResponse;
import com.example.demo.exception.CafegoryException;
import com.example.demo.repository.StudyOnceRepository;
import com.example.demo.service.CafeQueryService;
import com.example.demo.service.StudyOnceQAndAQueryService;
import com.example.demo.service.StudyOnceQuestionService;
import com.example.demo.service.StudyOnceService;

import lombok.RequiredArgsConstructor;
Expand All @@ -40,7 +45,8 @@ public class StudyOnceController {
private final StudyOnceService studyOnceService;
private final CafegoryTokenManager cafegoryTokenManager;
private final CafeQueryService cafeQueryService;
private final StudyOnceRepository studyOnceRepository;
private final StudyOnceQuestionService studyOnceQuestionService;
private final StudyOnceQAndAQueryService studyOnceQAndAQueryService;

@GetMapping("/{studyOnceId:[0-9]+}")
public ResponseEntity<StudyOnceSearchResponse> search(@PathVariable Long studyOnceId) {
Expand Down Expand Up @@ -112,4 +118,36 @@ public ResponseEntity<StudyMembersResponse> findStudyMemberList(@PathVariable Lo
return ResponseEntity.ok(response);
}

@PostMapping("/{studyOnceId:[0-9]+}/question")
public ResponseEntity<StudyOnceQuestionResponse> saveQuestion(@PathVariable Long studyOnceId,
@RequestHeader("Authorization") String authorization,
@RequestBody @Validated StudyOnceQuestionRequest request) {
long memberId = cafegoryTokenManager.getIdentityId(authorization);
Long savedQuestionId = studyOnceQuestionService.saveQuestion(memberId, studyOnceId, request);
StudyOnceQuestionResponse response = studyOnceQAndAQueryService.searchQuestion(
savedQuestionId);
return ResponseEntity.ok(response);
}

@PatchMapping("/question/{questionId:[0-9]+}")
public ResponseEntity<StudyOnceQuestionResponse> updateQuestion(@PathVariable final Long questionId,
@RequestHeader("Authorization") String authorization,
@RequestBody @Validated StudyOnceQuestionUpdateRequest request) {
long memberId = cafegoryTokenManager.getIdentityId(authorization);
studyOnceQuestionService.updateQuestion(memberId, questionId, request);
StudyOnceQuestionResponse response = studyOnceQAndAQueryService.searchQuestion(questionId);
return ResponseEntity.ok(response);
}

@DeleteMapping("/question/{questionId:[0-9]+}")
public ResponseEntity<StudyOnceQuestionResponse> deleteQuestion(@PathVariable final Long questionId,
@RequestHeader("Authorization") String authorization) {
long memberId = cafegoryTokenManager.getIdentityId(authorization);
if (!studyOnceQuestionService.isPersonWhoAskedQuestion(memberId, questionId)) {
throw new CafegoryException(STUDY_ONCE_QUESTION_PERMISSION_DENIED);
}
StudyOnceQuestionResponse response = studyOnceQAndAQueryService.searchQuestion(questionId);
studyOnceQuestionService.deleteQuestion(questionId);
return ResponseEntity.ok(response);
}
}
59 changes: 59 additions & 0 deletions src/main/java/com/example/demo/domain/StudyOnceQuestion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.example.demo.domain;

import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Table(name = "study_once_question")
public class StudyOnceQuestion extends BaseEntity {

@Id
@GeneratedValue
@Column(name = "study_once_question_id")
private Long id;

private String content;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private MemberImpl member;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "study_once_id", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private StudyOnceImpl studyOnce;

@Builder
private StudyOnceQuestion(Long id, String content, MemberImpl member, StudyOnceImpl studyOnce) {
//todo content에 대한 검증 추가
this.id = id;
this.content = content;
this.member = member;
this.studyOnce = studyOnce;
}

public void changeContent(String content) {
//todo content 에 대한 검증 추가
this.content = content;
}

public boolean isPersonAsked(MemberImpl member) {
return this.member.getId().equals(member.getId());
}

}
19 changes: 19 additions & 0 deletions src/main/java/com/example/demo/dto/StudyOnceQuestionRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example.demo.dto;

import javax.validation.constraints.NotBlank;

import lombok.Getter;

@Getter
public class StudyOnceQuestionRequest {

@NotBlank
private String content;

public StudyOnceQuestionRequest() {
}

public StudyOnceQuestionRequest(String content) {
this.content = content;
}
}
13 changes: 13 additions & 0 deletions src/main/java/com/example/demo/dto/StudyOnceQuestionResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.demo.dto;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public class StudyOnceQuestionResponse {

private final Long questionId;
private final String content;
private final WriterResponse writer;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example.demo.dto;

import javax.validation.constraints.NotBlank;

import lombok.Getter;

@Getter
public class StudyOnceQuestionUpdateRequest {

@NotBlank
private String content;

public StudyOnceQuestionUpdateRequest() {
}

public StudyOnceQuestionUpdateRequest(String content) {
this.content = content;
}
}
2 changes: 2 additions & 0 deletions src/main/java/com/example/demo/exception/ExceptionType.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public enum ExceptionType {
STUDY_ONCE_LOCATION_CHANGE_PERMISSION_DENIED(FORBIDDEN, "스터디 리더만 장소 변경을 할 권한이 있습니다."),
STUDY_ONCE_EARLY_TAKE_ATTENDANCE(BAD_REQUEST, "스터디 출석체크는 스터디 시작 10분 이후여야 합니다."),
STUDY_ONCE_LATE_TAKE_ATTENDANCE(BAD_REQUEST, "스터디 출석체크는 스터디 진행시간 절반이 지나기전에만 변경할 수 있습니다. "),
STUDY_ONCE_QUESTION_NOT_FOUND(NOT_FOUND, "없는 카공 질문입니다."),
STUDY_ONCE_QUESTION_PERMISSION_DENIED(FORBIDDEN, "질문을 작성한 회원 본인만 수정 할 권한이 있습니다."),
MEMBER_NOT_FOUND(NOT_FOUND, "없는 회원입니다."),
REVIEW_NOT_FOUND(NOT_FOUND, "없는 리뷰입니다."),
REVIEW_OVER_CONTENT_SIZE(BAD_REQUEST, "리뷰 글자수가 최대 글자수 이하여야 합니다."),
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/example/demo/mapper/MemberMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.demo.mapper;

import com.example.demo.domain.MemberImpl;
import com.example.demo.dto.WriterResponse;

public class MemberMapper {

public WriterResponse toWriterResponse(MemberImpl member) {
return new WriterResponse(member.getId(), member.getName(), member.getThumbnailImage().getThumbnailImage());
}
}
8 changes: 8 additions & 0 deletions src/main/java/com/example/demo/mapper/StudyOnceMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
import com.example.demo.domain.CafeImpl;
import com.example.demo.domain.MemberImpl;
import com.example.demo.domain.StudyOnceImpl;
import com.example.demo.domain.StudyOnceQuestion;
import com.example.demo.dto.StudyOnceCreateRequest;
import com.example.demo.dto.StudyOnceForCafeResponse;
import com.example.demo.dto.StudyOnceQuestionResponse;
import com.example.demo.dto.StudyOnceSearchResponse;
import com.example.demo.dto.WriterResponse;

public class StudyOnceMapper {

Expand Down Expand Up @@ -59,4 +62,9 @@ public StudyOnceSearchResponse toStudyOnceSearchResponse(StudyOnceImpl saved, bo
.build();
}

public StudyOnceQuestionResponse toStudyOnceQuestionResponse(StudyOnceQuestion question,
WriterResponse writerResponse) {
return new StudyOnceQuestionResponse(question.getId(), question.getContent(), writerResponse);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.demo.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.example.demo.domain.StudyOnceQuestion;

public interface StudyOnceQuestionRepository extends JpaRepository<StudyOnceQuestion, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.demo.service;

import com.example.demo.dto.StudyOnceQuestionResponse;

public interface StudyOnceQAndAQueryService {

StudyOnceQuestionResponse searchQuestion(Long studyOnceQuestionId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.example.demo.service;

import static com.example.demo.exception.ExceptionType.*;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.domain.StudyOnceQuestion;
import com.example.demo.dto.StudyOnceQuestionResponse;
import com.example.demo.dto.WriterResponse;
import com.example.demo.exception.CafegoryException;
import com.example.demo.mapper.MemberMapper;
import com.example.demo.mapper.StudyOnceMapper;
import com.example.demo.repository.StudyOnceQuestionRepository;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class StudyOnceQAndAQueryServiceImpl implements StudyOnceQAndAQueryService {

private final StudyOnceQuestionRepository studyOnceQuestionRepository;
private final MemberMapper memberMapper;
private final StudyOnceMapper studyOnceMapper;

@Override
public StudyOnceQuestionResponse searchQuestion(Long studyOnceQuestionId) {
StudyOnceQuestion question = findStudyOnceQuestionById(studyOnceQuestionId);
WriterResponse writerResponse = memberMapper.toWriterResponse(question.getMember());
return studyOnceMapper.toStudyOnceQuestionResponse(question, writerResponse);
}

private StudyOnceQuestion findStudyOnceQuestionById(Long studyOnceQuestionId) {
return studyOnceQuestionRepository.findById(studyOnceQuestionId)
.orElseThrow(() -> new CafegoryException(STUDY_ONCE_QUESTION_NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.demo.service;

import com.example.demo.dto.StudyOnceQuestionRequest;
import com.example.demo.dto.StudyOnceQuestionUpdateRequest;

public interface StudyOnceQuestionService {

Long saveQuestion(Long memberId, Long studyOnceId, StudyOnceQuestionRequest request);

void updateQuestion(Long memberId, Long studyOnceQuestionId, StudyOnceQuestionUpdateRequest request);

void deleteQuestion(Long studyOnceQuestionId);

boolean isPersonWhoAskedQuestion(Long memberId, Long studyOnceQuestionId);
}
Loading

0 comments on commit 6e5f2d5

Please sign in to comment.