diff --git a/src/main/java/es/princip/ringus/application/mentor/service/MentorService.java b/src/main/java/es/princip/ringus/application/mentor/service/MentorService.java index 280dc9c..466b163 100644 --- a/src/main/java/es/princip/ringus/application/mentor/service/MentorService.java +++ b/src/main/java/es/princip/ringus/application/mentor/service/MentorService.java @@ -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(); } diff --git a/src/main/java/es/princip/ringus/domain/mentor/Mentor.java b/src/main/java/es/princip/ringus/domain/mentor/Mentor.java index d958a64..8fd90ca 100644 --- a/src/main/java/es/princip/ringus/domain/mentor/Mentor.java +++ b/src/main/java/es/princip/ringus/domain/mentor/Mentor.java @@ -38,8 +38,8 @@ public class Mentor { private Organization organization; // 자기소개 - @Column(name = "introduction", length = 500) - private String introduction; + @Embedded + private Introduction introduction; // 선호 시간대 @Embedded @@ -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, final List hashtags, final String message, final Portfolio portfolio, + final ProfileImage profileImage, final Long memberId ) { this.nickname = nickname; @@ -93,6 +94,7 @@ public Mentor( this.hashtags = hashtags; this.message = message; this.portfolio = portfolio; + this.profileImage = profileImage; this.memberId = memberId; } @@ -100,7 +102,7 @@ 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(); diff --git a/src/main/java/es/princip/ringus/domain/mentor/vo/Days.java b/src/main/java/es/princip/ringus/domain/mentor/vo/Days.java new file mode 100644 index 0000000..0449aea --- /dev/null +++ b/src/main/java/es/princip/ringus/domain/mentor/vo/Days.java @@ -0,0 +1,5 @@ +package es.princip.ringus.domain.mentor.vo; + +public enum Days { + MON, TUE, WED, THU, FRI, SAT, SUN +} \ No newline at end of file diff --git a/src/main/java/es/princip/ringus/domain/mentor/vo/DetailedJob.java b/src/main/java/es/princip/ringus/domain/mentor/vo/DetailedJob.java new file mode 100644 index 0000000..b3a95c6 --- /dev/null +++ b/src/main/java/es/princip/ringus/domain/mentor/vo/DetailedJob.java @@ -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; + } +} \ No newline at end of file diff --git a/src/main/java/es/princip/ringus/domain/mentor/vo/Introduction.java b/src/main/java/es/princip/ringus/domain/mentor/vo/Introduction.java new file mode 100644 index 0000000..8d4b97b --- /dev/null +++ b/src/main/java/es/princip/ringus/domain/mentor/vo/Introduction.java @@ -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; +} \ No newline at end of file diff --git a/src/main/java/es/princip/ringus/domain/mentor/vo/JobCategory.java b/src/main/java/es/princip/ringus/domain/mentor/vo/JobCategory.java new file mode 100644 index 0000000..3ead55a --- /dev/null +++ b/src/main/java/es/princip/ringus/domain/mentor/vo/JobCategory.java @@ -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 // 법률 +} \ No newline at end of file diff --git a/src/main/java/es/princip/ringus/domain/mentor/vo/Organization.java b/src/main/java/es/princip/ringus/domain/mentor/vo/Organization.java index cb49f53..0f64738 100644 --- a/src/main/java/es/princip/ringus/domain/mentor/vo/Organization.java +++ b/src/main/java/es/princip/ringus/domain/mentor/vo/Organization.java @@ -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; @@ -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; } diff --git a/src/main/java/es/princip/ringus/domain/mentor/vo/Timezone.java b/src/main/java/es/princip/ringus/domain/mentor/vo/Timezone.java index 9284af5..eb1baa2 100644 --- a/src/main/java/es/princip/ringus/domain/mentor/vo/Timezone.java +++ b/src/main/java/es/princip/ringus/domain/mentor/vo/Timezone.java @@ -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; @@ -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, + 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 getDays() { + return Set.of(days.split(", ")).stream() + .map(Days::valueOf) + .collect(Collectors.toSet()); + } } \ No newline at end of file diff --git a/src/main/java/es/princip/ringus/infra/storage/api/ProfileImageController.java b/src/main/java/es/princip/ringus/infra/storage/api/ProfileImageController.java index 2d00f60..d169547 100644 --- a/src/main/java/es/princip/ringus/infra/storage/api/ProfileImageController.java +++ b/src/main/java/es/princip/ringus/infra/storage/api/ProfileImageController.java @@ -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; @@ -23,15 +24,8 @@ public class ProfileImageController implements ProfileImageControllerDocs { */ @PostMapping("/image") public ResponseEntity> 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)); } diff --git a/src/main/java/es/princip/ringus/infra/storage/api/ProfileImageControllerDocs.java b/src/main/java/es/princip/ringus/infra/storage/api/ProfileImageControllerDocs.java index b8f346c..5e20b47 100644 --- a/src/main/java/es/princip/ringus/infra/storage/api/ProfileImageControllerDocs.java +++ b/src/main/java/es/princip/ringus/infra/storage/api/ProfileImageControllerDocs.java @@ -32,9 +32,6 @@ public interface ProfileImageControllerDocs { @PostMapping(value = "/image", consumes = "multipart/form-data") ResponseEntity> uploadProfileImage( @Parameter(description = "프로필 이미지 업로드 요청 데이터 (폼데이터 형식)", required = true) - @ModelAttribute ProfileUploadRequest request, - - @Parameter(hidden = true) - HttpSession session + @ModelAttribute ProfileUploadRequest request ); } diff --git a/src/main/java/es/princip/ringus/presentation/common/dto/IntroductionRequest.java b/src/main/java/es/princip/ringus/presentation/common/dto/IntroductionRequest.java new file mode 100644 index 0000000..9c1a6bf --- /dev/null +++ b/src/main/java/es/princip/ringus/presentation/common/dto/IntroductionRequest.java @@ -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); + } +} \ No newline at end of file diff --git a/src/main/java/es/princip/ringus/presentation/common/dto/OrganizationRequest.java b/src/main/java/es/princip/ringus/presentation/common/dto/OrganizationRequest.java index 4109d8c..daa6b6b 100644 --- a/src/main/java/es/princip/ringus/presentation/common/dto/OrganizationRequest.java +++ b/src/main/java/es/princip/ringus/presentation/common/dto/OrganizationRequest.java @@ -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); } } \ No newline at end of file diff --git a/src/main/java/es/princip/ringus/presentation/mentor/MentorController.java b/src/main/java/es/princip/ringus/presentation/mentor/MentorController.java index 533452b..84eda71 100644 --- a/src/main/java/es/princip/ringus/presentation/mentor/MentorController.java +++ b/src/main/java/es/princip/ringus/presentation/mentor/MentorController.java @@ -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; @@ -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> create(@Valid @RequestBody MentorRequest request) { - MentorResponse response = MentorResponse.from(mentorService.register(request)); + public ResponseEntity> create(@SessionMemberId Long memberId, @Valid @RequestBody MentorRequest request) { + MentorResponse response = MentorResponse.from(mentorService.register(memberId, request)); return ResponseEntity.ok(ApiResponseWrapper.success(HttpStatus.OK, "성공", response)); } diff --git a/src/main/java/es/princip/ringus/presentation/mentor/MentorControllerDocs.java b/src/main/java/es/princip/ringus/presentation/mentor/MentorControllerDocs.java index 4823876..c645ae6 100644 --- a/src/main/java/es/princip/ringus/presentation/mentor/MentorControllerDocs.java +++ b/src/main/java/es/princip/ringus/presentation/mentor/MentorControllerDocs.java @@ -1,5 +1,6 @@ package es.princip.ringus.presentation.mentor; +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; @@ -24,7 +25,7 @@ public interface MentorControllerDocs { @ApiResponse(responseCode = "409", description = "이미 가입된 이메일") }) @PostMapping - ResponseEntity> create(@Valid @RequestBody @Parameter(description = "멘토 등록 요청") MentorRequest request); + ResponseEntity> create(@SessionMemberId Long memberId, @Valid @RequestBody @Parameter(description = "멘토 등록 요청") MentorRequest request); @Operation(summary = "멘토 수정", description = "기존 멘토 정보를 수정합니다.") @ApiResponses(value = { diff --git a/src/main/java/es/princip/ringus/presentation/mentor/dto/EditMentorRequest.java b/src/main/java/es/princip/ringus/presentation/mentor/dto/EditMentorRequest.java index 5e20c13..9fe8612 100644 --- a/src/main/java/es/princip/ringus/presentation/mentor/dto/EditMentorRequest.java +++ b/src/main/java/es/princip/ringus/presentation/mentor/dto/EditMentorRequest.java @@ -1,6 +1,7 @@ package es.princip.ringus.presentation.mentor.dto; import es.princip.ringus.presentation.common.dto.EducationRequest; +import es.princip.ringus.presentation.common.dto.IntroductionRequest; import es.princip.ringus.presentation.common.dto.OrganizationRequest; import es.princip.ringus.presentation.common.dto.PortfolioRequest; import jakarta.validation.constraints.NotBlank; @@ -10,9 +11,8 @@ public record EditMentorRequest( @NotBlank Long mentorId, - @NotBlank String email, @NotBlank String nickname, - @NotBlank String introduction, + IntroductionRequest introduction, Set mentoringField, EducationRequest education, OrganizationRequest organization, diff --git a/src/main/java/es/princip/ringus/presentation/mentor/dto/MentorRequest.java b/src/main/java/es/princip/ringus/presentation/mentor/dto/MentorRequest.java index afc4a42..80c88dd 100644 --- a/src/main/java/es/princip/ringus/presentation/mentor/dto/MentorRequest.java +++ b/src/main/java/es/princip/ringus/presentation/mentor/dto/MentorRequest.java @@ -2,10 +2,13 @@ import es.princip.ringus.domain.common.Education; import es.princip.ringus.domain.mentor.Mentor; -import es.princip.ringus.domain.mentor.vo.*; +import es.princip.ringus.domain.mentor.vo.Hashtag; +import es.princip.ringus.domain.mentor.vo.Introduction; +import es.princip.ringus.domain.mentor.vo.MentoringField; import es.princip.ringus.presentation.common.dto.EducationRequest; import es.princip.ringus.presentation.common.dto.OrganizationRequest; import es.princip.ringus.presentation.common.dto.PortfolioRequest; +import es.princip.ringus.presentation.common.dto.ProfileImageRequest; import jakarta.validation.constraints.NotBlank; import java.util.List; @@ -13,16 +16,16 @@ import java.util.stream.Collectors; public record MentorRequest( - @NotBlank String email, @NotBlank String nickname, - @NotBlank String introduction, + Introduction introduction, Set mentoringField, EducationRequest education, OrganizationRequest organization, TimezoneRequest timezone, List hashtags, String message, - PortfolioRequest portfolio + PortfolioRequest portfolio, + ProfileImageRequest image ) { public Mentor toEntity(Long memberId) { return Mentor.builder() @@ -35,6 +38,7 @@ public Mentor toEntity(Long memberId) { .hashtags(hashtags.stream().map(Hashtag::new).toList()) .message(message) .portfolio(portfolio.toEntity()) + .profileImage(image.toEntity()) .memberId(memberId) .build(); } diff --git a/src/main/java/es/princip/ringus/presentation/mentor/dto/TimezoneRequest.java b/src/main/java/es/princip/ringus/presentation/mentor/dto/TimezoneRequest.java index c224e1d..52288e3 100644 --- a/src/main/java/es/princip/ringus/presentation/mentor/dto/TimezoneRequest.java +++ b/src/main/java/es/princip/ringus/presentation/mentor/dto/TimezoneRequest.java @@ -1,14 +1,17 @@ package es.princip.ringus.presentation.mentor.dto; +import es.princip.ringus.domain.mentor.vo.Days; import es.princip.ringus.domain.mentor.vo.Timezone; import java.time.LocalTime; +import java.util.Set; public record TimezoneRequest ( + Set days, LocalTime startTime, LocalTime endTime ) { public Timezone toEntity() { - return new Timezone(startTime, endTime); + return new Timezone(days, startTime, endTime); } } \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0566387..b307594 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -25,6 +25,12 @@ spring: ddl-auto: validate properties: hibernate: + show_sql: true + format_sql: true + highlight_sql: true + use_sql_comments: true + jdbc: + time_zone: Asia/Seoul dialect: org.hibernate.dialect.MySQLDialect data: redis: diff --git a/src/main/resources/db/migration/V1__init.sql b/src/main/resources/db/migration/V1__init.sql index 88cfb3d..082d0b7 100644 --- a/src/main/resources/db/migration/V1__init.sql +++ b/src/main/resources/db/migration/V1__init.sql @@ -1,93 +1,117 @@ +CREATE TABLE bookmark ( + bookmark_id BIGINT NOT NULL AUTO_INCREMENT, + created_at DATETIME(6), + mentee_id BIGINT NOT NULL, + mentor_id BIGINT NOT NULL, + updated_at DATETIME(6), + PRIMARY KEY (bookmark_id) +); -CREATE TABLE `file_member` ( - `is_verified` bit(1) DEFAULT NULL, - `created_at` datetime(6) DEFAULT NULL, - `file_member_id` bigint NOT NULL AUTO_INCREMENT, - `member_id` bigint DEFAULT NULL, - `updated_at` datetime(6) DEFAULT NULL, - `file_path` varchar(255) DEFAULT NULL, - PRIMARY KEY (`file_member_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE file_member ( + is_verified BIT, + created_at DATETIME(6), + file_member_id BIGINT NOT NULL AUTO_INCREMENT, + member_id BIGINT, + updated_at DATETIME(6), + file_path VARCHAR(255), + PRIMARY KEY (file_member_id) +); -CREATE TABLE `member` ( - `is_file_verified` bit(1) NOT NULL, - `is_profile_registered` bit(1) NOT NULL, - `is_university_verified` bit(1) NOT NULL, - `created_at` datetime(6) DEFAULT NULL, - `member_id` bigint NOT NULL AUTO_INCREMENT, - `updated_at` datetime(6) DEFAULT NULL, - `email` varchar(255) NOT NULL, - `password` varchar(255) NOT NULL, - `member_type` enum('ADMIN','MENTEE','MENTOR') DEFAULT NULL, - PRIMARY KEY (`member_id`), - UNIQUE KEY `UKmbmcqelty0fbrvxp1q58dn57t` (`email`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE member ( + is_file_verified BIT NOT NULL, + is_profile_registered BIT NOT NULL, + is_university_verified BIT NOT NULL, + created_at DATETIME(6), + member_id BIGINT NOT NULL AUTO_INCREMENT, + updated_at DATETIME(6), + email VARCHAR(255) NOT NULL, + password VARCHAR(255) NOT NULL, + member_type ENUM ('ADMIN', 'MENTEE', 'MENTOR'), + PRIMARY KEY (member_id) +); -CREATE TABLE `mentee` ( - `member_id` bigint DEFAULT NULL, - `mentee_id` bigint NOT NULL AUTO_INCREMENT, - `introduction` varchar(500) DEFAULT NULL, - `file_name` varchar(255) NOT NULL, - `file_path` varchar(255) NOT NULL, - `major` varchar(255) DEFAULT NULL, - `nickname` varchar(255) DEFAULT NULL, - `school_name` varchar(255) DEFAULT NULL, - PRIMARY KEY (`mentee_id`), - UNIQUE KEY `UK1esk9x4yr6uocrt4obtej4wie` (`nickname`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE mentee ( + member_id BIGINT, + mentee_id BIGINT NOT NULL AUTO_INCREMENT, + introduction VARCHAR(500), + file_name VARCHAR(255) NOT NULL, + file_path VARCHAR(255) NOT NULL, + major VARCHAR(255), + nickname VARCHAR(255), + school_name VARCHAR(255), + PRIMARY KEY (mentee_id) +); -CREATE TABLE `mentor` ( - `end_time` time(6) DEFAULT NULL, - `experience` int DEFAULT NULL, - `start_time` time(6) DEFAULT NULL, - `member_id` bigint DEFAULT NULL, - `mentor_id` bigint NOT NULL AUTO_INCREMENT, - `message` varchar(50) DEFAULT NULL, - `introduction` varchar(500) DEFAULT NULL, - `description` varchar(255) DEFAULT NULL, - `file_name` varchar(255) NOT NULL, - `file_path` varchar(255) NOT NULL, - `major` varchar(255) DEFAULT NULL, - `name` varchar(255) DEFAULT NULL, - `nickname` varchar(255) DEFAULT NULL, - `role` varchar(255) DEFAULT NULL, - `school_name` varchar(255) DEFAULT NULL, - `url` varchar(255) DEFAULT NULL, - PRIMARY KEY (`mentor_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE mentor ( + end_time TIME(6), + experience INTEGER, + start_time TIME(6), + member_id BIGINT, + mentor_id BIGINT NOT NULL AUTO_INCREMENT, + introduction_title VARCHAR(15), + message VARCHAR(50), + introduction_content VARCHAR(300), + description VARCHAR(255), + file_name VARCHAR(255) NOT NULL, + file_path VARCHAR(255) NOT NULL, + major VARCHAR(255), + name VARCHAR(255), + nickname VARCHAR(255), + school_name VARCHAR(255), + url VARCHAR(255), + days VARCHAR(255), + detailed_job ENUM ( + 'ACCOUNTING_FINANCE', 'AE', 'ANALYST', 'ART_DIRECTOR', 'B2B_SALES', 'B2C_SALES', 'BACKEND', 'BIO_RESEARCHER', + 'BI_ENGINEER', 'BRAND_DESIGN', 'BRAND_MARKETING', 'BROADCAST_PD', 'BUSINESS_DEVELOPMENT', 'CLINICAL_DOCTOR', + 'CLINICAL_RESEARCHER', 'CLOUD', 'COMPLIANCE', 'CONSULTANT', 'CONTENT_MARKETING', 'COPYWRITER', + 'CREATIVE_DIRECTING', 'CSM_CX', 'CX_MANAGER', 'DATA_ANALYST', 'DATA_ARCHITECT', 'DATA_ENGINEER', 'DATA_SCIENTIST', + 'DEVOPS', 'DIGITAL_SOCIAL_MARKETING', 'DOMESTIC_GRADUATE_SCHOOL', 'FRONTEND', 'FULLSTACK', 'GENERAL_AFFAIRS', + 'GRAPHIC_DESIGN', 'GROWTH_MARKETING', 'HR_OPERATION', 'HR_PLANNING', 'IB_PE_ALTERNATIVE_INVESTMENT', + 'IOS_ANDROID', 'KAM', 'LABOR', 'LAWYER', 'LAW_FIRM_STAFF', 'LEGAL_ADVISOR', 'LEGAL_COUNSEL', + 'MACHINE_LEARNING_ENGINEER', 'MEDIA_PLANNER', 'MEDICAL_DEVICE_RND', 'OPERATION_PLANNING', 'ORGANIZATION_CULTURE', + 'OTHER_DATA', 'OTHER_DESIGN', 'OTHER_DEVELOPMENT', 'OTHER_FINANCE_CONSULTING_VC', 'OTHER_GRADUATE_SCHOOL', + 'OTHER_HR_SUPPORT', 'OTHER_LEGAL', 'OTHER_MARKETING', 'OTHER_MEDICAL', 'OTHER_SALES_CUSTOMER', + 'OTHER_SERVICE_PLANNING', 'OVERSEAS_GRADUATE_SCHOOL', 'OVERSEAS_SALES', 'PATENT', 'PATENT_ENGINEER', + 'PERFORMANCE_MARKETING', 'PHARMACEUTICAL_RESEARCHER', 'PM_PO', 'PR', 'PRODUCT_DESIGN', 'RECRUITER', + 'RECRUITMENT', 'RESEARCH_ANALYST', 'SALES_SUPPORT', 'SECURITY', 'SERVICE_PLANNING', 'SOLUTION_CONSULTANT', + 'STARTUP', 'STRATEGY_PLANNING', 'SYSTEM_NETWORK', 'TALENT_DEVELOPMENT', 'TECHNICAL_SALES', 'UX_UI_DESIGN', + 'VC_INVESTMENT', 'WEB_DESIGN' + ), + job_category ENUM ('DATA', 'DESIGN', 'DEVELOPMENT', 'FINANCE_CONSULTING_VC', 'GRADUATE_SCHOOL', 'HR_SUPPORT', 'LEGAL', 'MARKETING', 'MEDICAL', 'SALES_CUSTOMER', 'SERVICE_PLANNING'), + PRIMARY KEY (mentor_id) +); -CREATE TABLE `mentor_hashtags` ( - `mentor_id` bigint NOT NULL, - `value` varchar(255) DEFAULT NULL, - KEY `FKt3y0r48c7ok5lur8k568yt8kx` (`mentor_id`), - CONSTRAINT `FKt3y0r48c7ok5lur8k568yt8kx` FOREIGN KEY (`mentor_id`) REFERENCES `mentor` (`mentor_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE mentor_hashtags ( + mentor_id BIGINT NOT NULL, + value VARCHAR(255) +); -CREATE TABLE `mentor_mentoring_fields` ( - `mentor_id` bigint NOT NULL, - `mentoring_field` enum('INTERVIEW_PREPARATION','JOB_PREPARATION','PORTFOLIO','PRACTICAL_SKILLS') DEFAULT NULL, - KEY `FK97ao36m77up6wdjhov0y93pc2` (`mentor_id`), - CONSTRAINT `FK97ao36m77up6wdjhov0y93pc2` FOREIGN KEY (`mentor_id`) REFERENCES `mentor` (`mentor_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE mentor_mentoring_fields ( + mentor_id BIGINT NOT NULL, + mentoring_field ENUM ('INTERVIEW_PREPARATION', 'JOB_PREPARATION', 'PORTFOLIO', 'PRACTICAL_SKILLS') +); -CREATE TABLE `service_term` ( - `required` bit(1) DEFAULT NULL, - `service_term_tag` varchar(255) NOT NULL, - PRIMARY KEY (`service_term_tag`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE service_term ( + required BIT, + service_term_tag VARCHAR(255) NOT NULL, + PRIMARY KEY (service_term_tag) +); --- `service_term` 테이블에 3개 데이터 삽입 -INSERT INTO `service_term` (`service_term_tag`, `required`) VALUES - ('TERMS_OF_SERVICE', 1), - ('PRIVACY_POLICY', 1), - ('MARKETING_CONSENT', 0); -CREATE TABLE `service_term_agreement` ( - `agreed` bit(1) DEFAULT NULL, - `agreed_at` datetime(6) DEFAULT NULL, - `created_at` datetime(6) DEFAULT NULL, - `member_id` bigint NOT NULL, - `updated_at` datetime(6) DEFAULT NULL, - `tag` varchar(255) DEFAULT NULL, - KEY `FKl7bp8w5ehipkfnre066psfv7x` (`member_id`), - CONSTRAINT `FKl7bp8w5ehipkfnre066psfv7x` FOREIGN KEY (`member_id`) REFERENCES `member` (`member_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +CREATE TABLE service_term_agreement ( + agreed BIT, + agreed_at DATETIME(6), + created_at DATETIME(6), + member_id BIGINT NOT NULL, + updated_at DATETIME(6), + tag VARCHAR(255) +); + +-- 제약조건 추가 +ALTER TABLE member ADD CONSTRAINT UNIQUE (email); +ALTER TABLE mentee ADD CONSTRAINT UNIQUE (nickname); + +ALTER TABLE bookmark ADD CONSTRAINT FOREIGN KEY (mentee_id) REFERENCES mentee (mentee_id); +ALTER TABLE bookmark ADD CONSTRAINT FOREIGN KEY (mentor_id) REFERENCES mentor (mentor_id); +ALTER TABLE mentor_hashtags ADD FOREIGN KEY (mentor_id) REFERENCES mentor (mentor_id); +ALTER TABLE mentor_mentoring_fields ADD FOREIGN KEY (mentor_id) REFERENCES mentor (mentor_id); +ALTER TABLE service_term_agreement ADD FOREIGN KEY (member_id) REFERENCES member (member_id); \ No newline at end of file diff --git a/src/main/resources/db/migration/V2__addbookmarks.sql b/src/main/resources/db/migration/V2__addbookmarks.sql deleted file mode 100644 index 45f4350..0000000 --- a/src/main/resources/db/migration/V2__addbookmarks.sql +++ /dev/null @@ -1,106 +0,0 @@ - -CREATE TABLE IF NOT EXISTS `file_member` ( - `is_verified` bit(1) DEFAULT NULL, - `created_at` datetime(6) DEFAULT NULL, - `file_member_id` bigint NOT NULL AUTO_INCREMENT, - `member_id` bigint DEFAULT NULL, - `updated_at` datetime(6) DEFAULT NULL, - `file_path` varchar(255) DEFAULT NULL, - PRIMARY KEY (`file_member_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - -CREATE TABLE IF NOT EXISTS `member` ( - `is_file_verified` bit(1) NOT NULL, - `is_profile_registered` bit(1) NOT NULL, - `is_university_verified` bit(1) NOT NULL, - `created_at` datetime(6) DEFAULT NULL, - `member_id` bigint NOT NULL AUTO_INCREMENT, - `updated_at` datetime(6) DEFAULT NULL, - `email` varchar(255) NOT NULL, - `password` varchar(255) NOT NULL, - `member_type` enum('ADMIN','MENTEE','MENTOR') DEFAULT NULL, - PRIMARY KEY (`member_id`), - UNIQUE KEY `UKmbmcqelty0fbrvxp1q58dn57t` (`email`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - -CREATE TABLE IF NOT EXISTS `mentee` ( - `member_id` bigint DEFAULT NULL, - `mentee_id` bigint NOT NULL AUTO_INCREMENT, - `introduction` varchar(500) DEFAULT NULL, - `file_name` varchar(255) NOT NULL, - `file_path` varchar(255) NOT NULL, - `major` varchar(255) DEFAULT NULL, - `nickname` varchar(255) DEFAULT NULL, - `school_name` varchar(255) DEFAULT NULL, - PRIMARY KEY (`mentee_id`), - UNIQUE KEY `UK1esk9x4yr6uocrt4obtej4wie` (`nickname`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - -CREATE TABLE IF NOT EXISTS `mentor` ( - `end_time` time(6) DEFAULT NULL, - `experience` int DEFAULT NULL, - `start_time` time(6) DEFAULT NULL, - `member_id` bigint DEFAULT NULL, - `mentor_id` bigint NOT NULL AUTO_INCREMENT, - `message` varchar(50) DEFAULT NULL, - `introduction` varchar(500) DEFAULT NULL, - `description` varchar(255) DEFAULT NULL, - `file_name` varchar(255) NOT NULL, - `file_path` varchar(255) NOT NULL, - `major` varchar(255) DEFAULT NULL, - `name` varchar(255) DEFAULT NULL, - `nickname` varchar(255) DEFAULT NULL, - `role` varchar(255) DEFAULT NULL, - `school_name` varchar(255) DEFAULT NULL, - `url` varchar(255) DEFAULT NULL, - PRIMARY KEY (`mentor_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - -CREATE TABLE IF NOT EXISTS `mentor_hashtags` ( - `mentor_id` bigint NOT NULL, - `value` varchar(255) DEFAULT NULL, - KEY `FKt3y0r48c7ok5lur8k568yt8kx` (`mentor_id`), - CONSTRAINT `FKt3y0r48c7ok5lur8k568yt8kx` FOREIGN KEY (`mentor_id`) REFERENCES `mentor` (`mentor_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - -CREATE TABLE IF NOT EXISTS `mentor_mentoring_fields` ( - `mentor_id` bigint NOT NULL, - `mentoring_field` enum('INTERVIEW_PREPARATION','JOB_PREPARATION','PORTFOLIO','PRACTICAL_SKILLS') DEFAULT NULL, - KEY `FK97ao36m77up6wdjhov0y93pc2` (`mentor_id`), - CONSTRAINT `FK97ao36m77up6wdjhov0y93pc2` FOREIGN KEY (`mentor_id`) REFERENCES `mentor` (`mentor_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - -CREATE TABLE IF NOT EXISTS `service_term` ( - `required` bit(1) DEFAULT NULL, - `service_term_tag` varchar(255) NOT NULL, - PRIMARY KEY (`service_term_tag`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - --- `service_term` 테이블에 3개 데이터 삽입 -INSERT INTO `service_term` (`service_term_tag`, `required`) VALUES - ('TERMS_OF_SERVICE', 1), - ('PRIVACY_POLICY', 1), - ('MARKETING_CONSENT', 0); -CREATE TABLE IF NOT EXISTS `service_term_agreement` ( - `agreed` bit(1) DEFAULT NULL, - `agreed_at` datetime(6) DEFAULT NULL, - `created_at` datetime(6) DEFAULT NULL, - `member_id` bigint NOT NULL, - `updated_at` datetime(6) DEFAULT NULL, - `tag` varchar(255) DEFAULT NULL, - KEY `FKl7bp8w5ehipkfnre066psfv7x` (`member_id`), - CONSTRAINT `FKl7bp8w5ehipkfnre066psfv7x` FOREIGN KEY (`member_id`) REFERENCES `member` (`member_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - -CREATE TABLE IF NOT EXISTS `bookmark` ( - - `bookmark_id` BIGINT NOT NULL AUTO_INCREMENT, - `mentee_id` BIGINT NOT NULL, - `mentor_id` BIGINT NOT NULL, - `created_at` datetime(6) DEFAULT NULL, - `updated_at` datetime(6) DEFAULT NULL, - - PRIMARY KEY (`bookmark_id`), - CONSTRAINT `FK_bookmark_mentee` FOREIGN KEY (`mentee_id`) REFERENCES `mentee` (`mentee_id`) ON DELETE CASCADE, - CONSTRAINT `FK_bookmark_mentor` FOREIGN KEY (`mentor_id`) REFERENCES `mentor` (`mentor_id`) ON DELETE CASCADE - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/src/main/resources/db/migration/V2__insert_term.sql b/src/main/resources/db/migration/V2__insert_term.sql new file mode 100644 index 0000000..3bde3f1 --- /dev/null +++ b/src/main/resources/db/migration/V2__insert_term.sql @@ -0,0 +1,5 @@ +-- `service_term` 테이블에 3개 데이터 삽입 +INSERT INTO `service_term` (`service_term_tag`, `required`) VALUES + ('TERMS_OF_SERVICE', 1), + ('PRIVACY_POLICY', 1), + ('MARKETING_CONSENT', 0); \ No newline at end of file