bibimbap/.atp/work-session/20260630-153323/artifacts/handoff-prompt.md

9.1 KiB

작업용 프롬프트 — 클로드 디자인 리디자인 산출물 반영 (새 세션용)

이 문서는 검토 세션(sid 20260630-153323)의 산출물이다. 새 세션에 아래 "프롬프트" 블록을 그대로 붙여넣어 실제 구현을 진행한다. 코드 변경은 새 세션에서 한다.


0. 한 줄 요약

외부 클로드 디자인 툴이 만든 리디자인 산출물(Bibimbap 커뮤니티 웹사이트 리디자인.zip — 7 JSP + bibimbap.css + 3 jspf + error.jsp)을 우리 프로젝트에 반영한다. 단, 파일 통째 교체가 아니라 "공유 bibimbap.css 신설 + 디자인의 클래스/구조 개선을 기존 JSP에 입히는 비주얼 레이어 방식" 으로 한다. 산출물의 라우트·CSRF·include·모델명은 전부 우리 실제와 다르므로 그대로 쓰면 깨진다.

1. 산출물 위치

  • zip: /Users/wemadeplay/Downloads/Bibimbap 커뮤니티 웹사이트 리디자인.zip
  • 압축 해제본(검토 세션이 풀어둠): <scratchpad>/redesign/jsp/... (새 세션에선 zip을 다시 풀어 참조)
  • 구성: jsp/css/bibimbap.css(15KB, 핵심), jsp/01-home.jsp 02-login 03-signup 06-game-detail 07-terms 08-profile 10-recruit-form, jsp/error/error.jsp, jsp/fragments/{posts-empty,recruit-empty,review-comment-form}.jspf. (preview.html은 zip에 없음)

2. 디자인 산출물이 우리 현실과 다른 점 (그대로 쓰면 안 되는 이유)

항목 디자인 가정 우리 실제 (근거)
context path ${ctx} ${pageContext.request.contextPath} (header.jsp:197) — ${ctx} 미정의
header include /WEB-INF/views/common/header.jsp + header가 <html><head>를 연다고 가정 /WEB-INF/views/header.jsp (common/ 없음). header.jsp는 doctype/head 없이 nav 마크업 + 자체 style만(header.jsp:1-20). 각 페이지가 자체 <!DOCTYPE><html><head> 보유
폼 제출 classic <form method=post action=/login> 로그인·회원가입·로그아웃·리뷰·모집은 JSON API + JS AJAX 제출. login.jsp는 window.BibimbapCsrf로 제출(login.jsp:286)
CSRF 토큰 전무 CsrfTokens.getOrCreate(session) → 폼은 hidden <input name="_csrf">(login.jsp:211,224), AJAX는 window.BibimbapCsrf.headers() 헤더(theme-init.jsp:19-27). 상태변경 전부 필수
게임 라우트 /games, /games/{id} (복수) /game/{id} (단수, GameController.java:136). 게임목록 전용 /games 라우트 없음 — 홈 /가 목록(WebMvcController:70)
리뷰/댓글 폼 POST /games/{id}/reviews JSON API /game/{id}/reviews (GET/POST/PUT/DELETE, GameReviewController:73~) — JS로 소비
모집 작성 POST /recruit /recruit/new POST(JSON, location 반환, RecruitController:49). 기존 recruit-form.jsp도 AJAX
프로필/비번찾기 /profile, /password/reset /profile 존재(/{pageName}→profile.jsp). /password/reset 라우트 없음 → 디자인의 "비밀번호 찾기" 링크는 기능 미존재
에러 페이지 error/error.jsp + web.xml <error-page> web.xml 없음(Spring Boot WAR). /error→뷰 errer(오타 파일명 그대로, WebMvcController:47-55), 모델 ${statusCode}
CSS 외부 bibimbap.css link 가정 css/js 디렉토리 미존재. 현재 스타일은 각 페이지/header.jsp 인라인 <style>
폰트 Pretendard·JetBrains Mono (css엔 @import 없음) 프로젝트 제약 "외부 라이브러리 0" → CDN 금지. 미설정 시 system 폰트로 degrade

ALLOWED_PAGES(제너릭 페이지 서버) = error, login, profile, signup, terms, operation-policy, "" (WebMvcController 내). game-detail/recruit/posts는 전용 컨트롤러.

3. 결정된 접근 (사용자 승인됨)

  • CSS: 공유 bibimbap.css 신설src/main/webapp/css/bibimbap.css (Tomcat DefaultServlet 서빙, CLAUDE.md 정책).
  • 파일 통째 교체 금지. 특히 game-detail.jsp(90KB, WebGL 로더·6축 평가·리뷰 CRUD·CSRF 내장) — 디자인 06은 단순 iframe 목업이라 통째 교체 시 기능 소실. CSS 클래스/구조 개선만 이식.
  • 범위: 우선순위 일부부터(아래 5절 순서). 1차 검증 후 확장.

