Skip to content

Commit 5f4ed66

Browse files
Merge pull request #252 from DevKor-github/develop
#250 ~ #251 반영해 운영 서버 배포
2 parents 56e46ee + 8cfdbda commit 5f4ed66

6 files changed

Lines changed: 302 additions & 27 deletions

File tree

src/main/java/org/devkor/apu/saerok_server/domain/ad/api/AdminAdController.java

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525
import org.devkor.apu.saerok_server.domain.ad.core.entity.Ad;
2626
import org.devkor.apu.saerok_server.domain.ad.core.entity.AdPlacement;
2727
import org.devkor.apu.saerok_server.domain.ad.core.entity.Slot;
28+
import org.devkor.apu.saerok_server.global.security.principal.UserPrincipal;
2829
import org.devkor.apu.saerok_server.global.shared.infra.ImageDomainService;
2930
import org.springframework.security.access.prepost.PreAuthorize;
31+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
3032
import org.springframework.web.bind.annotation.*;
3133

3234
import java.util.List;
@@ -83,9 +85,11 @@ public AdminAdListResponse listAds() {
8385
security = @SecurityRequirement(name = "bearerAuth")
8486
)
8587
public AdminAdListResponse.Item createAd(
86-
@Valid @RequestBody AdminCreateAdRequest request
88+
@Valid @RequestBody AdminCreateAdRequest request,
89+
@AuthenticationPrincipal UserPrincipal admin
8790
) {
8891
Ad ad = adminAdService.createAd(
92+
admin.getId(),
8993
request.name(),
9094
request.memo(),
9195
request.objectKey(),
@@ -115,9 +119,11 @@ public AdminAdListResponse.Item createAd(
115119
)
116120
public AdminAdListResponse.Item updateAd(
117121
@PathVariable Long id,
118-
@Valid @RequestBody AdminUpdateAdRequest request
122+
@Valid @RequestBody AdminUpdateAdRequest request,
123+
@AuthenticationPrincipal UserPrincipal admin
119124
) {
120125
Ad ad = adminAdService.updateAd(
126+
admin.getId(),
121127
id,
122128
request.name(),
123129
request.memo(),
@@ -146,8 +152,9 @@ public AdminAdListResponse.Item updateAd(
146152
summary = "광고 삭제",
147153
security = @SecurityRequirement(name = "bearerAuth")
148154
)
149-
public void deleteAd(@PathVariable Long id) {
150-
adminAdService.deleteAd(id);
155+
public void deleteAd(@PathVariable Long id,
156+
@AuthenticationPrincipal UserPrincipal admin) {
157+
adminAdService.deleteAd(admin.getId(), id);
151158
}
152159

153160
/* ───────────── 광고 이미지 Presigned URL ───────────── */
@@ -204,9 +211,11 @@ public AdminSlotListResponse listSlots() {
204211
security = @SecurityRequirement(name = "bearerAuth")
205212
)
206213
public AdminSlotListResponse.Item createSlot(
207-
@Valid @RequestBody AdminCreateSlotRequest request
214+
@Valid @RequestBody AdminCreateSlotRequest request,
215+
@AuthenticationPrincipal UserPrincipal admin
208216
) {
209217
Slot slot = adminSlotService.createSlot(
218+
admin.getId(),
210219
request.getName(),
211220
request.getMemo(),
212221
request.getFallbackRatio(),
@@ -232,9 +241,11 @@ public AdminSlotListResponse.Item createSlot(
232241
)
233242
public AdminSlotListResponse.Item updateSlot(
234243
@PathVariable Long id,
235-
@Valid @RequestBody AdminUpdateSlotRequest request
244+
@Valid @RequestBody AdminUpdateSlotRequest request,
245+
@AuthenticationPrincipal UserPrincipal admin
236246
) {
237247
Slot slot = adminSlotService.updateSlot(
248+
admin.getId(),
238249
id,
239250
request.getMemo(),
240251
request.getFallbackRatio(),
@@ -258,14 +269,15 @@ public AdminSlotListResponse.Item updateSlot(
258269
summary = "슬롯 삭제",
259270
security = @SecurityRequirement(name = "bearerAuth")
260271
)
261-
public void deleteSlot(@PathVariable Long id) {
262-
adminSlotService.deleteSlot(id);
272+
public void deleteSlot(@PathVariable Long id,
273+
@AuthenticationPrincipal UserPrincipal admin) {
274+
adminSlotService.deleteSlot(admin.getId(), id);
263275
}
264276

265277
/* ───────────── 광고 배치(AdPlacement) 관리 ───────────── */
266278

267279
@GetMapping("/placement")
268-
@PreAuthorize("hasRole('ADMIN_EDITOR')")
280+
@PreAuthorize("hasAnyRole('ADMIN_VIEWER','ADMIN_EDITOR')")
269281
@Operation(
270282
summary = "광고 배치 목록 조회",
271283
security = @SecurityRequirement(name = "bearerAuth")
@@ -300,9 +312,11 @@ public AdminAdPlacementListResponse listPlacements() {
300312
security = @SecurityRequirement(name = "bearerAuth")
301313
)
302314
public AdminAdPlacementListResponse.Item createPlacement(
303-
@Valid @RequestBody AdminCreateAdPlacementRequest request
315+
@Valid @RequestBody AdminCreateAdPlacementRequest request,
316+
@AuthenticationPrincipal UserPrincipal admin
304317
) {
305318
AdPlacement placement = adminAdPlacementService.createPlacement(
319+
admin.getId(),
306320
request.adId(),
307321
request.slotId(),
308322
request.startDate(),
@@ -339,9 +353,11 @@ public AdminAdPlacementListResponse.Item createPlacement(
339353
)
340354
public AdminAdPlacementListResponse.Item updatePlacement(
341355
@PathVariable Long id,
342-
@Valid @RequestBody AdminUpdateAdPlacementRequest request
356+
@Valid @RequestBody AdminUpdateAdPlacementRequest request,
357+
@AuthenticationPrincipal UserPrincipal admin
343358
) {
344359
AdPlacement placement = adminAdPlacementService.updatePlacement(
360+
admin.getId(),
345361
id,
346362
request.slotId(),
347363
request.startDate(),
@@ -376,7 +392,8 @@ public AdminAdPlacementListResponse.Item updatePlacement(
376392
summary = "광고 배치 삭제",
377393
security = @SecurityRequirement(name = "bearerAuth")
378394
)
379-
public void deletePlacement(@PathVariable Long id) {
380-
adminAdPlacementService.deletePlacement(id);
395+
public void deletePlacement(@PathVariable Long id,
396+
@AuthenticationPrincipal UserPrincipal admin) {
397+
adminAdPlacementService.deletePlacement(admin.getId(), id);
381398
}
382399
}

src/main/java/org/devkor/apu/saerok_server/domain/ad/application/AdminAdPlacementService.java

Lines changed: 96 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,20 @@
77
import org.devkor.apu.saerok_server.domain.ad.core.repository.AdPlacementRepository;
88
import org.devkor.apu.saerok_server.domain.ad.core.repository.AdRepository;
99
import org.devkor.apu.saerok_server.domain.ad.core.repository.SlotRepository;
10+
import org.devkor.apu.saerok_server.domain.admin.core.entity.AdminAuditAction;
11+
import org.devkor.apu.saerok_server.domain.admin.core.entity.AdminAuditLog;
12+
import org.devkor.apu.saerok_server.domain.admin.core.entity.AdminAuditTargetType;
13+
import org.devkor.apu.saerok_server.domain.admin.core.repository.AdminAuditLogRepository;
1014
import org.devkor.apu.saerok_server.global.shared.exception.NotFoundException;
15+
import org.devkor.apu.saerok_server.domain.user.core.entity.User;
16+
import org.devkor.apu.saerok_server.domain.user.core.repository.UserRepository;
1117
import org.springframework.stereotype.Service;
1218
import org.springframework.transaction.annotation.Transactional;
1319

1420
import java.time.LocalDate;
1521
import java.util.List;
22+
import java.util.LinkedHashMap;
23+
import java.util.Map;
1624

1725
@Service
1826
@RequiredArgsConstructor
@@ -22,13 +30,16 @@ public class AdminAdPlacementService {
2230
private final AdPlacementRepository adPlacementRepository;
2331
private final AdRepository adRepository;
2432
private final SlotRepository slotRepository;
33+
private final AdminAuditLogRepository adminAuditLogRepository;
34+
private final UserRepository userRepository;
2535

2636
@Transactional(readOnly = true)
2737
public List<AdPlacement> listPlacements() {
2838
return adPlacementRepository.findAll();
2939
}
3040

31-
public AdPlacement createPlacement(Long adId,
41+
public AdPlacement createPlacement(Long adminUserId,
42+
Long adId,
3243
Long slotId,
3344
LocalDate startDate,
3445
LocalDate endDate,
@@ -39,10 +50,31 @@ public AdPlacement createPlacement(Long adId,
3950
Slot slot = slotRepository.findById(slotId)
4051
.orElseThrow(() -> new NotFoundException("존재하지 않는 슬롯 id예요."));
4152
AdPlacement placement = AdPlacement.create(ad, slot, startDate, endDate, weight, enabled);
42-
return adPlacementRepository.save(placement);
53+
AdPlacement saved = adPlacementRepository.save(placement);
54+
55+
User admin = loadAdmin(adminUserId);
56+
Map<String, Object> metadata = new LinkedHashMap<>();
57+
metadata.put("adId", saved.getAd().getId());
58+
metadata.put("slotId", saved.getSlot().getId());
59+
metadata.put("startDate", saved.getStartDate());
60+
metadata.put("endDate", saved.getEndDate());
61+
metadata.put("weight", saved.getWeight());
62+
metadata.put("enabled", saved.getEnabled());
63+
64+
adminAuditLogRepository.save(AdminAuditLog.of(
65+
admin,
66+
AdminAuditAction.AD_PLACEMENT_CREATED,
67+
AdminAuditTargetType.AD_PLACEMENT,
68+
saved.getId(),
69+
null,
70+
metadata
71+
));
72+
73+
return saved;
4374
}
4475

45-
public AdPlacement updatePlacement(Long id,
76+
public AdPlacement updatePlacement(Long adminUserId,
77+
Long id,
4678
Long slotId,
4779
LocalDate startDate,
4880
LocalDate endDate,
@@ -52,18 +84,78 @@ public AdPlacement updatePlacement(Long id,
5284
.orElseThrow(() -> new NotFoundException("존재하지 않는 광고 배치 id예요."));
5385

5486
Slot slot = null;
87+
Long previousSlotId = placement.getSlot() != null ? placement.getSlot().getId() : null;
88+
LocalDate previousStartDate = placement.getStartDate();
89+
LocalDate previousEndDate = placement.getEndDate();
90+
Short previousWeight = placement.getWeight();
91+
Boolean previousEnabled = placement.getEnabled();
5592
if (slotId != null) {
5693
slot = slotRepository.findById(slotId)
5794
.orElseThrow(() -> new NotFoundException("존재하지 않는 슬롯 id예요."));
5895
}
5996

6097
placement.update(slot, startDate, endDate, weight, enabled);
98+
99+
User admin = loadAdmin(adminUserId);
100+
Map<String, Object> previous = new LinkedHashMap<>();
101+
previous.put("slotId", previousSlotId);
102+
previous.put("startDate", previousStartDate);
103+
previous.put("endDate", previousEndDate);
104+
previous.put("weight", previousWeight);
105+
previous.put("enabled", previousEnabled);
106+
107+
Map<String, Object> metadata = new LinkedHashMap<>();
108+
metadata.put("adId", placement.getAd().getId());
109+
metadata.put("slotId", placement.getSlot().getId());
110+
metadata.put("startDate", placement.getStartDate());
111+
metadata.put("endDate", placement.getEndDate());
112+
metadata.put("weight", placement.getWeight());
113+
metadata.put("enabled", placement.getEnabled());
114+
metadata.put("previous", previous);
115+
116+
adminAuditLogRepository.save(AdminAuditLog.of(
117+
admin,
118+
AdminAuditAction.AD_PLACEMENT_UPDATED,
119+
AdminAuditTargetType.AD_PLACEMENT,
120+
placement.getId(),
121+
null,
122+
metadata
123+
));
61124
return placement;
62125
}
63126

64-
public void deletePlacement(Long id) {
127+
public void deletePlacement(Long adminUserId, Long id) {
65128
AdPlacement placement = adPlacementRepository.findById(id)
66129
.orElseThrow(() -> new NotFoundException("존재하지 않는 광고 배치 id예요."));
130+
Long adId = placement.getAd().getId();
131+
Long slotId = placement.getSlot().getId();
132+
LocalDate startDate = placement.getStartDate();
133+
LocalDate endDate = placement.getEndDate();
134+
Short weight = placement.getWeight();
135+
Boolean enabled = placement.getEnabled();
67136
adPlacementRepository.delete(placement);
137+
138+
User admin = loadAdmin(adminUserId);
139+
Map<String, Object> metadata = new LinkedHashMap<>();
140+
metadata.put("adId", adId);
141+
metadata.put("slotId", slotId);
142+
metadata.put("startDate", startDate);
143+
metadata.put("endDate", endDate);
144+
metadata.put("weight", weight);
145+
metadata.put("enabled", enabled);
146+
147+
adminAuditLogRepository.save(AdminAuditLog.of(
148+
admin,
149+
AdminAuditAction.AD_PLACEMENT_DELETED,
150+
AdminAuditTargetType.AD_PLACEMENT,
151+
id,
152+
null,
153+
metadata
154+
));
155+
}
156+
157+
private User loadAdmin(Long adminUserId) {
158+
return userRepository.findById(adminUserId)
159+
.orElseThrow(() -> new NotFoundException("관리자 계정이 존재하지 않아요"));
68160
}
69161
}

0 commit comments

Comments
 (0)