Skip to content
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@ out/
application-secret.yml

###
.env**
.env**

AGENTS.md
2 changes: 2 additions & 0 deletions src/main/java/ceos/backend/BackendApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableAsync
@EnableScheduling
@EnableJpaAuditing
public class BackendApplication {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public void signUp(@RequestBody @Valid SignUpRequest signUpRequest) {

@Operation(summary = "둜그인")
@PostMapping("/signin")
public TokenResponse signIn(HttpServletRequest request, @RequestBody @Valid SignInRequest signInRequest) {
public TokenResponse signIn(
HttpServletRequest request, @RequestBody @Valid SignInRequest signInRequest) {
log.info("둜그인");
String device = request.getHeader("User-Agent").contains("mobile") ? MOBILE : WEB;
return adminService.signIn(device, signInRequest);
Expand Down Expand Up @@ -72,7 +73,8 @@ public void resetPwd(

@Operation(summary = "λ‘œκ·Έμ•„μ›ƒ")
@PostMapping("/logout")
public void logout(HttpServletRequest request, @AuthenticationPrincipal AdminDetails adminUser) {
public void logout(
HttpServletRequest request, @AuthenticationPrincipal AdminDetails adminUser) {
log.info("λ‘œκ·Έμ•„μ›ƒ");
String device = request.getHeader("User-Agent").contains("mobile") ? MOBILE : WEB;
adminService.logout(device, adminUser);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public TokenResponse signIn(String device, SignInRequest signInRequest) {

// 토큰 λ°œκΈ‰
final String accessToken = tokenProvider.createAccessToken(admin.getId(), authentication);
final String refreshToken = tokenProvider.createRefreshToken(admin.getId(), authentication, redisKey);
final String refreshToken =
tokenProvider.createRefreshToken(admin.getId(), authentication, redisKey);

return adminMapper.toTokenResponse(accessToken, refreshToken);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

package ceos.backend.domain.application;


Expand Down Expand Up @@ -38,13 +37,25 @@ public class ApplicationController {
@Operation(summary = "μ§€μ›μž λͺ©λ‘ 보기")
@GetMapping
public GetApplications getApplications(
@Parameter(schema = @Schema(allowableValues = {"PRODUCT", "DESIGN", "FRONTEND", "BACKEND"}))
@RequestParam(value = "part", required = false, defaultValue = "") Part part,
@Parameter(
schema =
@Schema(
allowableValues = {
"PRODUCT",
"DESIGN",
"FRONTEND",
"BACKEND"
}))
@RequestParam(value = "part", required = false, defaultValue = "")
Part part,
@Parameter(schema = @Schema(allowableValues = {"PASS", "FAIL"}))
@RequestParam(value = "docPass", required = false, defaultValue = "") Pass docPass,
@RequestParam(value = "docPass", required = false, defaultValue = "")
Pass docPass,
@Parameter(schema = @Schema(allowableValues = {"PASS", "FAIL"}))
@RequestParam(value = "finalPass", required = false, defaultValue = "") Pass finalPass,
@RequestParam(value = "applicantName", required = false, defaultValue = "") String applicantName,
@RequestParam(value = "finalPass", required = false, defaultValue = "")
Pass finalPass,
@RequestParam(value = "applicantName", required = false, defaultValue = "")
String applicantName,
@RequestParam("pageNum") int pageNum,
@RequestParam("limit") int limit) {
log.info("μ§€μ›μž λͺ©λ‘ 보기");
Expand Down Expand Up @@ -145,7 +156,8 @@ public void updateDocumentPassStatus(

@Operation(summary = "λ©΄μ ‘ μ°Έμ—¬ κ°€λŠ₯ μ—¬λΆ€ 확인", description = "resultDateDoc ~ resultDateFinal μ „λ‚ ")
@GetMapping(value = "/{applicationId}/interview/availability")
public GetInterviewAvailability getInterviewAvailability(@PathVariable("applicationId") Long applicationId) {
public GetInterviewAvailability getInterviewAvailability(
@PathVariable("applicationId") Long applicationId) {
log.info("λ©΄μ ‘ μ°Έμ—¬ κ°€λŠ₯ μ—¬λΆ€ 확인");
return applicationService.getInterviewAvailability(applicationId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.DynamicInsert;

import java.util.ArrayList;
import java.util.List;

@DynamicInsert
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package ceos.backend.domain.application.domain;


import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import java.util.stream.Stream;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.stream.Stream;

@Getter
@RequiredArgsConstructor
public enum AvailableCheck {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ceos.backend.domain.application.dto.response;


import ceos.backend.domain.application.domain.Application;
import ceos.backend.domain.application.domain.AvailableCheck;
import lombok.Builder;
Expand All @@ -23,5 +24,4 @@ public static GetFinalAvailability of(Application application) {
.reason(application.getFinalUnableReason())
.build();
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ceos.backend.domain.application.dto.response;


import ceos.backend.domain.application.domain.Application;
import ceos.backend.domain.application.domain.AvailableCheck;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package ceos.backend.domain.application.exception.exceptions;


import ceos.backend.domain.application.exception.ApplicationErrorCode;
import ceos.backend.global.error.BaseErrorException;

public class NotDeletableDuringRecruitment extends BaseErrorException {
public static final NotDeletableDuringRecruitment EXCEPTION = new NotDeletableDuringRecruitment();
public static final NotDeletableDuringRecruitment EXCEPTION =
new NotDeletableDuringRecruitment();

private NotDeletableDuringRecruitment() {
super(ApplicationErrorCode.NOT_DELETABLE_DURING_RECRUITMENT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@
import ceos.backend.global.common.dto.AwsSESMail;
import ceos.backend.global.common.dto.SlackUnavailableReason;
import ceos.backend.global.common.event.Event;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.UUID;

@Slf4j
@Component
@RequiredArgsConstructor
Expand Down Expand Up @@ -84,5 +83,4 @@ public Application getApplicationByUuidAndEmailForUpdate(String uuid, String ema
throw ApplicantNotFound.EXCEPTION;
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
import ceos.backend.domain.application.domain.Pass;
import ceos.backend.global.common.entity.Part;
import jakarta.persistence.LockModeType;
import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.Optional;

public interface ApplicationRepository
extends JpaRepository<Application, Long>, ApplicationRepositoryCustom {
@Query("select distinct a from Application a" + " where a.applicantInfo.email = :email")
Expand All @@ -22,7 +21,6 @@ public interface ApplicationRepository
@Query("select distinct a from Application a" + " where a.applicantInfo.uuid = :uuid")
Optional<Application> findByUuid(@Param("uuid") String uuid);


@Query(
"select a from Application a"
+ " where a.applicantInfo.uuid = :uuid"
Expand All @@ -38,7 +36,6 @@ Optional<Application> findByUuidAndEmail(
Optional<Application> findByUuidAndEmailWithPessimisticLock(
@Param("uuid") String uuid, @Param("email") String email);


@Query("select count(a) > 0 from Application a" + " where a.applicantInfo.email = :email")
boolean existsByEmail(@Param("email") String email);

Expand Down Expand Up @@ -77,9 +74,7 @@ Page<Application> findAllByPartAndDocumentPassAndFinalPass(
@Param("convertedFinalPass") Pass convertedFinalPass,
PageRequest pageRequest);


@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select a from Application a where a.id = :id")
Optional<Application> findByIdWithPessimisticLock(@Param("id") Long id);

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ceos.backend.domain.application.service;

import static ceos.backend.domain.application.domain.AvailableCheck.AVAILABLE;
import static ceos.backend.domain.application.domain.AvailableCheck.UNAVAILABLE;

import ceos.backend.domain.application.domain.*;
import ceos.backend.domain.application.dto.request.CreateApplicationRequest;
Expand Down Expand Up @@ -27,7 +29,6 @@
import ceos.backend.global.common.entity.Part;
import ceos.backend.global.util.InterviewDateTimeConvertor;
import ceos.backend.global.util.ParsedDurationConvertor;

import java.time.LocalDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand All @@ -36,9 +37,6 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static ceos.backend.domain.application.domain.AvailableCheck.AVAILABLE;
import static ceos.backend.domain.application.domain.AvailableCheck.UNAVAILABLE;

@Service
@RequiredArgsConstructor
public class ApplicationService {
Expand Down Expand Up @@ -161,6 +159,7 @@ public void updateInterviewAttendance(

if (request.getAvailable() == AVAILABLE) {
application.updateInterviewCheck(AVAILABLE);
application.updateInterviewUnableReason(null);
} else {
application.updateInterviewCheck(UNAVAILABLE);
application.updateInterviewUnableReason(request.getReason());
Expand Down Expand Up @@ -191,6 +190,7 @@ public void updateParticipationAvailability(

if (request.getAvailable() == AVAILABLE) {
application.updateFinalCheck(AVAILABLE);
application.updateFinalUnableReason(null);
} else {
application.updateFinalCheck(UNAVAILABLE);
application.updateFinalUnableReason(request.getReason());
Expand Down Expand Up @@ -237,7 +237,8 @@ public GetInterviewTime getInterviewTime(Long applicationId) {
public void updateInterviewTime(Long applicationId, UpdateInterviewTime updateInterviewTime) {
recruitmentValidator.validateBetweenStartDateDocAndResultDateDoc(); // κΈ°κ°„ 검증
applicationValidator.validateExistingApplicant(applicationId); // μœ μ € 검증
final Application application = applicationHelper.getApplicationByIdForUpdate(applicationId);
final Application application =
applicationHelper.getApplicationByIdForUpdate(applicationId);
applicationValidator.validateDocumentPassStatus(application); // μ„œλ₯˜ 톡과 검증
final List<Interview> interviews = interviewRepository.findAll();
final String duration =
Expand All @@ -256,14 +257,14 @@ public GetInterviewAvailability getInterviewAvailability(Long applicationId) {
return GetInterviewAvailability.of(application);
}


@Transactional
@TransactionLog
public void updateDocumentPassStatus(Long applicationId, UpdatePassStatus updatePassStatus) {
recruitmentValidator.validateBetweenStartDateDocAndResultDateDoc(); // κΈ°κ°„ 검증
applicationValidator.validateExistingApplicant(applicationId); // μœ μ € 검증

final Application application = applicationHelper.getApplicationByIdForUpdate(applicationId);
final Application application =
applicationHelper.getApplicationByIdForUpdate(applicationId);
application.updateDocumentPass(updatePassStatus.getPass());
}

Expand All @@ -272,7 +273,8 @@ public void updateDocumentPassStatus(Long applicationId, UpdatePassStatus update
public void updateFinalPassStatus(Long applicationId, UpdatePassStatus updatePassStatus) {
recruitmentValidator.validateBetweenResultDateDocAndResultDateFinal(); // κΈ°κ°„ 검증
applicationValidator.validateExistingApplicant(applicationId); // μœ μ € 검증
final Application application = applicationHelper.getApplicationByIdForUpdate(applicationId);
final Application application =
applicationHelper.getApplicationByIdForUpdate(applicationId);
applicationValidator.validateDocumentPassStatus(application); // μ„œλ₯˜ 톡과 검증

application.updateFinalPass(updatePassStatus.getPass());
Expand All @@ -287,16 +289,14 @@ public GetFinalAvailability getFinalAvailability(Long applicationId) {
return GetFinalAvailability.of(application);
}


@Transactional
public void deleteAllApplications() {
Recruitment recruitment = recruitmentHelper.takeRecruitment();
// ν˜„μž¬ μ‹œκ°„μ΄ resultDateFinal 이전이면 μ‚­μ œ λΆˆκ°€
if(LocalDateTime.now().isBefore(recruitment.getResultDateFinal())) {
if (LocalDateTime.now().isBefore(recruitment.getResultDateFinal())) {
throw NotDeletableDuringRecruitment.EXCEPTION;
}
// application, applicationAnswer, applicationInterview μ‚­μ œ (cascade)
applicationRepository.deleteAll();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,11 @@ public void validateApplicantDocumentPass(Application application) {

public void validateApplicantInterviewCheckStatus(Application application) {
application.validateDocumentPass();
application.validateNotInterviewCheck();
}

public void validateApplicantActivityCheckStatus(Application application) {
application.validateDocumentPass();
application.validateFinalPass();
application.validateNotFinalCheck();
}

public void validateExistingApplicant(Long applicationId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ceos.backend.domain.management.domain;


import ceos.backend.domain.management.dto.request.UpdateManagementRequest;
import ceos.backend.domain.management.vo.ManagementVo;
import ceos.backend.global.common.entity.BaseEntity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ceos.backend.domain.management.dto.response;


import ceos.backend.domain.management.dto.ManagementDto;
import java.util.List;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ public GetAllPartManagementsResponse getAllPartManagements() {
managementRepository.findManagementAllByRoleOrderByNameAsc(
ManagementRole.PRESIDENCY);
List<Management> findAdvisors =
managementRepository.findManagementAllByRoleOrderByNameAsc(
ManagementRole.ADVISOR);
managementRepository.findManagementAllByRoleOrderByNameAsc(ManagementRole.ADVISOR);
List<Management> findGeneralAffairs =
managementRepository.findManagementAllByRoleOrderByNameAsc(
ManagementRole.GENERAL_AFFAIRS);
Expand All @@ -81,7 +80,11 @@ public GetAllPartManagementsResponse getAllPartManagements() {

GetAllPartManagementsResponse response =
managementMapper.toPartManagementList(
findPresidency, findAdvisors, findGeneralAffairs, findPartLeaders, findManagements);
findPresidency,
findAdvisors,
findGeneralAffairs,
findPartLeaders,
findManagements);

return response;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
import ceos.backend.domain.recruitment.dto.UserRecruitmentDTO;
import ceos.backend.domain.recruitment.helper.RecruitmentHelper;
import ceos.backend.domain.recruitment.repository.RecruitmentRepository;
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Slf4j
@Service
@RequiredArgsConstructor
Expand Down
Loading