From 44ae9c546f2788211089c408b4ce1f1b856ba800 Mon Sep 17 00:00:00 2001 From: djeon Date: Wed, 29 Oct 2025 05:51:01 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20rag=EC=9A=A9=20=ED=9A=8C=EC=9D=98?= =?UTF-8?q?=EB=A1=9D=ED=99=95=EC=A0=95=20event=20=EB=B0=9C=ED=96=89=20?= =?UTF-8?q?=EB=B0=8F=20meeting=20=EC=B0=B8=EC=84=9D=EC=9E=90=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=82=AD=EC=A0=9C=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../meeting/biz/service/MinutesService.java | 37 +++++++++++- .../meeting/infra/cache/CacheService.java | 54 +++++++++-------- .../infra/controller/MinutesController.java | 55 +++++++++++++++++- .../event/dto/MinutesFinalizedEvent.java | 58 +++++++++++++++++++ .../infra/event/dto/MinutesSectionDTO.java | 43 ++++++++++++++ .../event/publisher/EventHubPublisher.java | 11 ++++ .../infra/event/publisher/EventPublisher.java | 8 +++ .../event/publisher/NoOpEventPublisher.java | 7 +++ .../infra/gateway/entity/MeetingEntity.java | 2 +- 9 files changed, 247 insertions(+), 28 deletions(-) create mode 100644 meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/dto/MinutesFinalizedEvent.java create mode 100644 meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/dto/MinutesSectionDTO.java diff --git a/meeting/src/main/java/com/unicorn/hgzero/meeting/biz/service/MinutesService.java b/meeting/src/main/java/com/unicorn/hgzero/meeting/biz/service/MinutesService.java index 1112121..6e09c10 100644 --- a/meeting/src/main/java/com/unicorn/hgzero/meeting/biz/service/MinutesService.java +++ b/meeting/src/main/java/com/unicorn/hgzero/meeting/biz/service/MinutesService.java @@ -328,11 +328,11 @@ public class MinutesService implements } catch (Exception e) { log.warn("회의 정보 조회 실패 - meetingId: {}", minutes.getMeetingId(), e); } - + // TODO 정보는 추후 구현 (현재는 기본값) int todoCount = 0; int completedTodoCount = 0; - + // 참석자 수 계산 (모든 참석자) int participantCount = 0; try { @@ -340,7 +340,37 @@ public class MinutesService implements } catch (Exception e) { log.warn("참석자 수 계산 실패 - meetingId: {}", minutes.getMeetingId(), e); } - + + // 섹션 정보 변환 + List sectionDTOs = null; + try { + List sections = minutes.getSections(); + + // Minutes 도메인에 섹션이 없으면 DB에서 조회 + if (sections == null || sections.isEmpty()) { + sections = minutesSectionReader.findByMinutesIdOrderByOrder(minutes.getMinutesId()); + } + + // MinutesSection을 SectionDTO로 변환 + if (sections != null && !sections.isEmpty()) { + sectionDTOs = sections.stream() + .map(section -> com.unicorn.hgzero.meeting.biz.dto.SectionDTO.builder() + .sectionId(section.getSectionId()) + .minutesId(section.getMinutesId()) + .title(section.getTitle()) + .content(section.getContent()) + .sectionOrder(section.getOrder()) + .sectionType(section.getType()) + .isVerified(section.getVerified()) + .isLocked(section.getLocked()) + .lockedBy(section.getLockedBy()) + .build()) + .collect(Collectors.toList()); + } + } catch (Exception e) { + log.warn("섹션 정보 변환 실패 - minutesId: {}", minutes.getMinutesId(), e); + } + return MinutesDTO.builder() .minutesId(minutes.getMinutesId()) .meetingId(minutes.getMeetingId()) @@ -356,6 +386,7 @@ public class MinutesService implements .completedTodoCount(completedTodoCount) .participantCount(participantCount) .memo("") // 메모 필드는 추후 구현 + .sections(sectionDTOs) // 섹션 정보 추가 .build(); } } diff --git a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/cache/CacheService.java b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/cache/CacheService.java index b8cf220..543a924 100644 --- a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/cache/CacheService.java +++ b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/cache/CacheService.java @@ -52,7 +52,8 @@ public class CacheService { redisTemplate.opsForValue().set(key, value, Duration.ofSeconds(ttl)); log.debug("회의 정보 캐시 저장 - meetingId: {}", meetingId); } catch (Exception e) { - log.error("회의 정보 캐시 저장 실패 - meetingId: {}", meetingId, e); + log.warn("회의 정보 캐시 저장 실패 (서비스는 정상 동작) - meetingId: {}, 에러: {}", + meetingId, e.getMessage()); } } @@ -72,7 +73,8 @@ public class CacheService { return objectMapper.readValue(value, clazz); } } catch (Exception e) { - log.error("회의 정보 캐시 조회 실패 - meetingId: {}", meetingId, e); + log.warn("회의 정보 캐시 조회 실패 (DB에서 조회) - meetingId: {}, 에러: {}", + meetingId, e.getMessage()); } return null; } @@ -91,7 +93,8 @@ public class CacheService { redisTemplate.opsForValue().set(key, value, Duration.ofSeconds(ttl)); log.debug("회의록 정보 캐시 저장 - minutesId: {}", minutesId); } catch (Exception e) { - log.error("회의록 정보 캐시 저장 실패 - minutesId: {}", minutesId, e); + log.warn("회의록 정보 캐시 저장 실패 (서비스는 정상 동작) - minutesId: {}, 에러: {}", + minutesId, e.getMessage()); } } @@ -111,7 +114,8 @@ public class CacheService { return objectMapper.readValue(value, clazz); } } catch (Exception e) { - log.error("회의록 정보 캐시 조회 실패 - minutesId: {}", minutesId, e); + log.warn("회의록 정보 캐시 조회 실패 (DB에서 조회) - minutesId: {}, 에러: {}", + minutesId, e.getMessage()); } return null; } @@ -130,7 +134,8 @@ public class CacheService { redisTemplate.opsForValue().set(key, value, Duration.ofSeconds(ttl)); log.debug("대시보드 데이터 캐시 저장 - userId: {}", userId); } catch (Exception e) { - log.error("대시보드 데이터 캐시 저장 실패 - userId: {}", userId, e); + log.warn("대시보드 데이터 캐시 저장 실패 (서비스는 정상 동작) - userId: {}, 에러: {}", + userId, e.getMessage()); } } @@ -150,7 +155,8 @@ public class CacheService { return objectMapper.readValue(value, clazz); } } catch (Exception e) { - log.error("대시보드 데이터 캐시 조회 실패 - userId: {}", userId, e); + log.warn("대시보드 데이터 캐시 조회 실패 (DB에서 조회) - userId: {}, 에러: {}", + userId, e.getMessage()); } return null; } @@ -169,7 +175,8 @@ public class CacheService { redisTemplate.opsForValue().set(key, value, Duration.ofSeconds(ttl)); log.debug("세션 정보 캐시 저장 - sessionId: {}", sessionId); } catch (Exception e) { - log.error("세션 정보 캐시 저장 실패 - sessionId: {}", sessionId, e); + log.warn("세션 정보 캐시 저장 실패 (서비스는 정상 동작) - sessionId: {}, 에러: {}", + sessionId, e.getMessage()); } } @@ -189,7 +196,8 @@ public class CacheService { return objectMapper.readValue(value, clazz); } } catch (Exception e) { - log.error("세션 정보 캐시 조회 실패 - sessionId: {}", sessionId, e); + log.warn("세션 정보 캐시 조회 실패 - sessionId: {}, 에러: {}", + sessionId, e.getMessage()); } return null; } @@ -206,7 +214,7 @@ public class CacheService { redisTemplate.delete(key); log.debug("캐시 삭제 - key: {}", key); } catch (Exception e) { - log.error("캐시 삭제 실패 - key: {}", prefix + id, e); + log.warn("캐시 삭제 실패 - key: {}, 에러: {}", prefix + id, e.getMessage()); } } @@ -223,7 +231,7 @@ public class CacheService { log.debug("패턴 캐시 삭제 - pattern: {}, count: {}", pattern, keys.size()); } } catch (Exception e) { - log.error("패턴 캐시 삭제 실패 - pattern: {}", pattern, e); + log.warn("패턴 캐시 삭제 실패 - pattern: {}, 에러: {}", pattern, e.getMessage()); } } @@ -234,7 +242,7 @@ public class CacheService { redisTemplate.opsForValue().set(MINUTES_LIST_PREFIX + cacheKey, value, Duration.ofMinutes(10)); log.debug("회의록 목록 캐시 저장 - key: {}", cacheKey); } catch (Exception e) { - log.error("회의록 목록 캐시 저장 실패 - key: {}", cacheKey, e); + log.warn("회의록 목록 캐시 저장 실패 (서비스는 정상 동작) - key: {}, 에러: {}", cacheKey, e.getMessage()); } } @@ -245,7 +253,7 @@ public class CacheService { return objectMapper.readValue(value, MinutesListResponse.class); } } catch (Exception e) { - log.error("회의록 목록 캐시 조회 실패 - key: {}", cacheKey, e); + log.warn("회의록 목록 캐시 조회 실패 (DB에서 조회) - key: {}, 에러: {}", cacheKey, e.getMessage()); } return null; } @@ -256,7 +264,7 @@ public class CacheService { redisTemplate.opsForValue().set(MINUTES_DETAIL_PREFIX + minutesId, value, Duration.ofMinutes(5)); log.debug("회의록 상세 캐시 저장 - minutesId: {}", minutesId); } catch (Exception e) { - log.error("회의록 상세 캐시 저장 실패 - minutesId: {}", minutesId, e); + log.warn("회의록 상세 캐시 저장 실패 (서비스는 정상 동작) - minutesId: {}, 에러: {}", minutesId, e.getMessage()); } } @@ -267,7 +275,7 @@ public class CacheService { return objectMapper.readValue(value, MinutesDetailResponse.class); } } catch (Exception e) { - log.error("회의록 상세 캐시 조회 실패 - minutesId: {}", minutesId, e); + log.warn("회의록 상세 캐시 조회 실패 (DB에서 조회) - minutesId: {}, 에러: {}", minutesId, e.getMessage()); } return null; } @@ -289,7 +297,7 @@ public class CacheService { redisTemplate.opsForValue().set(TODO_LIST_PREFIX + cacheKey, value, Duration.ofMinutes(10)); log.debug("Todo 목록 캐시 저장 - key: {}", cacheKey); } catch (Exception e) { - log.error("Todo 목록 캐시 저장 실패 - key: {}", cacheKey, e); + log.warn("Todo 목록 캐시 저장 실패 (서비스는 정상 동작) - key: {}, 에러: {}", cacheKey, e.getMessage()); } } @@ -300,7 +308,7 @@ public class CacheService { return objectMapper.readValue(value, TodoListResponse.class); } } catch (Exception e) { - log.error("Todo 목록 캐시 조회 실패 - key: {}", cacheKey, e); + log.warn("Todo 목록 캐시 조회 실패 (DB에서 조회) - key: {}, 에러: {}", cacheKey, e.getMessage()); } return null; } @@ -327,7 +335,7 @@ public class CacheService { redisTemplate.opsForValue().set(TEMPLATE_LIST_PREFIX + cacheKey, value, Duration.ofHours(1)); log.debug("템플릿 목록 캐시 저장 - key: {}", cacheKey); } catch (Exception e) { - log.error("템플릿 목록 캐시 저장 실패 - key: {}", cacheKey, e); + log.warn("템플릿 목록 캐시 저장 실패 (서비스는 정상 동작) - key: {}, 에러: {}", cacheKey, e.getMessage()); } } @@ -338,7 +346,7 @@ public class CacheService { return objectMapper.readValue(value, TemplateListResponse.class); } } catch (Exception e) { - log.error("템플릿 목록 캐시 조회 실패 - key: {}", cacheKey, e); + log.warn("템플릿 목록 캐시 조회 실패 (DB에서 조회) - key: {}, 에러: {}", cacheKey, e.getMessage()); } return null; } @@ -349,7 +357,7 @@ public class CacheService { redisTemplate.opsForValue().set(TEMPLATE_DETAIL_PREFIX + templateId, value, Duration.ofHours(1)); log.debug("템플릿 상세 캐시 저장 - templateId: {}", templateId); } catch (Exception e) { - log.error("템플릿 상세 캐시 저장 실패 - templateId: {}", templateId, e); + log.warn("템플릿 상세 캐시 저장 실패 (서비스는 정상 동작) - templateId: {}, 에러: {}", templateId, e.getMessage()); } } @@ -360,7 +368,7 @@ public class CacheService { return objectMapper.readValue(value, TemplateDetailResponse.class); } } catch (Exception e) { - log.error("템플릿 상세 캐시 조회 실패 - templateId: {}", templateId, e); + log.warn("템플릿 상세 캐시 조회 실패 (DB에서 조회) - templateId: {}, 에러: {}", templateId, e.getMessage()); } return null; } @@ -372,7 +380,7 @@ public class CacheService { redisTemplate.opsForValue().set(AI_ANALYSIS_PREFIX + minutesId, value, Duration.ofHours(1)); log.debug("AI 분석 결과 캐시 저장 - minutesId: {}", minutesId); } catch (Exception e) { - log.error("AI 분석 결과 캐시 저장 실패 - minutesId: {}", minutesId, e); + log.warn("AI 분석 결과 캐시 저장 실패 (서비스는 정상 동작) - minutesId: {}, 에러: {}", minutesId, e.getMessage()); } } @@ -385,7 +393,7 @@ public class CacheService { return Optional.of(analysis); } } catch (Exception e) { - log.error("AI 분석 결과 캐시 조회 실패 - minutesId: {}", minutesId, e); + log.warn("AI 분석 결과 캐시 조회 실패 (새로 생성) - minutesId: {}, 에러: {}", minutesId, e.getMessage()); } return Optional.empty(); } @@ -395,7 +403,7 @@ public class CacheService { redisTemplate.delete(AI_ANALYSIS_PREFIX + minutesId); log.debug("AI 분석 캐시 삭제 - minutesId: {}", minutesId); } catch (Exception e) { - log.error("AI 분석 캐시 삭제 실패 - minutesId: {}", minutesId, e); + log.warn("AI 분석 캐시 삭제 실패 - minutesId: {}, 에러: {}", minutesId, e.getMessage()); } } } \ No newline at end of file diff --git a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java index 8aec3a8..324ffa2 100644 --- a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java +++ b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java @@ -19,6 +19,8 @@ import com.unicorn.hgzero.meeting.infra.event.publisher.EventPublisher; import com.unicorn.hgzero.meeting.infra.gateway.AiServiceGateway; import com.unicorn.hgzero.meeting.biz.dto.AiAnalysisDTO; import com.unicorn.hgzero.meeting.infra.event.dto.MinutesAnalysisRequestEvent; +import com.unicorn.hgzero.meeting.infra.event.dto.MinutesFinalizedEvent; +import com.unicorn.hgzero.meeting.infra.event.dto.MinutesSectionDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.responses.ApiResponses; @@ -242,9 +244,60 @@ public class MinutesController { // 캐시 무효화 (목록 캐시) cacheService.evictCacheMinutesList(userId); - // 회의록 확정 이벤트 발행 + // 회의록 확정 이벤트 발행 (알림용 - 기존) eventPublisher.publishMinutesFinalized(minutesId, finalizedMinutes.getTitle(), userId, userName); + // RAG 서비스용 회의록 확정 이벤트 발행 (완전한 데이터 포함) + try { + // 회의 정보 조회 + Meeting meeting = meetingService.getMeeting(finalizedMinutes.getMeetingId()); + + // 섹션 정보 변환 + List sectionDTOs = finalizedMinutes.getSections().stream() + .map(section -> MinutesSectionDTO.builder() + .sectionId(section.getSectionId()) + .type(section.getSectionType()) + .title(section.getTitle()) + .content(section.getContent()) + .order(section.getSectionOrder()) + .verified(section.getIsVerified()) + .build()) + .collect(Collectors.toList()); + + // MinutesFinalizedEvent 생성 + MinutesFinalizedEvent ragEvent = MinutesFinalizedEvent.builder() + .timestamp(LocalDateTime.now()) + .data(MinutesFinalizedEvent.MinutesData.builder() + // Meeting 정보 + .meetingId(meeting.getMeetingId()) + .title(meeting.getTitle()) + .purpose(meeting.getPurpose()) + .description(meeting.getDescription()) + .scheduledAt(meeting.getScheduledAt()) + .location(meeting.getLocation()) + .organizerId(meeting.getOrganizerId()) + // Minutes 정보 + .minutesId(finalizedMinutes.getMinutesId()) + .status(finalizedMinutes.getStatus()) + .version(finalizedMinutes.getVersion()) + .createdBy(finalizedMinutes.getCreatedBy()) + .finalizedBy(userId) + .finalizedAt(finalizedMinutes.getFinalizedAt()) + // 섹션 정보 + .sections(sectionDTOs) + .build()) + .build(); + + // RAG용 이벤트 발행 + eventPublisher.publishMinutesFinalizedForRAG(ragEvent); + log.info("RAG용 회의록 확정 이벤트 발행 완료 - minutesId: {}, meetingId: {}", + minutesId, meeting.getMeetingId()); + } catch (Exception e) { + log.error("RAG용 회의록 확정 이벤트 발행 실패 - minutesId: {}, error: {}", + minutesId, e.getMessage(), e); + // RAG 이벤트 발행 실패는 무시하고 진행 (회의록 확정 자체는 성공) + } + log.info("회의록 확정 성공 - minutesId: {}", minutesId); return ResponseEntity.ok(ApiResponse.success(response)); diff --git a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/dto/MinutesFinalizedEvent.java b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/dto/MinutesFinalizedEvent.java new file mode 100644 index 0000000..cd03337 --- /dev/null +++ b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/dto/MinutesFinalizedEvent.java @@ -0,0 +1,58 @@ +package com.unicorn.hgzero.meeting.infra.event.dto; + +import lombok.Builder; +import lombok.Getter; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 회의록 확정 이벤트 + * RAG 서비스에서 회의록 embedding 생성 및 저장을 위한 이벤트 + */ +@Getter +@Builder +public class MinutesFinalizedEvent { + + /** + * 이벤트 타입 + */ + private final String eventType = "MINUTES_FINALIZED"; + + /** + * 이벤트 발생 시간 + */ + private final LocalDateTime timestamp; + + /** + * 이벤트 데이터 + */ + private final MinutesData data; + + /** + * 회의록 상세 데이터 + */ + @Getter + @Builder + public static class MinutesData { + // Meeting 정보 + private final String meetingId; + private final String title; + private final String purpose; + private final String description; + private final LocalDateTime scheduledAt; + private final String location; + private final String organizerId; + + // Minutes 정보 + private final String minutesId; + private final String status; + private final Integer version; + private final String createdBy; + private final String finalizedBy; + private final LocalDateTime finalizedAt; + + // 섹션 정보 + private final List sections; + } +} diff --git a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/dto/MinutesSectionDTO.java b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/dto/MinutesSectionDTO.java new file mode 100644 index 0000000..39609f2 --- /dev/null +++ b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/dto/MinutesSectionDTO.java @@ -0,0 +1,43 @@ +package com.unicorn.hgzero.meeting.infra.event.dto; + +import lombok.Builder; +import lombok.Getter; + +/** + * 회의록 섹션 DTO + * Event Hub 메시지에 포함될 섹션 정보 + */ +@Getter +@Builder +public class MinutesSectionDTO { + + /** + * 섹션 ID + */ + private final String sectionId; + + /** + * 섹션 타입 (DISCUSSION, DECISION, ACTION_ITEM 등) + */ + private final String type; + + /** + * 섹션 제목 + */ + private final String title; + + /** + * 섹션 내용 + */ + private final String content; + + /** + * 섹션 순서 + */ + private final Integer order; + + /** + * 검증 여부 + */ + private final Boolean verified; +} diff --git a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/publisher/EventHubPublisher.java b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/publisher/EventHubPublisher.java index 79654a9..9d18213 100644 --- a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/publisher/EventHubPublisher.java +++ b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/publisher/EventHubPublisher.java @@ -11,6 +11,7 @@ import com.unicorn.hgzero.meeting.infra.event.dto.MeetingEndedEvent; import com.unicorn.hgzero.meeting.infra.event.dto.TodoAssignedEvent; import com.unicorn.hgzero.meeting.infra.event.dto.NotificationRequestEvent; import com.unicorn.hgzero.meeting.infra.event.dto.MinutesAnalysisRequestEvent; +import com.unicorn.hgzero.meeting.infra.event.dto.MinutesFinalizedEvent; import java.time.LocalDate; import java.time.LocalDateTime; import lombok.extern.slf4j.Slf4j; @@ -157,6 +158,16 @@ public class EventHubPublisher implements EventPublisher { EventHubConstants.EVENT_TYPE_MINUTES_ANALYSIS_REQUEST); } + @Override + public void publishMinutesFinalizedForRAG(MinutesFinalizedEvent event) { + publishEvent(event, event.getData().getMinutesId(), + EventHubConstants.TOPIC_MINUTES, + EventHubConstants.EVENT_TYPE_MINUTES_FINALIZED); + + log.info("RAG용 회의록 확정 이벤트 발행 완료 - minutesId: {}, meetingId: {}", + event.getData().getMinutesId(), event.getData().getMeetingId()); + } + /** * 이벤트 발행 공통 메서드 * diff --git a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/publisher/EventPublisher.java b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/publisher/EventPublisher.java index 0073401..1609f77 100644 --- a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/publisher/EventPublisher.java +++ b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/publisher/EventPublisher.java @@ -5,6 +5,7 @@ import com.unicorn.hgzero.meeting.infra.event.dto.MeetingEndedEvent; import com.unicorn.hgzero.meeting.infra.event.dto.TodoAssignedEvent; import com.unicorn.hgzero.meeting.infra.event.dto.NotificationRequestEvent; import com.unicorn.hgzero.meeting.infra.event.dto.MinutesAnalysisRequestEvent; +import com.unicorn.hgzero.meeting.infra.event.dto.MinutesFinalizedEvent; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -62,6 +63,13 @@ public interface EventPublisher { */ void publishMinutesFinalized(String minutesId, String title, String finalizedBy, String finalizedByName); + /** + * 회의록 확정 이벤트 발행 (RAG 서비스용 완전한 이벤트) + * + * @param event 회의록 확정 이벤트 (전체 데이터 포함) + */ + void publishMinutesFinalizedForRAG(MinutesFinalizedEvent event); + /** * 회의 생성 알림 발행 (편의 메서드) * 참석자에게 회의 초대 이메일 발송 diff --git a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/publisher/NoOpEventPublisher.java b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/publisher/NoOpEventPublisher.java index 03a4743..7a6c211 100644 --- a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/publisher/NoOpEventPublisher.java +++ b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/event/publisher/NoOpEventPublisher.java @@ -5,6 +5,7 @@ import com.unicorn.hgzero.meeting.infra.event.dto.MeetingEndedEvent; import com.unicorn.hgzero.meeting.infra.event.dto.TodoAssignedEvent; import com.unicorn.hgzero.meeting.infra.event.dto.NotificationRequestEvent; import com.unicorn.hgzero.meeting.infra.event.dto.MinutesAnalysisRequestEvent; +import com.unicorn.hgzero.meeting.infra.event.dto.MinutesFinalizedEvent; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Primary; @@ -72,4 +73,10 @@ public class NoOpEventPublisher implements EventPublisher { public void publishMinutesAnalysisRequest(MinutesAnalysisRequestEvent event) { log.debug("[NoOp] Minutes analysis request event: minutesId={}", event.getMinutesId()); } + + @Override + public void publishMinutesFinalizedForRAG(MinutesFinalizedEvent event) { + log.debug("[NoOp] Minutes finalized for RAG: minutesId={}, meetingId={}", + event.getData().getMinutesId(), event.getData().getMeetingId()); + } } diff --git a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/gateway/entity/MeetingEntity.java b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/gateway/entity/MeetingEntity.java index 28d7173..f840303 100644 --- a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/gateway/entity/MeetingEntity.java +++ b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/gateway/entity/MeetingEntity.java @@ -65,7 +65,7 @@ public class MeetingEntity extends BaseTimeEntity { /** * 회의 참석자 목록 (일대다 관계) */ - @OneToMany(mappedBy = "meeting", cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(mappedBy = "meeting", cascade = CascadeType.ALL, orphanRemoval = false) @Builder.Default private List participants = new ArrayList<>();