Skip to content

Commit

Permalink
Merge pull request #26 from nunsongCookie/main
Browse files Browse the repository at this point in the history
Feat: CI/CD 배포 테스트를 위한 머지 요청
  • Loading branch information
Jixoo-IT authored Dec 26, 2024
2 parents 2aa20bb + f0ae9fe commit 5a7840d
Show file tree
Hide file tree
Showing 51 changed files with 1,208 additions and 18 deletions.
9 changes: 0 additions & 9 deletions .github/ISSUE_TEMPLATE/PULL_REQUEST_TEMPLATE.md

This file was deleted.

23 changes: 23 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## 📌연관 이슈
<!-- #Issue_number -->

## ✨작업 내용
<!-- 작업 코드 내용 -->

## PR 유형

- [ ] 새로운 기능 추가
- [ ] 버그 수정
- [ ] CSS 등 사용자 UI 디자인 변경
- [ ] 코드에 영향을 주지 않는 변경사항(오타 수정, 탭 사이즈 변경, 변수명 변경)
- [ ] 코드 리팩토링
- [ ] 주석 추가 및 수정
- [ ] 문서 수정
- [ ] 테스트 추가, 테스트 리팩토링
- [ ] 빌드 부분 혹은 패키지 매니저 수정
- [ ] 파일 혹은 폴더명 수정
- [ ] 파일 혹은 폴더 삭제

## 스크린샷 (선택)

## 📑비고
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ out/

### VS Code ###
.vscode/

