diff --git a/build/reports/problems/problems-report.html b/build/reports/problems/problems-report.html
index 1c3a789..06ca36a 100644
--- a/build/reports/problems/problems-report.html
+++ b/build/reports/problems/problems-report.html
@@ -650,7 +650,7 @@ code + .copy-button {
diff --git a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingAiController.java b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingAiController.java
index b39e8d6..ac6f50e 100644
--- a/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingAiController.java
+++ b/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingAiController.java
@@ -1,5 +1,7 @@
package com.unicorn.hgzero.meeting.infra.controller;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.unicorn.hgzero.common.dto.ApiResponse;
import com.unicorn.hgzero.meeting.biz.domain.AgendaSection;
import com.unicorn.hgzero.meeting.biz.domain.Meeting;
@@ -19,6 +21,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
+import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -36,6 +39,7 @@ public class MeetingAiController {
private final MinutesService minutesService;
private final AgendaSectionService agendaSectionService;
private final MeetingService meetingService;
+ private final ObjectMapper objectMapper;
@GetMapping("/{meetingId}/ai/participant-minutes")
@Operation(
@@ -162,8 +166,10 @@ public class MeetingAiController {
}
private AgendaSectionResponse.AgendaSectionItem convertToAgendaSectionItem(AgendaSection section) {
- // todos와 pendingItems는 JSON 문자열이므로 파싱 필요 (현재는 null로 처리)
- List todos = null;
+ // todos JSON 파싱
+ List todos = parseTodosJson(section.getTodos());
+
+ // pendingItems는 사용하지 않으므로 null 처리
List pendingItems = null;
return AgendaSectionResponse.AgendaSectionItem.builder()
@@ -180,12 +186,57 @@ public class MeetingAiController {
.build();
}
+ /**
+ * todos JSON 문자열을 파싱하여 TodoItem 리스트로 변환
+ * JSON 구조: [{"title": "...", "assignee": "...", "dueDate": "...", "description": "...", "priority": "..."}]
+ */
+ private List parseTodosJson(String todosJson) {
+ if (todosJson == null || todosJson.trim().isEmpty()) {
+ return new ArrayList<>();
+ }
+
+ try {
+ List todoJsonList = objectMapper.readValue(
+ todosJson,
+ new TypeReference>() {}
+ );
+
+ return todoJsonList.stream()
+ .map(json -> AgendaSectionResponse.AgendaSectionItem.TodoItem.builder()
+ .title(json.getTitle())
+ .assignee(json.getAssignee())
+ .dueDate(json.getDueDate())
+ .description(json.getDescription())
+ .priority(json.getPriority())
+ .build())
+ .collect(Collectors.toList());
+
+ } catch (Exception e) {
+ log.error("Failed to parse todos JSON: {}", todosJson, e);
+ return new ArrayList<>();
+ }
+ }
+
+ /**
+ * JSON 파싱을 위한 임시 DTO
+ */
+ @lombok.Data
+ private static class TodoJson {
+ private String title;
+ private String assignee;
+ private String dueDate;
+ private String description;
+ private String priority;
+ }
+
private MeetingStatisticsResponse buildMeetingStatistics(String meetingId) {
Meeting meeting = meetingService.getMeeting(meetingId);
List sections = agendaSectionService.getAgendaSectionsByMeetingId(meetingId);
- // AI가 추출한 Todo 수 계산 (todos는 JSON 문자열이므로 현재는 0으로 처리)
- int todoCount = 0;
+ // AI가 추출한 Todo 수 계산
+ int todoCount = sections.stream()
+ .mapToInt(s -> parseTodosJson(s.getTodos()).size())
+ .sum();
// 회의 시간 계산
Integer durationMinutes = null;