Skip to content

Feat/admin notice - #181

Closed
isoo127 wants to merge 3 commits into
mainfrom
feat/admin-notice
Closed

isoo127 wants to merge 3 commits into
mainfrom
feat/admin-notice

Conversation

@isoo127

@isoo127 isoo127 commented Sep 23, 2026

Copy link
Copy Markdown
Member

✏️ 작업 개요

어드민에 공지(Notice) 관리 탭을 추가했습니다. 기존 notice 도메인은 조회 API만 있고 데이터를 넣을 수단이 없었는데, 이번에 어드민 화면에서 직접 관리할 수 있게 했습니다.

관리 대상은 세 가지입니다.

  • 공지사항(Announcement) — 앱에 노출되는 공개 공지. 목록·생성·수정·삭제
  • 시스템 정보(SystemInfo) — 앱 필수 버전, 점검 모드
  • 개인 알림(Notice) — 특정 유저에게 1회성 메시지 발송

작업 중 필수 버전을 Android / iOS로 분리했습니다. 스토어 심사 주기가 달라 한쪽만 먼저 배포되는 경우를 기존 단일 컬럼으로는 감당할 수 없었습니다.

🔨 작업 상세 내용

  1. 공지사항 CRUD

    • GET/POST/PATCH/DELETE /admin/notice/announcement 추가
    • 생성 시 EN/KO 섹션을 한 폼에서 입력받아, 채운 언어마다 행을 따로 만들고 만료 시각은 공유합니다. 번역 누락을 막기 위함입니다
    • 같은 언어를 중복으로 보내면 400으로 거부
    • 삭제는 하드 삭제. 만료 시각을 과거로 바꾸면 앱에서는 내려가고 목록에는 Expired 뱃지로 남습니다
  2. 필수 앱 버전 OS별 분리

    • system_info.version → android_version / ios_version
    • GET/PATCH /admin/notice/system 추가
    • POST /api/notice/personal에 platform 파라미터 필수 추가 (ANDROID / IOS). 어느 쪽 버전과 비교할지 서버가 알아야 합니다
    • 응답의 version 필드는 그대로 두고 해당 OS의 요구 버전을 담습니다. 응답 구조 변경 없음
    • 공용 AppPlatform enum 신설 (global/common/domain)
  3. 개인 알림 발송

    • GET /admin/notice/user — 이메일 또는 닉네임 정확 일치로 수신자 조회
    • POST /admin/notice/personal — 메시지 발송
    • 덮어쓰기가 아니라 누적입니다. 유저가 앱을 켜면 쌓인 메시지가 한 번에 내려가고 즉시 삭제됩니다
  4. 어드민 화면 (/admin/notices)

    • 시스템 / 공지사항 / 개인 알림 3개 섹션, 기존 관리자 페이지 컴포넌트 재사용
    • 점검 모드를 켤 때는 확인 다이얼로그를 띄웁니다. 전체 유저를 막는 동작이라 오클릭 방지용
    • i18n 한/영 키 추가
  5. 네비게이션 프래그먼트 정리

    • siteNav(hidePackList, hidePackCreate, hidePuzzleCache, hideCommunityPuzzles) → siteNav(active)
    • 탭을 추가하려면 어차피 호출부 9곳을 모두 고쳐야 해서, 이참에 쓰이지 않던 hidePackCreate 인자를 제거하고 문자열 하나로 바꿨습니다
  6. 보안 설정

    • /admin/notices, /admin/notice/**에 ADMIN 권한 적용
    • 현재 .anyRequest().authenticated()라 명시하지 않으면 일반 로그인 유저도 접근 가능합니다
  7. 테스트

    • NoticeServiceTest — 언어별 행 분리, 중복 언어 거부, 플랫폼별 버전 게이트 교차 검증 등
    • AdminTemplateRenderTest — Spring 없이 Thymeleaf 엔진만 띄워 어드민 템플릿 12개 전체 렌더링. 프래그먼트 시그니처를 바꿨기 때문에 회귀 방지용으로 추가했습니다

💡 생각해볼 문제

  • 배포 시 마이그레이션이 필요합니다. ddl-auto: update는 컬럼을 추가만 하고 값은 복사하지 않습니다. 기존 DB에 그대로 배포하면 새 컬럼이 빈 문자열이 되고, 모든 유저가 강제 업데이트 화면에 갇힙니다. 로컬에서 재현해 확인했습니다.

    UPDATE system_info
    SET android_version = version, ios_version = version
    WHERE id = 1 AND (android_version = '' OR ios_version = '');

    배포 직후 위 SQL을 실행하거나, 어드민 화면에서 버전을 입력하고 저장해도 동일하게 복구됩니다. 신규 DB는 DataInitializer가 채우므로 해당 없습니다.

  • 기존 version 컬럼은 남겨뒀습니다. ddl-auto가 컬럼을 지우지 못해 NOT NULL인 채로 남습니다. 롤백 여지를 고려해 DROP COLUMN은 미뤘는데, 정리 시점을 정하면 좋겠습니다.

@isoo127 isoo127 closed this Sep 23, 2026
@isoo127
isoo127 deleted the feat/admin-notice branch September 23, 2026 05:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants