Files
sodalive-backend-spring-boot/docs/20261030_공지사항예약공개/client-prompt.md
T

6.7 KiB

관리자 공지 예약 공개 API 연동 작업

아래 요구사항에 따라 기존 ADMIN 공지사항 생성·수정 화면의 API 연동을 변경하세요. 이 작업은 기존 화면에 예약 공개 입력과 처리만 추가하며 화면을 새로 설계하지 않습니다. 아래 API 계약을 기준으로 작업하며 실제 연결은 대상 API 사용 가능 여부를 확인한다.

작업 범위

  • 기존 공지 생성과 수정 기능에 선택적 예약 공개 시각 publishAt 입력과 전송을 추가합니다.
  • API 요청·응답 및 화면 상태 연결만 다룹니다. 서버 구현이나 서버 설정을 변경하지 않습니다.
  • 기존 화면 구조와 사용자 동작을 유지하고, 필요한 API 연동만 수정합니다.

공통 계약

  • 기존 ADMIN Bearer 인증을 재사용합니다. 새 인증 흐름이나 권한 체계를 만들지 않습니다.
  • 성공은 ApiResponse의 success, message, data, errorProperty envelope로 판별합니다. HTTP 200이어도 success: false면 실패입니다.
  • 오류 응답의 기존 필드를 보존하고, 사용자에게는 응답 message를 표시합니다. 인증 오류는 기존 로그인 흐름을 따릅니다.
  • 시각 문자열은 모두 Asia/Seoul 기준 yyyy-MM-dd HH:mm:ss입니다. T, Z, offset, 밀리초를 포함하지 않습니다.
  • 브라우저 시간대를 거쳐 변환하거나 KST 시각을 다시 변환하지 않습니다. 표시·입력한 시각을 그대로 계약 형식으로 보내 이중 시간대 이동을 막습니다.

생성

POST /notice

요청 필드: title, content, 선택 필드 publishAt (string | null).

{
  "title": "서비스 점검 안내",
  "content": "점검 시간과 안내 내용",
  "publishAt": "2026-11-15 09:00:00"
}
  • publishAt 생략 또는 null은 즉시 공개입니다.
  • 미래의 유효한 시각 문자열은 예약 공개입니다. 예시 시각은 실제 요청 시점보다 미래여야 합니다.
  • 현재 또는 과거 시각은 허용하지 않습니다. 오류를 정상 성공처럼 처리하지 않습니다.
  • 요청에 isScheduled, createdAt, isActive를 추가하지 않습니다. 생성 성공 응답의 data는 숫자 공지 ID입니다.

수정

PUT /notice

요청 필드: 필수 id, 선택 title, content, publishAt (string | null).

{
  "id": 42,
  "publishAt": "2026-11-20 10:30:00"
}
  • publishAt 생략은 기존 예약 상태를 보존합니다. 제목만 또는 본문만 수정할 때도 이 규칙을 따릅니다.
  • 명시적 null은 아직 공개되지 않은 예약 공지를 지금 공개하겠다는 의도일 때만 보냅니다.
  • 미래 시각 문자열은 아직 공개되지 않은 예약 공지의 예약 시각을 변경합니다. 시각만 변경하는 요청도 유효합니다.
  • 이미 공개된 공지는 제목·본문 수정은 허용되지만 공개 시각 변경은 허용되지 않습니다. 그런 요청의 API 실패를 존중하고 우회하거나 재시도하지 않습니다.
  • 제목만 수정할 때 폼에 조회한 publishAt 값이 있어도 요청에서 반드시 생략합니다. 기본값 null을 무심코 직렬화하지 말고, 사용자가 즉시 공개 전환을 명시한 경우에만 publishAt: null을 보냅니다.
  • 수정 성공 시 data의 구체적인 값에 의존하지 않습니다. success를 확인한 뒤 목록을 다시 조회합니다.

관리자 목록

GET /api/v2/admin/notices?page=0&size=20

기존 ADMIN 인증을 사용합니다. 공개된 항목만 반환하는 공개 공지 API를 대신 사용하지 않습니다. ADMIN 토큰으로 공개 API를 호출해도 예약 공개 전 공지는 반환되지 않습니다.

응답 data 형식:

{
  "totalCount": 1,
  "noticeList": [
    {
      "id": 42,
      "title": "서비스 점검 안내",
      "content": "점검 시간과 안내 내용",
      "isActive": true,
      "isScheduled": true,
      "publishAt": "2026-11-15 09:00:00",
      "createdAt": "2026-10-30 14:20:00"
    }
  ]
}

각 항목은 id, title, content, isActive, isScheduled, publishAt, createdAt을 가집니다. publishAt은 공개 시각 문자열 또는 null이며, 예약을 즉시 공개로 전환한 항목에는 전환 시각이 들어 있습니다. null은 시각을 지정하지 않고 즉시 등록한 공지입니다. 목록에는 활성 공개 공지와 아직 공개되지 않은 활성 예약 공지가 모두 포함됩니다. 페이지 인덱스는 0부터 시작하고 totalCount는 이 관리자 목록의 전체 대상 건수입니다.

별도의 공지 상세 API는 없습니다. 편집 시 목록에서 받은 전체 항목을 사용하고, 존재하지 않는 상세 경로를 만들지 않습니다.

날짜 표시와 목록 갱신

  • 예약 공개 공지의 날짜 표시는 publishAt의 KST 날짜를 사용합니다.
  • 즉시 생성된 공지와 예약에서 즉시 공개로 전환한 공지의 날짜 표시는 원래 등록 시각인 createdAt의 KST 날짜를 사용합니다.
  • isScheduled는 응답 전용 표시 상태이며 요청에 보내지 않습니다. 예약이 자연 공개된 뒤에도 true일 수 있으므로 이를 미공개 여부로 해석하지 않습니다. isScheduled와 미래 publishAt을 함께 화면 동작 판단에 참고할 수 있지만, 공개 경계를 최종 판단하는 주체는 API입니다. 클라이언트 시계나 이 불리언만으로 공개 상태를 확정하거나 API 거부를 무시하지 않습니다.
  • 생성·수정 성공 후 목록을 다시 조회합니다. 응답은 공개 시각 내림차순, 같은 시각이면 ID 내림차순입니다. 이 순서를 유지하고 표시 날짜를 기준으로 클라이언트에서 재정렬하지 않습니다. 특히 예약을 즉시 공개로 전환한 경우 표시 날짜는 원래 등록일이지만 목록 순서는 공개 시각 변경에 따라 달라질 수 있습니다.
  • 목록을 불러오거나 저장할 수 없을 때 임의의 공개 API로 자동 대체하지 않습니다. API 실패를 보존해 기존 오류 흐름으로 처리합니다.

완료 확인

  • 생성에서 publishAt 생략/null은 즉시 공개, 미래 시각은 예약 요청으로 전달됩니다.
  • 수정에서 publishAt 생략은 보존, 명시적 null은 의도된 즉시 전환, 미래 시각은 재예약으로 전달됩니다. 제목만 수정할 때 publishAt은 생략됩니다.
  • 관리자 목록은 위 경로와 페이지 파라미터를 사용하며 응답의 success를 확인하고 목록 순서를 유지합니다.
  • 모든 시각 요청·표시는 KST yyyy-MM-dd HH:mm:ss이며 브라우저 시간대 변환을 추가하지 않습니다.