Feat: 대시보드 조회 API에 생성자 여부 추가

This commit is contained in:
cyjadela 2025-10-28 20:33:27 +09:00
parent ad76059db6
commit 6c005ec923
6 changed files with 6077 additions and 1095 deletions

View File

@ -650,7 +650,7 @@ code + .copy-button {
<script type="text/javascript">
function configurationCacheProblems() { return (
// begin-report-data
{"diagnostics":[{"locations":[{"path":"/Users/daewoong/home/workspace/HGZero/common/src/main/java/com/unicorn/hgzero/common/security/JwtTokenProvider.java"},{"taskPath":":common:compileJava"}],"problem":[{"text":"/Users/daewoong/home/workspace/HGZero/common/src/main/java/com/unicorn/hgzero/common/security/JwtTokenProvider.java uses or overrides a deprecated API."}],"severity":"ADVICE","problemDetails":[{"text":"Note: /Users/daewoong/home/workspace/HGZero/common/src/main/java/com/unicorn/hgzero/common/security/JwtTokenProvider.java uses or overrides a deprecated API."}],"contextualLabel":"/Users/daewoong/home/workspace/HGZero/common/src/main/java/com/unicorn/hgzero/common/security/JwtTokenProvider.java uses or overrides a deprecated API.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.filename","displayName":"/Users/daewoong/home/workspace/HGZero/common/src/main/java/com/unicorn/hgzero/common/security/JwtTokenProvider.java uses or overrides a deprecated API."}]},{"locations":[{"path":"/Users/daewoong/home/workspace/HGZero/common/src/main/java/com/unicorn/hgzero/common/security/JwtTokenProvider.java"},{"taskPath":":common:compileJava"}],"problem":[{"text":"Recompile with -Xlint:deprecation for details."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Recompile with -Xlint:deprecation for details."}],"contextualLabel":"Recompile with -Xlint:deprecation for details.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.recompile","displayName":"Recompile with -Xlint:deprecation for details."}]},{"locations":[{"path":"/Users/daewoong/home/workspace/HGZero/user/src/main/java/com/unicorn/hgzero/user/service/UserServiceImpl.java"},{"taskPath":":user:compileJava"}],"problem":[{"text":"/Users/daewoong/home/workspace/HGZero/user/src/main/java/com/unicorn/hgzero/user/service/UserServiceImpl.java uses or overrides a deprecated API."}],"severity":"ADVICE","problemDetails":[{"text":"Note: /Users/daewoong/home/workspace/HGZero/user/src/main/java/com/unicorn/hgzero/user/service/UserServiceImpl.java uses or overrides a deprecated API."}],"contextualLabel":"/Users/daewoong/home/workspace/HGZero/user/src/main/java/com/unicorn/hgzero/user/service/UserServiceImpl.java uses or overrides a deprecated API.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.filename","displayName":"/Users/daewoong/home/workspace/HGZero/user/src/main/java/com/unicorn/hgzero/user/service/UserServiceImpl.java uses or overrides a deprecated API."}]},{"locations":[{"path":"/Users/daewoong/home/workspace/HGZero/user/src/main/java/com/unicorn/hgzero/user/service/UserServiceImpl.java"},{"taskPath":":user:compileJava"}],"problem":[{"text":"Recompile with -Xlint:deprecation for details."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Recompile with -Xlint:deprecation for details."}],"contextualLabel":"Recompile with -Xlint:deprecation for details.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.recompile","displayName":"Recompile with -Xlint:deprecation for details."}]},{"locations":[{"path":"/Users/daewoong/home/workspace/HGZero/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/dto/request/InviteParticipantRequest.java"},{"taskPath":":meeting:compileJava"}],"problem":[{"text":"Some input files use or override a deprecated API."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Some input files use or override a deprecated API."}],"contextualLabel":"Some input files use or override a deprecated API.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.plural","displayName":"Some input files use or override a deprecated API."}]},{"locations":[{"path":"/Users/daewoong/home/workspace/HGZero/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/dto/request/InviteParticipantRequest.java"},{"taskPath":":meeting:compileJava"}],"problem":[{"text":"Recompile with -Xlint:deprecation for details."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Recompile with -Xlint:deprecation for details."}],"contextualLabel":"Recompile with -Xlint:deprecation for details.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.recompile","displayName":"Recompile with -Xlint:deprecation for details."}]}],"problemsReport":{"totalProblemCount":6,"buildName":"hgzero","requestedTasks":"clean bootJar","documentationLink":"https://docs.gradle.org/8.14/userguide/reporting_problems.html","documentationLinkCaption":"Problem report","summaries":[]}}
{"diagnostics":[{"locations":[{"path":"/Users/adela/home/workspace/recent/HGZero/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/gateway/entity/MinutesSectionEntity.java"},{"taskPath":":meeting:compileJava"}],"problem":[{"text":"/Users/adela/home/workspace/recent/HGZero/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/gateway/entity/MinutesSectionEntity.java uses or overrides a deprecated API."}],"severity":"ADVICE","problemDetails":[{"text":"Note: /Users/adela/home/workspace/recent/HGZero/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/gateway/entity/MinutesSectionEntity.java uses or overrides a deprecated API."}],"contextualLabel":"/Users/adela/home/workspace/recent/HGZero/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/gateway/entity/MinutesSectionEntity.java uses or overrides a deprecated API.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.filename","displayName":"/Users/adela/home/workspace/recent/HGZero/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/gateway/entity/MinutesSectionEntity.java uses or overrides a deprecated API."}]},{"locations":[{"path":"/Users/adela/home/workspace/recent/HGZero/meeting/src/main/java/com/unicorn/hgzero/meeting/infra/gateway/entity/MinutesSectionEntity.java"},{"taskPath":":meeting:compileJava"}],"problem":[{"text":"Recompile with -Xlint:deprecation for details."}],"severity":"ADVICE","problemDetails":[{"text":"Note: Recompile with -Xlint:deprecation for details."}],"contextualLabel":"Recompile with -Xlint:deprecation for details.","problemId":[{"name":"java","displayName":"Java compilation"},{"name":"compilation","displayName":"Compilation"},{"name":"compiler.note.deprecated.recompile","displayName":"Recompile with -Xlint:deprecation for details."}]}],"problemsReport":{"totalProblemCount":2,"buildName":"hgzero","requestedTasks":":meeting:bootRun","documentationLink":"https://docs.gradle.org/8.14/userguide/reporting_problems.html","documentationLinkCaption":"Problem report","summaries":[]}}
// end-report-data
);}
</script>

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,7 @@ public class DashboardDTO {
private final String location;
private final Integer participantCount;
private final String status;
private final String userRole; // CREATOR, PARTICIPANT
}
/**
@ -76,6 +77,7 @@ public class DashboardDTO {
private final String status;
private final Integer participantCount;
private final LocalDateTime lastModified;
private final String userRole; // CREATOR, PARTICIPANT
}
/**
@ -93,6 +95,8 @@ public class DashboardDTO {
* Dashboard 도메인 객체로부터 DashboardDTO 생성
*/
public static DashboardDTO from(Dashboard dashboard) {
String currentUserId = dashboard.getUserId();
return DashboardDTO.builder()
.upcomingMeetings(dashboard.getUpcomingMeetings().stream()
.map(meeting -> UpcomingMeetingDTO.builder()
@ -103,6 +107,7 @@ public class DashboardDTO {
.location(null) // Meeting 도메인에 location이 없음
.participantCount(meeting.getParticipants() != null ? meeting.getParticipants().size() : 0)
.status(meeting.getStatus())
.userRole(currentUserId.equals(meeting.getOrganizerId()) ? "CREATOR" : "PARTICIPANT")
.build())
.toList())
.activeTodos(dashboard.getAssignedTodos().stream()
@ -124,6 +129,7 @@ public class DashboardDTO {
.status(minutes.getStatus())
.participantCount(0) // Minutes 도메인에 participantCount가 없음
.lastModified(minutes.getLastModifiedAt())
.userRole(currentUserId.equals(minutes.getCreatedBy()) ? "CREATOR" : "PARTICIPANT")
.build())
.toList())
.statistics(StatisticsDTO.builder()

View File

@ -66,6 +66,9 @@ public class DashboardResponse {
@Schema(description = "회의 상태", example = "SCHEDULED")
private final String status;
@Schema(description = "사용자 역할", example = "CREATOR", allowableValues = {"CREATOR", "PARTICIPANT"})
private final String userRole;
public static UpcomingMeetingResponse from(DashboardDTO.UpcomingMeetingDTO dto) {
return UpcomingMeetingResponse.builder()
.meetingId(dto.getMeetingId())
@ -75,6 +78,7 @@ public class DashboardResponse {
.location(dto.getLocation())
.participantCount(dto.getParticipantCount())
.status(dto.getStatus())
.userRole(dto.getUserRole())
.build();
}
}
@ -102,6 +106,9 @@ public class DashboardResponse {
@Schema(description = "최종 수정 시간", example = "2025-01-23T16:30:00")
private final LocalDateTime lastModified;
@Schema(description = "사용자 역할", example = "CREATOR", allowableValues = {"CREATOR", "PARTICIPANT"})
private final String userRole;
public static RecentMinutesResponse from(DashboardDTO.RecentMinutesDTO dto) {
return RecentMinutesResponse.builder()
.minutesId(dto.getMinutesId())
@ -110,6 +117,7 @@ public class DashboardResponse {
.status(dto.getStatus())
.participantCount(dto.getParticipantCount())
.lastModified(dto.getLastModified())
.userRole(dto.getUserRole())
.build();
}
}

View File

@ -1,15 +1,10 @@
package com.unicorn.hgzero.meeting.infra.mapper;
import com.unicorn.hgzero.meeting.biz.domain.Dashboard;
import com.unicorn.hgzero.meeting.biz.domain.Meeting;
import com.unicorn.hgzero.meeting.biz.domain.Minutes;
import com.unicorn.hgzero.meeting.biz.dto.DashboardDTO;
import com.unicorn.hgzero.meeting.infra.dto.response.DashboardResponse;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* Dashboard 도메인 객체를 Response DTO로 변환하는 매퍼
*/
@ -24,90 +19,8 @@ public class DashboardResponseMapper {
return null;
}
List<DashboardResponse.UpcomingMeetingResponse> upcomingMeetings = toUpcomingMeetingResponses(dashboard.getUpcomingMeetings());
List<DashboardResponse.RecentMinutesResponse> myMinutes = toRecentMinutesResponses(dashboard.getRecentMinutes());
return DashboardResponse.builder()
.upcomingMeetings(upcomingMeetings)
.myMinutes(myMinutes)
.statistics(toStatisticsResponse(dashboard, upcomingMeetings.size()))
.build();
}
/**
* Meeting 목록을 UpcomingMeetingResponse 목록으로 변환
*/
private List<DashboardResponse.UpcomingMeetingResponse> toUpcomingMeetingResponses(List<Meeting> meetings) {
if (meetings == null || meetings.isEmpty()) {
return Collections.emptyList();
}
return meetings.stream()
.map(this::toUpcomingMeetingResponse)
.collect(Collectors.toList());
}
/**
* Meeting을 UpcomingMeetingResponse로 변환
*/
private DashboardResponse.UpcomingMeetingResponse toUpcomingMeetingResponse(Meeting meeting) {
return DashboardResponse.UpcomingMeetingResponse.builder()
.meetingId(meeting.getMeetingId())
.title(meeting.getTitle())
.startTime(meeting.getScheduledAt())
.endTime(meeting.getEndTime())
.location(meeting.getLocation())
.participantCount(meeting.getParticipants() != null ? meeting.getParticipants().size() : 0)
.status(meeting.getStatus())
.build();
}
/**
* Minutes 목록을 RecentMinutesResponse 목록으로 변환
*/
private List<DashboardResponse.RecentMinutesResponse> toRecentMinutesResponses(List<Minutes> minutesList) {
if (minutesList == null || minutesList.isEmpty()) {
return Collections.emptyList();
}
return minutesList.stream()
.map(this::toRecentMinutesResponse)
.collect(Collectors.toList());
}
/**
* Minutes를 RecentMinutesResponse로 변환
*/
private DashboardResponse.RecentMinutesResponse toRecentMinutesResponse(Minutes minutes) {
return DashboardResponse.RecentMinutesResponse.builder()
.minutesId(minutes.getMinutesId())
.title(minutes.getTitle())
.meetingDate(minutes.getCreatedAt())
.status(minutes.getStatus())
.participantCount(0) // Meeting 정보가 필요한데 현재 Minutes에 직접적인 참석자 정보가 없음
.lastModified(minutes.getLastModifiedAt() != null ?
minutes.getLastModifiedAt() : minutes.getCreatedAt())
.build();
}
/**
* Dashboard.Statistics를 StatisticsResponse로 변환
*/
private DashboardResponse.StatisticsResponse toStatisticsResponse(Dashboard dashboard, int upcomingMeetingsCount) {
Dashboard.Statistics statistics = dashboard.getStatistics();
if (statistics == null) {
return DashboardResponse.StatisticsResponse.builder()
.upcomingMeetingsCount(upcomingMeetingsCount)
.draftMinutesCount(0)
.build();
}
return DashboardResponse.StatisticsResponse.builder()
.upcomingMeetingsCount(upcomingMeetingsCount)
.draftMinutesCount(statistics.getDraftMinutes() != null ?
statistics.getDraftMinutes() : 0)
.build();
// Dashboard 도메인을 DashboardDTO로 변환한 DashboardResponse로 변환
DashboardDTO dashboardDTO = DashboardDTO.from(dashboard);
return DashboardResponse.from(dashboardDTO);
}
}

View File

@ -28,7 +28,7 @@ spring:
use_sql_comments: true
dialect: org.hibernate.dialect.PostgreSQLDialect
hibernate:
ddl-auto: ${JPA_DDL_AUTO:update}
ddl-auto: ${JPA_DDL_AUTO:none}
# Redis Configuration
data: