Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @Gyuhyeok99 @nayonsoso @wibaek
37 changes: 37 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CI with Gradle

on:
pull_request:
branches: [ "develop", "release", "master" ]

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
checks: write

steps:
- name: Checkout the code
uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

- name: Make Gradle wrapper executable
run: chmod +x ./gradlew

- name: Build with Gradle Wrapper
run: ./gradlew build

- name: Publish Test Report
uses: mikepenz/action-junit-report@v5
if: success() || failure()
with:
report_paths: '**/build/test-results/test/TEST-*.xml'
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
import com.example.solidconnection.admin.dto.GpaScoreResponse;
import com.example.solidconnection.admin.dto.GpaScoreSearchResponse;
import com.example.solidconnection.admin.dto.GpaScoreUpdateRequest;
import com.example.solidconnection.admin.dto.LanguageTestScoreResponse;
import com.example.solidconnection.admin.dto.LanguageTestScoreSearchResponse;
import com.example.solidconnection.admin.dto.LanguageTestScoreUpdateRequest;
import com.example.solidconnection.admin.dto.ScoreSearchCondition;
import com.example.solidconnection.admin.service.AdminGpaScoreService;
import com.example.solidconnection.admin.service.AdminLanguageTestScoreService;
import com.example.solidconnection.custom.response.PageResponse;
import com.example.solidconnection.util.PagingUtils;
import jakarta.validation.Valid;
Expand All @@ -18,6 +22,7 @@
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
Expand All @@ -28,7 +33,9 @@
public class AdminScoreController {

private final AdminGpaScoreService adminGpaScoreService;
private final AdminLanguageTestScoreService adminLanguageTestScoreService;

// todo: 추후 커스텀 페이지 객체 & argumentResolver를 적용 필요
@GetMapping("/gpas")
public ResponseEntity<PageResponse<GpaScoreSearchResponse>> searchGpaScores(
@Valid @ModelAttribute ScoreSearchCondition scoreSearchCondition,
Expand All @@ -40,12 +47,33 @@ public ResponseEntity<PageResponse<GpaScoreSearchResponse>> searchGpaScores(
return ResponseEntity.ok(PageResponse.of(page));
}

@PatchMapping("/gpas/{gpa-score-id}")
@PutMapping("/gpas/{gpa-score-id}")
public ResponseEntity<GpaScoreResponse> updateGpaScore(
@PathVariable("gpa-score-id") Long gpaScoreId,
@Valid @RequestBody GpaScoreUpdateRequest request
) {
GpaScoreResponse response = adminGpaScoreService.updateGpaScore(gpaScoreId, request);
return ResponseEntity.ok(response);
}

// todo: 추후 커스텀 페이지 객체 & argumentResolver를 적용 필요
@GetMapping("/language-tests")
public ResponseEntity<PageResponse<LanguageTestScoreSearchResponse>> searchLanguageTestScores(
@Valid @ModelAttribute ScoreSearchCondition scoreSearchCondition,
@PageableDefault(page = 1) Pageable pageable
) {
PagingUtils.validatePage(pageable.getPageNumber(), pageable.getPageSize());
Pageable internalPageable = PageRequest.of(pageable.getPageNumber() - 1, pageable.getPageSize());
Page<LanguageTestScoreSearchResponse> page = adminLanguageTestScoreService.searchLanguageTestScores(scoreSearchCondition, internalPageable);
return ResponseEntity.ok(PageResponse.of(page));
}

@PutMapping("/language-tests/{language-test-score-id}")
public ResponseEntity<LanguageTestScoreResponse> updateLanguageTestScore(
@PathVariable("language-test-score-id") Long languageTestScoreId,
@Valid @RequestBody LanguageTestScoreUpdateRequest request
) {
LanguageTestScoreResponse response = adminLanguageTestScoreService.updateLanguageTestScore(languageTestScoreId, request);
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ public record GpaScoreUpdateRequest(
VerifyStatus verifyStatus,

String rejectedReason
) {
) implements ScoreUpdateRequest {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.solidconnection.admin.dto;

import com.example.solidconnection.type.LanguageTestType;

public record LanguageTestResponse(
LanguageTestType languageTestType,
String languageTestScore,
String languageTestReportUrl
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.example.solidconnection.admin.dto;

import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.type.LanguageTestType;
import com.example.solidconnection.type.VerifyStatus;

public record LanguageTestScoreResponse(
long id,
LanguageTestType languageTestType,
String languageTestScore,
VerifyStatus verifyStatus,
String rejectedReason
) {
public static LanguageTestScoreResponse from(LanguageTestScore languageTestScore) {
return new LanguageTestScoreResponse(
languageTestScore.getId(),
languageTestScore.getLanguageTest().getLanguageTestType(),
languageTestScore.getLanguageTest().getLanguageTestScore(),
languageTestScore.getVerifyStatus(),
languageTestScore.getRejectedReason()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.solidconnection.admin.dto;

public record LanguageTestScoreSearchResponse(
LanguageTestScoreStatusResponse languageTestScoreStatusResponse,
SiteUserResponse siteUserResponse
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.solidconnection.admin.dto;

import com.example.solidconnection.type.VerifyStatus;

import java.time.ZonedDateTime;

public record LanguageTestScoreStatusResponse(
long id,
LanguageTestResponse languageTestResponse,
VerifyStatus verifyStatus,
String rejectedReason,
ZonedDateTime createdAt,
ZonedDateTime updatedAt
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.solidconnection.admin.dto;

import com.example.solidconnection.custom.validation.annotation.RejectedReasonRequired;
import com.example.solidconnection.type.LanguageTestType;
import com.example.solidconnection.type.VerifyStatus;
import jakarta.validation.constraints.NotNull;

@RejectedReasonRequired
public record LanguageTestScoreUpdateRequest(

@NotNull(message = "어학 유형을 입력해주세요.")
LanguageTestType languageTestType,

@NotNull(message = "어학 점수를 입력해주세요.")
String languageTestScore,

@NotNull(message = "승인 상태를 설정해주세요.")
VerifyStatus verifyStatus,

String rejectedReason
) implements ScoreUpdateRequest {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.solidconnection.admin.dto;

import com.example.solidconnection.type.VerifyStatus;

public interface ScoreUpdateRequest {
VerifyStatus verifyStatus();
String rejectedReason();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.example.solidconnection.admin.service;

import com.example.solidconnection.admin.dto.LanguageTestScoreResponse;
import com.example.solidconnection.admin.dto.LanguageTestScoreSearchResponse;
import com.example.solidconnection.admin.dto.LanguageTestScoreUpdateRequest;
import com.example.solidconnection.admin.dto.ScoreSearchCondition;
import com.example.solidconnection.application.domain.LanguageTest;
import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
import com.example.solidconnection.type.VerifyStatus;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.example.solidconnection.custom.exception.ErrorCode.LANGUAGE_TEST_SCORE_NOT_FOUND;

@RequiredArgsConstructor
@Service
public class AdminLanguageTestScoreService {

private final LanguageTestScoreRepository languageTestScoreRepository;

@Transactional(readOnly = true)
public Page<LanguageTestScoreSearchResponse> searchLanguageTestScores(ScoreSearchCondition scoreSearchCondition, Pageable pageable) {
return languageTestScoreRepository.searchLanguageTestScores(scoreSearchCondition, pageable);
}

@Transactional
public LanguageTestScoreResponse updateLanguageTestScore(Long languageTestScoreId, LanguageTestScoreUpdateRequest request) {
LanguageTestScore languageTestScore = languageTestScoreRepository.findById(languageTestScoreId)
.orElseThrow(() -> new CustomException(LANGUAGE_TEST_SCORE_NOT_FOUND));
languageTestScore.updateLanguageTestScore(
new LanguageTest(
request.languageTestType(),
request.languageTestScore(),
languageTestScore.getLanguageTest().getLanguageTestReportUrl()
),
request.verifyStatus(),
request.verifyStatus() == VerifyStatus.REJECTED ? request.rejectedReason() : null
);
return LanguageTestScoreResponse.from(languageTestScore);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.example.solidconnection.application.service.ApplicationQueryService;
import com.example.solidconnection.application.service.ApplicationSubmissionService;
import com.example.solidconnection.custom.resolver.AuthorizedUser;
import com.example.solidconnection.custom.security.annotation.RequireAdminAccess;
import com.example.solidconnection.siteuser.domain.SiteUser;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
Expand All @@ -32,12 +33,13 @@ public ResponseEntity<ApplicationSubmissionResponse> apply(
@AuthorizedUser SiteUser siteUser,
@Valid @RequestBody ApplyRequest applyRequest
) {
boolean result = applicationSubmissionService.apply(siteUser, applyRequest);
ApplicationSubmissionResponse applicationSubmissionResponse = applicationSubmissionService.apply(siteUser, applyRequest);
return ResponseEntity
.status(HttpStatus.OK)
.body(new ApplicationSubmissionResponse(result));
.body(applicationSubmissionResponse);
}

@RequireAdminAccess
@GetMapping
public ResponseEntity<ApplicationsResponse> getApplicants(
@AuthorizedUser SiteUser siteUser,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class Application {
@Column(length = 100)
private String nicknameForApply;

@Column(columnDefinition = "int not null default 0")
@Column(columnDefinition = "int not null default 1")
private Integer updateCount;

@Column(length = 50, nullable = false)
Expand Down Expand Up @@ -76,7 +76,7 @@ public Application(
this.gpa = gpa;
this.languageTest = languageTest;
this.term = term;
this.updateCount = 0;
this.updateCount = 1;
this.verifyStatus = PENDING;
}

Expand Down Expand Up @@ -115,7 +115,7 @@ public Application(
this.gpa = gpa;
this.languageTest = languageTest;
this.term = term;
this.updateCount = 0;
this.updateCount = 1;
this.firstChoiceUniversity = firstChoiceUniversity;
this.secondChoiceUniversity = secondChoiceUniversity;
this.thirdChoiceUniversity = thirdChoiceUniversity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package com.example.solidconnection.application.dto;

import com.example.solidconnection.application.domain.Application;

public record ApplicationSubmissionResponse(
boolean isSuccess) {
int applyCount
) {
public static ApplicationSubmissionResponse from(Application application) {
return new ApplicationSubmissionResponse(application.getUpdateCount());
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.example.solidconnection.application.service;

import com.example.solidconnection.application.domain.Application;
import com.example.solidconnection.application.dto.ApplicationSubmissionResponse;
import com.example.solidconnection.application.dto.ApplyRequest;
import com.example.solidconnection.application.dto.UniversityChoiceRequest;
import com.example.solidconnection.application.repository.ApplicationRepository;
Expand Down Expand Up @@ -49,15 +50,10 @@ public class ApplicationSubmissionService {
key = {"applications:all"},
cacheManager = "customCacheManager"
)
public boolean apply(SiteUser siteUser, ApplyRequest applyRequest) {
public ApplicationSubmissionResponse apply(SiteUser siteUser, ApplyRequest applyRequest) {
UniversityChoiceRequest universityChoiceRequest = applyRequest.universityChoiceRequest();

Long gpaScoreId = applyRequest.gpaScoreId();
Long languageTestScoreId = applyRequest.languageTestScoreId();
GpaScore gpaScore = getValidGpaScore(siteUser, gpaScoreId);
LanguageTestScore languageTestScore = getValidLanguageTestScore(siteUser, languageTestScoreId);

Optional<Application> application = applicationRepository.findBySiteUserAndTerm(siteUser, term);
GpaScore gpaScore = getValidGpaScore(siteUser, applyRequest.gpaScoreId());
LanguageTestScore languageTestScore = getValidLanguageTestScore(siteUser, applyRequest.languageTestScoreId());

UniversityInfoForApply firstChoiceUniversity = universityInfoForApplyRepository
.getUniversityInfoForApplyByIdAndTerm(universityChoiceRequest.firstChoiceUniversityId(), term);
Expand All @@ -68,22 +64,19 @@ public boolean apply(SiteUser siteUser, ApplyRequest applyRequest) {
.map(id -> universityInfoForApplyRepository.getUniversityInfoForApplyByIdAndTerm(id, term))
.orElse(null);

if (application.isEmpty()) {
Application newApplication = new Application(siteUser, gpaScore.getGpa(), languageTestScore.getLanguageTest(),
term, firstChoiceUniversity, secondChoiceUniversity, thirdChoiceUniversity, getRandomNickname());
newApplication.setVerifyStatus(VerifyStatus.APPROVED);
applicationRepository.save(newApplication);
} else {
Application before = application.get();
validateUpdateLimitNotExceed(before);
before.setIsDeleteTrue(); // 기존 이력 soft delete 수행한다.

Application newApplication = new Application(siteUser, gpaScore.getGpa(), languageTestScore.getLanguageTest(),
term, before.getUpdateCount() + 1, firstChoiceUniversity, secondChoiceUniversity, thirdChoiceUniversity, getRandomNickname());
newApplication.setVerifyStatus(VerifyStatus.APPROVED);
applicationRepository.save(newApplication);
}
return true;
Optional<Application> existingApplication = applicationRepository.findBySiteUserAndTerm(siteUser, term);
int updateCount = existingApplication
.map(application -> {
validateUpdateLimitNotExceed(application);
application.setIsDeleteTrue();
return application.getUpdateCount() + 1;
})
.orElse(1);
Application newApplication = new Application(siteUser, gpaScore.getGpa(), languageTestScore.getLanguageTest(),
term, updateCount, firstChoiceUniversity, secondChoiceUniversity, thirdChoiceUniversity, getRandomNickname());
newApplication.setVerifyStatus(VerifyStatus.APPROVED);
applicationRepository.save(newApplication);
return ApplicationSubmissionResponse.from(newApplication);
}

private GpaScore getValidGpaScore(SiteUser siteUser, Long gpaScoreId) {
Expand Down
Loading
Loading