4. 하드 제약 (위반 금지)

  1. 모든 상태변경(폼/AJAX)에 CSRF 적용 — 기존 _csrf hidden 또는 window.BibimbapCsrf 패턴 재사용. 디자인 폼엔 없으니 반드시 추가.
  2. ${ctx}${pageContext.request.contextPath} 치환 (또는 각 페이지 head에 <c:set var="ctx" value="${pageContext.request.contextPath}"/> 1줄 추가 후 유지 — 택1, 일관).
  3. include 경로 common/ 제거 → /WEB-INF/views/header.jsp, footer.jsp. 디자인의 <jsp:include header>(head를 연다는 가정)는 버리고, 기존 페이지의 자체 head 구조 유지.
  4. 외부 라이브러리/CDN 0. 폰트 CDN 추가 금지(system 폰트 fallback 허용, 또는 로컬 폰트 별도 합의).
  5. MyBatis #{} 바인딩, JSP 출력 escape(HtmlUtils.htmlEscape/JSTL), 클라 렌더 textContent — 기존 보안 원칙 유지.
  6. 모델 속성명은 디자인 placeholder(${games},${game.title},${myGames},${reviews} 등)가 아니라 각 페이지 기존 JSP가 실제 쓰는 이름을 사용 — 구현 전 해당 JSP에서 확인.

5. 권장 작업 순서 (단위별 커밋)

  1. bibimbap.css 도입 (최저위험·최고가치): src/main/webapp/css/bibimbap.css 생성(zip의 css 복사, 폰트 줄은 system fallback로 조정). 전 페이지 head에서 로드되도록 theme-init.jsp(각 페이지 head에 include되는지 먼저 확인) 또는 각 페이지 head<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bibimbap.css"> 1줄. header.jsp/기존 인라인 <style>과 클래스 충돌 점검.
  2. Empty-state 파편 3종: posts-empty.jspf·recruit-empty.jspf/WEB-INF/views/fragments/에 두고 posts-list.jsp/recruit-list.jsp의 빈 분기에 include. 라우트는 실제값(/posts/new, /recruit/new)으로 수정.
  3. 홈(index.jsp): 히어로 + 정렬칩 + 등록유도 카드. 모델/라우트는 index.jsp 실제값(홈 /, 검색파라미터 q)에 맞춤.
  4. 로그인/회원가입: 디자인의 pw-toggle·강도막대·일치표시·에러슬롯 마크업/클래스만 기존 login.jsp/signup.jsp에 이식. 제출은 기존 AJAX+window.BibimbapCsrf 유지. /password/reset 링크는 라우트 신설 합의 전까지 비노출.
  5. 약관(terms.jsp): sticky 목차+조항 카드 구조 적용. 본문은 기존 terms.jsp 전문 유지(디자인 전문으로 덮어쓰기 전 차이 확인).
  6. 프로필(profile.jsp): 헤더+내 게임 행+공개토글. 공개토글 action은 실제 게임 visibility API(/game/{id} 계열, GameController 확인)로, CSRF 포함.
  7. 게임상세(game-detail.jsp): ⚠️ 통째 교체 금지. detail-meta 한 줄·16:9 player·review-cta·별점 CSS만 이식, 기존 WebGL/6축/리뷰 로직·CSRF 보존.
  8. errer.jsp: 디자인 error/error.jsp의 empty-state 403/404 마크업을 errer.jsp에 이식, ${statusCode} 분기. 파일명·뷰명 errer 유지(컨트롤러 매핑).
  9. 모집 작성(recruit-form.jsp): 글자수·필수표시·sticky 라이브 미리보기 이식. 제출은 /recruit/new POST + 기존 AJAX/CSRF.

6. 검증 (코드 변경 시 필수)

  • L1: WAR 빌드(./mvnw -q -DskipTests package 또는 프로젝트 표준) 성공 + JSP EL/JSTL 문법 오류 0.
  • L2: 로컬 기동 후 각 변경 화면 스모크 — 로그인/회원가입 제출 동작(CSRF 통과), 게임상세 WebGL 플레이/리뷰 작성, 모집 작성 제출. docs/development/verification-strategies.md 기준.
  • 변경 후 graph-refresh-checker + docs 반영(docs-first).

▶▶ 새 세션에 붙여넣을 프롬프트

/atp:task 클로드 디자인 리디자인 산출물(zip: /Users/wemadeplay/Downloads/Bibimbap 커뮤니티 웹사이트 리디자인.zip)을
우리 프로젝트에 반영한다. 접근은 "파일 통째 교체가 아니라, 공유 src/main/webapp/css/bibimbap.css 신설 +
디자인의 클래스/구조 개선을 기존 WEB-INF/views JSP에 입히는 비주얼 레이어 방식".

검토 세션 핸드오프 문서를 먼저 읽어라: .atp/work-session/20260630-153323/artifacts/handoff-prompt.md
(디자인↔현실 불일치 표, 하드 제약, 작업 순서가 거기 정리돼 있다.)

하드 제약: (1) 모든 상태변경에 CSRF(_csrf hidden 또는 window.BibimbapCsrf) (2) ${ctx} 금지→
${pageContext.request.contextPath} (3) include는 /WEB-INF/views/header.jsp (common/ 없음), 각 페이지
자체 head 유지 (4) 외부 라이브러리/CDN 0 (5) game-detail.jsp 통째 교체 금지(WebGL/6축/리뷰 로직 보존)
(6) 모델 속성명은 디자인 placeholder가 아니라 각 기존 JSP 실제값 사용.

순서: 1) bibimbap.css 도입+head link  2) empty-state 파편 3종  3) 홈  4) 로그인/회원가입(마크업만, 제출은
기존 AJAX 유지)  5) 약관  6) 프로필  7) 게임상세(이식만)  8) errer.jsp(파일명 유지)  9) 모집작성.
각 단위 커밋 + 변경 화면 빌드/스모크 검증.