From c4bd8064ec958464b50f8afbecd09d360f7346ee Mon Sep 17 00:00:00 2001 From: Minseo-Jo Date: Fri, 31 Oct 2025 11:35:25 +0900 Subject: [PATCH] =?UTF-8?q?=ED=9A=8C=EC=9D=98=20=EC=A2=85=EB=A3=8C=20?= =?UTF-8?q?=EC=8B=9C=20AI=20=EC=9D=91=EB=8B=B5=20=EC=B2=98=EB=A6=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 - MeetingEndDTO.TodoSummaryDTO에 assignee 필드 추가 - AI 응답의 todos를 직접 DTO로 변환하여 반환 - 안건별 todos 매핑 로직 개선 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../hgzero/meeting/biz/dto/MeetingEndDTO.java | 1 + .../biz/service/EndMeetingService.java | 47 ++++++++++--------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/meeting/src/main/java/com/unicorn/hgzero/meeting/biz/dto/MeetingEndDTO.java b/meeting/src/main/java/com/unicorn/hgzero/meeting/biz/dto/MeetingEndDTO.java index 7e38d6a..834e72c 100644 --- a/meeting/src/main/java/com/unicorn/hgzero/meeting/biz/dto/MeetingEndDTO.java +++ b/meeting/src/main/java/com/unicorn/hgzero/meeting/biz/dto/MeetingEndDTO.java @@ -41,5 +41,6 @@ public class MeetingEndDTO { @Builder public static class TodoSummaryDTO { private final String title; + private final String assignee; } } \ No newline at end of file diff --git a/meeting/src/main/java/com/unicorn/hgzero/meeting/biz/service/EndMeetingService.java b/meeting/src/main/java/com/unicorn/hgzero/meeting/biz/service/EndMeetingService.java index ab0839c..ef4969d 100644 --- a/meeting/src/main/java/com/unicorn/hgzero/meeting/biz/service/EndMeetingService.java +++ b/meeting/src/main/java/com/unicorn/hgzero/meeting/biz/service/EndMeetingService.java @@ -124,8 +124,8 @@ public class EndMeetingService implements EndMeetingUseCase { meetingRepository.save(meeting); log.info("회의 상태 업데이트 완료 - status: {}", meeting.getStatus()); - // 9. 응답 DTO 생성 - MeetingEndDTO result = createMeetingEndDTO(meeting, analysis, todos, participantMinutesList.size()); + // 9. 응답 DTO 생성 (AI 응답의 todos를 그대로 사용) + MeetingEndDTO result = createMeetingEndDTO(meeting, aiResponse, todos.size(), participantMinutesList.size()); log.info("회의 종료 처리 완료 - meetingId: {}, 안건 수: {}, Todo 수: {}", meetingId, analysis.getAgendaAnalyses().size(), todos.size()); @@ -308,7 +308,8 @@ public class EndMeetingService implements EndMeetingUseCase { private List createAndSaveTodos(MeetingEntity meeting, ConsolidateResponse aiResponse, MeetingAnalysis analysis) { List todos = aiResponse.getAgendaSummaries().stream() .flatMap(agenda -> { - // agendaId는 향후 Todo와 안건 매핑에 사용될 수 있음 (현재는 사용하지 않음) + // 안건 번호를 description에 저장하여 나중에 필터링에 사용 + Integer agendaNumber = agenda.getAgendaNumber(); List todoList = agenda.getTodos() != null ? agenda.getTodos() : List.of(); return todoList.stream() .map(todo -> TodoEntity.builder() @@ -316,6 +317,7 @@ public class EndMeetingService implements EndMeetingUseCase { .meetingId(meeting.getMeetingId()) .minutesId(meeting.getMeetingId()) // 실제로는 minutesId 필요 .title(todo.getTitle()) + .description("안건" + agendaNumber) // 안건 번호를 description에 임시 저장 .assigneeId(todo.getAssignee() != null ? todo.getAssignee() : "") // AI가 추출한 담당자 .status("PENDING") .build()); @@ -342,33 +344,36 @@ public class EndMeetingService implements EndMeetingUseCase { } /** - * 회의 종료 결과 DTO 생성 + * 회의 종료 결과 DTO 생성 (AI 응답 직접 사용) */ - private MeetingEndDTO createMeetingEndDTO(MeetingEntity meeting, MeetingAnalysis analysis, - List todos, int participantCount) { + private MeetingEndDTO createMeetingEndDTO(MeetingEntity meeting, ConsolidateResponse aiResponse, + int todoCount, int participantCount) { // 회의 소요 시간 계산 int durationMinutes = calculateDurationMinutes(meeting.getStartedAt(), meeting.getEndedAt()); - // 안건별 요약 DTO 생성 - List agendaSummaries = analysis.getAgendaAnalyses().stream() + // AI 응답의 안건 정보를 그대로 DTO로 변환 (todos 포함) + List agendaSummaries = aiResponse.getAgendaSummaries().stream() .map(agenda -> { - // 해당 안건의 Todo 필터링 (agendaId가 없을 수 있음) - List agendaTodos = todos.stream() - .filter(todo -> agenda.getAgendaId().equals(todo.getMinutesId())) // 임시 매핑 - .map(todo -> MeetingEndDTO.TodoSummaryDTO.builder() + // 안건별 todos 변환 + List todoList = new ArrayList<>(); + if (agenda.getTodos() != null) { + for (ExtractedTodoDTO todo : agenda.getTodos()) { + todoList.add(MeetingEndDTO.TodoSummaryDTO.builder() .title(todo.getTitle()) - .build()) - .collect(Collectors.toList()); + .assignee(todo.getAssignee()) + .build()); + } + } return MeetingEndDTO.AgendaSummaryDTO.builder() - .title(agenda.getTitle()) - .aiSummaryShort(agenda.getAiSummaryShort()) + .title(agenda.getAgendaTitle()) + .aiSummaryShort(agenda.getSummaryShort()) .details(MeetingEndDTO.AgendaDetailsDTO.builder() - .discussion(agenda.getDiscussion()) + .discussion(agenda.getSummary()) .decisions(agenda.getDecisions()) .pending(agenda.getPending()) .build()) - .todos(agendaTodos) + .todos(todoList) .build(); }) .collect(Collectors.toList()); @@ -377,9 +382,9 @@ public class EndMeetingService implements EndMeetingUseCase { .title(meeting.getTitle()) .participantCount(participantCount) .durationMinutes(durationMinutes) - .agendaCount(analysis.getAgendaAnalyses().size()) - .todoCount(todos.size()) - .keywords(analysis.getKeywords()) + .agendaCount(aiResponse.getAgendaSummaries().size()) + .todoCount(todoCount) + .keywords(aiResponse.getKeywords()) .agendaSummaries(agendaSummaries) .build(); }