Skip to content

Commit

Permalink
Feat: 요약 및 문제 생성 API 구현 (#33)
Browse files Browse the repository at this point in the history
* Style: formatting통일 (#30)

* Feat: 요약 및 문제 생성 API 구현 (#32)

* Rename: AI Task 도메인 이름 변경

- llm 으로 변경

* Refactor: LLM 도메인 애플리케이션 계층과 프레젠테이션 계층 응답 분리

* Feat: LLM 작업 진행 상태 확인 기능 구현

* Feat: 요약 및 문제 결과 조회 기능 구현

* Feat: 요약 및 문제 생성 기능 구현

- AI 서버와 통신하는 부분 제외하고 기능 구현
- 임시 UUID 를 통해 task 저장

* Feat: LLM 서버 콜백 기능 구현

- LLM 서버가 API 콜을 통해 페이지별 요약 및 문제 내용 전달
- task id 를 통해 조회하여 요약 내용과 문제 내용 업데이트

* Refactor: 변수 이름 변경

- 필드명 카멜케이스로 변경

* Refactor: 통일성 없는 부분 수정

- 필드명 변경
- 변수 추출

* Refactor: 예외 종류, 메서드 네이밍 변경

- LLMQueryService 예외 타입 변경
- SummaryAndProblemUpdateResponse 메서드 네이밍 변경

* Refactor: LLMQueryService 응답과 LLMController 응답 분리

---------

Co-authored-by: yugyeom <[email protected]>
  • Loading branch information
hynseoj and yugyeom-ghim authored Sep 27, 2024
1 parent 303b89e commit 458ec9d
Show file tree
Hide file tree
Showing 61 changed files with 1,090 additions and 341 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,5 @@ gradle-app.setting
!/src/main/resources/application.yml
!/src/main/resources/application-local.yml
!/src/main/resources/logback-spring.xml

.idea/
38 changes: 0 additions & 38 deletions src/main/java/notai/aiTask/application/AITaskService.java

This file was deleted.

10 changes: 0 additions & 10 deletions src/main/java/notai/aiTask/application/command/AITaskCommand.java

This file was deleted.

7 changes: 0 additions & 7 deletions src/main/java/notai/aiTask/domain/AITaskRepository.java

This file was deleted.

28 changes: 0 additions & 28 deletions src/main/java/notai/aiTask/presentation/AITaskController.java

This file was deleted.

18 changes: 0 additions & 18 deletions src/main/java/notai/aiTask/presentation/request/AITaskRequest.java

This file was deleted.

This file was deleted.

5 changes: 2 additions & 3 deletions src/main/java/notai/auth/Auth.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package notai.auth;

import io.swagger.v3.oas.annotations.Hidden;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Hidden
@Target(PARAMETER)
@Retention(RUNTIME)
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/notai/auth/AuthArgumentResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ public class AuthArgumentResolver implements HandlerMethodArgumentResolver {

@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(Auth.class)
&& parameter.getParameterType().equals(Long.class);
return parameter.hasParameterAnnotation(Auth.class) && parameter.getParameterType().equals(Long.class);
}

@Override
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/notai/client/HttpInterfaceUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import org.springframework.web.service.invoker.HttpServiceProxyFactory;

public class HttpInterfaceUtil {
public static <T> T createHttpInterface(RestClient restClient, Class<T> clazz) {
HttpServiceProxyFactory build = HttpServiceProxyFactory
.builderFor(RestClientAdapter.create(restClient)).build();
return build.createClient(clazz);
}
public static <T> T createHttpInterface(RestClient restClient, Class<T> clazz) {
HttpServiceProxyFactory build =
HttpServiceProxyFactory.builderFor(RestClientAdapter.create(restClient)).build();
return build.createClient(clazz);
}
}
4 changes: 2 additions & 2 deletions src/main/java/notai/client/oauth/OauthClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

public interface OauthClient {

OauthProvider oauthProvider();
OauthProvider oauthProvider();

Member fetchMember(String accessToken);
Member fetchMember(String accessToken);
}
28 changes: 13 additions & 15 deletions src/main/java/notai/client/oauth/OauthClientComposite.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package notai.client.oauth;

import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
import notai.common.exception.type.BadRequestException;
import notai.member.domain.Member;
import notai.member.domain.OauthProvider;
Expand All @@ -9,25 +11,21 @@
import java.util.Optional;
import java.util.Set;

import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;

@Component
public class OauthClientComposite {

private final Map<OauthProvider, OauthClient> oauthClients;
private final Map<OauthProvider, OauthClient> oauthClients;

public OauthClientComposite(Set<OauthClient> oauthClients) {
this.oauthClients = oauthClients.stream()
.collect(toMap(OauthClient::oauthProvider, identity()));
}
public OauthClientComposite(Set<OauthClient> oauthClients) {
this.oauthClients = oauthClients.stream().collect(toMap(OauthClient::oauthProvider, identity()));
}

public Member fetchMember(OauthProvider oauthProvider, String accessToken) {
return oauthClients.get(oauthProvider).fetchMember(accessToken);
}
public Member fetchMember(OauthProvider oauthProvider, String accessToken) {
return oauthClients.get(oauthProvider).fetchMember(accessToken);
}

public OauthClient getOauthClient(OauthProvider oauthProvider) {
return Optional.ofNullable(oauthClients.get(oauthProvider)).orElseThrow(
() -> new BadRequestException("지원하지 않는 소셜 로그인 타입입니다."));
}
public OauthClient getOauthClient(OauthProvider oauthProvider) {
return Optional.ofNullable(oauthClients.get(oauthProvider)).orElseThrow(() -> new BadRequestException(
"지원하지 않는 소셜 로그인 타입입니다."));
}
}
8 changes: 4 additions & 4 deletions src/main/java/notai/client/oauth/kakao/KakaoClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ public class KakaoClientConfig {

@Bean
public KakaoClient kakaoClient() {
RestClient restClient = RestClient.builder()
.defaultStatusHandler(HttpStatusCode::isError, (request, response) -> {
RestClient restClient = RestClient.builder().defaultStatusHandler(HttpStatusCode::isError,
(request, response) -> {
String responseData = new String(response.getBody().readAllBytes());
log.error("카카오톡 API 오류 : {}", responseData);
throw new ExternalApiException(responseData, response.getStatusCode().value());
})
.build();
}
).build();
return createHttpInterface(restClient, KakaoClient.class);
}
}
39 changes: 20 additions & 19 deletions src/main/java/notai/comment/domain/Comment.java
Original file line number Diff line number Diff line change
@@ -1,51 +1,52 @@
package notai.comment.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.*;
import static jakarta.persistence.FetchType.LAZY;
import static jakarta.persistence.GenerationType.IDENTITY;
import jakarta.validation.constraints.NotNull;
import static lombok.AccessLevel.PROTECTED;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import notai.common.domain.RootEntity;
import notai.member.domain.Member;

import static jakarta.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;
import notai.post.domain.Post;

@Entity
@Table(name = "comment")
@Getter
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor
public class Comment extends RootEntity<Long> {

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

@NotNull
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "member_id")
private Member member;

@NotNull
@Column
private Long postId;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "post_id")
private Post post;

@NotNull
@Column
private Long parentCommentId;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "parent_comment_id", referencedColumnName = "id")
private Comment parentComment;

@NotNull
@Column(length = 255)
private String content;

public Comment(
Member member,
Long postId,
String content
Member member, Post post, String content
) {
this.member = member;
this.postId = postId;
this.post = post;
this.content = content;
}

Expand Down
6 changes: 2 additions & 4 deletions src/main/java/notai/common/config/AuthConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ public class AuthConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/api/**")
.excludePathPatterns("/api/members/oauth/login/**")
.excludePathPatterns("/api/members/token/refresh");
registry.addInterceptor(authInterceptor).addPathPatterns("/api/**").excludePathPatterns(
"/api/members/oauth/login/**").excludePathPatterns("/api/members/token/refresh");
}

@Override
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/notai/common/config/AuthInterceptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import notai.auth.TokenService;
import static org.springframework.http.HttpHeaders.AUTHORIZATION;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import static org.springframework.http.HttpHeaders.AUTHORIZATION;

@Component
public class AuthInterceptor implements HandlerInterceptor {
private final TokenService tokenService;
Expand Down
24 changes: 8 additions & 16 deletions src/main/java/notai/common/config/SwaggerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,22 @@ public SwaggerConfig(@Value("${server-url}") String serverUrl) {
@Bean
public OpenAPI openAPI() {
String jwt = "JWT";
SecurityRequirement securityRequirement = new SecurityRequirement()
.addList(jwt);
Components components = new Components()
.addSecuritySchemes(jwt, new SecurityScheme()
.name(jwt)
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.description("토큰값을 입력하여 인증을 활성화할 수 있습니다.")
.bearerFormat("JWT")
);
SecurityRequirement securityRequirement = new SecurityRequirement().addList(jwt);
Components components = new Components().addSecuritySchemes(jwt, new SecurityScheme().name(jwt)
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.description("토큰값을 입력하여 인증을 활성화할 수 있습니다.")
.bearerFormat("JWT"));
Server server = new Server();
server.setUrl(serverUrl);
return new OpenAPI()
.components(new Components())
return new OpenAPI().components(new Components())
.info(apiInfo())
.addSecurityItem(securityRequirement)
.components(components)
.addServersItem(server);
}

private Info apiInfo() {
return new Info()
.title("notai API")
.description("notai API 문서입니다.")
.version("0.0.1");
return new Info().title("notai API").description("notai API 문서입니다.").version("0.0.1");
}
}
3 changes: 1 addition & 2 deletions src/main/java/notai/common/domain/RootEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import static lombok.AccessLevel.PROTECTED;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
Expand All @@ -12,8 +13,6 @@
import java.time.LocalDateTime;
import java.util.Objects;

import static lombok.AccessLevel.PROTECTED;

@Getter
@NoArgsConstructor(access = PROTECTED)
@EntityListeners(AuditingEntityListener.class)
Expand Down
Loading

0 comments on commit 458ec9d

Please sign in to comment.