### ENV ###
/src/main/resources/properties/env.properties
10 changes: 6 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ repositories {
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/site/examready2025/quiz/config/EnvConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package site.examready2025.quiz.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource("classpath:properties/env.properties")
public class EnvConfig {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package site.examready2025.quiz.domain.answer.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import site.examready2025.quiz.domain.answer.dto.AnswerBatchRequestDto;
import site.examready2025.quiz.domain.answer.dto.AnswerRequestDto;
import site.examready2025.quiz.domain.answer.service.AnswerService;

import java.util.List;

@RestController
@RequiredArgsConstructor
@CrossOrigin(origins = "http://localhost:5173")
public class AnswerController {

private final AnswerService answerService;

// @PostMapping("/api/answers")
// public ResponseEntity<String> saveAnswers(@RequestBody AnswerBatchRequestDto requestDto){
// answerService.saveAnswers(requestDto.getResponseId(), requestDto.getAnswers());
// return ResponseEntity.status(HttpStatus.CREATED).body("답변 저장 완료");
// }

@PostMapping("/api/answers")
public ResponseEntity<String> saveAnswers(@RequestBody AnswerBatchRequestDto requestDto){
answerService.saveAnswers(requestDto.getResponseId(), requestDto.getQuizId(), requestDto.getAnswers());

return ResponseEntity.status(HttpStatus.CREATED).body("답변 저장 완료");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package site.examready2025.quiz.domain.answer.dto;

import lombok.Getter;

import java.util.List;

@Getter
public class AnswerBatchRequestDto {
private Long responseId;
private Long quizId;
private List<AnswerRequestDto> answers;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package site.examready2025.quiz.domain.answer.dto;

import lombok.Getter;

@Getter
public class AnswerRequestDto {

private Long questionId;
private Long selectedChoiceId;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package site.examready2025.quiz.domain.answer.entity;

import jakarta.persistence.*;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import site.examready2025.quiz.domain.choice.entity.Choice;
import site.examready2025.quiz.domain.question.entity.Question;
import site.examready2025.quiz.domain.response.entity.Response;

@Entity
@Getter
@NoArgsConstructor
@Table(name = "answer")
public class Answer {

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

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "response_id", nullable = false)
private Response response;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "question_id", nullable = false)
private Question question;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "selected_option_id", nullable = false)
private Choice selectedChoice;

@Builder
public Answer(Response response, Question question, Choice selectedChoice) {
this.response = response;
this.question = question;
this.selectedChoice = selectedChoice;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package site.examready2025.quiz.domain.answer.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import site.examready2025.quiz.domain.answer.entity.Answer;

import java.util.List;

public interface AnswerRepository extends JpaRepository<Answer, Long> {
List<Answer> findByResponseId(Long responseId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package site.examready2025.quiz.domain.answer.service;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import site.examready2025.quiz.domain.answer.dto.AnswerRequestDto;
import site.examready2025.quiz.domain.answer.entity.Answer;
import site.examready2025.quiz.domain.answer.repository.AnswerRepository;
import site.examready2025.quiz.domain.choice.entity.Choice;
import site.examready2025.quiz.domain.choice.repository.ChoiceRepository;
import site.examready2025.quiz.domain.question.repository.QuestionRepository;
import site.examready2025.quiz.domain.response.entity.Response;
import site.examready2025.quiz.domain.response.repository.ResponseRepository;

import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional
public class AnswerService {

private final AnswerRepository answerRepository;
private final ResponseRepository responseRepository;
private final QuestionRepository questionRepository;
private final ChoiceRepository choiceRepository;


public void saveAnswers(Long responseId, Long quizId, List<AnswerRequestDto> answerRequestDtos){
Response response = responseRepository.findById(responseId).orElseThrow(()-> new IllegalArgumentException("해당 퀴즈 세션을 찾을 수 없습니다."));

for(AnswerRequestDto dto : answerRequestDtos){
// quizId, questionId, selectedChoiceId로 Choice를 검색
Choice choice= choiceRepository.findByQuizIdAndQuestionIdAndId(quizId, dto.getQuestionId(), dto.getSelectedChoiceId())
.orElseThrow(()-> new IllegalArgumentException("quizId로 Choice를 찾을 수 없습니다."));

Answer answer = Answer.builder()
.response(response)
.question(choice.getQuestion())
.selectedChoice(choice)
.build();
answerRepository.save(answer);
}
}

// public void saveAnswers(Long responseId, List<AnswerRequestDto> answerRequestDtos){
//
// for(AnswerRequestDto dto : answerRequestDtos){
// Response response = responseRepository.findById(responseId).orElseThrow(()-> new IllegalArgumentException("해당 퀴즈 세션을 찾을 수 없습니다. response id : "+responseId));
// Question question = questionRepository.findById(dto.getQuestionId())
// .orElseThrow(()-> new IllegalArgumentException("해당 질문을 찾을 수 없습니다. 질문 id : "+ dto.getQuestionId()));
//
// Choice choice = choiceRepository.findById(dto.getSelectedChoiceId()).orElseThrow(()-> new IllegalArgumentException("해당 보기를 찾을 수 없습니다. 보기 id : "+dto.getSelectedChoiceId()));
//
// Answer answer = Answer.builder()
// .response(response)
// .question(question)
// .selectedChoice(choice)
// .build();
// answerRepository.save(answer);
// }
// }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package site.examready2025.quiz.domain.choice.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import site.examready2025.quiz.domain.choice.dto.ChoiceBatchRequestDto;
import site.examready2025.quiz.domain.choice.dto.ChoiceRequestDto;
import site.examready2025.quiz.domain.choice.dto.ChoiceResponseDto;
import site.examready2025.quiz.domain.choice.service.ChoiceService;

import java.util.List;

@RestController
@RequiredArgsConstructor
@CrossOrigin(origins = "http://localhost:5173")
public class ChoiceController {

private final ChoiceService choiceService;

// @PostMapping("/api/choices")
// public ResponseEntity<String> addChoices(@RequestBody List<ChoiceRequestDto> choiceRequestDtos){
// choiceService.addChoices(choiceRequestDtos);
// return ResponseEntity.status(HttpStatus.CREATED).body("보기 저장 완료");
// }

@PostMapping("/api/choices")
public ResponseEntity<String> addChoices(@RequestBody ChoiceBatchRequestDto choiceBatchRequestDto){
choiceService.addChoices(choiceBatchRequestDto.getQuizId(), choiceBatchRequestDto.getChoices());
return ResponseEntity.status(HttpStatus.CREATED).body("보기 저장 완료");
}

// 특정 퀴즈 속한 choice 반환
@GetMapping("/api/choices/{quizId}")
public ResponseEntity<List<ChoiceResponseDto>> getChoicesByQuiz(@PathVariable("quizId") Long quizId){
List<ChoiceResponseDto> choices = choiceService.getChoicesByQuiz(quizId);
return ResponseEntity.ok(choices);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package site.examready2025.quiz.domain.choice.dto;

import lombok.Getter;

import java.util.List;

@Getter
public class ChoiceBatchRequestDto {

private Long quizId;
private List<ChoiceRequestDto> choices;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package site.examready2025.quiz.domain.choice.dto;

import lombok.Getter;

import java.util.List;

@Getter
public class ChoiceRequestDto {

private Long questionId;
private String correctAnswer;
private List<String> wrongAnswers;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package site.examready2025.quiz.domain.choice.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class ChoiceResponseDto {

private Long id;
private Long questionId;
private String answer;
private boolean isCorrect;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package site.examready2025.quiz.domain.choice.entity;

import jakarta.persistence.*;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import site.examready2025.quiz.domain.question.entity.Question;
import site.examready2025.quiz.domain.quiz.entity.Quiz;

@Entity
@Getter
@NoArgsConstructor
@Table(name = "choice")
public class Choice {

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

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "quiz_id", nullable = false)
private Quiz quiz;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "question_id", nullable = false)
private Question question;

@Column(nullable = false, length = 50)
private String answer;

@Column(nullable = false)
private boolean isCorrect;

@Builder
public Choice(Quiz quiz, Question question, String answer, boolean isCorrect) {
this.quiz = quiz;
this.question = question;
this.answer = answer;
this.isCorrect = isCorrect;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package site.examready2025.quiz.domain.choice.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import site.examready2025.quiz.domain.choice.entity.Choice;

import java.util.List;
import java.util.Optional;

@Repository
public interface ChoiceRepository extends JpaRepository<Choice, Long> {

//@Query("SELECT c FROM Choice c WHERE c.quiz.id = :quizId AND c.question.id = :questionId AND c.id = :choiceId")
Optional<Choice> findByQuizIdAndQuestionIdAndId(Long quizId, Long questionId, Long choiceId);

List<Choice> findByQuizId(Long quizId);
}
Loading

0 comments on commit 5a7840d

Please sign in to comment.