Skip to content
Merged
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
3 changes: 0 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ dependencies {
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.5'

//JSON 타입 사용
implementation 'io.hypersistence:hypersistence-utils-hibernate-62:3.7.0'

//queryDsl
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
Expand Down
9 changes: 2 additions & 7 deletions src/main/java/UMC/career_mate/domain/recruit/Recruit.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
package UMC.career_mate.domain.recruit;

import io.hypersistence.utils.hibernate.type.json.JsonType;
import jakarta.persistence.*;

import java.time.LocalDateTime;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Type;

@Entity
@Table(name = "recruits")
Expand Down Expand Up @@ -45,9 +41,8 @@ public class Recruit {
private String employmentName; // 고용(근무) 형태 값
private String salaryName; // 연봉 값

@Type(JsonType.class)
@Column(columnDefinition = "json")
private List<String> jobNames; // 직무 키워드
@Column(columnDefinition = "TEXT")
private String hashtags; // 직무 키워드

private String region; // 근무 지역
private String industryName; // 산업군
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public class RecruitController {
private final RecruitQueryService recruitQueryService;

@Operation(
summary = "추천 채용 공고 조회 API",
description = """
summary = "추천 채용 공고 조회 API",
description = """
추천 채용 공고를 조회하는 API입니다.\n\n
page의 값은 1부터 시작이고, 기본 값은 1입니다.\n\n
size의 기본값은 6입니다.\n\n
Expand All @@ -43,26 +43,26 @@ public class RecruitController {
""")
@GetMapping
public ApiResponse<PageResponseDTO<RecommendRecruitsDTO>> getRecommendRecruitList(
@RequestParam(defaultValue = "1", required = false) int page,
@RequestParam(defaultValue = "6", required = false) int size,
@RequestParam(defaultValue = "POSTING_DESC", required = false) RecruitSortType recruitSortType,
@LoginMember Member member
@RequestParam(defaultValue = "1", required = false) int page,
@RequestParam(defaultValue = "6", required = false) int size,
@RequestParam(defaultValue = "POSTING_DESC", required = false) RecruitSortType recruitSortType,
@LoginMember Member member
) {
return ApiResponse.onSuccess(
recruitQueryService.getRecommendRecruitList(page, size, recruitSortType, member));
recruitQueryService.getRecommendRecruitList(page, size, recruitSortType, member));
}

@Operation(
summary = "채용 공고 요약 페이지 조회 API",
description = """
summary = "채용 공고 요약 페이지 조회 API",
description = """
채용 공고 요약 페이지를 조회하는 API입니다.\n\n
recruitId : 조회하려는 채용 공고 pk 값
""")
@GetMapping("/{recruitId}")
public ResponseEntity<ApiResponse<RecruitInfoDTO>> getRecruitInfo(@PathVariable Long recruitId,
@LoginMember Member member) {
@LoginMember Member member) {
return ResponseEntity.ok(
ApiResponse.onSuccess(recruitQueryService.findRecruitInfo(member, recruitId)));
ApiResponse.onSuccess(recruitQueryService.findRecruitInfo(member, recruitId)));
}

@Deprecated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringEscapeUtils;
Expand All @@ -42,7 +41,7 @@ public static Recruit toRecruit(Job job, String recruitUrl, String companyInfoUr
.educationLevelName(educationLevel.getDescription())
.employmentName(job.position().jobType().name())
.salaryName(job.salary().name())
.jobNames(Arrays.asList(job.position().jobCode().name()))
.hashtags(job.position().jobCode().name())
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

hashtags 할당 전 유효성 검사가 필요합니다.

직접 할당하기 전에 다음 사항들을 검증하는 것이 좋습니다:

  • null 체크
  • 특수문자 처리
  • 최대 길이 검증

예시 코드:

-.hashtags(job.position().jobCode().name())
+.hashtags(validateAndFormatHashtags(job.position().jobCode().name()))

+private static String validateAndFormatHashtags(String hashtags) {
+    if (hashtags == null) return "";
+    return hashtags.trim().replaceAll("[^\\w\\s,]", "");
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.hashtags(job.position().jobCode().name())
.hashtags(validateAndFormatHashtags(job.position().jobCode().name()))
// ... other code in the file ...
private static String validateAndFormatHashtags(String hashtags) {
if (hashtags == null) return "";
return hashtags.trim().replaceAll("[^\\w\\s,]", "");
}

.region(StringEscapeUtils.unescapeHtml4(
job.position().location().name()))
.industryName(job.position().industry().name())
Expand All @@ -67,13 +66,6 @@ public static RecruitThumbNailInfoDTO toRecruitThumbNailInfoDTO(Recruit recruit,
.title(recruit.getTitle())
.deadLine(formatDeadLine(recruit))
.isScrapped(isScrapped)
.experienceLevelCode(recruit.getExperienceLevelCode())
.experienceLevelMin(recruit.getExperienceLevelMin())
.experienceLevelMax(recruit.getExperienceLevelMax())
.experienceLevelName(recruit.getExperienceLevelName())
.educationLevelCode(recruit.getEducationLevelCode())
.educationLevelName(recruit.getEducationLevelName())
.postingDate(recruit.getPostingDate())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package UMC.career_mate.domain.recruit.dto.response;

import java.time.LocalDateTime;
import java.util.List;
import lombok.Builder;

Expand All @@ -16,18 +15,7 @@ public record RecruitThumbNailInfoDTO(
String companyName,
String title,
String deadLine,
boolean isScrapped,

/**
* TODO: 아래로는 (필터링, 정렬) 잘 되는지 확인용 데이터, 나중에 삭제 예정
*/
Integer experienceLevelCode, // 경력 코드 : 0(경력무관), 1(신입), 2(경력), 3(신입/경력)
Integer experienceLevelMin, // 경력 년수 최소 값
Integer experienceLevelMax, // 경력 년수 최대 값
String experienceLevelName,
Integer educationLevelCode, // 학력 코드 0(학력무관), 1(고등학교졸업), 2(대학졸업(2,3년)), 3(대학졸업(4년)), 4(석사졸업), 5(박사졸업) 등
String educationLevelName,
LocalDateTime postingDate
boolean isScrapped
) {

}
Expand Down
125 changes: 87 additions & 38 deletions src/main/java/UMC/career_mate/domain/recruit/enums/RecruitKeyword.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,116 +7,164 @@ public enum RecruitKeyword {

BACKEND {
@Override
public List<String> getIncludeKeywordList() {
return List.of("Back", "Backend", "Back-end", "BACK", "백엔드", "서버", "시스템");
public List<String> getIncludeTitleKeywordList() {
return List.of("Back", "Backend", "Back-end", "백엔드", "서버", "시스템");
}

@Override
public List<String> getExcludeKeywordList() {
public List<String> getExcludeTitleKeywordList() {
return null;
}

@Override
public List<String> getIncludeHashtagKeywordList() {
return null;
}
}
,
BACKEND_SPRING {
@Override
public List<String> getIncludeKeywordList() {
return List.of("Back", "Backend", "Back-end", "BACK", "백엔드", "서버", "시스템");
public List<String> getIncludeTitleKeywordList() {
return List.of("Back", "Backend", "Back-end", "백엔드", "서버", "시스템");
}

@Override
public List<String> getExcludeKeywordList() {
return List.of("Node", "Node.js", "NODE", "javascript", "Python", "Django", "C++", "PHP", "C#");
public List<String> getExcludeTitleKeywordList() {
return List.of("Node", "Node.js", "javascript", "Python", "Django", "C++", "PHP", "C#");
}

@Override
public List<String> getIncludeHashtagKeywordList() {
return List.of("Spring", "SpringBoot");
}
},
BACKEND_NODE {
@Override
public List<String> getIncludeKeywordList() {
return List.of("Back", "Backend", "Back-end", "BACK", "백엔드", "서버", "시스템");
public List<String> getIncludeTitleKeywordList() {
return List.of("Back", "Backend", "Back-end", "백엔드", "서버", "시스템");
}

@Override
public List<String> getExcludeTitleKeywordList() {
return List.of("JAVA", "Spring", "Python", "Django", "C++", "PHP", "C#");
}

@Override
public List<String> getExcludeKeywordList() {
return List.of("java", "JAVA", "spring", "Spring", "SPRING", "Python", "Django", "C++", "PHP", "C#");
public List<String> getIncludeHashtagKeywordList() {
return List.of("Node.js");
}
},
BACKEND_DJANGO {
@Override
public List<String> getIncludeKeywordList() {
return List.of("Back", "Backend", "Back-end", "BACK", "백엔드", "서버", "시스템");
public List<String> getIncludeTitleKeywordList() {
return List.of("Back", "Backend", "Back-end", "백엔드", "서버", "시스템");
}

@Override
public List<String> getExcludeTitleKeywordList() {
return List.of("JAVA", "Spring", "javascript", "Node", "Node.js", "C++", "PHP", "C#");
}

@Override
public List<String> getExcludeKeywordList() {
return List.of("java", "JAVA", "spring", "Spring", "SPRING", "javascript", "Node",
"Node.js", "NODE", "C++", "PHP", "C#");
public List<String> getIncludeHashtagKeywordList() {
return List.of("Django", "Python");
}
},
FRONTEND {
@Override
public List<String> getIncludeKeywordList() {
return List.of("Front", "FRONT", "Frontend", "Front-end", "프론트엔드", "프론트");
public List<String> getIncludeTitleKeywordList() {
return List.of("Front", "Frontend", "Front-end", "프론트엔드", "프론트");
}

@Override
public List<String> getExcludeTitleKeywordList() {
return null;
}

@Override
public List<String> getExcludeKeywordList() {
public List<String> getIncludeHashtagKeywordList() {
return null;
}
},
FRONTEND_REACT {
@Override
public List<String> getIncludeKeywordList() {
return List.of("react");
public List<String> getIncludeTitleKeywordList() {
return List.of("React");
}

@Override
public List<String> getExcludeKeywordList() {
public List<String> getExcludeTitleKeywordList() {
return null;
}

@Override
public List<String> getIncludeHashtagKeywordList() {
return List.of("React");
}
},
FRONTEND_IOS {
@Override
public List<String> getIncludeKeywordList() {
return List.of("ios");
public List<String> getIncludeTitleKeywordList() {
return List.of("iOS");
}

@Override
public List<String> getExcludeKeywordList() {
public List<String> getExcludeTitleKeywordList() {
return null;
}

@Override
public List<String> getIncludeHashtagKeywordList() {
return List.of("iOS", "Swift");
}
},
FRONTEND_ANDROID {
@Override
public List<String> getIncludeKeywordList() {
return List.of("android");
public List<String> getIncludeTitleKeywordList() {
return List.of("Android");
}

@Override
public List<String> getExcludeKeywordList() {
public List<String> getExcludeTitleKeywordList() {
return null;
}

@Override
public List<String> getIncludeHashtagKeywordList() {
return List.of("Android");
}
},
DESIGNER {
@Override
public List<String> getIncludeKeywordList() {
return List.of("웹 디자이너", "웹디자이너", "UI", "UX", "디자인", "design", "DESIGN");
public List<String> getIncludeTitleKeywordList() {
return List.of("웹 디자이너", "웹디자이너", "UI", "UX", "디자인", "design");
}

@Override
public List<String> getExcludeTitleKeywordList() {
return List.of("영상디자인", "영상 디자인");
}

@Override
public List<String> getExcludeKeywordList() {
return List.of("영상디자인", "영상 디자인"); // 굿즈 디자인은? 뺴야하는가
public List<String> getIncludeHashtagKeywordList() {
return List.of("모바일디자인", "앱디자인", "웹디자인", "UI/UX디자인");
}
},
PM {
@Override
public List<String> getIncludeKeywordList() {
return List.of("PM", "Project Manager", "Product Manager", "PROJECT MANAGER",
"PRODUCT MANAGER", "프로젝트 매니저", "프로덕트 매니저");
public List<String> getIncludeTitleKeywordList() {
return List.of("PM", "Project Manager", "Product Manager", "프로젝트 매니저", "프로덕트 매니저");
}

@Override
public List<String> getExcludeKeywordList() {
public List<String> getExcludeTitleKeywordList() {
return null;
}

@Override
public List<String> getIncludeHashtagKeywordList() {
return List.of("개발PM", "PM(프로젝트매니저)", "PL(프로젝트리더)");
}
}

;
Expand All @@ -141,6 +189,7 @@ public static RecruitKeyword getRecruitKeywordFromProfileJob(Job job) {
}


public abstract List<String> getIncludeKeywordList();
public abstract List<String> getExcludeKeywordList();
public abstract List<String> getIncludeTitleKeywordList();
public abstract List<String> getExcludeTitleKeywordList();
public abstract List<String> getIncludeHashtagKeywordList();
}
Loading