Skip to content

Commit

Permalink
Style: 코드 포맷팅 통일 (#36)
Browse files Browse the repository at this point in the history
* Feat: 요약 및 문제 생성 API 구현 (#4)

* 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 응답 분리

* Feat: 폴더 관련 기능 구현 (#6)

* Init: 프로젝트 기본설정 세팅

- 프로젝트 생성
- .gitignore설정
- 프로젝트 의존성 추가
- application.yml 설정파일 구성

* Init: 프로젝트 기본 구조 및 공통 컴포넌트 설정

- 공통 설정 클래스 추가 (JPA, QueryDSL, Swagger, Web)
- 공통 도메인 엔티티 (RootEntity) 정의
- 예외 처리 관련 클래스 및 타입 구현
- JSON 변환을 위한 AttributeConverter 추가
- 유틸리티 클래스 (Math) 추가

* Chore: Folder 도메인 폴더 구조 셋업

폴더 구조 셋업 작업

* Feat: Folder 도메인의 엔티티 생성

엔티티 생성자, 부모-자식간 연결로직 생성

* refactor: 자기 참조 관계 설정 수정

기존, 다대일 양방향 관계에서 다대일 단방향 관계로 설정하고, 삭제 등의 이슈 발생시 Service 계층에서 함수의 재귀사용을 통해 삭제할 예정

* Chore: Document 도메인 폴더 구조 셋업

폴더 구조 셋업 및 엔티티 생성

* Feat: Lombok 라이브러리 활용하여 기본 생성자 생성

기본 생성자 생성 lombok 라이브러리 활용하여 대체

* chore: name 필드의 length 50으로 설정

name 필드 (Document, Folder) 의 length = 50 으로 설정

* chore: Domain 계층의 Repository가 QueryRepository 상속받도록 함

상속 작업 수행

* chore: Member 도메인 매핑 작업 수행

Member 도메인 매핑 작업 수행

* chore: Member 도메인과 Folder 도메인 연결 작업 수행

Member 도메인과 Folder 도메인 연결 작업 수행

* feat: 루트 폴더 생성하는 기능 구현

루트 폴더 생성하는 기능 구현

* feat: 서브폴더 생성하는 기능 구현

서브 폴더 생성하는 기능 구현

* feat: 폴더를 루트로 이동시키는 기능 구현

폴더를 루트로 이동시키는 기능 구현

* feat: 새로운 폴더 내부로 이동시키는 기능 구현

새로운 폴더 내부로 이동시키는 기능 구현

* feat: 계층형 구조의 폴더 탐색 기능 구현

계층형 구조의 폴더 탐색 기능 구현

* test: 재귀적으로 폴더를 조회하는 테스트 코드 작성

재귀적으로 폴더 조회하는 테스트코드 작성

* remove: 사용하지 않는 QueryDSL 관련 파일 삭제

사용하지 않는 QueryDSL 관련 파일 삭제

* refactor: formatting 적용

formatting 적용

* feat: 폴더 재귀적으로 삭제하는 기능 구현

폴더 재귀적으로 삭제하는 기능 구현

* feat: @onDelete 어노테이션을 사용하여 삭제 기능 구현

삭제 기능 구현

* feat: 폴더 구조의 조회를 간편하게 개선

폴더 구조의 조회 간편하게 개선

* feat: 루트에 폴더를 생성하는 API 구현

루트에 폴더를 생성하는 API 구현

* feat: 서브 폴더를 생성하는 API 구현

서브 폴더 생성하는 API 구현

* feat: 폴더 이동하는 API 구현

폴더 이동하는 API 구현

* refactor: 중복된 함수 기능 병합 작업 수행

중복된 함수 기능 병합 작업 수행

* feat: 폴더 조회 API 구현

폴더 조회 API 구현

* feat: 폴더 삭제 API 구현

폴더 삭제 API 구현

* rename: 함수명 변경

함수 명 변경

* refactor: 메서드 분리 작업 수행

메서드 분리 작업 수행

* refactor: Delete API 204 로 반환

204로 반환

* feat: 요청마다 DTO를 다르게 설정

요청마다 DTO 다르게 설정

* refactor: 타입추론방식에서 타입명시방식으로 변경

타입명시방식으로 코드 스타일 변경

* refactor: 도메인 값에 대한 검증은 도메인계층으로 옮김

도메인 계층으로 값에 대한 검증 이동

* refactor: Owner가 아닌 폴더에 접근하려고 하는 경우 NotFoundException 예외 발생

예외 발생

---------

Co-authored-by: rladbrua0207 <[email protected]>

* Style: 코드 포맷팅 통일

* Refactor: 예외 종류 변경

---------

Co-authored-by: 윤정훈 <[email protected]>
Co-authored-by: rladbrua0207 <[email protected]>
  • Loading branch information
3 people authored Sep 29, 2024
1 parent 31cf7a8 commit ad9062e
Show file tree
Hide file tree
Showing 42 changed files with 438 additions and 128 deletions.
5 changes: 5 additions & 0 deletions .idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions src/main/java/notai/auth/Auth.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
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
5 changes: 4 additions & 1 deletion src/main/java/notai/auth/TokenPair.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
package notai.auth;

public record TokenPair(String accessToken, String refreshToken) {
public record TokenPair(
String accessToken,
String refreshToken
) {
}
28 changes: 11 additions & 17 deletions src/main/java/notai/auth/TokenService.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,17 @@ public TokenService(TokenProperty tokenProperty, MemberRepository memberReposito
}

public String createAccessToken(Long memberId) {
return Jwts.builder()
.claim(MEMBER_ID_CLAIM, memberId)
.issuedAt(new Date())
.expiration(new Date(System.currentTimeMillis() + accessTokenExpirationMillis))
.signWith(secretKey, Jwts.SIG.HS512)
.compact();
return Jwts.builder().claim(MEMBER_ID_CLAIM,
memberId
).issuedAt(new Date()).expiration(new Date(System.currentTimeMillis() + accessTokenExpirationMillis)).signWith(secretKey,
Jwts.SIG.HS512
).compact();
}

private String createRefreshToken() {
return Jwts.builder()
.issuedAt(new Date())
.expiration(new Date(System.currentTimeMillis() + refreshTokenExpirationMillis))
.signWith(secretKey, Jwts.SIG.HS512)
.compact();
return Jwts.builder().issuedAt(new Date()).expiration(new Date(System.currentTimeMillis() + refreshTokenExpirationMillis)).signWith(secretKey,
Jwts.SIG.HS512
).compact();
}

public TokenPair createTokenPair(Long memberId) {
Expand Down Expand Up @@ -71,12 +68,9 @@ public TokenPair refreshTokenPair(String refreshToken) {

public Long extractMemberId(String token) {
try {
return Jwts.parser()
.verifyWith(secretKey)
.build()
.parseSignedClaims(token)
.getPayload()
.get(MEMBER_ID_CLAIM, Long.class);
return Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token).getPayload().get(MEMBER_ID_CLAIM,
Long.class
);
} catch (Exception e) {
throw new UnAuthorizedException("유효하지 않은 토큰입니다.");
}
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/notai/client/oauth/OauthClientComposite.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
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 @@ -11,6 +9,9 @@
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 {

Expand Down
48 changes: 26 additions & 22 deletions src/main/java/notai/client/oauth/kakao/KakaoMemberResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,33 @@

@JsonNaming(value = SnakeCaseStrategy.class)
public record KakaoMemberResponse(
Long id,
boolean hasSignedUp,
LocalDateTime connectedAt,
KakaoAccount kakaoAccount) {
Long id,
boolean hasSignedUp,
LocalDateTime connectedAt,
KakaoAccount kakaoAccount
) {

public Member toDomain() {
return new Member(
new OauthId(String.valueOf(id), OauthProvider.KAKAO),
kakaoAccount.email,
kakaoAccount.profile.nickname);
}
public Member toDomain() {
return new Member(
new OauthId(String.valueOf(id), OauthProvider.KAKAO),
kakaoAccount.email,
kakaoAccount.profile.nickname
);
}

@JsonNaming(value = SnakeCaseStrategy.class)
public record KakaoAccount(
Profile profile,
boolean emailNeedsAgreement,
boolean isEmailValid,
boolean isEmailVerified,
String email) {
}
@JsonNaming(value = SnakeCaseStrategy.class)
public record KakaoAccount(
Profile profile,
boolean emailNeedsAgreement,
boolean isEmailValid,
boolean isEmailVerified,
String email
) {
}

@JsonNaming(value = SnakeCaseStrategy.class)
public record Profile(
String nickname) {
}
@JsonNaming(value = SnakeCaseStrategy.class)
public record Profile(
String nickname
) {
}
}
7 changes: 4 additions & 3 deletions src/main/java/notai/comment/domain/Comment.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package notai.comment.domain;

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 notai.post.domain.Post;

import static jakarta.persistence.FetchType.LAZY;
import static jakarta.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;

@Entity
@Table(name = "comment")
@Getter
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/notai/common/config/AuthInterceptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
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
3 changes: 2 additions & 1 deletion src/main/java/notai/common/domain/RootEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

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 @@ -13,6 +12,8 @@
import java.time.LocalDateTime;
import java.util.Objects;

import static lombok.AccessLevel.PROTECTED;

@Getter
@NoArgsConstructor(access = PROTECTED)
@EntityListeners(AuditingEntityListener.class)
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/notai/document/domain/Document.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package notai.document.domain;

import jakarta.persistence.*;
import static jakarta.persistence.GenerationType.IDENTITY;
import jakarta.validation.constraints.NotNull;
import static lombok.AccessLevel.PROTECTED;
import lombok.Getter;
import lombok.NoArgsConstructor;
import notai.common.domain.RootEntity;
import notai.folder.domain.Folder;

import static jakarta.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;

@Entity
@Table(name = "document")
@Getter
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/notai/folder/application/FolderQueryService.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,34 @@
package notai.folder.application;

import lombok.RequiredArgsConstructor;
import notai.folder.application.result.FolderFindResult;
import notai.folder.domain.Folder;
import notai.folder.domain.FolderRepository;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class FolderQueryService {

private final FolderRepository folderRepository;

public List<FolderFindResult> getFolders(Long memberId, Long parentFolderId) {
List<Folder> folders = getFoldersWithMemberAndParent(memberId, parentFolderId);
// document read
return folders.stream().map(this::getFolderResult).toList();
}

private List<Folder> getFoldersWithMemberAndParent(Long memberId, Long parentFolderId) {
if (parentFolderId == null) {
return folderRepository.findAllByMemberIdAndParentFolderIsNull(memberId);
}
return folderRepository.findAllByMemberIdAndParentFolderId(memberId, parentFolderId);
}

private FolderFindResult getFolderResult(Folder folder) {
Long parentFolderId = folder.getParentFolder() != null ? folder.getParentFolder().getId() : null;
return FolderFindResult.of(folder.getId(), parentFolderId, folder.getName());
}
}
60 changes: 60 additions & 0 deletions src/main/java/notai/folder/application/FolderService.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,69 @@
package notai.folder.application;

import lombok.RequiredArgsConstructor;
import notai.common.exception.type.BadRequestException;
import notai.folder.application.result.FolderMoveResult;
import notai.folder.application.result.FolderSaveResult;
import notai.folder.domain.Folder;
import notai.folder.domain.FolderRepository;
import notai.folder.presentation.request.FolderMoveRequest;
import notai.folder.presentation.request.FolderSaveRequest;
import notai.member.domain.Member;
import notai.member.domain.MemberRepository;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class FolderService {

private final FolderRepository folderRepository;
private final MemberRepository memberRepository;

public FolderSaveResult saveRootFolder(Long memberId, FolderSaveRequest folderSaveRequest) {
Member member = memberRepository.getById(memberId);
Folder folder = new Folder(member, folderSaveRequest.name());
Folder savedFolder = folderRepository.save(folder);
return getFolderSaveResult(savedFolder);
}

public FolderSaveResult saveSubFolder(Long memberId, FolderSaveRequest folderSaveRequest) {
Member member = memberRepository.getById(memberId);
Folder parentFolder = folderRepository.getById(folderSaveRequest.parentFolderId());
Folder folder = new Folder(member, folderSaveRequest.name(), parentFolder);
Folder savedFolder = folderRepository.save(folder);
return getFolderSaveResult(savedFolder);
}

public FolderMoveResult moveRootFolder(Long memberId, Long id) {
Folder folder = folderRepository.getById(id);
folder.validateOwner(memberId);
folder.moveRootFolder();
folderRepository.save(folder);
return getFolderMoveResult(folder);
}

public FolderMoveResult moveNewParentFolder(Long memberId, Long id, FolderMoveRequest folderMoveRequest) {
Folder folder = folderRepository.getById(id);
Folder parentFolder = folderRepository.getById(folderMoveRequest.targetFolderId());
folder.validateOwner(memberId);
folder.moveNewParentFolder(parentFolder);
folderRepository.save(folder);
return getFolderMoveResult(folder);
}

public void deleteFolder(Long memberId, Long id) {
if (!folderRepository.existsByMemberIdAndId(memberId, id)) {
throw new BadRequestException("올바르지 않은 요청입니다.");
}
folderRepository.deleteById(id);
}

private FolderSaveResult getFolderSaveResult(Folder folder) {
Long parentFolderId = folder.getParentFolder() != null ? folder.getParentFolder().getId() : null;
return FolderSaveResult.of(folder.getId(), parentFolderId, folder.getName());
}

private FolderMoveResult getFolderMoveResult(Folder folder) {
return FolderMoveResult.of(folder.getId(), folder.getName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package notai.folder.application.result;

public record FolderFindResult(
Long id,
Long parentId,
String name
) {
public static FolderFindResult of(Long id, Long parentId, String name) {
return new FolderFindResult(id, parentId, name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package notai.folder.application.result;

public record FolderMoveResult(
Long id,
String name
) {
public static FolderMoveResult of(Long id, String name) {
return new FolderMoveResult(id, name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package notai.folder.application.result;

public record FolderSaveResult(
Long id,
Long parentId,
String name
) {
public static FolderSaveResult of(Long id, Long parentId, String name) {
return new FolderSaveResult(id, parentId, name);
}
}
Loading

0 comments on commit ad9062e

Please sign in to comment.