Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/api-specs/notification-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@
| Method | Path | 설명 |
|---|---|---|
| `POST` | `/api/v1/admin/notices` | 공지사항/이벤트 작성 (즉시 전체 발송) |
| `GET` | `/api/v1/admin/notices/options` | 공지 작성 시 선택 가능한 `category` 목록 조회 |
| `GET` | `/api/v1/admin/notices/target-count` | 지금 등록하면 몇 대의 디바이스에 발송되는지 미리 조회 |
| `GET` | `/api/v1/admin/notices` | 공지 목록 조회 (`category`, `page`, `size` 쿼리) |
| `GET` | `/api/v1/admin/notices/{noticeId}` | 공지 상세 조회 |
Expand All @@ -371,6 +372,22 @@

응답은 `AdminNoticeDetailResponse` (`notificationId`, `category`, `detailCode`, `title`, `body`, `referenceId`, `createdAt`).

**`GET /api/v1/admin/notices/options`**

공지 작성 폼의 카테고리 선택지를 서버 enum 기준으로 내려줍니다. `ALL`은 목록 조회 필터용이라 작성 옵션에는 포함되지 않습니다.

성공 응답 `200 OK`:

```json
{
"statusCode": 200,
"data": {
"categories": ["CONTENT", "NOTICE", "EVENT"]
},
"error": null
}
```

**`GET /api/v1/admin/notices/target-count`**

`NOTICE`/`EVENT` 공지를 지금 등록하면 몇 대의 디바이스에 발송되는지 미리 조회합니다. `notifyAdminNotice`가 사용하는 것과 동일하게 '이벤트 및 소식 알림' 설정이 ON인 유저의 등록된 디바이스 수 기준입니다. `CONTENT` 카테고리 공지는 애초에 이 대상자 산정을 타지 않으므로 참고용으로만 사용하세요.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.swyp.picke.domain.admin.dto.notification.response.AdminNoticeDeliveryResultResponse;
import com.swyp.picke.domain.admin.dto.notification.response.AdminNoticeDetailResponse;
import com.swyp.picke.domain.admin.dto.notification.response.AdminNoticeListResponse;
import com.swyp.picke.domain.admin.dto.notification.response.AdminNoticeOptionsResponse;
import com.swyp.picke.domain.admin.dto.notification.response.AdminNoticeTargetCountResponse;
import com.swyp.picke.domain.admin.service.AdminNotificationService;
import com.swyp.picke.domain.notification.enums.NotificationCategory;
Expand Down Expand Up @@ -44,6 +45,12 @@ public ApiResponse<AdminNoticeDetailResponse> createNotice(
return ApiResponse.onSuccess(adminNotificationService.createNotice(request));
}

@Operation(summary = "공지사항 작성 옵션 조회", description = "공지 작성 시 선택 가능한 category 목록을 내려준다.")
@GetMapping("/options")
public ApiResponse<AdminNoticeOptionsResponse> getOptions() {
return ApiResponse.onSuccess(adminNotificationService.getOptions());
}

@Operation(summary = "공지사항 목록 조회")
@GetMapping
public ApiResponse<AdminNoticeListResponse> getNotices(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.swyp.picke.domain.admin.dto.notification.response;

import java.util.List;

public record AdminNoticeOptionsResponse(
List<String> categories
) {}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.swyp.picke.domain.admin.dto.notification.response.AdminNoticeDeliveryResultResponse;
import com.swyp.picke.domain.admin.dto.notification.response.AdminNoticeDetailResponse;
import com.swyp.picke.domain.admin.dto.notification.response.AdminNoticeListResponse;
import com.swyp.picke.domain.admin.dto.notification.response.AdminNoticeOptionsResponse;
import com.swyp.picke.domain.admin.dto.notification.response.AdminNoticeSummaryResponse;
import com.swyp.picke.domain.admin.dto.notification.response.AdminNoticeTargetCountResponse;
import com.swyp.picke.domain.notification.entity.Notification;
Expand All @@ -17,6 +18,7 @@
import com.swyp.picke.domain.notification.service.NotificationService;
import com.swyp.picke.global.common.exception.CustomException;
import com.swyp.picke.global.common.exception.ErrorCode;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
Expand Down Expand Up @@ -112,6 +114,15 @@ public AdminNoticeTargetCountResponse getTargetCount() {
return new AdminNoticeTargetCountResponse(notificationDispatchService.countAdminNoticeTargets());
}

public AdminNoticeOptionsResponse getOptions() {
List<String> categories = List.of(
NotificationCategory.CONTENT.name(),
NotificationCategory.NOTICE.name(),
NotificationCategory.EVENT.name()
);
return new AdminNoticeOptionsResponse(categories);
}

private NotificationCategory normalizeCategory(NotificationCategory category) {
if (category == null || category == NotificationCategory.ALL) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,12 @@ void getTargetCount_returnsCount() {

assertThat(response.targetCount()).isEqualTo(1200);
}

@Test
@DisplayName("공지 작성 시 선택 가능한 카테고리 목록을 조회한다")
void getOptions_returnsCreatableCategories() {
var response = adminNotificationService.getOptions();

assertThat(response.categories()).containsExactly("CONTENT", "NOTICE", "EVENT");
}
}
Loading