Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.haru.api.domain.lastOpened.entity;

import com.haru.api.domain.lastOpened.entity.enums.DocumentType;

public interface Documentable {
Long getId();
String getTitle();
Long getWorkspaceId();
DocumentType getDocumentType();
String getThumbnailKeyName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.haru.api.domain.lastOpened.entity.UserDocumentId;
import com.haru.api.domain.lastOpened.entity.UserDocumentLastOpened;
import com.haru.api.domain.lastOpened.entity.enums.DocumentType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

Expand All @@ -19,4 +20,7 @@ public interface UserDocumentLastOpenedRepository extends JpaRepository<UserDocu
"AND udlo.title LIKE %:title% " +
"ORDER BY udlo.lastOpened DESC")
List<UserDocumentLastOpened> findRecentDocumentsByTitle(Long workspaceId, Long userId, String title);

@Query("SELECT lo FROM UserDocumentLastOpened lo WHERE lo.id.documentId = :documentId AND lo.id.documentType = :documentType")
List<UserDocumentLastOpened> findByDocumentIdAndDocumentType(Long documentId, DocumentType documentType);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
package com.haru.api.domain.lastOpened.service;

import com.haru.api.domain.lastOpened.entity.Documentable;
import com.haru.api.domain.lastOpened.entity.enums.DocumentType;
import com.haru.api.domain.user.entity.User;

import java.util.List;

public interface UserDocumentLastOpenedService {

void updateLastOpened(Long userId, DocumentType documentType, Long documentId, Long workspaceId, String title);

void createInitialRecordsForWorkspaceUsers(List<User> usersInWorkspace, Documentable document);

void deleteRecordsForWorkspaceUsers(Documentable document);

void updateRecordsForWorkspaceUsers(Documentable document);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.haru.api.domain.lastOpened.service;

import com.haru.api.domain.lastOpened.entity.Documentable;
import com.haru.api.domain.lastOpened.entity.UserDocumentId;
import com.haru.api.domain.lastOpened.entity.UserDocumentLastOpened;
import com.haru.api.domain.lastOpened.entity.enums.DocumentType;
Expand All @@ -14,6 +15,8 @@
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
Expand Down Expand Up @@ -46,4 +49,66 @@ public void updateLastOpened(Long userId, DocumentType documentType, Long docume
log.info("userDocumentLastOpened updated for userId: {}, documentId:{}, workspaceId:{}, title:{}", record.getUser().getId(), record.getId().getDocumentId(), workspaceId, title);
}

@Override
public void createInitialRecordsForWorkspaceUsers(List<User> usersInWorkspace, Documentable document) {

// 저장할 엔티티 리스트 생성
List<UserDocumentLastOpened> recordsToSave = recordsToProcess(usersInWorkspace, document);

// 전체 save
if (!recordsToSave.isEmpty()) {
userDocumentLastOpenedRepository.saveAll(recordsToSave);
}
}

@Override
public void deleteRecordsForWorkspaceUsers(Documentable documentable) {

// 해당 문서 id, 문서 타입에 해당하는 last opened 튜플 검색
List<UserDocumentLastOpened> recordsToUpdate = userDocumentLastOpenedRepository.findByDocumentIdAndDocumentType(documentable.getId(), documentable.getDocumentType());

if (!recordsToUpdate.isEmpty()) {
userDocumentLastOpenedRepository.deleteAllInBatch(recordsToUpdate);
}

}

@Override
public void updateRecordsForWorkspaceUsers(Documentable documentable) {

// 해당 문서 id, 문서 타입에 해당하는 last opened 튜플 검색
List<UserDocumentLastOpened> recordsToUpdate = userDocumentLastOpenedRepository.findByDocumentIdAndDocumentType(documentable.getId(), documentable.getDocumentType());

if (!recordsToUpdate.isEmpty()) {
for (UserDocumentLastOpened record : recordsToUpdate) {
record.updateTitle(documentable.getTitle());
}
}
}

private List<UserDocumentLastOpened> recordsToProcess(List<User> usersInWorkspace, Documentable document) {
// 처리할 엔티티들을 담을 리스트 생성
List<UserDocumentLastOpened> recordsToProcess = new ArrayList<>();

for (User user : usersInWorkspace) {
UserDocumentId documentId = new UserDocumentId(
user.getId(),
document.getId(),
document.getDocumentType()
);

UserDocumentLastOpened newRecord = UserDocumentLastOpened.builder()
.id(documentId)
.user(user)
.title(document.getTitle())
.workspaceId(document.getWorkspaceId())
.thumbnailKeyName(document.getThumbnailKeyName())
.build();

recordsToProcess.add(newRecord);
}

return recordsToProcess;
}

}
21 changes: 20 additions & 1 deletion src/main/java/com/haru/api/domain/meeting/entity/Meeting.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.haru.api.domain.meeting.entity;

