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: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ src/main/resources/.env

### Querydsl ###
src/main/generated/

### Claude Code ###
CLAUDE.md
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ dependencies {

// Prometheus
implementation 'io.micrometer:micrometer-registry-prometheus'

}

// Q클래스 생성 경로 설정
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
package org.sopt.kareer.domain.member.controller;


import static org.sopt.kareer.global.config.swagger.SwaggerResponseDescription.*;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.sopt.kareer.domain.member.dto.request.MemberOnboardRequest;
import org.sopt.kareer.domain.member.dto.request.MemberTermsRequest;
import org.sopt.kareer.domain.member.dto.request.MypageRequest;
import org.sopt.kareer.domain.member.dto.response.*;
import org.sopt.kareer.domain.member.service.*;
import org.sopt.kareer.domain.member.service.LocalizedOnboardQueryService;
import org.sopt.kareer.domain.member.service.MemberService;
import org.sopt.kareer.domain.roadmap.dto.response.RoadmapTestResponse;
import org.sopt.kareer.domain.roadmap.service.*;
import org.sopt.kareer.domain.roadmap.service.RoadMapService;
import org.sopt.kareer.domain.roadmap.service.RoadmapTranslationService;
import org.sopt.kareer.global.annotation.CustomExceptionDescription;
import org.sopt.kareer.global.auth.service.AuthService;
import org.sopt.kareer.global.config.swagger.SwaggerResponseDescription;
import org.sopt.kareer.global.response.BaseResponse;
import org.springframework.http.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import static org.sopt.kareer.global.config.swagger.SwaggerResponseDescription.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/members")
Expand All @@ -32,7 +37,7 @@ public class MemberController {

private final MemberService memberService;
private final RoadMapService roadMapService;
private final RoadmapAsyncService roadmapAsyncService;
private final RoadmapTranslationService roadmapTranslationService;
private final AuthService authService;
private final LocalizedOnboardQueryService localizedOnboardQueryService;

Expand Down Expand Up @@ -97,7 +102,9 @@ public ResponseEntity<BaseResponse<OnboardFieldsResponse>> getOnboardFields() {
public ResponseEntity<BaseResponse<Void>> generateRoadmap(
@AuthenticationPrincipal Long memberId) {

roadMapService.createRoadmap(memberId);
var target = roadMapService.createRoadmap(memberId);

roadmapTranslationService.translateAllLanguages(target);

return ResponseEntity.status(HttpStatus.OK)
.body(BaseResponse.ok("AI 로드맵 생성에 성공하였습니다."));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.sopt.kareer.domain.member.entity.enums;

public enum LocalizedOnboardCategoryType {
public enum LocalizedOnboardCategoryType {
FIELD,
MAJOR,
UNIVERSITY,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.sopt.kareer.domain.roadmap.dto.translation;

import java.util.List;

public record RoadmapTranslationTarget(List<PhaseTarget> phases) {

public record PhaseTarget(
Long phaseId,
String goal,
String description,
List<PhaseActionTarget> actions
) {}

public record PhaseActionTarget(
Long phaseActionId,
String title,
String description,
String importance,
List<GuidelineTarget> guidelines,
List<MistakeTarget> mistakes,
List<ActionItemTarget> actionItems
) {}

public record GuidelineTarget(Long guidelineId, String content) {}

public record MistakeTarget(Long mistakeId, String content) {}

public record ActionItemTarget(Long actionItemId, String title) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.sopt.kareer.domain.roadmap.entity;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Table(name = "action_item_translations",
uniqueConstraints = @UniqueConstraint(columnNames = {"action_item_id", "language"}))
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ActionItemTranslation {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "action_item_id", nullable = false)
private ActionItem actionItem;

@Column(nullable = false, length = 10)
private String language;

private String title;

public static ActionItemTranslation create(ActionItem actionItem, String language, String title) {
return ActionItemTranslation.builder()
.actionItem(actionItem)
.language(language)
.title(title)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.sopt.kareer.domain.roadmap.entity;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Table(name = "phase_action_guideline_translations",
uniqueConstraints = @UniqueConstraint(columnNames = {"guideline_id", "language"}))
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PhaseActionGuidelineTranslation {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "guideline_id", nullable = false)
private PhaseActionGuideline guideline;

@Column(nullable = false, length = 10)
private String language;

@Column(columnDefinition = "TEXT")
private String content;

public static PhaseActionGuidelineTranslation create(PhaseActionGuideline guideline, String language, String content) {
return PhaseActionGuidelineTranslation.builder()
.guideline(guideline)
.language(language)
.content(content)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.sopt.kareer.domain.roadmap.entity;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Table(name = "phase_action_mistake_translations",
uniqueConstraints = @UniqueConstraint(columnNames = {"mistake_id", "language"}))
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PhaseActionMistakeTranslation {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "mistake_id", nullable = false)
private PhaseActionMistake mistake;

@Column(nullable = false, length = 10)
private String language;

@Column(columnDefinition = "TEXT")
private String content;

public static PhaseActionMistakeTranslation create(PhaseActionMistake mistake, String language, String content) {
return PhaseActionMistakeTranslation.builder()
.mistake(mistake)
.language(language)
.content(content)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.sopt.kareer.domain.roadmap.entity;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Table(name = "phase_action_translations",
uniqueConstraints = @UniqueConstraint(columnNames = {"phase_actions_id", "language"}))
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PhaseActionTranslation {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "phase_actions_id", nullable = false)
private PhaseAction phaseAction;

@Column(nullable = false, length = 10)
private String language;

private String title;

@Column(columnDefinition = "TEXT")
private String description;

@Column(columnDefinition = "TEXT")
private String importance;

public static PhaseActionTranslation create(PhaseAction phaseAction, String language,
String title, String description, String importance) {
return PhaseActionTranslation.builder()
.phaseAction(phaseAction)
.language(language)
.title(title)
.description(description)
.importance(importance)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.sopt.kareer.domain.roadmap.entity;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Table(name = "phase_translations",
uniqueConstraints = @UniqueConstraint(columnNames = {"phase_id", "language"}))
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PhaseTranslation {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "phase_id", nullable = false)
private Phase phase;

@Column(nullable = false, length = 10)
private String language;

@Column(nullable = false)
private String goal;

@Column(nullable = false, columnDefinition = "TEXT")
private String description;

public static PhaseTranslation create(Phase phase, String language, String goal, String description) {
return PhaseTranslation.builder()
.phase(phase)
.language(language)
.goal(goal)
.description(description)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.sopt.kareer.domain.roadmap.repository;

import org.sopt.kareer.domain.roadmap.entity.ActionItemTranslation;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface ActionItemTranslationRepository extends JpaRepository<ActionItemTranslation, Long> {

List<ActionItemTranslation> findAllByActionItem_IdInAndLanguage(List<Long> actionItemIds, String language);

void deleteAllByActionItem_IdInAndLanguage(List<Long> actionItemIds, String language);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.sopt.kareer.domain.roadmap.repository;

import org.sopt.kareer.domain.roadmap.entity.PhaseActionGuidelineTranslation;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface PhaseActionGuidelineTranslationRepository extends JpaRepository<PhaseActionGuidelineTranslation, Long> {

List<PhaseActionGuidelineTranslation> findAllByGuideline_PhaseAction_IdIn(List<Long> phaseActionIds);

@Query("""
SELECT t.content
FROM PhaseActionGuidelineTranslation t
WHERE t.guideline.phaseAction.id = :phaseActionId
AND t.language = :language
ORDER BY t.guideline.id ASC
""")
List<String> findContentByPhaseActionIdAndLanguage(@Param("phaseActionId") Long phaseActionId,
@Param("language") String language);

void deleteAllByGuideline_PhaseAction_IdInAndLanguage(List<Long> phaseActionIds, String language);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.sopt.kareer.domain.roadmap.repository;

import org.sopt.kareer.domain.roadmap.entity.PhaseActionMistakeTranslation;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface PhaseActionMistakeTranslationRepository extends JpaRepository<PhaseActionMistakeTranslation, Long> {

List<PhaseActionMistakeTranslation> findAllByMistake_PhaseAction_IdIn(List<Long> phaseActionIds);

@Query("""
SELECT t.content
FROM PhaseActionMistakeTranslation t
WHERE t.mistake.phaseAction.id = :phaseActionId
AND t.language = :language
ORDER BY t.mistake.id ASC
""")
List<String> findContentByPhaseActionIdAndLanguage(@Param("phaseActionId") Long phaseActionId,
@Param("language") String language);

void deleteAllByMistake_PhaseAction_IdInAndLanguage(List<Long> phaseActionIds, String language);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.sopt.kareer.domain.roadmap.repository;

import org.sopt.kareer.domain.roadmap.entity.PhaseActionTranslation;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
import java.util.Optional;

public interface PhaseActionTranslationRepository extends JpaRepository<PhaseActionTranslation, Long> {

List<PhaseActionTranslation> findAllByPhaseAction_IdInAndLanguage(List<Long> phaseActionIds, String language);

Optional<PhaseActionTranslation> findByPhaseAction_IdAndLanguage(Long phaseActionId, String language);

void deleteAllByPhaseAction_IdInAndLanguage(List<Long> phaseActionIds, String language);
}
Loading
Loading