Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2c6c145
Initial commit
jinhahakim Oct 18, 2024
f292a2b
:tada:Setup
Oct 18, 2024
c72c992
add properties file
Oct 18, 2024
0dae6f8
update
Oct 18, 2024
008ef12
fix: conflict 해결
minahYu Nov 22, 2024
c26e189
fix: 패키지 이름 변경
minahYu Nov 22, 2024
969abac
chore: postgresql 의존성 추가
minahYu Nov 22, 2024
9e972dd
feat: CompanyInfo 요청 DTO 생성
minahYu Nov 22, 2024
13706ea
feat: Consulting 요청 DTO 생성
minahYu Nov 22, 2024
c284fe9
feat: Consulting 응답 DTO 생성
minahYu Nov 22, 2024
4931c35
feat: ConsultingErrorCode 생성
minahYu Nov 22, 2024
a9a2965
feat: Company 엔티티 생성
minahYu Nov 22, 2024
29d2ddc
feat: CompanyRepository 생성 및 CompanyRepository에 existsByUserId 메서드 구현
minahYu Nov 22, 2024
e10d428
feat: ConsultingController 및 createConsulting 메서드 생성
minahYu Nov 22, 2024
5b6941d
feat: ConsultingService에 sendToAi 메서드 구현
minahYu Nov 22, 2024
3f18563
feat: CompanyService에 saveCompanyInfo 메서드 구현
minahYu Nov 22, 2024
61c2e98
refac: createConsulting 메서드 리턴타입 변경
minahYu Nov 22, 2024
cc43e18
feat: Member와 Company 간의 연관관계 설정 및 매핑
minahYu Nov 23, 2024
87722a7
feat: Consulting 엔티티 생성
minahYu Nov 23, 2024
18c0742
feat: Consulting과 Company간의 연관관계 설정 및 매핑
minahYu Nov 23, 2024
ba04ead
feat: CommonErrorCode 생성
minahYu Nov 23, 2024
3c884e9
feat: ConsultingRepository 생성
minahYu Nov 23, 2024
ccafe6f
fix: 테이블 매핑 변경에 따른 saveCompanyInfo 메서드 수정
minahYu Nov 23, 2024
022c191
feat: Company, Consulting 엔티티에 getter 어노테이션 추가
minahYu Nov 24, 2024
7b45342
feat: Consulting 관련 DTO 생성 및 변경
minahYu Nov 24, 2024
f706a2c
feat: Consulting 관련 에러코드 추가
minahYu Nov 24, 2024
8b97925
feat: ConsultingRepository에 findByCompanyId 추가
minahYu Nov 24, 2024
d79d9a8
feat: ConsultingRequest에 JsonProperty 어노테이션 추가
minahYu Nov 24, 2024
520efc2
refac: sendToAi 메서드 수정
minahYu Nov 24, 2024
546c289
remove: 불필요한 코드 삭제
minahYu Nov 24, 2024
aca3657
refac: createOrGetConsulting 메서드 수정
minahYu Nov 24, 2024
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Backend
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
runtimeOnly 'org.postgresql:postgresql'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
Expand All @@ -48,4 +49,4 @@ dependencies {

tasks.named('test') {
useJUnitPlatform()
}
}
Empty file modified gradlew
100644 → 100755
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.swOnCampus.AIPlatform.domain.consulting.entity;

