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
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ public class MentorService {
private final MentorRepository mentorRepository;

@Transactional
public Long register(MentorRequest request) {
Member member = memberRepository.findByEmail(request.email())
.orElseThrow(() -> new CustomRuntimeException(SignUpErrorCode.DUPLICATE_EMAIL));
Mentor mentor = request.toEntity(member.getId());
public Long register(Long memberId, MentorRequest request) {
Mentor mentor = request.toEntity(memberId);
return mentorRepository.save(mentor).getId();
}

Expand Down
10 changes: 6 additions & 4 deletions src/main/java/es/princip/ringus/domain/mentor/Mentor.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public class Mentor {
private Organization organization;

// 자기소개
@Column(name = "introduction", length = 500)
private String introduction;
@Embedded
private Introduction introduction;

// 선호 시간대
@Embedded
Expand Down Expand Up @@ -76,12 +76,13 @@ public Mentor(
final String nickname,
final Education education,
final Organization organization,
final String introduction,
final Introduction introduction,
final Timezone timezone,
final Set<MentoringField> mentoringField,
final List<Hashtag> hashtags,
final String message,
final Portfolio portfolio,
final ProfileImage profileImage,
final Long memberId
) {
this.nickname = nickname;
Expand All @@ -93,14 +94,15 @@ public Mentor(
this.hashtags = hashtags;
this.message = message;
this.portfolio = portfolio;
this.profileImage = profileImage;
this.memberId = memberId;
}

public void edit(final EditMentorRequest request) {
this.nickname = request.nickname();
this.education = request.education().toEntity();
this.organization = request.organization().toEntity();
this.introduction = request.introduction();
this.introduction = request.introduction().toEntity();
this.timezone = request.timezone().toEntity();
this.mentoringField = request.mentoringField().stream().map(MentoringField::valueOf).collect(Collectors.toSet());
this.hashtags = request.hashtags().stream().map(Hashtag::new).toList();
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/es/princip/ringus/domain/mentor/vo/Days.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package es.princip.ringus.domain.mentor.vo;

public enum Days {
MON, TUE, WED, THU, FRI, SAT, SUN
}
120 changes: 120 additions & 0 deletions src/main/java/es/princip/ringus/domain/mentor/vo/DetailedJob.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package es.princip.ringus.domain.mentor.vo;

public enum DetailedJob {
// Marketing
BRAND_MARKETING(JobCategory.MARKETING), // 브랜드 마케팅
PERFORMANCE_MARKETING(JobCategory.MARKETING), // 퍼포먼스 마케팅
DIGITAL_SOCIAL_MARKETING(JobCategory.MARKETING), // 디지털/소셜 마케팅
GROWTH_MARKETING(JobCategory.MARKETING), // 그로스 마케팅
PR(JobCategory.MARKETING), // PR
AE(JobCategory.MARKETING), // AE
CONTENT_MARKETING(JobCategory.MARKETING), // 콘텐츠 마케팅
CREATIVE_DIRECTING(JobCategory.MARKETING), // 크리에이티브 디렉팅
COPYWRITER(JobCategory.MARKETING), // 카피라이터
MEDIA_PLANNER(JobCategory.MARKETING), // 미디어 플래너
BROADCAST_PD(JobCategory.MARKETING), // 방송PD/영상PD
OTHER_MARKETING(JobCategory.MARKETING), // 기타

// Service Planning
SERVICE_PLANNING(JobCategory.SERVICE_PLANNING), // 서비스기획
PM_PO(JobCategory.SERVICE_PLANNING), // PM/PO
STRATEGY_PLANNING(JobCategory.SERVICE_PLANNING), // 전략 기획
OPERATION_PLANNING(JobCategory.SERVICE_PLANNING), // 운영/기획
BUSINESS_DEVELOPMENT(JobCategory.SERVICE_PLANNING), // 사업 개발
CX_MANAGER(JobCategory.SERVICE_PLANNING), // CX 매니저
STARTUP(JobCategory.SERVICE_PLANNING), // 창업
OTHER_SERVICE_PLANNING(JobCategory.SERVICE_PLANNING), // 기타

// Design
UX_UI_DESIGN(JobCategory.DESIGN), // UX/UI디자인
GRAPHIC_DESIGN(JobCategory.DESIGN), // 그래픽 디자인
PRODUCT_DESIGN(JobCategory.DESIGN), // 상품 디자인
BRAND_DESIGN(JobCategory.DESIGN), // 브랜드 디자인
WEB_DESIGN(JobCategory.DESIGN), // 웹 디자인
ART_DIRECTOR(JobCategory.DESIGN), // 아트 디렉터
OTHER_DESIGN(JobCategory.DESIGN), // 기타

// Development
FRONTEND(JobCategory.DEVELOPMENT), // 프론트엔드
BACKEND(JobCategory.DEVELOPMENT), // 백엔드
FULLSTACK(JobCategory.DEVELOPMENT), // 풀스택 개발자
IOS_ANDROID(JobCategory.DEVELOPMENT), // iOS/Android 개발자
DEVOPS(JobCategory.DEVELOPMENT), // DevOps 엔지니어
CLOUD(JobCategory.DEVELOPMENT), // 클라우드 엔지니어
SYSTEM_NETWORK(JobCategory.DEVELOPMENT), // 시스템/네트워크 엔지니어
SECURITY(JobCategory.DEVELOPMENT), // 보안 엔지니어
OTHER_DEVELOPMENT(JobCategory.DEVELOPMENT), // 기타

// Graduate School
DOMESTIC_GRADUATE_SCHOOL(JobCategory.GRADUATE_SCHOOL), // 국내 대학원
OVERSEAS_GRADUATE_SCHOOL(JobCategory.GRADUATE_SCHOOL), // 해외 대학원
OTHER_GRADUATE_SCHOOL(JobCategory.GRADUATE_SCHOOL), // 기타

// HR Support
HR_PLANNING(JobCategory.HR_SUPPORT), // 인사기획
RECRUITMENT(JobCategory.HR_SUPPORT), // 채용담당
TALENT_DEVELOPMENT(JobCategory.HR_SUPPORT), // 인재육성/교육담당
ORGANIZATION_CULTURE(JobCategory.HR_SUPPORT), // 조직문화담당
LABOR(JobCategory.HR_SUPPORT), // 노무담당
GENERAL_AFFAIRS(JobCategory.HR_SUPPORT), // 총무/경영지원
HR_OPERATION(JobCategory.HR_SUPPORT), // 인사운영
RECRUITER(JobCategory.HR_SUPPORT), // 리크루터
OTHER_HR_SUPPOReT(JobCategory.HR_SUPPORT), // 기타

// Sales Customer
B2B_SALES(JobCategory.SALES_CUSTOMER), // 기업영업(B2B)
B2C_SALES(JobCategory.SALES_CUSTOMER), // 개인영업(B2C)
OVERSEAS_SALES(JobCategory.SALES_CUSTOMER), // 해외영업
TECHNICAL_SALES(JobCategory.SALES_CUSTOMER), // 기술영업
SOLUTION_CONSULTANT(JobCategory.SALES_CUSTOMER), // 솔루션 컨설턴트
KAM(JobCategory.SALES_CUSTOMER), // 주요고객관리(KAM)
SALES_SUPPORT(JobCategory.SALES_CUSTOMER), // 영업관리/지원
CSM_CX(JobCategory.SALES_CUSTOMER), // CSM/CX
OTHER_SALES_CUSTOMER(JobCategory.SALES_CUSTOMER), // 기타

// Finance Consulting VC
CONSULTANT(JobCategory.FINANCE_CONSULTING_VC), // 컨설턴트
VC_INVESTMENT(JobCategory.FINANCE_CONSULTING_VC), // VC/투자
IB_PE_ALTERNATIVE_INVESTMENT(JobCategory.FINANCE_CONSULTING_VC), // IB/PE/대체투자
ANALYST(JobCategory.FINANCE_CONSULTING_VC), // 에널리스트
ACCOUNTING_FINANCE(JobCategory.FINANCE_CONSULTING_VC), // 회계/재무
OTHER_FINANCE_CONSULTING_VC(JobCategory.FINANCE_CONSULTING_VC), // 기타

// Data
DATA_SCIENTIST(JobCategory.DATA), // 데이터 사이언티스트
DATA_ENGINEER(JobCategory.DATA), // 데이터 엔지니어
DATA_ANALYST(JobCategory.DATA), // 데이터 애널리스트
BI_ENGINEER(JobCategory.DATA), // BI 엔지니어
MACHINE_LEARNING_ENGINEER(JobCategory.DATA), // 머신러닝 엔지니어
DATA_ARCHITECT(JobCategory.DATA), // 데이터 아키텍트
RESEARCH_ANALYST(JobCategory.DATA), // 리서치 애널리스트
OTHER_DATA(JobCategory.DATA), // 기타

// Medical
CLINICAL_DOCTOR(JobCategory.MEDICAL), // 임상의사
CLINICAL_RESEARCHER(JobCategory.MEDICAL), // 임상연구원
MEDICAL_DEVICE_RND(JobCategory.MEDICAL), // 의료기기 연구개발
PHARMACEUTICAL_RESEARCHER(JobCategory.MEDICAL), // 제약회사 연구원
BIO_RESEARCHER(JobCategory.MEDICAL), // 바이오 연구원
OTHER_MEDICAL(JobCategory.MEDICAL), // 기타

// Legal
LAWYER(JobCategory.LEGAL), // 변호사
LEGAL_COUNSEL(JobCategory.LEGAL), // 법무담당
PATENT(JobCategory.LEGAL), // 특허담당
COMPLIANCE(JobCategory.LEGAL), // 준법감시인(컴플라이언스)
LAW_FIRM_STAFF(JobCategory.LEGAL), // 법무법인 사무직
LEGAL_ADVISOR(JobCategory.LEGAL), // 법률자문
PATENT_ENGINEER(JobCategory.LEGAL), // 특허엔지니어
OTHER_LEGAL(JobCategory.LEGAL); // 기타

private final JobCategory category;

DetailedJob(JobCategory category) {
this.category = category;
}

public JobCategory getCategory() {
return category;
}
}
22 changes: 22 additions & 0 deletions src/main/java/es/princip/ringus/domain/mentor/vo/Introduction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package es.princip.ringus.domain.mentor.vo;

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

// 자기소개
@Getter
@Embeddable
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Introduction {
// 제목
@Column(name="introduction_title", length = 15)
private String title;
// 내용
@Column(name="introduction_content", length = 300)
private String content;
}
14 changes: 14 additions & 0 deletions src/main/java/es/princip/ringus/domain/mentor/vo/JobCategory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package es.princip.ringus.domain.mentor.vo;
public enum JobCategory {
MARKETING, // 마케팅/ 광고홍보/ 미디어
SERVICE_PLANNING, // 서비스 기획/ 사업/ 운영
DESIGN, // 디자인
DEVELOPMENT, // 개발
GRADUATE_SCHOOL, // 대학원
HR_SUPPORT, // 인사/ 채용/ 경영지원
SALES_CUSTOMER, // 영업/ 고객
FINANCE_CONSULTING_VC, // 금융/ 컨설팅/ VC/ 재무
DATA, // 데이터
MEDICAL, // 의료
LEGAL // 법률
}
16 changes: 14 additions & 2 deletions src/main/java/es/princip/ringus/domain/mentor/vo/Organization.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package es.princip.ringus.domain.mentor.vo;

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand All @@ -14,8 +17,17 @@
public class Organization {
// 조직명 (필수)
private String name;
// 직무 (필수)
private String role;

// 직무
@Enumerated(EnumType.STRING)
@Column(name = "job_category")
private JobCategory jobCategory;

// 세부 직무
@Enumerated(EnumType.STRING)
@Column(name = "detailed_job")
private DetailedJob detailedJob;

// 경력 (필수)
private int experience;
}
28 changes: 24 additions & 4 deletions src/main/java/es/princip/ringus/domain/mentor/vo/Timezone.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

import jakarta.persistence.Embeddable;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalTime;
import java.util.Set;
import java.util.stream.Collectors;

@Getter
@Embeddable
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Timezone {

private String days;
private LocalTime startTime;
private LocalTime endTime;

Expand All @@ -23,4 +23,24 @@ private void validateTime(LocalTime time) {
throw new IllegalArgumentException("Time must be between 8:00 AM and 11:30 PM in 30-minute intervals");
}
}

public Timezone(
final Set<Days> days,
final LocalTime startTime,
final LocalTime endTime
) {
this.days = days.stream()
.map(Days::name)
.collect(Collectors.joining(", "));
validateTime(startTime);
this.startTime = startTime;
validateTime(endTime);
this.endTime = endTime;
}

public Set<Days> getDays() {
return Set.of(days.split(", ")).stream()
.map(Days::valueOf)
.collect(Collectors.toSet());
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package es.princip.ringus.infra.storage.api;

import es.princip.ringus.domain.exception.MemberErrorCode;
import es.princip.ringus.global.annotation.SessionMemberId;
import es.princip.ringus.global.exception.CustomRuntimeException;
import es.princip.ringus.global.util.ApiResponseWrapper;
import es.princip.ringus.infra.storage.application.StorageProfileImageService;
Expand All @@ -23,15 +24,8 @@ public class ProfileImageController implements ProfileImageControllerDocs {
*/
@PostMapping("/image")
public ResponseEntity<ApiResponseWrapper<Void>> uploadProfileImage(
@ModelAttribute ProfileUploadRequest request,
HttpSession session
@ModelAttribute ProfileUploadRequest request
) {

Long memberId = (Long)session.getAttribute("memberId");
if(memberId == null){
throw new CustomRuntimeException(MemberErrorCode.SESSION_EXPIRED);
}

String filePath = storageProfileService.uploadProfileImage(request);
return ResponseEntity.ok(ApiResponseWrapper.success(HttpStatus.OK, filePath));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ public interface ProfileImageControllerDocs {
@PostMapping(value = "/image", consumes = "multipart/form-data")
ResponseEntity<ApiResponseWrapper<Void>> uploadProfileImage(
@Parameter(description = "프로필 이미지 업로드 요청 데이터 (폼데이터 형식)", required = true)
@ModelAttribute ProfileUploadRequest request,

@Parameter(hidden = true)
HttpSession session
@ModelAttribute ProfileUploadRequest request
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package es.princip.ringus.presentation.common.dto;

import es.princip.ringus.domain.mentor.vo.Introduction;

public record IntroductionRequest(
String title,
String content
) {
public Introduction toEntity() {
return new Introduction(title, content);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package es.princip.ringus.presentation.common.dto;

import es.princip.ringus.domain.mentor.vo.DetailedJob;
import es.princip.ringus.domain.mentor.vo.JobCategory;
import es.princip.ringus.domain.mentor.vo.Organization;

public record OrganizationRequest(
String name,
String role,
int experience
String name,
JobCategory jobCategory,
DetailedJob detailedJob,
int experience
) {
public Organization toEntity() {
return new Organization(name, role, experience);
return new Organization(name, jobCategory, detailedJob, experience);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package es.princip.ringus.presentation.mentor;

import es.princip.ringus.application.mentor.service.MentorService;
import es.princip.ringus.global.annotation.SessionMemberId;
import es.princip.ringus.global.util.ApiResponseWrapper;
import es.princip.ringus.presentation.mentor.dto.EditMentorRequest;
import es.princip.ringus.presentation.mentor.dto.EditMentorResponse;
Expand All @@ -15,13 +16,13 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/mentor")
public class MentorController implements MentorControllerDocs{
public class MentorController implements MentorControllerDocs{

private final MentorService mentorService;

@PostMapping
public ResponseEntity<ApiResponseWrapper<MentorResponse>> create(@Valid @RequestBody MentorRequest request) {
MentorResponse response = MentorResponse.from(mentorService.register(request));
public ResponseEntity<ApiResponseWrapper<MentorResponse>> create(@SessionMemberId Long memberId, @Valid @RequestBody MentorRequest request) {
MentorResponse response = MentorResponse.from(mentorService.register(memberId, request));
return ResponseEntity.ok(ApiResponseWrapper.success(HttpStatus.OK, "성공", response));
}

Expand Down
Loading