Skip to content

Commit

Permalink
Merge pull request #559 from SWM-NM/feat/#545
Browse files Browse the repository at this point in the history
[REFACTOR] 코드를 수정할 때 입력한 코드를 저장하는 API 추가 및 스웨거 설명 추가
  • Loading branch information
miiiinju1 authored Nov 2, 2023
2 parents e2258b7 + 96aaa5c commit d6410e5
Show file tree
Hide file tree
Showing 23 changed files with 239 additions and 81 deletions.
16 changes: 13 additions & 3 deletions src/main/java/swm_nm/morandi/config/swagger/SwaggerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public Docket memberApi() {
.build()
.apiInfo(apiInfo());
}

@Bean
public Docket testDuringApi() {
return new Docket(DocumentationType.OAS_30)
Expand All @@ -44,7 +43,6 @@ public Docket testDuringApi() {
.build()
.apiInfo(apiInfo());
}

@Bean
public Docket testExitApi() {
return new Docket(DocumentationType.OAS_30)
Expand All @@ -57,7 +55,6 @@ public Docket testExitApi() {
.build()
.apiInfo(apiInfo());
}

@Bean
public Docket testInfoApi() {
return new Docket(DocumentationType.OAS_30)
Expand Down Expand Up @@ -106,6 +103,19 @@ public Docket codeSubmitApi() {
.build()
.apiInfo(apiInfo());
}

@Bean
public Docket practiceProblemApi() {
return new Docket(DocumentationType.OAS_30)
.servers(serverLocal, testServer)
.groupName("practice-api")
.useDefaultResponseMessages(false)
.select()
.apis(RequestHandlerSelectors.basePackage("swm_nm.morandi.domain.practice.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Practice Swagger")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ private void saveSubmitTempCode(SubmitCodeDto submitCodeDto)
{
String ongoingTestKey = redisKeyGenerator.generateOngoingTestKey();
Long testId = ((TestInfo) Optional.ofNullable(redisTemplate.opsForValue().get(ongoingTestKey))
.orElseThrow(() -> new MorandiException(SubmitErrorCode.TEST_NOT_EXIST))).testId;
.orElseThrow(() -> new MorandiException(SubmitErrorCode.TEST_NOT_EXIST))).getTestId();

tempCodeService.saveTempCode(testId, submitCodeDto.getProblemNumber(), submitCodeDto.getLanguage(), submitCodeDto.getSourceCode());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,49 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import swm_nm.morandi.domain.practice.dto.PracticeExitDto;
import swm_nm.morandi.domain.practice.dto.PracticeIdDto;
import swm_nm.morandi.domain.practice.dto.PracticeResultDto;
import swm_nm.morandi.domain.practice.dto.PracticeStartDto;
import swm_nm.morandi.domain.practice.dto.PracticeStartResponseDto;
import swm_nm.morandi.domain.practice.service.PracticeProblemService;
import swm_nm.morandi.domain.testDuring.dto.InputData;
import swm_nm.morandi.domain.testDuring.dto.OutputDto;
import swm_nm.morandi.domain.testDuring.dto.TestCaseInputData;
import swm_nm.morandi.domain.testDuring.service.RunCodeService;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/practices")
public class PracticeController {

private final PracticeProblemService practiceProblemService;

private final RunCodeService runCodeService;
@PostMapping
@Operation(summary = "연습 문제 시작하기", description = "사용자가 임의로 백준 문제 번호를 골라서 문제를 풀려고 시도할 때 테이블을 구성합니다.")
public ResponseEntity<PracticeIdDto> practiceStart(@RequestBody PracticeStartDto practiceStartDto) {
PracticeIdDto practiceIdDto = practiceProblemService.savePraticeProblems(practiceStartDto.getBojProblemId());
return new ResponseEntity(practiceIdDto, HttpStatus.OK);
public ResponseEntity<PracticeStartResponseDto> practiceStart(@RequestBody PracticeStartDto practiceStartDto) {
PracticeStartResponseDto practiceStartResponseDto = practiceProblemService.startPractices(practiceStartDto.getBojProblemId());
return new ResponseEntity(practiceStartResponseDto, HttpStatus.OK);
}
@PostMapping("/exit")
@Operation(summary = "연습 문제 종료하기", description = "사용자가 시도한 연습문제를 종료할 경우 결과 데이터를 반환합니다.")
public ResponseEntity<PracticeResultDto> practiceExit(@RequestBody PracticeExitDto practiceExitDto) {
PracticeResultDto practiceResultDto = practiceProblemService.practiceResult(practiceExitDto.getPracticeProblemId());
return new ResponseEntity<>(practiceResultDto, HttpStatus.OK);
}

@PostMapping("/output")
@Operation(summary = "연습문제 코드 실행 결과값 반환", description = "사용자가 특정 코드를 실행할 경우 결과값을 제공합니다. " +
"입력 데이터는 practiceProblemId, language, code, input으로 구성됩니다." )
public ResponseEntity<OutputDto> getOutputResult(@RequestBody InputData inputData) throws Exception {
return new ResponseEntity<>(runCodeService.runCode(inputData), HttpStatus.OK);
}

@PostMapping("/tc-output")
@Operation(summary = "테스트케이스 실행 결과값 반환", description = "사용자가 특정 코드를 실행할 경우 결과값을 제공합니다. " +
"입력 데이터는 practiceProblemId, language, code, input, output으로 구성됩니다.")
public ResponseEntity<List<OutputDto>> getTestCaseOutputResult(@RequestBody TestCaseInputData testCaseInputData) throws Exception {
return new ResponseEntity<>(runCodeService.runTestCaseCode(testCaseInputData), HttpStatus.OK);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package swm_nm.morandi.domain.practice.dto;

import lombok.*;

@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PracticeProblemCode {
private String pythonCode;
private String cppCode;
private String javaCode;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package swm_nm.morandi.domain.practice.dto;

import lombok.*;

@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PracticeProblemInfo {
private Long practiceProblemId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,9 @@ public class PracticeResultDto {
private String solvedTime;

public static PracticeResultDto getPracticeResultDto(PracticeProblem practiceProblem) {
Long practiceProblemSolvedTime = practiceProblem.getSolvedTime();
String solvedTime = (practiceProblemSolvedTime == null) ?
null : String.format("%d:%02d", practiceProblemSolvedTime / 60, practiceProblemSolvedTime % 60);
PracticeResultDto practiceResultDto = PracticeResultDto.builder()
.practiceDate(practiceProblem.getPracticeDate())
.isSolved(practiceProblem.getIsSolved())
.solvedTime(solvedTime)
.build();

return practiceResultDto;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package swm_nm.morandi.domain.practice.dto;

import lombok.*;
import swm_nm.morandi.domain.testDuring.dto.PracticeProblemCodeDto;

@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PracticeStartResponseDto {
private Long practiceProblemId;
private String pythonCode;
private String javaCode;
private String cppCode;
public static PracticeStartResponseDto getPracticeStartResponseDto
(Long practiceProblemId, PracticeProblemCodeDto practiceProblemCodeDto) {
return PracticeStartResponseDto.builder()
.practiceProblemId(practiceProblemId)
.pythonCode(practiceProblemCodeDto.getPythonCode())
.javaCode(practiceProblemCodeDto.getJavaCode())
.cppCode(practiceProblemCodeDto.getCppCode())
.build();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
import lombok.*;
import swm_nm.morandi.domain.common.BaseEntity;
import swm_nm.morandi.domain.member.entity.Member;
import swm_nm.morandi.domain.practice.dto.PracticeStatus;
import swm_nm.morandi.domain.problem.entity.Problem;

import javax.persistence.*;
import java.time.LocalDate;
import java.time.LocalDateTime;

@Entity
@Getter @Setter
Expand All @@ -24,8 +22,6 @@ public class PracticeProblem extends BaseEntity {

private Boolean isSolved;

private Long solvedTime;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PROBLEM_ID")
private Problem problem;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package swm_nm.morandi.domain.practice.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import swm_nm.morandi.domain.practice.dto.PracticeProblemInfo;
import swm_nm.morandi.domain.practice.entity.PracticeProblem;
import swm_nm.morandi.domain.practice.repository.PracticeProblemRepository;
import swm_nm.morandi.global.exception.MorandiException;
import swm_nm.morandi.global.exception.errorcode.PracticeProblemErrorCode;
import swm_nm.morandi.redis.utils.RedisKeyGenerator;

@Service
@RequiredArgsConstructor
@Slf4j
public class PracticeCheckService {

private final RedisKeyGenerator redisKeyGenerator;

private final RedisTemplate<String, Object> redisTemplate;
public PracticeProblemInfo getPracticeProblemInfo(Long bojProblemId) {
String ongoingPracticeProblemKey = redisKeyGenerator.generateOngoingPracticeProblemKey(bojProblemId);
PracticeProblemInfo practiceProblemInfo
= (PracticeProblemInfo) redisTemplate.opsForValue().get(ongoingPracticeProblemKey);
return practiceProblemInfo;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
import org.springframework.stereotype.Service;
import swm_nm.morandi.domain.member.entity.Member;
import swm_nm.morandi.domain.member.repository.MemberRepository;
import swm_nm.morandi.domain.practice.dto.PracticeIdDto;
import swm_nm.morandi.domain.practice.dto.PracticeProblemInfo;
import swm_nm.morandi.domain.practice.dto.PracticeStartResponseDto;
import swm_nm.morandi.domain.practice.dto.PracticeResultDto;
import swm_nm.morandi.domain.practice.entity.PracticeProblem;
import swm_nm.morandi.domain.practice.repository.PracticeProblemRepository;
import swm_nm.morandi.domain.problem.entity.Problem;
import swm_nm.morandi.domain.problem.repository.ProblemRepository;
import swm_nm.morandi.domain.testDuring.dto.PracticeProblemCodeDto;
import swm_nm.morandi.domain.testDuring.service.TempCodeService;
import swm_nm.morandi.domain.testStart.service.TempCodeInitializer;
import swm_nm.morandi.global.exception.MorandiException;
import swm_nm.morandi.global.exception.errorcode.MemberErrorCode;
import swm_nm.morandi.global.exception.errorcode.PracticeProblemErrorCode;
Expand All @@ -25,37 +29,53 @@
@Slf4j
public class PracticeProblemService {

private final PracticeCheckService practiceCheckService;

private final TempCodeInitializer tempCodeInitializer;

private final TempCodeService tempCodeService;

private final ProblemRepository problemRepository;

private final MemberRepository memberRepository;

private final PracticeProblemRepository practiceProblemRepository;

public PracticeIdDto savePraticeProblems(Long bojProblemId) {
public PracticeStartResponseDto startPractices(Long bojProblemId) {
Long memberId = SecurityUtils.getCurrentMemberId();
Member member = memberRepository.findById(memberId).orElseThrow(
() -> new MorandiException(MemberErrorCode.MEMBER_NOT_FOUND));

Optional<PracticeProblem> optionalPracticeProblem = practiceProblemRepository.
findByMember_MemberIdAndProblem_BojProblemId(memberId, bojProblemId);
PracticeProblemInfo practiceProblemInfo = practiceCheckService.getPracticeProblemInfo(bojProblemId);

if (optionalPracticeProblem.isPresent()) {
PracticeProblem practiceProblem = optionalPracticeProblem.get();
return PracticeIdDto.getPracticeIdDto(practiceProblem.getPracticeProblemId());
if (practiceProblemInfo != null) {
return getPracticeStartResponseDto(practiceProblemInfo.getPracticeProblemId());
}

Problem problem = problemRepository.findProblemByBojProblemId(bojProblemId).orElseThrow(
() -> new MorandiException(ProblemErrorCode.PROBLEM_NOT_FOUND));

PracticeProblem addPracticeProblem = PracticeProblem.builder()
PracticeProblem practiceProblem = PracticeProblem.builder()
.isSolved(false)
.practiceDate(LocalDate.now())
.problem(problem)
.member(member)
.build();

PracticeProblem savedPracticeProblem = practiceProblemRepository.save(addPracticeProblem);
return PracticeIdDto.getPracticeIdDto(savedPracticeProblem.getPracticeProblemId());
PracticeProblem savedPracticeProblem = practiceProblemRepository.save(practiceProblem);

tempCodeInitializer.initializePracticeTempCodeCache(savedPracticeProblem);

return getPracticeStartResponseDto(savedPracticeProblem.getPracticeProblemId());
}

private PracticeStartResponseDto getPracticeStartResponseDto(Long practiceProblemId) {
PracticeProblemCodeDto practiceProblemCodeDto = getPracticeProblemCodeDto(practiceProblemId);
PracticeStartResponseDto practiceStartResponseDto = PracticeStartResponseDto.getPracticeStartResponseDto(practiceProblemId,
practiceProblemCodeDto);
return practiceStartResponseDto;
}
private PracticeProblemCodeDto getPracticeProblemCodeDto(Long practiceProblemId) {
return tempCodeService.getPracticeProblemTempCode(practiceProblemId);
}

public PracticeResultDto practiceResult(Long practiceProblemId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
import org.springframework.web.bind.annotation.*;
import swm_nm.morandi.domain.testDuring.dto.*;
import swm_nm.morandi.domain.testExit.dto.AttemptProblemDto;

import swm_nm.morandi.domain.testDuring.service.RunCodeService;
import swm_nm.morandi.domain.testDuring.service.TempCodeService;
import swm_nm.morandi.domain.testDuring.service.SolvedCheckService;

import java.util.List;
Expand All @@ -26,16 +24,18 @@ public class TestDuringController {
private final SolvedCheckService solvedCheckService;

@PostMapping("/output")
@Operation(summary = "코드 실행 결과값 반환", description = "사용자가 특정 코드를 실행할 경우 결과값을 제공합니다.")
@Operation(summary = "코드 실행 결과값 반환", description = "사용자가 특정 코드를 실행할 경우 결과값을 제공합니다. " +
"입력 데이터는 testId, problemNumber, language, code, input으로 구성됩니다.")
public ResponseEntity<OutputDto> getOutputResult
(@RequestBody InputData inputData) throws Exception {
return new ResponseEntity<>(runCodeService.runCode(inputData), HttpStatus.OK);
}
@PostMapping("/tc-output")
@Operation(summary = "테스트케이스 실행 결과값 반환", description = "사용자가 특정 코드를 실행할 경우 결과값을 제공합니다.")
@Operation(summary = "테스트케이스 실행 결과값 반환", description = "사용자가 특정 코드를 실행할 경우 결과값을 제공합니다. " +
"입력 데이터는 testId, problemNumber, language, code, input, output으로 구성됩니다.")
public ResponseEntity<List<OutputDto>> getTestCaseOutputResult
(@RequestBody TestInputData testInputData) throws Exception {
return new ResponseEntity<>(runCodeService.runTestCaseCode(testInputData), HttpStatus.OK);
(@RequestBody TestCaseInputData testCaseInputData) throws Exception {
return new ResponseEntity<>(runCodeService.runTestCaseCode(testCaseInputData), HttpStatus.OK);
}
@PostMapping("/is-solved")
@Operation(summary = "테스트 문제 정답 여부 확인", description = "테스트 문제의 정답 여부를 확인 및 반환합니다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
@AllArgsConstructor
@Builder
public class InputData {
private Long practiceProblemId;
private Long testId;
private Integer problemNumber;
private Language language;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package swm_nm.morandi.domain.testDuring.dto;

import lombok.*;

@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PracticeProblemCodeDto {
private String pythonCode;
private String cppCode;
private String javaCode;
public static PracticeProblemCodeDto getPracticeProblemCodeDto(TempCodeDto tempCodeDto) {
return PracticeProblemCodeDto.builder()
.pythonCode(tempCodeDto.getPythonCode())
.cppCode(tempCodeDto.getCppCode())
.javaCode(tempCodeDto.getJavaCode())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class TestInputData {
public class TestCaseInputData {
private Long practiceProblemId;
private Long testId;
private Integer problemNumber;
private Language language;
Expand Down
Loading

0 comments on commit d6410e5

Please sign in to comment.