import com.swOnCampus.AIPlatform.domain.member.entity.Member;
import com.swOnCampus.AIPlatform.global.entity.BaseEntity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "company")
public class Company extends BaseEntity {

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

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", nullable = false)
private Member member;

@Column(nullable = false)
private String name;

@Column(nullable = false)
private String companySize;

@Column(nullable = false)
private String industry;

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

@OneToOne(mappedBy = "company", cascade = CascadeType.ALL, orphanRemoval = true)
private Consulting consulting;

@Builder
public Company(Member member, String name, String companySize, String industry,
String painPoint) {
this.member = member;
this.name = name;
this.companySize = companySize;
this.industry = industry;
this.painPoint = painPoint;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.swOnCampus.AIPlatform.domain.consulting.entity;

import com.swOnCampus.AIPlatform.global.entity.BaseEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "consulting")
public class Consulting extends BaseEntity {

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

@OneToOne
@JoinColumn(name = "company_id", nullable = false)
private Company company; // 기업 입력 정보 (채팅방)

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

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

@Builder
public Consulting(Company company, String result, String summary) {
this.company = company;
this.result = result;
this.summary = summary;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.swOnCampus.AIPlatform.domain.consulting.exception;

import com.swOnCampus.AIPlatform.global.exception.ErrorCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;

@Getter
@RequiredArgsConstructor
public enum ConsultingErrorCode implements ErrorCode {
// 404
NOT_EXIST_CONSULTING(HttpStatus.NOT_FOUND, "해당 기업에 대한 컨설팅 결과가 존재하지 않습니다.");

private final HttpStatus httpStatus;
private final String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.swOnCampus.AIPlatform.domain.consulting.repository;

import com.swOnCampus.AIPlatform.domain.consulting.entity.Company;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CompanyRepository extends JpaRepository<Company, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.swOnCampus.AIPlatform.domain.consulting.repository;

import com.swOnCampus.AIPlatform.domain.consulting.entity.Consulting;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ConsultingRepository extends JpaRepository<Consulting, Long> {

Optional<Consulting> findByCompanyId(Long companyId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.swOnCampus.AIPlatform.domain.consulting.service;

import com.swOnCampus.AIPlatform.domain.consulting.web.dto.request.CompanyInfoRequest;
import com.swOnCampus.AIPlatform.domain.consulting.web.dto.response.ConsultingResponse;

public interface CompanyService {

ConsultingResponse createOrGetConsulting(
Long memberId,
CompanyInfoRequest companyInfoRequest,
Long chatRoomId
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.swOnCampus.AIPlatform.domain.consulting.service;

import com.swOnCampus.AIPlatform.domain.consulting.entity.Company;
import com.swOnCampus.AIPlatform.domain.consulting.entity.Consulting;
import com.swOnCampus.AIPlatform.domain.consulting.exception.ConsultingErrorCode;
import com.swOnCampus.AIPlatform.domain.consulting.repository.CompanyRepository;
import com.swOnCampus.AIPlatform.domain.consulting.repository.ConsultingRepository;
import com.swOnCampus.AIPlatform.domain.consulting.web.dto.ConsultingSave;
import com.swOnCampus.AIPlatform.domain.consulting.web.dto.request.CompanyInfoRequest;
import com.swOnCampus.AIPlatform.domain.consulting.web.dto.request.ConsultingRequest;
import com.swOnCampus.AIPlatform.domain.consulting.web.dto.response.ConsultingResponse;
import com.swOnCampus.AIPlatform.domain.member.entity.Member;
import com.swOnCampus.AIPlatform.domain.member.repository.MemberRepository;
import com.swOnCampus.AIPlatform.global.exception.CommonErrorCode;
import com.swOnCampus.AIPlatform.global.exception.GlobalException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class CompanyServiceImpl implements CompanyService {

private final CompanyRepository companyRepository;
private final MemberRepository memberRepository;
private final ConsultingRepository consultingRepository;
private final ConsultingService consultingService;

@Override
public ConsultingResponse createOrGetConsulting(
Long memberId,
CompanyInfoRequest companyInfoRequest,
Long companyId // 채팅방 id
) {
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new GlobalException(CommonErrorCode.NOT_EXIST_MEMBER));

if (companyId == null) {
companyId = createCompanyWithConsulting(member, companyInfoRequest);
}
Consulting consulting = consultingRepository.findByCompanyId(companyId)
.orElseThrow(() -> new GlobalException(ConsultingErrorCode.NOT_EXIST_CONSULTING));

return new ConsultingResponse(consulting.getSummary());
}

private Long createCompanyWithConsulting(Member member, CompanyInfoRequest companyInfoRequest) {
Company company = Company.builder()
.member(member)
.name(companyInfoRequest.name())
.companySize(companyInfoRequest.companySize())
.industry(companyInfoRequest.industry())
.painPoint(companyInfoRequest.painPoint())
.build();
companyRepository.save(company);

ConsultingRequest consultingRequest = new ConsultingRequest(
companyInfoRequest.industry(),
companyInfoRequest.companySize(),
companyInfoRequest.painPoint()
);

ConsultingSave result = consultingService.getConsultingResult(consultingRequest);

Consulting consulting = Consulting.builder()
.company(company)
.result(result.result())
.summary(result.summary())
.build();
consultingRepository.save(consulting);

return consulting.getCompany().getId();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.swOnCampus.AIPlatform.domain.consulting.service;

import com.swOnCampus.AIPlatform.domain.consulting.web.dto.ConsultingSave;
import com.swOnCampus.AIPlatform.domain.consulting.web.dto.request.ConsultingRequest;

public interface ConsultingService {

ConsultingSave getConsultingResult(ConsultingRequest request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.swOnCampus.AIPlatform.domain.consulting.service;

import com.swOnCampus.AIPlatform.domain.consulting.web.dto.ConsultingSave;
import com.swOnCampus.AIPlatform.domain.consulting.web.dto.request.ConsultingRequest;
import com.swOnCampus.AIPlatform.domain.consulting.web.dto.response.ConsultingAiResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

@Service
@RequiredArgsConstructor
public class ConsultingServiceImpl implements ConsultingService {

private final RestTemplate restTemplate;

@Value("${ai.api.url}")
private String aiApiUrl;

@Override
public ConsultingSave getConsultingResult(ConsultingRequest request) {
ConsultingSave response = new ConsultingSave(
sendRequestToAi(request, false).result(),
sendRequestToAi(request, true).result()
);

return response;
}

private ConsultingAiResponse sendRequestToAi(ConsultingRequest request, boolean summary) {
String url = UriComponentsBuilder.fromHttpUrl(aiApiUrl + "/api/consulting")
.queryParam("summary", summary)
.toUriString();

return restTemplate.postForObject(url, request, ConsultingAiResponse.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.swOnCampus.AIPlatform.domain.consulting.web.controller;

import com.swOnCampus.AIPlatform.domain.consulting.service.CompanyService;
import com.swOnCampus.AIPlatform.domain.consulting.web.dto.request.CompanyInfoRequest;
import com.swOnCampus.AIPlatform.domain.consulting.web.dto.response.ConsultingResponse;
import com.swOnCampus.AIPlatform.domain.member.entity.Member;
import com.swOnCampus.AIPlatform.global.annotation.LoginMember;
import com.swOnCampus.AIPlatform.global.response.ApiResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/consulting")
public class ConsultingController {

private final CompanyService companyService;

@PostMapping()
public ResponseEntity<ApiResponse<?>> createConsulting(
@LoginMember Member member,
@RequestBody CompanyInfoRequest companyInfoRequest,
@RequestParam(required = false) Long companyId // 채팅방 id
) {
ConsultingResponse result = companyService.createOrGetConsulting(
member.getMemberId(), companyInfoRequest, companyId);

ApiResponse<ConsultingResponse> response = ApiResponse.createSuccess(HttpStatus.OK.value(),
result, "컨설팅 결과가 생성되었습니다.");

return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.swOnCampus.AIPlatform.domain.consulting.web.dto;

public record ConsultingSave(
String result,
String summary
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.swOnCampus.AIPlatform.domain.consulting.web.dto.request;

import jakarta.validation.constraints.NotBlank;

public record CompanyInfoRequest(
@NotBlank(message="회사명을 입력해주세요.")
String name,
@NotBlank(message="기업규모를 입력해주세요.")
String companySize,
@NotBlank(message="산업 분야를 입력해주세요.")
String industry,
@NotBlank(message="Pain Point를 입력해주세요.")
String painPoint
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.swOnCampus.AIPlatform.domain.consulting.web.dto.request;

import com.fasterxml.jackson.annotation.JsonProperty;

public record ConsultingRequest(
@JsonProperty("industry") String industry,
@JsonProperty("company_size") String companySize,
@JsonProperty("pain_point") String painPoint
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.swOnCampus.AIPlatform.domain.consulting.web.dto.response;

public record ConsultingAiResponse(
String result
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.swOnCampus.AIPlatform.domain.consulting.web.dto.response;

public record ConsultingResponse(
String summary
) {

}
Loading
Loading