Skip to content

Commit

Permalink
Feat: AI서버에서 STT 결과 응답 왔을때 STT 결과 처리하는 기능 구현 (#27)
Browse files Browse the repository at this point in the history
* Feat: POST 저장 기능, OCR 구현, 폴더 수정, 페이지별 조회 기능 구현 및 배포 (#66) (#67)

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

* 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: OCR 로직 구현 (#21)

* 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 예외 발생

예외 발생

---------



* Style: 코드 포맷팅 통일

* Refactor: 예외 종류 변경

---------




* 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 예외 발생

예외 발생

---------



---------




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

* Style: 코드 포맷팅 통일

* Refactor: 예외 종류 변경

---------




* 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 를 사용하도록 변경

---------




* 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로 변경

---------




* 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 설정

루트 자료 추가 기능 구현

---------





* 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: 테스트코드 재작성

테스트코드 재작성

* refactor: Controller -> RestController 로 변경

변경작업 수행

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

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

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

페이지 정보 유효성 검사

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

수정

* remove: consumes 를 다 허용해줌

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

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

폴더 이름 변경 기능 추가

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

OCR 결과 조회 기능 구현

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

삭제 기능을 수정

* chore: 에러 메시지 INVALID_DOCUMENT_PAGE 추가

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

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

---------






* Refactor: 녹음 API 상태 코드 변경 (#25)

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

* 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 예외 발생

예외 발생

---------



* Style: 코드 포맷팅 통일

* Refactor: 예외 종류 변경

---------




* 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 예외 발생

예외 발생

---------



---------




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

* Style: 코드 포맷팅 통일

* Refactor: 예외 종류 변경

---------




* Remove: .idea 폴더 삭제

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

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

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

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

* Chore: Weekly5 로 rebase

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

---------




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

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

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

* Refactor: 예외 메시지 수정

* refactor: 녹음 파일 업로드, 페이지 넘김 이벤트 처리 api 상태코드 변경

- 200 -> 201

---------




* Feat: 페이지별 api 구현 및 리팩토링 (#24)

* Refactor: 예외 로깅 추가

- LLMQueryService 예외 로깅

* Refactor: LLM 테이블 이름 변경

* Refactor: 명세 변경으로 인한 AI 서버 결과 Request DTO 변경

* Refactor: 요약, 문제와 LLM 연관관계 변경

- 다대일에서 일대일로 변경
- LLM 이 연관관계 주인

* Refactor: LLMService 메서드 네이밍 변경

- task 를 페이지별로 생성하므로 의미를 더 잘 나타낼 수 있도록 복수형으로 변경

* Refactor: Problem, Summary QueryRepository 인터페이스 사용

* Refactor: LLM 테이블 이름 변경

* Refactor: 명세 변경으로 인한 AI 서버 결과 Request DTO 변경

* Refactor: 요약, 문제와 LLM 연관관계 변경

- 다대일에서 일대일로 변경
- LLM 이 연관관계 주인

* Refactor: LLMService 메서드 네이밍 변경

- task 를 페이지별로 생성하므로 의미를 더 잘 나타낼 수 있도록 복수형으로 변경

* Rebase: Weekly8 로 리베이스

* Refactor: Problem, Summary QueryRepository 인터페이스화

* Feat: 페이지별 AI 기능 상태 조회 api 구현

* Refactor: Problem, Summary 도메인 unique 제약 조건 추가

* Feat: 페이지별 AI 기능 결과 확인 API 구현

* Refactor: 상태, 결과 조회시 요청 기록이 없는 경우 처리 수정

- 예외를 발생시키지 않고, 요청없음 enum 값이나 empty list 등을 반환하도록 수정

* feat: AI 기능 요청시 기존 내역이 존재하는 경우 처리

- Summary 와 Problem 레코드 재활용
- LLM task 삭제 후 재생성(taskId 변경으로 인한)

* Style: LLM으로 시작하는 클래스명 Llm으로 통일 (#26)

---------

Co-authored-by: Hyun-Seo Jeong <[email protected]>
Co-authored-by: hynseoj <[email protected]>
Co-authored-by: Cindy <[email protected]>
Co-authored-by: 윤정훈 <[email protected]>
Co-authored-by: mingjuu <[email protected]>
Co-authored-by: Minju Song <[email protected]>

* Feat: AI서버에서 STT 결과 응답 왔을때 STT 결과 처리하는 기능 구현

---------

Co-authored-by: Hyun-Seo Jeong <[email protected]>
Co-authored-by: hynseoj <[email protected]>
Co-authored-by: Cindy <[email protected]>
Co-authored-by: 윤정훈 <[email protected]>
Co-authored-by: mingjuu <[email protected]>
Co-authored-by: Minju Song <[email protected]>
  • Loading branch information
7 people authored Nov 1, 2024
1 parent f342234 commit d0e1294
Show file tree
Hide file tree
Showing 22 changed files with 917 additions and 42 deletions.
10 changes: 5 additions & 5 deletions src/main/java/notai/client/ai/AiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

import notai.client.ai.request.LlmTaskRequest;
import notai.client.ai.response.TaskResponse;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.service.annotation.PostExchange;

import java.io.InputStream;

public interface AiClient {

@PostExchange(url = "/api/ai/llm")
TaskResponse submitLlmTask(@RequestBody LlmTaskRequest request);

@PostExchange(url = "/api/ai/stt")
TaskResponse submitSttTask(@RequestPart("audio") MultipartFile audioFile);
@PostExchange(url = "/api/ai/stt", contentType = MediaType.MULTIPART_FORM_DATA_VALUE)
TaskResponse submitSttTask(@RequestBody InputStream audioFileStream);
}

31 changes: 22 additions & 9 deletions src/main/java/notai/common/exception/ErrorMessages.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@ public enum ErrorMessages {
ANNOTATION_NOT_FOUND("주석을 찾을 수 없습니다."),

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

// ocr
OCR_RESULT_NOT_FOUND("OCR 데이터를 찾을 수 없습니다."), OCR_TASK_ERROR("PDF 파일을 통해 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_RESULT_ERROR("AI 요약 및 문제 생성 중에 문제가 발생했습니다."),
LLM_TASK_LOG_NOT_FOUND("AI 작업 기록을 찾을 수 없습니다."),
LLM_TASK_RESULT_ERROR("AI 요약 및 문제 생성 중에 문제가 발생했습니다."),

// problem
PROBLEM_NOT_FOUND("문제 정보를 찾을 수 없습니다."),
Expand All @@ -33,19 +36,29 @@ public enum ErrorMessages {
RECORDING_NOT_FOUND("녹음 파일을 찾을 수 없습니다."),

// external api call
KAKAO_API_ERROR("카카오 API 호출에 예외가 발생했습니다."), AI_SERVER_ERROR("AI 서버 API 호출에 예외가 발생했습니다."),
KAKAO_API_ERROR("카카오 API 호출에 예외가 발생했습니다."),
AI_SERVER_ERROR("AI 서버 API 호출에 예외가 발생했습니다."),

// auth
INVALID_ACCESS_TOKEN("유효하지 않은 토큰입니다."), INVALID_REFRESH_TOKEN("유요하지 않은 Refresh Token입니다."), EXPIRED_REFRESH_TOKEN(
"만료된 Refresh Token입니다."), INVALID_LOGIN_TYPE("지원하지 않는 소셜 로그인 타입입니다."), NOTFOUND_ACCESS_TOKEN(
"토큰 정보가 존재하지 않습니다."),
INVALID_ACCESS_TOKEN("유효하지 않은 토큰입니다."),
INVALID_REFRESH_TOKEN("유요하지 않은 Refresh Token입니다."),
EXPIRED_REFRESH_TOKEN("만료된 Refresh Token입니다."),
INVALID_LOGIN_TYPE("지원하지 않는 소셜 로그인 타입입니다."),
NOTFOUND_ACCESS_TOKEN("토큰 정보가 존재하지 않습니다."),

// stt
STT_TASK_NOT_FOUND("음성 인식 작업을 찾을 수 없습니다."),
STT_TASK_ERROR("음성 인식 작업 중에 오류가 발생했습니다."),

// json conversion
JSON_CONVERSION_ERROR("JSON-객체 변환 중에 오류가 발생했습니다."),

// etc
INVALID_FILE_TYPE("지원하지 않는 파일 형식입니다."), FILE_NOT_FOUND("존재하지 않는 파일입니다."), FILE_SAVE_ERROR(
"파일을 저장하는 과정에서 오류가 발생했습니다."), INVALID_AUDIO_ENCODING("오디오 파일이 잘못되었습니다.");
INVALID_FILE_TYPE("지원하지 않는 파일 형식입니다."),
FILE_NOT_FOUND("존재하지 않는 파일입니다."),
FILE_SAVE_ERROR("파일을 저장하는 과정에서 오류가 발생했습니다."),
INVALID_AUDIO_ENCODING("오디오 파일이 잘못되었습니다."),
FILE_READ_ERROR("파일을 읽는 과정에서 오류가 발생했습니다.");

private final String message;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package notai.pageRecording.domain;

import notai.pageRecording.query.PageRecordingQueryRepository;
import notai.recording.domain.Recording;
import org.springframework.data.jpa.repository.JpaRepository;

public interface PageRecordingRepository extends JpaRepository<PageRecording, Long> {
import java.util.List;

public interface PageRecordingRepository extends
JpaRepository<PageRecording, Long>, PageRecordingQueryRepository {

List<PageRecording> findAllByRecording(Recording recording);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package notai.pageRecording.query;

import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import notai.pageRecording.domain.PageRecording;

@Repository
@RequiredArgsConstructor
public class PageRecordingQueryRepository {
import java.util.List;

private final JPAQueryFactory queryFactory;
public interface PageRecordingQueryRepository {

List<PageRecording> findAllByRecordingIdOrderByStartTime(Long recordingId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package notai.pageRecording.query;

import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import notai.pageRecording.domain.PageRecording;
import static notai.pageRecording.domain.QPageRecording.pageRecording;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
@RequiredArgsConstructor
public class PageRecordingQueryRepositoryImpl implements PageRecordingQueryRepository{

private final JPAQueryFactory queryFactory;

public List<PageRecording> findAllByRecordingIdOrderByStartTime(Long recordingId) {
return queryFactory.selectFrom(pageRecording)
.where(pageRecording.recording.id.eq(recordingId))
.orderBy(pageRecording.startTime.asc())
.fetch();
}
}
11 changes: 8 additions & 3 deletions src/main/java/notai/recording/application/RecordingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import lombok.RequiredArgsConstructor;
import notai.common.domain.vo.FilePath;
import static notai.common.exception.ErrorMessages.FILE_SAVE_ERROR;
import static notai.common.exception.ErrorMessages.INVALID_AUDIO_ENCODING;
import notai.common.exception.type.BadRequestException;
import notai.common.exception.type.InternalServerErrorException;
import notai.common.utils.AudioDecoder;
Expand All @@ -12,6 +14,8 @@
import notai.recording.application.result.RecordingSaveResult;
import notai.recording.domain.Recording;
import notai.recording.domain.RecordingRepository;
import notai.stt.application.SttTaskService;
import notai.stt.application.command.SttRequestCommand;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -20,9 +24,6 @@
import java.nio.file.Path;
import java.nio.file.Paths;

import static notai.common.exception.ErrorMessages.FILE_SAVE_ERROR;
import static notai.common.exception.ErrorMessages.INVALID_AUDIO_ENCODING;

@Service
@Transactional
@RequiredArgsConstructor
Expand All @@ -32,6 +33,7 @@ public class RecordingService {
private final DocumentRepository documentRepository;
private final AudioDecoder audioDecoder;
private final FileManager fileManager;
private final SttTaskService sttTaskService;

@Value("${file.audio.basePath}")
private String audioBasePath;
Expand All @@ -52,6 +54,9 @@ public RecordingSaveResult saveRecording(RecordingSaveCommand command) {
fileManager.save(binaryAudioData, outputPath);
savedRecording.updateFilePath(filePath);

SttRequestCommand sttCommand = new SttRequestCommand(savedRecording.getId(), filePath.getFilePath());
sttTaskService.submitSttTask(sttCommand);

return RecordingSaveResult.of(savedRecording.getId(), foundDocument.getId(), savedRecording.getCreatedAt());

} catch (IllegalArgumentException e) {
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/notai/stt/application/SttService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package notai.stt.application;

import lombok.RequiredArgsConstructor;
import notai.pageRecording.domain.PageRecording;
import notai.pageRecording.domain.PageRecordingRepository;
import notai.recording.domain.Recording;
import notai.stt.application.command.UpdateSttResultCommand;
import notai.stt.application.dto.SttPageMatchedDto;
import notai.stt.domain.Stt;
import notai.stt.domain.SttRepository;
import notai.sttTask.domain.SttTask;
import notai.sttTask.domain.SttTaskRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
@RequiredArgsConstructor
public class SttService {
private final SttRepository sttRepository;
private final SttTaskRepository sttTaskRepository;
private final PageRecordingRepository pageRecordingRepository;

/**
* AI 서버로부터 받은 STT 결과를 처리하여 페이지별 STT 데이터를 생성하고 저장합니다.
* 1. STT 테스크와 관련 엔티티들을 조회
* 2. 음성 인식된 단어들을 페이지와 매칭
* 3. 매칭 결과를 저장하고 테스크를 완료 처리
*/
public void updateSttResult(UpdateSttResultCommand command) {
SttTask sttTask = sttTaskRepository.getById(command.taskId());
Stt stt = sttTask.getStt();
Recording recording = stt.getRecording();
List<PageRecording> pageRecordings = pageRecordingRepository.findAllByRecordingIdOrderByStartTime(recording.getId());

SttPageMatchedDto matchedResult = stt.matchWordsWithPages(command.words(), pageRecordings);
List<Stt> pageMatchedSttResults = Stt.createFromMatchedResult(recording, matchedResult);
sttRepository.saveAll(pageMatchedSttResults);

sttTask.complete();
sttTaskRepository.save(sttTask);
}
}
61 changes: 61 additions & 0 deletions src/main/java/notai/stt/application/SttTaskService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package notai.stt.application;

import lombok.RequiredArgsConstructor;
import notai.client.ai.AiClient;
import notai.client.ai.response.TaskResponse;
import static notai.common.exception.ErrorMessages.FILE_NOT_FOUND;
import static notai.common.exception.ErrorMessages.FILE_READ_ERROR;
import notai.common.exception.type.FileProcessException;
import notai.common.exception.type.NotFoundException;
import notai.llm.domain.TaskStatus;
import notai.recording.domain.Recording;
import notai.recording.domain.RecordingRepository;
import notai.stt.application.command.SttRequestCommand;
import notai.stt.domain.Stt;
import notai.stt.domain.SttRepository;
import notai.sttTask.domain.SttTask;
import notai.sttTask.domain.SttTaskRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

@Service
@Transactional
@RequiredArgsConstructor
public class SttTaskService {
private final AiClient aiClient;
private final SttRepository sttRepository;
private final SttTaskRepository sttTaskRepository;
private final RecordingRepository recordingRepository;

public void submitSttTask(SttRequestCommand command) {
Recording recording = recordingRepository.getById(command.recordingId());
File audioFile = validateAudioFile(command.audioFilePath());

try (FileInputStream fileInputStream = new FileInputStream(audioFile)) {
TaskResponse response = aiClient.submitSttTask(fileInputStream);
createAndSaveSttTask(recording, response);
} catch (IOException e) {
throw new FileProcessException(FILE_READ_ERROR);
}
}

private File validateAudioFile(String audioFilePath) {
File audioFile = new File(audioFilePath);
if (!audioFile.exists()) {
throw new NotFoundException(FILE_NOT_FOUND);
}
return audioFile;
}

private void createAndSaveSttTask(Recording recording, TaskResponse response) {
Stt stt = new Stt(recording);
sttRepository.save(stt);

SttTask sttTask = new SttTask(response.taskId(), stt, TaskStatus.PENDING);
sttTaskRepository.save(sttTask);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package notai.stt.application.command;

public record SttRequestCommand(
Long recordingId,
String audioFilePath
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package notai.stt.application.command;

import java.util.List;
import java.util.UUID;

public record UpdateSttResultCommand(
UUID taskId,
List<Word> words
) {
public record Word(
String word,
double start,
double end
) {
}
}
19 changes: 19 additions & 0 deletions src/main/java/notai/stt/application/dto/SttPageMatchedDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package notai.stt.application.dto;

import java.util.List;

public record SttPageMatchedDto(
List<PageMatchedContent> pageContents
) {
public record PageMatchedContent(
Integer pageNumber,
String content,
List<PageMatchedWord> words
) {}

public record PageMatchedWord(
String word,
Integer startTime,
Integer endTime
) {}
}
Loading

0 comments on commit d0e1294

Please sign in to comment.