Chore: 회의 종료 API 실제 데이터 연동

This commit is contained in:
cyjadela 2025-10-27 16:48:17 +09:00
parent 43792c1674
commit e5337385f4
8 changed files with 3652 additions and 7 deletions

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
@ -328,9 +329,20 @@ public class MeetingService implements
log.debug("Found minutes: {}", minutes.getTitle());
}
// 5. 기본 분석 정보 생성 (실제 AI 분석은 AI 서비스에서 비동기 처리)
MeetingAnalysis analysis = createBasicAnalysis(meeting, minutes);
// 5. 기존 분석 데이터 확인 사용 또는 새로 생성
Optional<MeetingAnalysis> existingAnalysis = meetingAnalysisReader.findLatestByMeetingId(meetingId);
MeetingAnalysis analysis;
if (existingAnalysis.isPresent()) {
// 기존 분석 데이터가 있으면 사용
analysis = existingAnalysis.get();
log.info("Using existing analysis data for meeting: {}", meetingId);
} else {
// 기존 분석 데이터가 없으면 새로 생성
analysis = createBasicAnalysis(meeting, minutes);
meetingAnalysisWriter.save(analysis);
log.info("Created new analysis data for meeting: {}", meetingId);
}
// TODO: AI 서비스에 비동기 분석 요청 전송
// aiAnalysisClient.requestAnalysis(meeting.getMeetingId(), minutes.getMinutesId());

View File

@ -14,6 +14,11 @@ public interface MeetingAnalysisReader {
*/
Optional<MeetingAnalysis> findByMeetingId(String meetingId);
/**
* 회의 ID로 가장 최근 분석 결과 조회
*/
Optional<MeetingAnalysis> findLatestByMeetingId(String meetingId);
/**
* 분석 ID로 분석 결과 조회
*/

View File

@ -42,6 +42,13 @@ public class MeetingAnalysisGateway implements MeetingAnalysisReader, MeetingAna
.map(MeetingAnalysisEntity::toDomain);
}
@Override
public Optional<MeetingAnalysis> findLatestByMeetingId(String meetingId) {
log.debug("Finding latest meeting analysis by meetingId: {}", meetingId);
return repository.findFirstByMeetingIdOrderByCreatedAtDesc(meetingId)
.map(MeetingAnalysisEntity::toDomain);
}
@Override
public MeetingAnalysis save(MeetingAnalysis analysis) {
log.debug("Saving meeting analysis: {}", analysis.getAnalysisId());

View File

@ -6,6 +6,8 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.LocalDateTime;
import java.util.List;
@ -52,33 +54,68 @@ public class MeetingAnalysisEntity {
* Entity를 도메인으로 변환
*/
public MeetingAnalysis toDomain() {
// JSON 파싱은 실제 구현에서는 ObjectMapper 사용
// 현재는 Mock으로 처리
List<MeetingAnalysis.AgendaAnalysis> agendaAnalyses = parseAgendaAnalyses();
return MeetingAnalysis.builder()
.analysisId(this.analysisId)
.meetingId(this.meetingId)
.minutesId(this.minutesId)
.keywords(this.keywords)
.agendaAnalyses(List.of()) // Mock
.agendaAnalyses(agendaAnalyses)
.status(this.status)
.completedAt(this.completedAt)
.createdAt(this.createdAt)
.build();
}
/**
* JSON 문자열을 AgendaAnalysis 리스트로 파싱
*/
private List<MeetingAnalysis.AgendaAnalysis> parseAgendaAnalyses() {
if (agendaAnalysesJson == null || agendaAnalysesJson.trim().isEmpty() || "{}".equals(agendaAnalysesJson.trim())) {
return List.of();
}
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(agendaAnalysesJson, new TypeReference<List<MeetingAnalysis.AgendaAnalysis>>() {});
} catch (Exception e) {
// JSON 파싱 실패 리스트 반환
return List.of();
}
}
/**
* 도메인에서 Entity로 변환
*/
public static MeetingAnalysisEntity fromDomain(MeetingAnalysis domain) {
String agendaAnalysesJson = convertAgendaAnalysesToJson(domain.getAgendaAnalyses());
return MeetingAnalysisEntity.builder()
.analysisId(domain.getAnalysisId())
.meetingId(domain.getMeetingId())
.minutesId(domain.getMinutesId())
.keywords(domain.getKeywords())
.agendaAnalysesJson("{}") // Mock JSON
.agendaAnalysesJson(agendaAnalysesJson)
.status(domain.getStatus())
.completedAt(domain.getCompletedAt())
.createdAt(domain.getCreatedAt())
.build();
}
/**
* AgendaAnalysis 리스트를 JSON 문자열로 변환
*/
private static String convertAgendaAnalysesToJson(List<MeetingAnalysis.AgendaAnalysis> agendaAnalyses) {
if (agendaAnalyses == null || agendaAnalyses.isEmpty()) {
return "[]";
}
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(agendaAnalyses);
} catch (Exception e) {
return "[]";
}
}
}

View File

@ -21,4 +21,9 @@ public interface MeetingAnalysisJpaRepository extends JpaRepository<MeetingAnaly
* 회의록 ID로 분석 결과 조회
*/
Optional<MeetingAnalysisEntity> findByMinutesId(String minutesId);
/**
* 회의 ID로 가장 최근 분석 결과 조회
*/
Optional<MeetingAnalysisEntity> findFirstByMeetingIdOrderByCreatedAtDesc(String meetingId);
}