Chore: 회의록 상세 조회 API - AgendaSection 업데이트 반영

This commit is contained in:
cyjadela 2025-10-29 13:26:20 +09:00
parent 77f38abe48
commit 764a620980
3 changed files with 3136 additions and 40 deletions

File diff suppressed because it is too large Load Diff

View File

@ -920,8 +920,10 @@ public class MinutesController {
.modifiedAt(agendaSection.getUpdatedAt() != null ? agendaSection.getUpdatedAt() : LocalDateTime.now()) .modifiedAt(agendaSection.getUpdatedAt() != null ? agendaSection.getUpdatedAt() : LocalDateTime.now())
.build(); .build();
// 안건 상세 내용 구성 - JSON 파싱 // 안건 상세 내용 구성
List<String> discussionsList = parseJsonToList(agendaSection.getDiscussions()); // discussions는 이제 TEXT 타입이므로 별도 파싱 로직 적용
List<String> discussionsList = parseDiscussionsText(agendaSection.getDiscussions());
// decisions는 JSON 문자열로 저장되어 있으므로 파싱 필요
List<String> decisionsList = parseJsonToList(agendaSection.getDecisions()); List<String> decisionsList = parseJsonToList(agendaSection.getDecisions());
MinutesDetailResponse.AgendaDetails details = MinutesDetailResponse.AgendaDetails.builder() MinutesDetailResponse.AgendaDetails details = MinutesDetailResponse.AgendaDetails.builder()
@ -1055,6 +1057,41 @@ public class MinutesController {
return discussions; return discussions;
} }
/**
* AgendaSection의 discussions TEXT 필드 파싱
*/
private List<String> parseDiscussionsText(String discussions) {
if (discussions == null || discussions.trim().isEmpty()) {
return new ArrayList<>();
}
// **논의 사항:** 형식으로 저장된 텍스트 파싱
List<String> discussionsList = new ArrayList<>();
// 줄바꿈으로 분리하고 - 시작하는 항목 추출
String[] lines = discussions.split("\n");
for (String line : lines) {
line = line.trim();
if (line.startsWith("-") || line.startsWith("") || line.startsWith("*")) {
// 불릿 포인트 제거
String item = line.substring(1).trim();
if (!item.isEmpty()) {
discussionsList.add(item);
}
} else if (!line.isEmpty() && !line.contains("논의") && !line.contains(":**")) {
// 불릿 포인트가 없는 텍스트도 포함
discussionsList.add(line);
}
}
if (discussionsList.isEmpty()) {
// 구조화되지 않은 경우 전체 텍스트 반환
discussionsList.add(discussions.trim());
}
return discussionsList;
}
/** /**
* 회의록 섹션 내용에서 결정사항 추출 * 회의록 섹션 내용에서 결정사항 추출
*/ */

View File

@ -3,11 +3,14 @@ package com.unicorn.hgzero.meeting.infra.gateway.entity;
import com.unicorn.hgzero.common.entity.BaseTimeEntity; import com.unicorn.hgzero.common.entity.BaseTimeEntity;
import com.unicorn.hgzero.meeting.biz.domain.AgendaSection; import com.unicorn.hgzero.meeting.biz.domain.AgendaSection;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.*; import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
/** /**
* 회의 안건 섹션 엔티티 * 안건별 회의록 섹션 Entity
* agenda_sections 테이블과 매핑 * PostgreSQL JSON 컬럼을 사용하여 구조화된 데이터 저장
*/ */
@Entity @Entity
@Table(name = "agenda_sections") @Table(name = "agenda_sections")
@ -18,7 +21,7 @@ import lombok.*;
public class AgendaSectionEntity extends BaseTimeEntity { public class AgendaSectionEntity extends BaseTimeEntity {
@Id @Id
@Column(length = 36) @Column(name = "id", length = 36)
private String id; private String id;
@Column(name = "minutes_id", length = 36, nullable = false) @Column(name = "minutes_id", length = 36, nullable = false)
@ -39,20 +42,20 @@ public class AgendaSectionEntity extends BaseTimeEntity {
@Column(name = "discussions", columnDefinition = "TEXT") @Column(name = "discussions", columnDefinition = "TEXT")
private String discussions; private String discussions;
@Column(name = "decisions", columnDefinition = "TEXT") @Column(name = "decisions", columnDefinition = "json")
private String decisions; private String decisions;
@Column(name = "opinions", columnDefinition = "TEXT") @Column(name = "pending_items", columnDefinition = "json")
private String opinions;
@Column(name = "pending_items", columnDefinition = "TEXT")
private String pendingItems; private String pendingItems;
@Column(name = "todos", columnDefinition = "TEXT") @Column(name = "opinions", columnDefinition = "json")
private String opinions;
@Column(name = "todos", columnDefinition = "json")
private String todos; private String todos;
/** /**
* 도메인 객체로 변환 * Domain 객체로 변환
*/ */
public AgendaSection toDomain() { public AgendaSection toDomain() {
return AgendaSection.builder() return AgendaSection.builder()
@ -64,8 +67,8 @@ public class AgendaSectionEntity extends BaseTimeEntity {
.aiSummaryShort(this.aiSummaryShort) .aiSummaryShort(this.aiSummaryShort)
.discussions(this.discussions) .discussions(this.discussions)
.decisions(this.decisions) .decisions(this.decisions)
.opinions(this.opinions)
.pendingItems(this.pendingItems) .pendingItems(this.pendingItems)
.opinions(this.opinions)
.todos(this.todos) .todos(this.todos)
.createdAt(this.getCreatedAt()) .createdAt(this.getCreatedAt())
.updatedAt(this.getUpdatedAt()) .updatedAt(this.getUpdatedAt())
@ -73,21 +76,22 @@ public class AgendaSectionEntity extends BaseTimeEntity {
} }
/** /**
* 도메인 객체에서 엔티티 생성 * Domain 객체에서 Entity 생성
*/ */
public static AgendaSectionEntity fromDomain(AgendaSection domain) { public static AgendaSectionEntity fromDomain(AgendaSection section) {
return AgendaSectionEntity.builder() return AgendaSectionEntity.builder()
.id(domain.getId()) .id(section.getId())
.minutesId(domain.getMinutesId()) .minutesId(section.getMinutesId())
.meetingId(domain.getMeetingId()) .meetingId(section.getMeetingId())
.agendaNumber(domain.getAgendaNumber()) .agendaNumber(section.getAgendaNumber())
.agendaTitle(domain.getAgendaTitle()) .agendaTitle(section.getAgendaTitle())
.aiSummaryShort(domain.getAiSummaryShort()) .aiSummaryShort(section.getAiSummaryShort())
.discussions(domain.getDiscussions()) .discussions(section.getDiscussions())
.decisions(domain.getDecisions()) .decisions(section.getDecisions())
.opinions(domain.getOpinions()) .pendingItems(section.getPendingItems())
.pendingItems(domain.getPendingItems()) .opinions(section.getOpinions())
.todos(domain.getTodos()) .todos(section.getTodos())
.build(); .build();
} }
} }