@@ -71,9 +71,11 @@ public RoutineResponse.RoutineCreateResultDTO saveRoutineWithRoutineHashtags(
7171 // 3. 예산의 createdMonth로 이번 달 판단
7272 String createdMonth = budget .getCreatedMonth ();
7373
74- // 4. 이번 달 동일 예산에 대한 루틴 존재 여부 확인 (PESSIMISTIC_WRITE)
75- if (routineRepository .findForUpdateByUserAndBudgetAndMonth (userId , budgetId , createdMonth ).isPresent ()) {
76- throw new ErrorHandler (ROUTINE_ALREADY_EXIST );
74+ // 4. 이번 달 동일 예산에 대한 루틴 존재 여부 확인 (단, userId=1 은 중복 허용)
75+ if (!userId .equals (1L )) { // ✅ userId=1일 때는 중복 검사 스킵
76+ if (routineRepository .findForUpdateByUserAndBudgetAndMonth (userId , budgetId , createdMonth ).isPresent ()) {
77+ throw new ErrorHandler (ROUTINE_ALREADY_EXIST );
78+ }
7779 }
7880
7981 // 5. 카테고리 총합 계산
@@ -92,14 +94,14 @@ public RoutineResponse.RoutineCreateResultDTO saveRoutineWithRoutineHashtags(
9294 }
9395
9496 // 7. 루틴 저장
95- // - 동시에 같은 (user, budget, createdMonth) 조합이 저장되는 경쟁 상황 방지
96- // - 유니크 제약 위반 발생 시 DataIntegrityViolationException을 잡아 예외 변환
9797 Routine routine = RoutineConverter .toRoutine (user , budget , request , createdMonth );
9898 try {
9999 routineRepository .save (routine );
100100 } catch (Exception e ) {
101101 // 혹시 경쟁 상황으로 유니크 제약 위반 시
102- throw new ErrorHandler (ROUTINE_ALREADY_EXIST );
102+ if (!userId .equals (1L )) { // ✅ userId=1일 때는 예외 변환하지 않음
103+ throw new ErrorHandler (ROUTINE_ALREADY_EXIST );
104+ }
103105 }
104106
105107 // 8. RoutineAmount 저장
@@ -146,8 +148,8 @@ public void applyRoutineToBudget(Long userId, Long routineId, RoutineRequest.App
146148 throw new ErrorHandler (ErrorStatus .BUDGE_UNAUTHORIZED );
147149 }
148150
149- // 이미 루틴 적용된 예산이라면 예외
150- if (Boolean .TRUE .equals (budget .getIsFromRoutine ())) {
151+ // 이미 루틴 적용된 예산이라면 예외 (단, userId=1은 중복 허용)
152+ if (! userId . equals ( 1L ) && Boolean .TRUE .equals (budget .getIsFromRoutine ())) {
151153 throw new ErrorHandler (ErrorStatus .ROUTINE_ALREADY_APPLIED );
152154 }
153155
0 commit comments