import com.haru.api.domain.lastOpened.entity.Documentable;
import com.haru.api.domain.lastOpened.entity.enums.DocumentType;
import com.haru.api.domain.user.entity.User;
import com.haru.api.domain.workspace.entity.Workspace;
import com.haru.api.global.common.entity.BaseEntity;
Expand All @@ -18,7 +20,7 @@
@DynamicUpdate
@DynamicInsert
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Meeting extends BaseEntity {
public class Meeting extends BaseEntity implements Documentable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand Down Expand Up @@ -55,6 +57,9 @@ public class Meeting extends BaseEntity {
@Setter
private String audioFileKey;

@Column(columnDefinition = "TEXT")
private String thumbnailKeyName;

private Meeting(String title, String agendaResult, User user, Workspace workspace) {
this.title = title;
this.agendaResult = agendaResult;
Expand Down Expand Up @@ -83,4 +88,18 @@ public void addTag(Keyword keyword) {
.build();
this.meetingKeywords.add(meetingKeyword);
}

public void initThumbnailKey(String thumbnailKey) {
this.thumbnailKeyName = thumbnailKey;
}

@Override
public Long getWorkspaceId() {
return this.workspace.getId();
}

@Override
public DocumentType getDocumentType() {
return DocumentType.AI_MEETING_MANAGER;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public interface MeetingRepository extends JpaRepository<Meeting, Long> {
@Query("SELECT m.workspace FROM Meeting m WHERE m.id = :meetingId")
Optional<Workspace> findWorkspaceByMeetingId(@Param("meetingId") Long meetingId);


@Query("SELECT m FROM Meeting m WHERE m.workspace.id = :workspaceId")
List<Meeting> findAllByWorkspaceId(Long workspaceId);

@Query("SELECT mt FROM Meeting mt " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.haru.api.domain.lastOpened.entity.UserDocumentLastOpened;
import com.haru.api.domain.lastOpened.entity.enums.DocumentType;
import com.haru.api.domain.lastOpened.repository.UserDocumentLastOpenedRepository;
import com.haru.api.domain.lastOpened.service.UserDocumentLastOpenedService;
import com.haru.api.domain.meeting.converter.MeetingConverter;
import com.haru.api.domain.meeting.dto.MeetingRequestDTO;
import com.haru.api.domain.meeting.dto.MeetingResponseDTO;
Expand Down Expand Up @@ -39,7 +40,6 @@
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.socket.CloseStatus;

import java.util.Optional;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
Expand All @@ -61,6 +61,7 @@ public class MeetingCommandServiceImpl implements MeetingCommandService {
private final KeywordRepository keywordRepository;
private final ChatGPTClient chatGPTClient;
private final UserDocumentLastOpenedRepository userDocumentLastOpenedRepository;
private final UserDocumentLastOpenedService userDocumentLastOpenedService;
private final WebSocketSessionRegistry webSocketSessionRegistry;

private final AmazonS3Manager s3Manager;
Expand Down Expand Up @@ -121,20 +122,10 @@ public MeetingResponseDTO.createMeetingResponse createMeeting(

Meeting savedMeeting = meetingRepository.save(newMeeting);

// meeting 생성 시 last opened에 추가
// 마지막으로 연 시간은 null

UserDocumentId documentId = new UserDocumentId(foundUser.getId(), savedMeeting.getId(), DocumentType.AI_MEETING_MANAGER);

userDocumentLastOpenedRepository.save(
UserDocumentLastOpened.builder()
.id(documentId)
.user(foundUser)
.title(savedMeeting.getTitle())
.workspaceId(foundWorkspace.getId())
.lastOpened(null)
.build()
);
// meeting 생성 시 워크스페이스에 속해있는 모든 유저에 대해
// last opened 테이블에 마지막으로 연 시간은 null로하여 추가
List<User> usersInWorkspace = userWorkspaceRepository.findUsersByWorkspaceId(foundWorkspace.getId());
userDocumentLastOpenedService.createInitialRecordsForWorkspaceUsers(usersInWorkspace, savedMeeting);

return MeetingConverter.toCreateMeetingResponse(savedMeeting);
}
Expand All @@ -146,26 +137,22 @@ public MeetingResponseDTO.createMeetingResponse createMeeting(
public void updateMeetingTitle(Long userId, Long meetingId, String newTitle) {


Meeting meeting = meetingRepository.findById(meetingId)
Meeting foundMeeting = meetingRepository.findById(meetingId)
.orElseThrow(() -> new MeetingHandler(ErrorStatus.MEETING_NOT_FOUND));

User foundUser = userRepository.findById(userId)
.orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND));

// 회의 생성자 권한 확인
if (!meeting.getCreator().getId().equals(userId)) {
if (!foundMeeting.getCreator().getId().equals(userId)) {
throw new MemberHandler(ErrorStatus.MEMBER_NO_AUTHORITY);
}

meeting.updateTitle(newTitle);
foundMeeting.updateTitle(newTitle);

// last opened title 수정
UserDocumentId userDocumentId = new UserDocumentId(userId, meetingId, DocumentType.AI_MEETING_MANAGER);

UserDocumentLastOpened foundUserDocumentLastOpened = userDocumentLastOpenedRepository.findById(userDocumentId)
.orElseThrow(() -> new UserDocumentLastOpenedHandler(ErrorStatus.USER_DOCUMENT_LAST_OPENED_NOT_FOUND));

foundUserDocumentLastOpened.updateTitle(newTitle);
// meeting 수정 시 워크스페이스에 속해있는 모든 유저에 대해
// last opened 테이블에서 해당 문서 정보 업데이트
userDocumentLastOpenedService.updateRecordsForWorkspaceUsers(foundMeeting);
}

@Override
Expand All @@ -189,13 +176,9 @@ public void deleteMeeting(Long userId, Long meetingId) {

meetingRepository.delete(foundMeeting);

// last opened 테이블 튜플 삭제
// last opened가 없어도 오류 X
UserDocumentId userDocumentId = new UserDocumentId(userId, meetingId, DocumentType.AI_MEETING_MANAGER);

Optional<UserDocumentLastOpened> foundUserDocumentLastOpened = userDocumentLastOpenedRepository.findById(userDocumentId);

foundUserDocumentLastOpened.ifPresent(userDocumentLastOpenedRepository::delete);
// meeting 삭제 시 워크스페이스에 속해있는 모든 유저에 대해
// last opened 테이블에서 해당 문서 id를 가지고 있는 튜플 모두 삭제
userDocumentLastOpenedService.deleteRecordsForWorkspaceUsers(foundMeeting);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.haru.api.domain.moodTracker.entity;

import com.haru.api.domain.lastOpened.entity.Documentable;
import com.haru.api.domain.lastOpened.entity.enums.DocumentType;
import com.haru.api.domain.moodTracker.entity.enums.MoodTrackerVisibility;
import com.haru.api.domain.user.entity.User;
import com.haru.api.domain.workspace.entity.Workspace;
Expand All @@ -22,7 +24,7 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class MoodTracker extends BaseEntity {
public class MoodTracker extends BaseEntity implements Documentable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // 설문ID
Expand All @@ -46,6 +48,9 @@ public class MoodTracker extends BaseEntity {
@Column(name = "due_date")
private LocalDateTime dueDate; // 마감일

@Column(columnDefinition = "TEXT")
private String thumbnailKeyName;

@Enumerated(EnumType.STRING)
@Column(length = 10)
private MoodTrackerVisibility visibility; // 공개범위 (PUBLIC, PRIVATE)
Expand All @@ -64,4 +69,18 @@ public void updateTitle(String title) {
}

public void createReport(String report) { this.report = report; }

public void initThumbnailKey(String thumbnailKey) {
this.thumbnailKeyName = thumbnailKey;
}

@Override
public Long getWorkspaceId() {
return this.getWorkspace().getId();
}

@Override
public DocumentType getDocumentType() {
return DocumentType.TEAM_MOOD_TRACKER;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

@Repository
public interface MoodTrackerRepository extends JpaRepository<MoodTracker, Long> {

@Query("SELECT m FROM Meeting m WHERE m.workspace.id = :workspaceId")
List<MoodTracker> findAllByWorkspaceId(Long workspaceId);

@Modifying
Expand Down
Loading