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
2 changes: 1 addition & 1 deletion build/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ info:
description: 공각심 API 문서
servers:
- url: 'http://localhost:3000/'
- url: 'http://13.125.231.189:3000/'
- url: 'http://13.209.11.7:3000/'
components:
securitySchemes:
BearerAuth:
Expand Down
10 changes: 0 additions & 10 deletions src/repositories/user.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,6 @@ export class SuggestionRepository {
});
}

// static async findSimilarUsersCertifications(userInfo: UserWithDetails) {
// const categoryNames = userInfo.users.map((uc) => uc.category.name);

// return prisma.certification.findMany({
// where: {
// category: { in: categoryNames },
// },
// take: 3,
// });
// }

// 신규 사용자와 일치하는 사용자가 없다면, 랜덤으로 certification에서 자동 3개 추천
static async findDefaultCertificationsByCategory(categoryNames: string[]) {
Expand Down
43 changes: 39 additions & 4 deletions src/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,49 @@ export class SuggestionService {

if (!users || users.length < 1) {
console.log("사용자가 카테고리를 선택하지 않았습니다.");
return await this.getDefaultRecommendations(userInfo);
return await this.getNoCategoryRecommend(userInfo);
}

const similarUsers = await this.findSimilarUsers(userInfo);

if (similarUsers.length > 0) {
if (Array.isArray(similarUsers) && similarUsers.length > 0) {
// 유사 사용자들의 exam 제목 추출 (중복 제거)
const examTitlesSet = new Set<string>();
similarUsers.forEach(({ user }) => {
user.exams.forEach((exam) => {
examTitlesSet.add(exam.title);
});
});

const examTitles = Array.from(examTitlesSet);


// 만약 추출된 exam 제목이 없으면 기본 추천 호출
if (examTitles.length === 0) {
return await this.getDefaultRecommendations(userInfo);
}

// exam 제목과 Certification.name이 일치하는 자격증 조회
const recommendedCertifications = await SuggestionRepository.getCertificationsByExamTitles(examTitles);

// 만약 추천된 자격증이 없으면 기본 추천 호출
if (!recommendedCertifications || recommendedCertifications.length === 0) {
return await this.getDefaultRecommendations(userInfo);
}

return this.mapToDto(recommendedCertifications);
}


// 유사 사용자가 없는 경우 기본 추천 실행
return await this.getDefaultRecommendations(userInfo);

} catch (error) {
console.error("추천 생성 중 오류:", error);
throw error;
}
}



// 유사 사용자 찾기: 전체 사용자 중에서 현재 사용자와의 유사도 계산
private static async findSimilarUsers(userInfo: UserWithDetails): Promise<UserSimilarityInfo[]> {
const allUsers = await SuggestionRepository.getAllUsersWithCategories();
Expand Down Expand Up @@ -112,6 +127,26 @@ export class SuggestionService {
category: cert.category,
})).slice(0, 3);
}

// 카테고리 없는 경우
private static async getNoCategoryRecommend(userInfo: UserWithDetails): Promise<SuggestInfoDto[]> {
// 지정된 자격증 ID 목록
const defaultCertificationIds = [1, 8, 27]; // TOEIC, 컴퓨터활용능력 1급 필기, 테셋

const defaultCertifications = await prisma.certification.findMany({
where: {
id: { in: defaultCertificationIds },
},
select: {
id: true,
name: true,
category: true,
},
orderBy: { id: 'asc' },
});

return this.mapToDto(defaultCertifications);
}
}

/** 가장 임박한 시험 최대 3개 조회 */
Expand Down