Skip to content

Commit

Permalink
Refactor: Document, Folder 이슈 해결 (#28)
Browse files Browse the repository at this point in the history
* Init: 프로젝트 기본설정 세팅

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

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

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

* Style: formatting통일 (#30)

* Chore : Annotation 폴더 구조 설정

* Feat : Annotation Domain Entity 설정

* Feat: Annotaion crud 구현

1. controller : api 명세대로 구현
2. service : R-CUD를 분리하는 service 구현
3. presentation : dto 구현

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

* Style: 코드 포맷팅 통일 (#36)

* 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]>

* Revert "Style: 코드 포맷팅 통일 (#36)" (#38)

This reverts commit ad9062e.

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

* 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]>

---------

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

* Style: 코드 포맷팅 통일 (#40)

* Style: 코드 포맷팅 통일

* Refactor: 예외 종류 변경

---------

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

* Remove: .idea 폴더 삭제

* Style: 코드 포맷팅 통일 (#41)

* refactor: 폴더의 삭제 방법 재귀형태로 찾아 삭제하도록 개선

개선

* chore: API 매칭 URL 수정 작업 진행

API 매칭 URL 수정 작업 진행

* remove: 불필요한 문서 상태 삭제

불필요한 문서 상태 삭제

* feat: PDF 저장하는 기능 구현

* remove: 불필요한 라이브러리 삭제

불필요한 라이브러리 삭제

* feat: Document 저장하는 기능 구현

* test: PDF Service에서 PDF 저장 로직 테스트코드 작성

PDF 저장 로직 테스트코드 작성

* feat: Document 저장 하는 기능 구현

Document 저장하는 기능 구현

* chore: PDF 처리 및 OCR 라이브러리

라이브러리 import

* feat: Document 생성 API 구현

Document 생성 API 구현

* feat: 자료 이름 수정 기능 구현

자료 이름 수정 기능 구현

* feat: 자료 조회 기능 구현

자료 조회 기능 구현

* feat: 자료 삭제 기능 구현

자료 삭제 기능 구현

* feat: 폴더 삭제시 자료도 함께 삭제되도록 기능 구현

삭제 기능 구현

* chore: PDF Setup

pdf 세팅

* Feat: 녹음 파일 업로드 기능 구현 (#8)

* Feat: 녹음 파일 업로드 기능 구현

- Recording 엔티티, 레포지토리, 컨트롤러 코드 작성
- 오디오 디코딩, 파일 저장 코드 작성

* Chore: Weekly5 로 rebase

* Refactor: file base path @value 를 사용하도록 변경

---------

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

* feat: 루트(메인)에 생성되는 Document 설정

루트 자료 추가 기능 구현

* Feat: 녹음-페이지 저장 기능 구현 (#10)

* Refactor: 메서드, 파라미터 이름 변경

* Feat: 녹음-페이지 저장 기능 구현

- 페이지 넘김 이벤트에 따라 녹음-페이지 테이블에 타임스탬프 저장

* Refactor: 예외 메시지 수정

* Feature/annotation 구현 완료 (#12)

* Feat : Annotation CRUD 구현

1. Controller : API 명세서 구현
2. Service : R-CUD를 QueryService, Serivce를 이용하여 구현
3. presentation : DTO 구현

* Refactor: @positive를 이용한 양수 검증

* Refactor: @NoArgsConstructor의 접근 수준을 PROTECTED로 변경

* Refactor: CreateAnnotationRequest에서 좌표 및 크기 검증 추가

* Refactor: DTO를 record로 통일

* Refactor: getById로 변경

* Refactor: record로 인한 형식 변경

* Refactor: 정적 팩토리 from으로 변경

* Refactor: ManyToOne의 fetch 형식 LAZY로 설정

* Refactor : 정적팩토리 from으로 인한 코드 변경

* Refactor : createAnnotation에서 누락된  savedAnnotatio 추가

* Refactor : pageNumbers 누락 -> 해당 내용을 반영한 Read 구현

* Refactor: CRUD test code 작성

* Refactor : getById로 변경

* Revert "Feature/annotation 구현 완료 (#12)" (#14)

This reverts commit 0dcf1d2.

* Feat: Annotation API 구현 (#15)

* Feat : Annotation CRUD 구현

1. Controller : API 명세서 구현
2. Service : R-CUD를 QueryService, Serivce를 이용하여 구현
3. presentation : DTO 구현

* Refactor: @positive를 이용한 양수 검증

* Refactor: @NoArgsConstructor의 접근 수준을 PROTECTED로 변경

* Refactor: CreateAnnotationRequest에서 좌표 및 크기 검증 추가

* Refactor: DTO를 record로 통일

* Refactor: getById로 변경

* Refactor: record로 인한 형식 변경

* Refactor: 정적 팩토리 from으로 변경

* Refactor: ManyToOne의 fetch 형식 LAZY로 설정

* Refactor : 정적팩토리 from으로 인한 코드 변경

* Refactor : createAnnotation에서 누락된  savedAnnotatio 추가

* Refactor : pageNumbers 누락 -> 해당 내용을 반영한 Read 구현

* Refactor: CRUD test code 작성

* Refactor : getById로 변경

---------

Co-authored-by: mingjuu <[email protected]>
Co-authored-by: Minju Song <[email protected]>

* Feat: 문서 도메인 관련 기능 구현 (#13)

* refactor: 폴더의 삭제 방법 재귀형태로 찾아 삭제하도록 개선

개선

* chore: API 매칭 URL 수정 작업 진행

API 매칭 URL 수정 작업 진행

* remove: 불필요한 문서 상태 삭제

불필요한 문서 상태 삭제

* feat: PDF 저장하는 기능 구현

* remove: 불필요한 라이브러리 삭제

불필요한 라이브러리 삭제

* feat: Document 저장하는 기능 구현

* test: PDF Service에서 PDF 저장 로직 테스트코드 작성

PDF 저장 로직 테스트코드 작성

* feat: Document 저장 하는 기능 구현

Document 저장하는 기능 구현

* chore: PDF 처리 및 OCR 라이브러리

라이브러리 import

* feat: Document 생성 API 구현

Document 생성 API 구현

* feat: 자료 이름 수정 기능 구현

자료 이름 수정 기능 구현

* feat: 자료 조회 기능 구현

자료 조회 기능 구현

* feat: 자료 삭제 기능 구현

자료 삭제 기능 구현

* feat: 폴더 삭제시 자료도 함께 삭제되도록 기능 구현

삭제 기능 구현

* chore: PDF Setup

pdf 세팅

* feat: 루트(메인)에 생성되는 Document 설정

루트 자료 추가 기능 구현

---------

Co-authored-by: rladbrua0207 <[email protected]>
Co-authored-by: mingjuu <[email protected]>
Co-authored-by: Hyun-Seo Jeong <[email protected]>

* chore: OCR 도메인 생성

도메인 생성

* feat: ID를 사용하여 엔티티 꺼내오는 작업 수행

엔티티 꺼내오는 작업 수행

* rename: PDF 관련 파일 이동

파일 이동

* feat: 문서 저장시 OCR 작업수행하는 기능

OCR 자동 작업 기능 구현

* refactor: PDF 저장 로직 개선

저장 로직 개선

* test: OCR 기능 작동 여부 테스트코드 작성

테스트 코드 작성

* refactor: 상수값 static 으로 따로 관리

상수값 관리하도록 피드백 반영

* feat: AOP 를 활용하여 Get요청시 ok를 바로 보내줄 수 있도록 기능 구현

AOP 활용 래퍼클래스 개발

* remove: 상의 후 도입할지 정해야하기때문에 우선 삭제

* Feat: AI Client기능 구현 (#18)

* Feat: AI Client기능 구현

* Test: AI Client 통합테스트 작성

* build: 빌드시 테스트에서 제외해야 할 테스트 태그 추가

* Test: AI Client 단위테스트 작성

* Feat: LLMService에 AI 서버 요청 기능 추가

* Test: LLMService AI_기능_요청 메서드에 클라이언트 단위테스트 코드 추가

* Chore: 불필요한 주석 제거

* Chore: 더미 AI서버 주소 추가

* Chore: 불필요한 impl클래스 제거 및 테스트코드 수정

* Feat: PDF 처리 기능 및 OCR 기능 (#19)

* chore: OCR 도메인 생성

도메인 생성

* feat: ID를 사용하여 엔티티 꺼내오는 작업 수행

엔티티 꺼내오는 작업 수행

* rename: PDF 관련 파일 이동

파일 이동

* feat: 문서 저장시 OCR 작업수행하는 기능

OCR 자동 작업 기능 구현

* refactor: PDF 저장 로직 개선

저장 로직 개선

* test: OCR 기능 작동 여부 테스트코드 작성

테스트 코드 작성

* refactor: 상수값 static 으로 따로 관리

상수값 관리하도록 피드백 반영

* feat: AOP 를 활용하여 Get요청시 ok를 바로 보내줄 수 있도록 기능 구현

AOP 활용 래퍼클래스 개발

* remove: 상의 후 도입할지 정해야하기때문에 우선 삭제

* Refactor: 에러 메시지 상수화 (#20)

* Refactor: 에러 메시지 상수화

* Refactor: 코드 통합 후 에러 메시지 상수화

* test: 테스트코드 재작성

테스트코드 재작성

* Fix: merge 하면서 잘못된 부분 수정

* refactor: Controller -> RestController 로 변경

변경작업 수행

* feat: PDF의 총 페이지 수 가져오는 기능 구현

총 페이지 수 가져오는 기능 구현

* feat: Document 도메인에서 페이지 정보 유효성 검사

페이지 정보 유효성 검사

* refactor: pdf주소만 받아 생성하던 Document 생성 로직 수정

수정

* remove: consumes 를 다 허용해줌

다 허용해주도럭 제약 조건 삭제

* Feat: Post 저장 기능 구현 (#17)

* Feat: Post 저장 기능 구현

* Feat: Post Id로 Post 1개 찾기 기능 구현

* Style: 코드리뷰 반영 - 변수선언과 변수 할당을 한줄에 하도록 변경

* Refactor: 코드리뷰 반영 : Post 조회 수행 위치 변경
- JPA 사용하는 단순 조회 쿼리를 PostService 와 PostRepository 에서 관리하도록 변경 (기존에는 PostQueryService 와 PostQueryRepository에서 관리했음)

* Fix: 코드리뷰 반영 : Post 조회시 ResponseBody 삭제
-uri 반환중이라 굳이 불필요해서 삭제함

* Fix: 코드리뷰 반영 : Post 저장 기능에서 Request와 Command 를 분리

* FIx: MemberAPI에 리소스가 생성되는 Response Status 200 -> 201로 변경 (#22)

* Release: 0.0.1 배포 (#23)

* Fix: 인증토큰 관련 오류 해결 및 오류메시지 추가

* Fix: 서버환경에 맞게 tesseract경로 수정

* Build: 도커파일 작성

* Fix: audio basePath 도커 볼륨에 연결

* feat: 폴더 이름 변경 기능 추가

폴더 이름 변경 기능 추가

* feat: OCR 결과 조회 기능 구현

OCR 결과 조회 기능 구현

* refactor: 폴더 삭제시 연결된 문서 삭제 기능 수정

삭제 기능을 수정

* chore: 에러 메시지 INVALID_DOCUMENT_PAGE 추가

* refactor: 하나의 페이지 당 최대 하나의 OCR 정보만 조회되도록 수정

기존 List -> Optional 로 리턴 타입 수정

* refactor: 이슈 사항에 맞게 코드 수정

코드 수정 및 에러 해결

* refactor: 이슈 해결

이슈 해결

* refactor: 루트폴더에 위치한 문서에 대해 이슈 처리

이슈 처리

* Refactor: pdf 저장 위치 @value로 설정 파일에서 관리하도록 변경

* Feat: 문서 소유 검증 로직 구현

* Style: 코드 포메팅 통일

---------

Co-authored-by: rladbrua0207 <[email protected]>
Co-authored-by: mingjuu <[email protected]>
Co-authored-by: Hyun-Seo Jeong <[email protected]>
Co-authored-by: Minju Song <[email protected]>
Co-authored-by: hynseoj <[email protected]>
Co-authored-by: Cindy <[email protected]>
Co-authored-by: YugyeomGhim <[email protected]>
  • Loading branch information
8 people authored Nov 1, 2024
1 parent 4e8c2f8 commit 89dfb1e
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 38 deletions.
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
7 changes: 4 additions & 3 deletions src/main/java/notai/common/exception/ErrorMessages.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ public enum ErrorMessages {
ANNOTATION_NOT_FOUND("주석을 찾을 수 없습니다."),

// document
DOCUMENT_NOT_FOUND("자료를 찾을 수 없습니다."),
DOCUMENT_NOT_FOUND("자료를 찾을 수 없습니다."),
INVALID_DOCUMENT_PAGE("존재하지 않는 페이지 입니다."),
UNAUTHORIZED_DOCUMENT_ACCESS("자료에 대한 권한이 없습니다."),

// ocr
OCR_RESULT_NOT_FOUND("OCR 데이터를 찾을 수 없습니다."),
OCR_RESULT_NOT_FOUND("OCR 데이터를 찾을 수 없습니다."),
OCR_TASK_ERROR("PDF 파일을 통해 OCR 작업을 수행하는데 실패했습니다."),

// folder
FOLDER_NOT_FOUND("폴더를 찾을 수 없습니다."),

// llm task
LLM_TASK_LOG_NOT_FOUND("AI 작업 기록을 찾을 수 없습니다."),
LLM_TASK_LOG_NOT_FOUND("AI 작업 기록을 찾을 수 없습니다."),
LLM_TASK_RESULT_ERROR("AI 요약 및 문제 생성 중에 문제가 발생했습니다."),

// problem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public List<DocumentFindResult> findDocuments(Long folderId) {
return documents.stream().map(this::getDocumentFindResult).toList();
}

public List<DocumentFindResult> findRootDocuments(Long memberId) {
List<Document> documents = documentRepository.findAllByMemberIdAndFolderIdIsNull(memberId);
return documents.stream().map(this::getDocumentFindResult).toList();
}

private DocumentFindResult getDocumentFindResult(Document document) {
return DocumentFindResult.of(document.getId(), document.getName(), document.getUrl());
}
Expand Down
50 changes: 37 additions & 13 deletions src/main/java/notai/document/application/DocumentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import notai.document.presentation.request.DocumentUpdateRequest;
import notai.folder.domain.Folder;
import notai.folder.domain.FolderRepository;
import notai.member.domain.Member;
import notai.member.domain.MemberRepository;
import notai.ocr.application.OCRService;
import notai.pdf.PdfService;
import notai.pdf.result.PdfSaveResult;
Expand All @@ -25,67 +27,89 @@ public class DocumentService {
private final OCRService ocrService;
private final DocumentRepository documentRepository;
private final FolderRepository folderRepository;
private final MemberRepository memberRepository;

private static final Long ROOT_FOLDER_ID = -1L;


public DocumentSaveResult saveDocument(
Long folderId, MultipartFile pdfFile, DocumentSaveRequest documentSaveRequest
Long memberId, Long folderId, MultipartFile pdfFile, DocumentSaveRequest documentSaveRequest
) {
PdfSaveResult pdfSaveResult = pdfService.savePdf(pdfFile);
Document document = saveAndReturnDocument(folderId, documentSaveRequest, pdfSaveResult);
Document document = saveAndReturnDocument(memberId, folderId, documentSaveRequest, pdfSaveResult);
ocrService.saveOCR(document, pdfSaveResult.pdf());
return DocumentSaveResult.of(document.getId(), document.getName(), document.getUrl());
}

public DocumentSaveResult saveRootDocument(
MultipartFile pdfFile, DocumentSaveRequest documentSaveRequest
Long memberId, MultipartFile pdfFile, DocumentSaveRequest documentSaveRequest
) {
PdfSaveResult pdfSaveResult = pdfService.savePdf(pdfFile);
Document document = saveAndReturnRootDocument(documentSaveRequest, pdfSaveResult);
Document document = saveAndReturnRootDocument(memberId, documentSaveRequest, pdfSaveResult);
ocrService.saveOCR(document, pdfSaveResult.pdf());
return DocumentSaveResult.of(document.getId(), document.getName(), document.getUrl());
}

public DocumentUpdateResult updateDocument(
Long folderId, Long documentId, DocumentUpdateRequest documentUpdateRequest
Long memberId, Long folderId, Long documentId, DocumentUpdateRequest documentUpdateRequest
) {
Document document = documentRepository.getById(documentId);
document.validateDocument(folderId);
Member member = memberRepository.getById(memberId);

document.validateOwner(member);

if (!folderId.equals(ROOT_FOLDER_ID)) {
document.validateDocument(folderId);
}
document.updateName(documentUpdateRequest.name());
Document savedDocument = documentRepository.save(document);
return DocumentUpdateResult.of(savedDocument.getId(), savedDocument.getName(), savedDocument.getUrl());
}

public void deleteDocument(
Long folderId, Long documentId
Long memberId, Long folderId, Long documentId
) {
Document document = documentRepository.getById(documentId);
document.validateDocument(folderId);
Member member = memberRepository.getById(memberId);

document.validateOwner(member);

if (!folderId.equals(ROOT_FOLDER_ID)) {
document.validateDocument(folderId);
}
ocrService.deleteAllByDocument(document);
documentRepository.delete(document);
}

public void deleteAllByFolder(
Folder folder
Long memberId, Folder folder
) {
List<Document> documents = documentRepository.findAllByFolderId(folder.getId());
for (Document document : documents) {
deleteDocument(folder.getId(), document.getId());
deleteDocument(memberId, folder.getId(), document.getId());
}
}

private Document saveAndReturnDocument(
Long folderId, DocumentSaveRequest documentSaveRequest, PdfSaveResult pdfSaveResult
Long memberId, Long folderId, DocumentSaveRequest documentSaveRequest, PdfSaveResult pdfSaveResult
) {
Member member = memberRepository.getById(memberId);
Folder folder = folderRepository.getById(folderId);
Document document = new Document(folder,
member,
documentSaveRequest.name(),
pdfSaveResult.pdfUrl(),
pdfSaveResult.totalPages()
);
return documentRepository.save(document);
}

private Document saveAndReturnRootDocument(DocumentSaveRequest documentSaveRequest, PdfSaveResult pdfSaveResult) {
Document document = new Document(documentSaveRequest.name(),
private Document saveAndReturnRootDocument(
Long memberId, DocumentSaveRequest documentSaveRequest, PdfSaveResult pdfSaveResult
) {
Member member = memberRepository.getById(memberId);
Document document = new Document(member,
documentSaveRequest.name(),
pdfSaveResult.pdfUrl(),
pdfSaveResult.totalPages()
);
Expand Down
22 changes: 18 additions & 4 deletions src/main/java/notai/document/domain/Document.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import notai.common.domain.RootEntity;
import static notai.common.exception.ErrorMessages.DOCUMENT_NOT_FOUND;
import static notai.common.exception.ErrorMessages.INVALID_DOCUMENT_PAGE;
import notai.common.exception.ErrorMessages;
import static notai.common.exception.ErrorMessages.*;
import notai.common.exception.type.NotFoundException;
import notai.common.exception.type.UnAuthorizedException;
import notai.folder.domain.Folder;
import notai.member.domain.Member;

@Slf4j
@Entity
Expand All @@ -28,6 +30,10 @@ public class Document extends RootEntity<Long> {
@JoinColumn(name = "folder_id", referencedColumnName = "id")
private Folder folder;

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

@NotNull
@Column(name = "name", length = 50)
private String name;
Expand All @@ -40,14 +46,16 @@ public class Document extends RootEntity<Long> {
@Column(name = "total_pages")
private Integer totalPages;

public Document(Folder folder, String name, String url, Integer totalPages) {
public Document(Folder folder, Member member, String name, String url, Integer totalPages) {
this.member = member;
this.folder = folder;
this.name = name;
this.url = url;
this.totalPages = totalPages;
}

public Document(String name, String url, Integer totalPages) {
public Document(Member member, String name, String url, Integer totalPages) {
this.member = member;
this.name = name;
this.url = url;
this.totalPages = totalPages;
Expand All @@ -68,4 +76,10 @@ public void validatePageNumber(Integer pageNumber) {
public void updateName(String name) {
this.name = name;
}

public void validateOwner(Member member) {
if (!this.member.equals(member)) {
throw new UnAuthorizedException(UNAUTHORIZED_DOCUMENT_ACCESS);
}
}
}
2 changes: 2 additions & 0 deletions src/main/java/notai/document/domain/DocumentRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ default Document getById(Long id) {
}

List<Document> findAllByFolderId(Long folderId);

List<Document> findAllByMemberIdAndFolderIdIsNull(Long memberId);
}
35 changes: 26 additions & 9 deletions src/main/java/notai/document/presentation/DocumentController.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package notai.document.presentation;

import lombok.RequiredArgsConstructor;
import notai.auth.Auth;
import notai.document.application.DocumentQueryService;
import notai.document.application.DocumentService;
import notai.document.application.result.DocumentFindResult;
Expand Down Expand Up @@ -31,15 +32,17 @@ public class DocumentController {

@PostMapping
public ResponseEntity<DocumentSaveResponse> saveDocument(
@Auth Long memberId,
@PathVariable Long folderId,
@RequestPart MultipartFile pdfFile,
@RequestPart DocumentSaveRequest documentSaveRequest
) {

DocumentSaveResult documentSaveResult;
if (folderId.equals(ROOT_FOLDER_ID)) {
documentSaveResult = documentService.saveRootDocument(pdfFile, documentSaveRequest);
documentSaveResult = documentService.saveRootDocument(memberId, pdfFile, documentSaveRequest);
} else {
documentSaveResult = documentService.saveDocument(folderId, pdfFile, documentSaveRequest);
documentSaveResult = documentService.saveDocument(memberId, folderId, pdfFile, documentSaveRequest);
}
DocumentSaveResponse response = DocumentSaveResponse.from(documentSaveResult);
String url = String.format(FOLDER_URL_FORMAT, folderId, response.id());
Expand All @@ -48,27 +51,41 @@ public ResponseEntity<DocumentSaveResponse> saveDocument(

@PutMapping(value = "/{id}")
public ResponseEntity<DocumentUpdateResponse> updateDocument(
@PathVariable Long folderId, @PathVariable Long id, @RequestBody DocumentUpdateRequest documentUpdateRequest
@Auth Long memberId,
@PathVariable Long folderId,
@PathVariable Long id,
@RequestBody DocumentUpdateRequest documentUpdateRequest
) {
DocumentUpdateResult documentUpdateResult = documentService.updateDocument(folderId, id, documentUpdateRequest);
DocumentUpdateResult documentUpdateResult = documentService.updateDocument(
memberId,
folderId,
id,
documentUpdateRequest
);
DocumentUpdateResponse response = DocumentUpdateResponse.from(documentUpdateResult);
return ResponseEntity.ok(response);
}

@GetMapping
public ResponseEntity<List<DocumentFindResponse>> getDocuments(
@PathVariable Long folderId
@Auth Long memberId, @PathVariable Long folderId
) {
List<DocumentFindResult> documentResults = documentQueryService.findDocuments(folderId);
List<DocumentFindResult> documentResults;
if (folderId.equals(ROOT_FOLDER_ID)) {
documentResults = documentQueryService.findRootDocuments(memberId);
} else {
documentResults = documentQueryService.findDocuments(folderId);
}

List<DocumentFindResponse> responses = documentResults.stream().map(DocumentFindResponse::from).toList();
return ResponseEntity.ok(responses);
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> getDocuments(
@PathVariable Long folderId, @PathVariable Long id
public ResponseEntity<Void> deleteDocument(
@Auth Long memberId, @PathVariable Long folderId, @PathVariable Long id
) {
documentService.deleteDocument(folderId, id);
documentService.deleteDocument(memberId, folderId, id);
return ResponseEntity.noContent().build();
}
}
2 changes: 1 addition & 1 deletion src/main/java/notai/folder/application/FolderService.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void deleteFolder(Long memberId, Long id) {
for (Folder subFolder : subFolders) {
deleteFolder(memberId, subFolder.getId());
}
documentService.deleteAllByFolder(folder);
documentService.deleteAllByFolder(memberId, folder);
folderRepository.delete(folder);
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/notai/ocr/domain/OCR.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class OCR extends RootEntity<Long> {
private Integer pageNumber;

@NotNull
@Column(name = "content", length = 255)
@Column(name = "content", columnDefinition = "TEXT")
private String content;

public OCR(Document document, Integer pageNumber, String content) {
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/notai/pdf/PdfService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import notai.pdf.result.PdfSaveResult;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

Expand All @@ -23,7 +24,8 @@
@RequiredArgsConstructor
public class PdfService {

private static final String STORAGE_DIR = "src/main/resources/pdf/";
@Value("${file.pdf.basePath}")
private String STORAGE_DIR;

public PdfSaveResult savePdf(MultipartFile file) {
try {
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ token: # todo production에서 secretKey 변경

file:
audio:
basePath: /app/audio/
basePath: audio/
pdf:
basePath: /app/pdf/
basePath: pdf/

tesseract:
library:
Expand Down

0 comments on commit 89dfb1e

Please sign in to comment.