1818import com .back .member .application .MemberService ;
1919import com .back .member .domain .Member ;
2020import com .back .member .domain .MemberRepository ;
21+ import lombok .extern .slf4j .Slf4j ;
2122import lombok .RequiredArgsConstructor ;
23+ import org .springframework .dao .DataAccessException ;
2224import org .springframework .cache .annotation .Cacheable ;
2325import org .springframework .context .ApplicationEventPublisher ;
2426import org .springframework .data .domain .*;
3133import java .util .List ;
3234
3335@ Service
36+ @ Slf4j
3437@ RequiredArgsConstructor
3538@ Transactional
3639public class LetterService implements SendLetterUseCase , InquiryLetterUseCase , AdminLetterUseCase {
@@ -178,18 +181,11 @@ public AdminLetterListRes getAdminLetters(String status, String query, int page,
178181 onlyUnassigned ,
179182 pageable );
180183
181- Page <AdminLetterListItem > mappedPage = letterPage .map (letter -> {
182- String latestAction = letterAdminActionLogRepository
183- .findByLetterIdOrderByCreateDateDesc (letter .getId ())
184- .stream ()
185- .findFirst ()
186- .map (log -> log .getActionType ().name ())
187- .orElse (null );
188- return AdminLetterListItem .from (
189- letter ,
190- letterRedisRepository .isWriting (letter .getId ()),
191- latestAction );
192- });
184+ Page <AdminLetterListItem > mappedPage = letterPage .map (letter ->
185+ AdminLetterListItem .from (
186+ letter ,
187+ isWritingStatusAvailable (letter .getId ()),
188+ getLatestAdminActionSafely (letter .getId ())));
193189
194190 return AdminLetterListRes .from (mappedPage );
195191 }
@@ -200,15 +196,11 @@ public AdminLetterDetailRes getAdminLetter(long id) {
200196 Letter letter = letterPort .findByIdForAdmin (id )
201197 .orElseThrow (() -> new ServiceException ("404-1" , "존재하지 않는 편지입니다." ));
202198
203- List <AdminLetterActionLogItem > actionLogs = letterAdminActionLogRepository
204- .findByLetterIdOrderByCreateDateDesc (letter .getId ())
205- .stream ()
206- .map (AdminLetterActionLogItem ::from )
207- .toList ();
199+ List <AdminLetterActionLogItem > actionLogs = getAdminActionLogsSafely (letter .getId ());
208200
209201 return AdminLetterDetailRes .from (
210202 letter ,
211- letterRedisRepository . isWriting (letter .getId ()),
203+ isWritingStatusAvailable (letter .getId ()),
212204 actionLogs );
213205 }
214206
@@ -325,6 +317,42 @@ private String resolveAdminNickname(long adminMemberId) {
325317 .orElse ("관리자#" + adminMemberId );
326318 }
327319
320+ private String getLatestAdminActionSafely (long letterId ) {
321+ try {
322+ return letterAdminActionLogRepository
323+ .findByLetterIdOrderByCreateDateDesc (letterId )
324+ .stream ()
325+ .findFirst ()
326+ .map (log -> log .getActionType ().name ())
327+ .orElse (null );
328+ } catch (DataAccessException exception ) {
329+ log .warn ("관리자 편지 최신 조치를 불러오지 못해 기본값으로 대체합니다. letterId={}" , letterId , exception );
330+ return null ;
331+ }
332+ }
333+
334+ private List <AdminLetterActionLogItem > getAdminActionLogsSafely (long letterId ) {
335+ try {
336+ return letterAdminActionLogRepository
337+ .findByLetterIdOrderByCreateDateDesc (letterId )
338+ .stream ()
339+ .map (AdminLetterActionLogItem ::from )
340+ .toList ();
341+ } catch (DataAccessException exception ) {
342+ log .warn ("관리자 편지 조치 이력을 불러오지 못해 빈 목록으로 대체합니다. letterId={}" , letterId , exception );
343+ return List .of ();
344+ }
345+ }
346+
347+ private boolean isWritingStatusAvailable (long letterId ) {
348+ try {
349+ return letterRedisRepository .isWriting (letterId );
350+ } catch (DataAccessException exception ) {
351+ log .warn ("관리자 편지 작성 중 상태를 불러오지 못해 false로 대체합니다. letterId={}" , letterId , exception );
352+ return false ;
353+ }
354+ }
355+
328356 private String normalizeQuery (String query ) {
329357 if (query == null || query .isBlank ()) {
330358 return null ;
0 commit comments