bibimbap/docs/changes/2026-06-18-w3-2-comments-re...

5.9 KiB

kind title session_id created_at status related_security_checklist related_work_log related_design
change W3-2 댓글/리뷰 분리 구현 20260618-104034 2026-06-18 implemented ../security/security-remediation-checklist.md ../work-log/2026-06-17-w3-feature-skeletons.md ../../.atp/work-session/20260618-104034/design.md

W3-2 댓글/리뷰 분리 구현 변경 이력

상위 골자: W3 사이트 플랫폼 기능 골자 카탈로그 §W3-2.

개요

기존 game_comments(닉네임 자유입력, localStorage 전용)를 서버 영속화 + 로그인 연동으로 전환하고, 별점 5점 + 서술 평가 형태의 game_reviews 도메인을 신설했다.

변경된 런타임 동작

1. 댓글 서버 영속화 전환

  • 이전: 댓글이 localStorage에만 저장. game_comments 매퍼·테이블은 고아 상태.
  • 이후: 댓글이 서버 DB game_comments에 영속. 새로고침·브라우저 변경 후에도 유지.
  • 기존 localStorage 댓글은 마이그레이션하지 않음(보안 [hold] 정합 — QG-2 결정).
  • game_comments.user_id bigint NULL FK 추가(비파괴, 레거시 nickname 레코드 보존).
  • content 200자 앱레벨 검증 신규 적용(이전: 길이 제한 없음).

2. game_reviews 도메인 신설

  • 신규 테이블 game_reviews: 게임당 1회 제한(partial UNIQUE WHERE is_delete IS NOT TRUE), rating smallint CHECK(1~5), body text.
  • "수정됨" 상태: in-row(updated_at > created_at). 별도 이력 테이블 없음(열람 권한 확정 시 후속).
  • 삭제: soft-delete(is_delete, deleted_at).

3. 권한 모델

  • 댓글/리뷰 수정·삭제: 작성자 본인(sessionUserId == 리소스.userId) OR 운영자(ROLE_ADMIN="ADMIN").
  • 운영자 role 부여 경로는 W1 RBAC 연결 시 활성(현재 휴면 — 부여자 없음).
  • 로그인 없는 쓰기 시도: 401.
  • CSRF 토큰 없는 상태 변경: 403.

4. 게임 삭제 cascade 확장

  • GameController.deleteGamesoftDeleteGameReviews 추가.
  • 게임 삭제 시 관련 리뷰도 soft-delete.

신규/변경 파일

신규 파일 (백엔드)

파일 설명
src/.../data/GameReviewData.java 리뷰 도메인 POJO
src/.../mapper/GameReviewsMapper.java 리뷰 MyBatis 매퍼
src/.../controller/api/GameCommentController.java 댓글 CRUD API (C1~C4)
src/.../controller/api/GameReviewController.java 리뷰 CRUD API (R1~R5)
docs/game-reviews-ddl.sql 권위 DDL (멱등 ALTER, 기존 DB 적용용)
src/test/.../GameCommentControllerTest.java 댓글 컨트롤러 단위 테스트 12건
src/test/.../GameReviewControllerTest.java 리뷰 컨트롤러 단위 테스트 13건

변경 파일

파일 변경 내용
src/.../data/GameCommentData.java userId 필드 추가
src/.../mapper/GameCommentsMapper.java user_id 기반 쿼리 확장
src/.../mapper/GamesMapper.java softDeleteGameReviews 추가
src/.../controller/api/GameController.java deleteGame cascade 확장, currentUserId/userRole 모델 노출
db/schema.sql game_reviews CREATE + game_comments user_id ALTER
src/main/webapp/WEB-INF/views/game-detail.jsp 댓글 localStorage→서버 fetch 교체, 리뷰 UI 신규(별점 위젯·수정됨 마커·게임당1회·로그인 게이트)
src/test/.../BibimbapApplicationTests.java GameCommentsMapper/GameReviewsMapper @MockBean 2개 추가

신규 API 9개

댓글 (GameCommentController)

ID 메서드 경로 설명
C1 GET /game/{id}/comments 댓글 목록 조회
C2 POST /game/{id}/comments 댓글 작성 (CSRF·로그인·200자 검증)
C3 PUT /game/{id}/comments/{commentId} 댓글 수정 (작성자/운영자)
C4 DELETE /game/{id}/comments/{commentId} 댓글 삭제 (작성자/운영자)

리뷰 (GameReviewController)

ID 메서드 경로 설명
R1 GET /game/{id}/reviews 리뷰 목록 조회
R2 GET /game/{id}/reviews/{reviewId} 리뷰 단건 조회
R3 POST /game/{id}/reviews 리뷰 작성 (게임당 1회, CSRF·로그인·rating 검증)
R4 PUT /game/{id}/reviews/{reviewId} 리뷰 수정 (수정됨 마커, 작성자/운영자)
R5 DELETE /game/{id}/reviews/{reviewId} 리뷰 삭제 (soft-delete, 작성자/운영자)

모든 상태 변경 API 공통 시퀀스: @Transactional → CsrfTokens.isValid (403) → sessionUserId (401) → 검증 (400) → mapper → JSON.

범위 밖 (미변경)

  • 좋아요: 여전히 localStorage 전용. 보안 체크리스트 B3 좋아요 항목 별도 관리.
  • 운영자 role 부여: ROLE_ADMIN 상수 정의만. 실제 부여 경로는 W1 RBAC 연결 시.
  • W2-3 집계 계약: game_reviews가 평점 공급원(rating 컬럼)까지만. AVG/COUNT 집계·뷰 미생성(W2-6 시상 후속).
  • 리뷰 이력 열람: in-row 수정됨 마커만. 이력 테이블은 열람 권한 확정 시 후속.

검증 결과 요약

레이어 결과
L1 단위 테스트 (31건) PASS (GameCommentControllerTest 12 + GameReviewControllerTest 13 + UserControllerCsrfTest 5 + BibimbapApplicationTests 1)
AGG-1 엔드포인트 수 PASS (Comment 4, Review 5)
AGG-3 CSRF 게이트 PASS (합산 6개)
AGG-2 DDL 3종 PASS
L3 브라우저 스모크 needs_user_verification
DDL 적용 needs_user_verification (docs/game-reviews-ddl.sql 참조)

이월 항목

  1. W2-3 평점 집계 계약 (SELECT AVG/COUNT) — W2-6 시상 후속.
  2. 운영자 role 부여 경로 — W1 RBAC/Interceptor 연결 시 활성.
  3. 다축(육각형) 평점 — 현재 단일 rating, game_review_axes 분리 여지(주석).
  4. 리뷰 이력 열람 권한 — 열람 정책 확정 시 별도 이력 테이블.
  5. GameCatalog 정적 폴백 게임 대상 댓글/리뷰 — DB 실제 게임만 기능 동작(폴백은 404).