11package com .back .global .init ;
22
3+ import com .back .domain .notification .entity .Notification ;
4+ import com .back .domain .notification .enums .NotificationType ;
5+ import com .back .domain .notification .repository .NotificationRepository ;
6+ import com .back .domain .cocktail .entity .Cocktail ;
7+ import com .back .domain .cocktail .enums .AlcoholBaseType ;
8+ import com .back .domain .cocktail .enums .AlcoholStrength ;
9+ import com .back .domain .cocktail .enums .CocktailType ;
310import com .back .domain .cocktail .repository .CocktailRepository ;
4- import com .back .domain .cocktail .service .CocktailService ;
11+ import com .back .domain .post .category .entity .Category ;
12+ import com .back .domain .post .category .repository .CategoryRepository ;
13+ import com .back .domain .post .comment .entity .Comment ;
14+ import com .back .domain .post .comment .repository .CommentRepository ;
15+ import com .back .domain .post .post .entity .Post ;
16+ import com .back .domain .post .post .entity .PostLike ;
17+ import com .back .domain .post .post .enums .PostLikeStatus ;
18+ import com .back .domain .post .post .repository .PostLikeRepository ;
19+ import com .back .domain .post .post .repository .PostRepository ;
20+ import com .back .domain .user .entity .User ;
21+ import com .back .domain .user .repository .UserRepository ;
22+ import org .springframework .transaction .annotation .Transactional ;
523import lombok .RequiredArgsConstructor ;
624import org .springframework .beans .factory .annotation .Autowired ;
725import org .springframework .boot .ApplicationRunner ;
1533@ RequiredArgsConstructor
1634public class DevInitData {
1735
36+ private final UserRepository userRepository ;
37+ private final CategoryRepository categoryRepository ;
38+ private final PostRepository postRepository ;
39+ private final CommentRepository commentRepository ;
40+ private final PostLikeRepository postLikeRepository ;
41+ private final NotificationRepository notificationRepository ;
1842 private final CocktailRepository cocktailRepository ;
19- private final CocktailService cocktailService ;
43+ private final com .back .domain .mybar .service .MyBarService myBarService ;
44+ private final com .back .domain .mybar .repository .MyBarRepository myBarRepository ;
2045
2146 @ Autowired
2247 @ Lazy
@@ -25,8 +50,257 @@ public class DevInitData {
2550 @ Bean
2651 ApplicationRunner devInitDataApplicationRunner () {
2752 return args -> {
28- // self.cocktailInit(); // 테스트용 데이터 삽입
53+ self .cocktailInit ();
54+ self .userInit ();
55+ // myBar는 사용자 활성 상태 기준으로 초기화가 필요하므로 boardInit(soft delete)보다 먼저 실행
56+ self .myBarInit ();
57+ self .boardInit ();
58+ self .notificationInit ();
2959 };
3060 }
31- }
3261
62+ @ Transactional
63+ public void cocktailInit () {
64+ if (cocktailRepository .count () > 0 ) return ;
65+
66+ // 1) 하이볼
67+ cocktailRepository .save (Cocktail .builder ()
68+ .cocktailName ("Highball" )
69+ .cocktailNameKo ("하이볼" )
70+ .alcoholStrength (AlcoholStrength .LIGHT )
71+ .cocktailType (CocktailType .LONG )
72+ .alcoholBaseType (AlcoholBaseType .WHISKY )
73+ .ingredient ("위스키, 탄산수, 얼음, 레몬피" )
74+ .recipe ("잔에 얼음 → 위스키 → 탄산수 → 가볍게 스터" )
75+ .cocktailImgUrl ("/img/cocktail/1.jpg" )
76+ .build ());
77+
78+ // 2) 진토닉
79+ cocktailRepository .save (Cocktail .builder ()
80+ .cocktailName ("Gin and Tonic" )
81+ .cocktailNameKo ("진토닉" )
82+ .alcoholStrength (AlcoholStrength .WEAK )
83+ .cocktailType (CocktailType .LONG )
84+ .alcoholBaseType (AlcoholBaseType .GIN )
85+ .ingredient ("진, 토닉워터, 얼음, 라임" )
86+ .recipe ("잔에 얼음 → 진 → 토닉워터 → 라임" )
87+ .cocktailImgUrl ("/img/cocktail/2.jpg" )
88+ .build ());
89+
90+ // 3) 올드패션드
91+ cocktailRepository .save (Cocktail .builder ()
92+ .cocktailName ("Old Fashioned" )
93+ .cocktailNameKo ("올드패션드" )
94+ .alcoholStrength (AlcoholStrength .STRONG )
95+ .cocktailType (CocktailType .SHORT )
96+ .alcoholBaseType (AlcoholBaseType .WHISKY )
97+ .ingredient ("버번 위스키, 설탕/시럽, 앙고스투라 비터스, 오렌지 필" )
98+ .recipe ("시럽+비터스 → 위스키 → 얼음 → 스터 → 오렌지 필" )
99+ .cocktailImgUrl ("/img/cocktail/3.jpg" )
100+ .build ());
101+
102+ // 4) 모히또
103+ cocktailRepository .save (Cocktail .builder ()
104+ .cocktailName ("Mojito" )
105+ .cocktailNameKo ("모히또" )
106+ .alcoholStrength (AlcoholStrength .LIGHT )
107+ .cocktailType (CocktailType .LONG )
108+ .alcoholBaseType (AlcoholBaseType .RUM )
109+ .ingredient ("라임, 민트, 설탕/시럽, 화이트 럼, 탄산수, 얼음" )
110+ .recipe ("라임+민트+시럽 머들 → 럼 → 얼음 → 탄산수" )
111+ .cocktailImgUrl ("/img/cocktail/4.jpg" )
112+ .build ());
113+ }
114+
115+ @ Transactional
116+ public void userInit () {
117+ userRepository .findByNickname ("사용자A" ).orElseGet (() ->
118+ userRepository .save (User .builder ().nickname ("사용자A" ).role ("USER" ).build ())
119+ );
120+ userRepository .findByNickname ("사용자B" ).orElseGet (() ->
121+ userRepository .save (User .builder ().nickname ("사용자B" ).role ("USER" ).build ())
122+ );
123+ userRepository .findByNickname ("사용자C" ).orElseGet (() ->
124+ userRepository .save (User .builder ().nickname ("사용자C" ).role ("USER" ).build ())
125+ );
126+ }
127+
128+ @ Transactional
129+ public void boardInit () {
130+ if (postRepository .count () > 0 ) return ;
131+
132+ User userA = userRepository .findByNickname ("사용자A" ).orElseThrow ();
133+ User userB = userRepository .findByNickname ("사용자B" ).orElseThrow ();
134+ User userC = userRepository .findByNickname ("사용자C" ).orElseThrow ();
135+
136+ Category free = categoryRepository .findAll ().stream ()
137+ .filter (c -> "자유" .equals (c .getName ()))
138+ .findFirst ()
139+ .orElseGet (() -> categoryRepository .save (Category .builder ()
140+ .name ("자유" )
141+ .description ("자유 게시판" )
142+ .build ()));
143+
144+ Post postA = postRepository .save (Post .builder ()
145+ .category (free )
146+ .user (userA )
147+ .title ("A의 게시글" )
148+ .content ("내용A" )
149+ .imageUrl ("/img/cocktail/1.jpg" )
150+ .build ());
151+
152+ Post postB = postRepository .save (Post .builder ()
153+ .category (free )
154+ .user (userB )
155+ .title ("B의 게시글" )
156+ .content ("내용B" )
157+ .imageUrl ("/img/cocktail/2.jpg" )
158+ .build ());
159+
160+ // 댓글: C가 A/B 게시글에 작성
161+ commentRepository .save (Comment .builder ()
162+ .post (postA )
163+ .user (userC )
164+ .content ("C의 댓글 on A" )
165+ .build ());
166+
167+ commentRepository .save (Comment .builder ()
168+ .post (postB )
169+ .user (userC )
170+ .content ("C의 댓글 on B" )
171+ .build ());
172+
173+ // 좋아요: A→B, B→A, C→A, C→B
174+ postLikeRepository .save (PostLike .builder ()
175+ .post (postB )
176+ .user (userA )
177+ .status (PostLikeStatus .LIKE )
178+ .build ());
179+ postB .increaseLikeCount ();
180+
181+ postLikeRepository .save (PostLike .builder ()
182+ .post (postA )
183+ .user (userB )
184+ .status (PostLikeStatus .LIKE )
185+ .build ());
186+ postA .increaseLikeCount ();
187+
188+ postLikeRepository .save (PostLike .builder ()
189+ .post (postA )
190+ .user (userC )
191+ .status (PostLikeStatus .LIKE )
192+ .build ());
193+ postA .increaseLikeCount ();
194+
195+ postLikeRepository .save (PostLike .builder ()
196+ .post (postB )
197+ .user (userC )
198+ .status (PostLikeStatus .LIKE )
199+ .build ());
200+ postB .increaseLikeCount ();
201+
202+ postRepository .save (postA );
203+ postRepository .save (postB );
204+
205+ // B 사용자 soft delete (게시글/좋아요/댓글 생성 후)
206+ User b = userRepository .findByNickname ("사용자B" ).orElseThrow ();
207+ b .markDeleted ("탈퇴한 사용자" );
208+ userRepository .save (b );
209+ }
210+
211+ @ Transactional
212+ public void notificationInit () {
213+ if (notificationRepository .count () > 0 ) return ;
214+
215+ // 게시글 소유자에게 COMMENT/LIKE 알림 생성
216+ Post postA = postRepository .findAll ().stream ()
217+ .filter (p -> "A의 게시글" .equals (p .getTitle ()))
218+ .findFirst ().orElse (null );
219+ Post postB = postRepository .findAll ().stream ()
220+ .filter (p -> "B의 게시글" .equals (p .getTitle ()))
221+ .findFirst ().orElse (null );
222+ if (postA == null || postB == null ) return ;
223+
224+ User ownerA = postA .getUser ();
225+ User ownerB = postB .getUser ();
226+
227+ notificationRepository .save (Notification .builder ()
228+ .user (ownerA )
229+ .post (postA )
230+ .type (NotificationType .COMMENT )
231+ .message ("새 댓글이 달렸습니다." )
232+ .build ());
233+
234+ notificationRepository .save (Notification .builder ()
235+ .user (ownerA )
236+ .post (postA )
237+ .type (NotificationType .LIKE )
238+ .message ("게시글에 좋아요가 추가되었습니다." )
239+ .build ());
240+
241+ notificationRepository .save (Notification .builder ()
242+ .user (ownerA )
243+ .post (postA )
244+ .type (NotificationType .LIKE )
245+ .message ("게시글에 좋아요가 추가되었습니다." )
246+ .build ());
247+
248+ notificationRepository .save (Notification .builder ()
249+ .user (ownerB )
250+ .post (postB )
251+ .type (NotificationType .COMMENT )
252+ .message ("새 댓글이 달렸습니다." )
253+ .build ());
254+
255+ notificationRepository .save (Notification .builder ()
256+ .user (ownerB )
257+ .post (postB )
258+ .type (NotificationType .LIKE )
259+ .message ("게시글에 좋아요가 추가되었습니다." )
260+ .build ());
261+
262+ notificationRepository .save (Notification .builder ()
263+ .user (ownerB )
264+ .post (postB )
265+ .type (NotificationType .LIKE )
266+ .message ("게시글에 좋아요가 추가되었습니다." )
267+ .build ());
268+ }
269+
270+ @ Transactional
271+ public void myBarInit () {
272+ if (myBarRepository .count () > 0 ) return ;
273+
274+ User userA = userRepository .findByNickname ("사용자A" ).orElseThrow ();
275+ User userB = userRepository .findByNickname ("사용자B" ).orElseThrow ();
276+ User userC = userRepository .findByNickname ("사용자C" ).orElseThrow ();
277+
278+ // 칵테일 참조 준비
279+ var cocktails = cocktailRepository .findAll ();
280+ Cocktail c1 = cocktails .stream ().filter (c -> "하이볼" .equals (c .getCocktailNameKo ())).findFirst ().orElse (null );
281+ Cocktail c2 = cocktails .stream ().filter (c -> "진토닉" .equals (c .getCocktailNameKo ())).findFirst ().orElse (null );
282+ Cocktail c3 = cocktails .stream ().filter (c -> "올드패션드" .equals (c .getCocktailNameKo ())).findFirst ().orElse (null );
283+ Cocktail c4 = cocktails .stream ().filter (c -> "모히또" .equals (c .getCocktailNameKo ())).findFirst ().orElse (null );
284+
285+ // 방어: 칵테일 누락 시 스킵
286+ if (c1 == null || c2 == null || c3 == null || c4 == null ) return ;
287+
288+ // A: c1(now-2d), c2(now-1d)
289+ myBarService .keep (userA .getId (), c1 .getId ());
290+ myBarService .keep (userA .getId (), c2 .getId ());
291+ myBarRepository .findByUser_IdAndCocktail_Id (userA .getId (), c1 .getId ()).ifPresent (m -> m .setKeptAt (java .time .LocalDateTime .now ().minusDays (2 )));
292+ myBarRepository .findByUser_IdAndCocktail_Id (userA .getId (), c2 .getId ()).ifPresent (m -> m .setKeptAt (java .time .LocalDateTime .now ().minusDays (1 )));
293+
294+ // B: c3 keep 후 unkeep -> DELETED
295+ myBarService .keep (userB .getId (), c3 .getId ());
296+ myBarService .unkeep (userB .getId (), c3 .getId ());
297+
298+ // C: c2(now-3d), c3(now-2d), c4(now-1h)
299+ myBarService .keep (userC .getId (), c2 .getId ());
300+ myBarService .keep (userC .getId (), c3 .getId ());
301+ myBarService .keep (userC .getId (), c4 .getId ());
302+ myBarRepository .findByUser_IdAndCocktail_Id (userC .getId (), c2 .getId ()).ifPresent (m -> m .setKeptAt (java .time .LocalDateTime .now ().minusDays (3 )));
303+ myBarRepository .findByUser_IdAndCocktail_Id (userC .getId (), c3 .getId ()).ifPresent (m -> m .setKeptAt (java .time .LocalDateTime .now ().minusDays (2 )));
304+ myBarRepository .findByUser_IdAndCocktail_Id (userC .getId (), c4 .getId ()).ifPresent (m -> m .setKeptAt (java .time .LocalDateTime .now ().minusHours (1 )));
305+ }
306+ }
0 commit comments