공지사항

NOTICE · /notice

실제 화면 열기 ↗
기능
5
API 호출
1
가드레일
4
id 가 테스트 이름
구현 단계
5 / 5
완료커뮤니티wvctesol-api :8080서버 컴포넌트58

개발 스펙

이 화면에서 할 수 있어야 하는 것 (4)

  • 공지 목록을 페이지 단위로 본다(588건).
  • 제목 · 내용 · 작성자로 검색한다.
  • 최신순 / 조회순으로 정렬을 바꾼다.
  • 상단 고정 공지가 먼저 보인다.

비즈니스 규칙 (4)

  • 정렬은 항상 고정공지(notice desc) 가 우선이고, 그 다음이 선택한 정렬이다.
    근거: nt_list.php:33 — order by nt_notice desc, {정렬} desc
  • 정렬 파라미터는 화이트리스트로 제한한다. 허용값 외에는 기본값으로 되돌린다.
    근거: nt_list.php:9
  • 검색은 제목 · 내용 · 작성자를 함께 본다(LIKE).
    근거: nt_list.php:19
  • 작성자명은 admin 테이블에서 조인해 가져온다.
    근거: nt_list.php:33 서브쿼리

API (1)

메서드경로권한모듈 · 설명
GET/api/community/notices공개
공지 목록.
domains:community:community-web
요청: ?page=1&size=15&keyword=&sort=latest|hits
응답: { items: [{ id, title, writer, hit, pinned, regdate }], total, page, size }

가드레일 (4) — id 가 곧 테스트 이름이다

id반드시 만족해야 하는 것등급
board-sort-whitelist
정렬 파라미터에 임의 컬럼명을 넣어도 SQL 에 그대로 들어가면 안 된다.
원본은 문자열을 그대로 order by 에 붙였다. 화이트리스트가 유일한 방어였다.
critical
board-search-injection-safe
검색어에 따옴표·SQL 예약어를 넣어도 정상 동작하고 오류가 나면 안 된다.
critical
notice-pinned-first
고정 공지는 정렬 방식과 무관하게 항상 목록 맨 위에 있어야 한다.
high
board-paging-bounds
page=0, page=-1, 범위를 넘는 page 에도 오류 없이 빈 목록이나 첫 페이지를 돌려줘야 한다.
high

구현 계획 (5/5)

  1. BoardType · BoardSort · BoardPost · BoardRepositorycommunity-domain
  2. BoardQueryUseCase — 목록·상세 공용community-app
  3. BoardTable · BoardRepositoryAdaptercommunity-infrastructure
  4. /api/community/notices 구현community-web
  5. Next.js 를 BFF 로 전환 — Prisma 직접 접근 제거wvctesol

서버 사이드 구현 계획 — 자바 객체별 요구사항 (5/5)

객체모듈책임 · 지켜야 할 것
BoardType
enum
community-domain
게시판 종류.
  • 경로로 받은 문자열은 이 열거형으로만 해석한다 — 임의 값이 테이블 이름이 되지 않는다.
  • 알 수 없는 값은 400 INVALID_BOARD.
BoardSort
enum
community-domain
정렬 기준. 열거형이 곧 화이트리스트다.
  • 원본은 정렬 문자열을 order by 에 그대로 붙였다. 여기서는 문자열이 SQL 로 흘러갈 길 자체를 없앤다.
  • 알 수 없는 값은 오류가 아니라 조용히 기본 정렬로 되돌린다.
BoardTable
record
community-infrastructure
게시판별 테이블·컬럼 차이를 모아 둔 곳.
  • 노출 플래그 이름이 제각각이고 값도 대소문자가 섞여 있다(pass_note 는 Y/N, faq 는 y/n) — upper() 로 맞춘다.
  • 공지만 고정 컬럼이, 수기·후기만 이미지가, Q&A 만 답변이 있다.
  • SQL 에 들어가는 식별자는 이 레코드가 정한 값뿐이다.
BoardRepositoryAdapter
class
community-infrastructure
다섯 테이블을 하나의 포트로 조회.
  • 구조가 거의 같아 엔티티를 다섯 벌 만들지 않고 네이티브 쿼리로 묶었다.
  • 검색어는 반드시 바인딩 파라미터로 넘긴다. 문자열 이어붙이기 금지.
  • 숨긴 글은 목록과 상세 양쪽에서 제외한다 — 상세만 빠뜨리면 id 로 뚫린다.
BoardQueryUseCase
service
community-app
목록·상세 조회.
  • PageRequest 가 page 0·음수·과대를 다듬는다. 오류를 내지 않는다.
  • 상세는 조회수를 정확히 1 올린다.

테스트 방법 (4)

가드레일종류확인 방법
board-sort-whiteliste2esort=nt_title;drop 같은 값으로 목록 요청 → 200 이고 기본 정렬로 동작
board-search-injection-safee2ekeyword=' OR 1=1 -- 로 검색 → 200 이고 결과가 전체가 되지 않음
notice-pinned-firste2e조회순 정렬에서도 고정 공지가 첫 행
board-paging-boundse2epage=0 · page=-1 · page=99999 각각 200 응답

스냅샷

NOTICE 스냅샷

기능 목록 (5)

데이터
  • ·API 조회/api/community/notices
  • ·조회 조건page, keyword, orderby
입력
  • ·1개
  • ·제출 버튼1개
  • ·입력 필드1개

화면 이동

← 이 화면으로 오는 곳
이 화면에서 가는 곳 →

연결

API
  • /api/community/notices
소스
src/app/notice/page.tsx