Skip to content

[Feat/#142] 공지 관리자 API 고정 여부 반영 및 목록·상세 조회 추가 - #143

Open
jjunh33 wants to merge 2 commits into
mainfrom
feat/#142-admin-notice-read-pin
Open

jjunh33 wants to merge 2 commits into
mainfrom
feat/#142-admin-notice-read-pin

Conversation

@jjunh33

@jjunh33 jjunh33 commented Oct 18, 2026

Copy link
Copy Markdown
Collaborator

#️⃣연관된 이슈

🎯 해결하려는 문제가 무엇인가요?

관리자 웹(stream-admin-web)의 공지 화면과 공지 관리자 API(#104)가 맞지 않습니다.

  • 등록·수정 폼에 "상단 고정" 스위치가 있어 고정 여부를 저장과 함께 보내는데, API는 작성에서 항상 비고정으로 만들고 수정(PUT)은 pinned를 읽지 않으며 고정은 PATCH /{noticeId}/pin으로만 바꿉니다. 지금 연결하면 스위치가 오류 없이 무시됩니다.
  • 수정 화면은 기존 공지를 불러와 채우고, 수정 API는 updatedAt을 요구합니다. 그런데 관리자용 조회가 없고 학생 앱 응답에도 pinned와 updatedAt이 없어서 수정 화면이 값을 얻을 방법이 없습니다.

❓ 왜 해결해야 하나요?

관리자 웹이 공지 API를 연동하려면 두 가지가 먼저 있어야 합니다. #104의 수정 API는 updatedAt을 받아올 조회가 없으면 실제로 쓸 수 없는 상태입니다.

⭐ 어떻게 해결했나요?

  • pinned를 작성·수정 요청에 추가(필수). NoticeCreateCommand·NoticeUpdateCommand·Notice가 함께 받습니다. 목록에서 빠르게 전환할 때 쓰도록 PATCH /{noticeId}/pin은 그대로 둡니다.
  • 관리자 목록 조회 GET /v1/admin/notices: keyword(제목 검색), page(0부터), size(1~100, 기본 20). 고정 우선, 최신순이고 항목은 noticeId, title, category, pinned, createdAt입니다. 검색은 물품 검색과 같은 LOCATE 방식이라 %·_도 글자 그대로 찾습니다. 공백 검색어는 조건 없음으로 취급합니다(NoticeServiceImpl.search).
  • 관리자 상세 조회 GET /v1/admin/notices/{noticeId}: title, content, category, pinned, images[{fileId, fileUrl}], attachments[{fileId, fileName, fileUrl}], createdAt, updatedAt(KST 기준 epoch 밀리초). 수정할 때 imageFileIds로 되돌려 보낼 수 있게 파일 ID를 함께 내려줍니다. 공지와 파일 두 도메인을 조합하므로 AdminNoticeReadUseCase가 맡습니다.
  • 시각 변환을 DateUtil로 통일: toEpochMillis/fromEpochMillis를 추가해 상세 응답(내보내기)과 수정 요청(받기)이 같은 기준을 쓰게 했습니다. 이전에는 수정 요청 쪽에만 변환이 있었습니다.

🧩 이 PR의 한계 & 트레이드오프

  • 새 JPQL을 실제 DB로 확인하지 못했습니다. 로컬에 DB가 없어서 NoticeJpaRepository.search는 dev에서 호출해 봐야 합니다. 물품 검색(LOCATE)과 열린피드백 목록(countQuery가 있는 Page 조회)의 패턴을 그대로 따랐고, 쿼리가 틀리면 앱 기동이 실패하므로 dev 배포 후 가장 먼저 확인이 필요합니다.
  • 본문 형식은 정하지 않았습니다. 명세는 HTML이고 관리자 웹은 일반 텍스트 TextArea로 입력받아 어긋나 있으며, 학생 앱이 렌더링하는 방식을 확인한 뒤 정할 일이라 이번에 건드리지 않았습니다.
  • updatedAt 비교가 완전한 원자적 보호가 아닌 점(#104에서 밝힌 한계)은 그대로입니다.
  • 목록은 제목 검색만 있고 카테고리 필터는 없습니다(화면에 없음).
  • 새 테스트는 추가하지 않았습니다. 동작 확인은 임시 테스트로만 했고 커밋하지 않았습니다.

⛓️ 기존 기능에 미치는 영향

  • 요청 호환이 깨집니다. 공지 작성·수정 요청에 pinned가 필수로 추가됩니다. [Feat/#103] 게시판(공지) 관리자 API 추가 #104 이후 이 API를 호출하는 클라이언트는 없습니다(관리자 웹은 아직 목업입니다).
  • NoticeService·NoticeRepository에 search가 추가됐고, NoticeCreateCommand·NoticeUpdateCommand에 pinned가 추가됐습니다. 학생 앱 공지 조회는 영향이 없습니다.
  • 스키마 변경·마이그레이션은 없습니다.

🔀 Edge Case & 실패 시나리오

상황 응답
작성·수정에서 pinned 누락 400 INVALID_INPUT ("고정 여부를 입력해 주세요.")
수정 시각이 저장된 값과 다름 409 NOTICE_UPDATE_CONFLICT (이때 pinned도 바뀌지 않음)
목록 size가 1~100 밖 / page 음수 400 INVALID_INPUT
없거나 삭제된 공지 상세 404 NOTICE_NOT_FOUND
공지가 연결한 파일이 삭제됨 상세에서 그 항목만 조용히 빠짐 (학생 앱 상세와 같은 정책)
keyword가 비었거나 공백 조건 없이 전체 조회

📋 검토한 대안과 선택 이유

  • 고정을 PATCH로만 두고 프런트가 등록 후 따로 호출하기: 호출 두 번이 원자적이지 않고, 폼 한 번 저장이 부분적으로만 반영될 수 있어 제외했습니다.
  • pinned를 선택값(미지정이면 유지)으로 받기: 수정이 전체 교체(PUT)라 누락이 곧 의도 불명확한 해제가 될 수 있어서 필수로 했습니다.
  • 학생 앱 조회 API를 관리자 웹이 재사용: pinned와 updatedAt이 없고 제목 검색·페이지네이션도 없어서 제외했습니다.
  • 목록을 커서 방식으로: 관리자 화면은 총 개수와 페이지 이동이 필요해서, 회비 목록처럼 오프셋 방식(PageParams/PageResponse)으로 했습니다.

💬 리뷰 포인트

  • [r] NoticeJpaRepository.search의 JPQL이 dev에서 정상 기동·조회되는지
  • [c] updatedAt 변환이 KST 기준이라는 가정(DateUtil). DB와 앱의 타임존 설정이 코드에 없고, 클라이언트는 상세에서 받은 값을 그대로 되돌려 보내기만 하면 됩니다.
  • [c] pinned를 필수로 둔 것. 선택값으로 바꾸는 게 낫다면 알려주세요.
  • [a] 상세 응답 클래스에 Admin 접두사를 붙인 것(학생 앱 NoticeDetailResponse와 Swagger 스키마 이름이 겹치지 않게)

관리자 웹의 공지 폼이 고정 여부를 등록·수정과 함께 보내고, 수정 화면이 기존 공지와 수정 시각을 불러와야 해서 맞춘다.
@coderabbitai

coderabbitai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Repository: billilge/stream-server/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8cf61da5-b8e7-426f-9ad5-9705f80c7f52
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

게시판(공지) 관리자 API 보완 — 고정 여부 반영, 목록·상세 조회 추가

1 participant