11package com .example .ai_tutor .domain .note .application ;
22
33import com .amazonaws .services .s3 .AmazonS3 ;
4+ import com .example .ai_tutor .domain .answer .domain .repository .AnswerRepository ;
45import com .example .ai_tutor .domain .folder .domain .Folder ;
56import com .example .ai_tutor .domain .folder .domain .repository .FolderRepository ;
6- import com .example .ai_tutor .domain .answer .domain .repository .AnswerRepository ;
77import com .example .ai_tutor .domain .note .domain .Note ;
88import com .example .ai_tutor .domain .note .domain .NoteStatus ;
99import com .example .ai_tutor .domain .note .domain .repository .NoteRepository ;
1212import com .example .ai_tutor .domain .note_student .application .NoteStudentService ;
1313import com .example .ai_tutor .domain .note_student .domain .NoteStudent ;
1414import com .example .ai_tutor .domain .note_student .domain .repository .NoteStudentRepository ;
15+ import com .example .ai_tutor .domain .openAPI .clova .ClovaService ;
1516import com .example .ai_tutor .domain .practice .domain .Practice ;
1617import com .example .ai_tutor .domain .practice .domain .repository .PracticeRepository ;
1718import com .example .ai_tutor .domain .professor .domain .Professor ;
2122import com .example .ai_tutor .global .DefaultAssert ;
2223import com .example .ai_tutor .global .config .security .token .UserPrincipal ;
2324import com .example .ai_tutor .global .payload .ApiResponse ;
25+ import com .fasterxml .jackson .databind .JsonNode ;
2426import lombok .RequiredArgsConstructor ;
27+ import lombok .extern .slf4j .Slf4j ;
2528import org .springframework .http .ResponseEntity ;
2629import org .springframework .stereotype .Service ;
2730import org .springframework .transaction .annotation .Transactional ;
31+ import org .springframework .web .multipart .MultipartFile ;
2832
2933import java .util .Random ;
3034import java .util .List ;
3135
3236@ Service
37+ @ Slf4j
3338@ RequiredArgsConstructor
3439@ Transactional (readOnly = true )
3540public class ProfessorNoteService {
@@ -42,41 +47,19 @@ public class ProfessorNoteService {
4247 private final NoteStudentRepository noteStudentRepository ;
4348 private final ProfessorRepository professorRepository ;
4449 private final NoteStudentService noteStudentService ;
50+ private final ClovaService clovaService ;
4551
4652 private final AmazonS3 amazonS3 ;
4753
48- // 수업 정보 조회
49- @ Transactional
50- public ResponseEntity <?> getFolderInfo (UserPrincipal userPrincipal , Long folderId ) {
51- validateUser (userPrincipal );
52- Folder folder = folderRepository .findById (folderId ).orElseThrow (() -> new IllegalArgumentException ("폴더를 찾을 수 없습니다." ));
53-
54- FolderInfoRes folderInfoRes = FolderInfoRes .builder ()
55- .folderName (folder .getFolderName ())
56- .professor (folder .getProfessor ().getUser ().getName ())
57- .build ();
58-
59- ApiResponse apiResponse = ApiResponse .builder ()
60- .check (true )
61- .information (folderInfoRes )
62- .build ();
63-
64- return ResponseEntity .ok (apiResponse );
65- }
66-
67-
6854 // 노트 생성
6955 @ Transactional
70- public ResponseEntity <?> createNewNote (UserPrincipal userPrincipal , Long folderId , NoteCreateReq noteCreateReq ) {
71- User user = validateUser (userPrincipal );
56+ public ResponseEntity <?> createNewNote (UserPrincipal userPrincipal , Long folderId , NoteCreateReq request ) {
57+ User user = getUser (userPrincipal );
7258 Folder folder = folderRepository .findById (folderId ).orElseThrow (() -> new IllegalArgumentException ("폴더를 찾을 수 없습니다." ));
7359 Professor professor = professorRepository .findByUser (user ).orElseThrow (() -> new IllegalArgumentException ("교수자를 찾을 수 없습니다." ));
7460
7561 DefaultAssert .isTrue (folder .getProfessor ().equals (professor ), "해당 폴더에 접근할 수 없습니다." );
76- Note note = Note .builder ()
77- .title (noteCreateReq .getTitle ())
78- .folder (folder )
79- .build ();
62+ Note note = Note .createNote (folder , request .getTitle (), null , null );
8063 noteRepository .save (note );
8164
8265 NoteAccessRes noteAccessRes = NoteAccessRes .builder ()
@@ -91,6 +74,37 @@ public ResponseEntity<?> createNewNote(UserPrincipal userPrincipal, Long folderI
9174 return ResponseEntity .ok (apiResponse );
9275 }
9376
77+ @ Transactional
78+ public boolean convertSpeechToText (Long noteId , MultipartFile file ) {
79+ // 1. Note 조회
80+ Note note = noteRepository .findById (noteId )
81+ .orElseThrow (() -> new IllegalArgumentException ("노트를 찾을 수 없습니다." ));
82+
83+ // 2. 기존 STT 변환이 있다면 중단
84+ if (note .getSttText () != null ) {
85+ log .info ("기존 STT 변환 데이터가 존재하므로 변환하지 않습니다." );
86+ return false ;
87+ }
88+
89+ try {
90+ // 3. CLOVA STT API 호출 (동기 처리)
91+ JsonNode response = clovaService .processSpeechToText (file ).block ();
92+ log .info ("CLOVA STT 응답: {}" , response );
93+
94+ // 4. STT 결과에서 텍스트 추출 및 저장
95+ String fullText = response .path ("text" ).asText ();
96+ note .updateStt (fullText , String .valueOf (response ));
97+ noteRepository .save (note );
98+
99+ log .info ("STT 변환 완료: {}" , noteId );
100+ return true ;
101+ } catch (Exception e ) {
102+ log .error ("STT 변환 중 오류 발생" , e );
103+ note .markSttFailed (); // 실패 상태 업데이트
104+ noteRepository .save (note );
105+ return false ;
106+ }
107+ }
94108
95109//
96110// // 녹음본이 아닌 영상을 업로드하는 방식으로 수정
@@ -153,7 +167,7 @@ public ResponseEntity<?> createNewNote(UserPrincipal userPrincipal, Long folderI
153167
154168 // 문제지 목록 조회
155169 public ResponseEntity <?> getAllNotesByFolder (UserPrincipal userPrincipal , Long folderId ) {
156- User user = validateUser (userPrincipal );
170+ User user = getUser (userPrincipal );
157171 Folder folder = folderRepository .findById (folderId ).orElseThrow (() -> new IllegalArgumentException ("폴더를 찾을 수 없습니다." ));
158172 DefaultAssert .isTrue (user == folder .getProfessor ().getUser (), "사용자가 일치하지 않습니다." );
159173
@@ -188,7 +202,7 @@ public ResponseEntity<?> getAllNotesByFolder(UserPrincipal userPrincipal, Long f
188202 // 문제지 삭제
189203 @ Transactional
190204 public ResponseEntity <?> deleteNoteById (UserPrincipal userPrincipal , Long noteId ) {
191- User user = validateUser (userPrincipal );
205+ User user = getUser (userPrincipal );
192206 Note note = noteRepository .findById (noteId ).orElseThrow (() -> new IllegalArgumentException ("노트를 찾을 수 없습니다." ));
193207
194208 Folder folder = note .getFolder ();
@@ -221,7 +235,7 @@ public ResponseEntity<?> deleteNoteById(UserPrincipal userPrincipal, Long noteId
221235 // 문제지 랜덤 코드 생성
222236 @ Transactional
223237 public ResponseEntity <?> createRandomCode (UserPrincipal userPrincipal , Long noteId ) {
224- validateUser (userPrincipal );
238+ getUser (userPrincipal );
225239 Note note = noteRepository .findById (noteId )
226240 .orElseThrow (() -> new IllegalArgumentException ("노트를 찾을 수 없습니다." ));
227241
@@ -265,7 +279,7 @@ private String generateRandomCode() {
265279 }
266280
267281 public ResponseEntity <?> getNoteResult (UserPrincipal userPrincipal , Long noteId ) {
268- validateUser (userPrincipal );
282+ getUser (userPrincipal );
269283 Note note = noteRepository .findById (noteId ).orElseThrow (() -> new IllegalArgumentException ("노트를 찾을 수 없습니다." ));
270284
271285 List <NoteStudent > noteStudentList = noteStudentRepository .findByNote (note );
@@ -298,8 +312,8 @@ public ResponseEntity<?> getNoteResult(UserPrincipal userPrincipal, Long noteId)
298312
299313 }
300314
301- private User validateUser (UserPrincipal userPrincipal ){
302- return userRepository .findById (userPrincipal . getId () ).orElseThrow (()
315+ private User getUser (UserPrincipal userPrincipal ){
316+ return userRepository .findById (1L ).orElseThrow (()
303317 -> new IllegalArgumentException ("사용자를 찾을 수 없습니다." ));
304318 }
305319}
0 commit comments