16 KiB
| schema_version | sid | started_at | ended_at | applied_changes | user_request | status | ||||
|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 20260618-121419 | 2026-06-18T12:14:19+09:00 | 2026-06-18T13:05:00+09:00 |
|
새로 추가한 기능(게임 리뷰/댓글, W3-2) 테스트하기 위한 더미 상황이 필요하다: 1. 게임 (dummy game) 2. 계정 (dummy account, 로그인 가능) 3. 이미 등록되어 있는 더미 리뷰 | done |
Summary
W3-2 게임 리뷰/댓글 기능 테스트용 더미 상황을 dev 스키마에 구축. 멱등 seed SQL
(db/seed-dev.sql) + 정리 SQL(db/seed-dev-teardown.sql) 작성 후 가동중 컨테이너
(bibimbap-db)에 적용. 구성: 로그인 가능 테스트 계정 1개(tester@bibimbap.local /
test1234!), 표시되는 더미 게임 1개(테스트 계정 소유), 별점 다양한 더미 리뷰 5개
(각자 다른 더미 유저 — game당 user 1리뷰 unique 제약 충족), 보너스 댓글 3개.
로그인 계정은 해당 게임에 리뷰가 없어 "직접 작성" 테스트도 가능.
핵심 제약 발견: 로그인 password_hash 는 BCrypt 가 아닌 자체 PBKDF2
(pbkdf2_sha256$210000$<saltB64>$<hashB64>, PBKDF2WithHmacSHA256/256bit/16B salt).
저장 해시가 실제 Java UserController.verifyPassword 경로로 검증됨을 JDK 컨테이너에서
교차 실행 확인(verify('test1234!')=true, 오답=false) → 로그인 동작 보장.
Invocations
- research-advisor: 인증 seed 경로 + 리뷰/댓글 유저귀속 + seed 적용경로 조사 (완료)
- artifact: research/index.md (file:line 근거 포함). 결론 = orchestrator 독립 조사와 일치.
- graph-refresh-checker: seed SQL 추가 후 graph staleness 판정 (running)
Decisions
- 적용 방식: 재사용 SQL 파일(db/seed-dev.sql) + 즉시 적용. (사용자 선택, 추천값)
- 로그인 자격: 기본값 tester@bibimbap.local / test1234! / 닉네임 '테스터'. (사용자 선택)
- 규모: 게임 1 + 리뷰 5(별점 5/4/3/5/2). (사용자 선택)
- 설계: 리뷰어는 별도 더미 유저 5명(unique 제약 game당 user 1리뷰 때문). 로그인 계정은 그 게임에 리뷰 없음(작성 테스트 가능). 게임 소유자 = 로그인 계정(getGamesByUserId 도 테스트).
- design/implementation-advisor 스킵: 스키마·계약·컬럼값 완비된 단일 seed SQL → orchestrator 직접 구현.
- 댓글 3개 보너스 포함: 신규 기능이 리뷰/댓글 동시 배치라 같은 더미 상황에 포함이 합리적.
Advisor Invocation Decision Log
- advisor: requirements-advisor decision: skip rationale: '요청 3항목 명확, seed 위치/자격/규모는 orchestrator 가 plan-gate(AskUserQuestion)로 직접 수렴' checked_at: 2026-06-18T12:14:30+09:00
- advisor: research-advisor decision: call rationale: '로그인 가능 계정 seed 위한 password_hash 알고리즘·provider·세션귀속이 미문서화 미지수' checked_at: 2026-06-18T12:15:00+09:00
- advisor: design-advisor decision: skip rationale: 'research 로 컬럼·계약·제약 전부 확정 → 설계 오픈질문 0, orchestrator 직접 설계' checked_at: 2026-06-18T12:30:00+09:00
- advisor: implementation-advisor decision: skip rationale: '단일 SQL 파일 산출, 파일 충돌 없음 → worker 분산 불요' checked_at: 2026-06-18T12:31:00+09:00
- advisor: verification-advisor decision: skip-direct rationale: 'orchestrator 가 매퍼 동등쿼리 + JDK 교차해시검증 + 멱등 재실행을 직접 실행해 AC 충족 확인' checked_at: 2026-06-18T12:45:00+09:00
user_signals
positive: [] negative: []
verified_by_me
- L1 (데이터 무결성 / 매퍼 동등 쿼리, 실 DB 실행):
- login identity 조회(provider=email): tester 1건 + password_hash 존재 → pass
- tester users.status=ACTIVE (로그인 필수 조건) → pass
- getVisibleGames 동등: '테스트 게임 (더미)' is_visible=true 포함 → pass
- listGameReviews(game): 5건, 최신순 정렬 + authorName JOIN 정상 → pass
- getActiveReviewByGameAndUser(game, tester): 0건 → 본인 리뷰 작성 테스트 가능 → pass
- listGameComments(game): 3건 → pass
- L2 (교차구현 해시 검증, 실제 Java verifyPassword 코드 경로, eclipse-temurin:21-jdk):
- verify('test1234!', 저장해시) = true → 로그인 성공 보장
- verify('wrongpass', 저장해시) = false → 음성 케이스 정상
- 멱등성: seed-dev.sql 재실행 후 카운트 불변(users6/games1/reviews5/comments3) → pass
- 로그 스캔: psql ON_ERROR_STOP=1 무에러, NOTICE 정상 → clean
needs_user_verification
- 런타임 UI 스모크 1회 (호스트에 JDK 없음 + bibimbap-app 미가동이라 자동 불가):
docker compose up --build(또는 호스트 실행) 으로 앱 기동- tester@bibimbap.local / test1234! 로 로그인 → 성공 확인
- '테스트 게임 (더미)' 상세 진입 → 기존 리뷰 5건 + 댓글 3건 표시 확인
- 로그인 상태로 리뷰 1건 + 댓글 1건 신규 작성 → 정상 등록 확인
graph_refresh
- 판정: partial-stale (but 본 세션 변경은 fresh).
- 본 세션 변경(db/seed-dev.sql, seed-dev-teardown.sql)은 src/docs graph scope 대상경로 밖 데이터 픽스처 → graph 영향 0, 재생성 불요(no-defer: 본 세션 무액션).
- partial-stale 트리거는 별도 작업단위(W3-2 댓글/리뷰 기능 구현 — GameCommentController/ GameReviewController/GameReviewsMapper/GameReviewData 등, 대부분 untracked). 해당 코드가 미커밋 진행중이라 지금 /graphify src/ 재생성은 시기상조 → open_items 로 권고만 이월하지 않고 "기능 커밋 시점 처리" 로 명시.
post-session-debug (로그인 server error 후속)
- 사용자 보고 "로그인 시 server error(500)". 진단 결과:
- 원인 = stale 앱 인스턴스(pid 59109, 6/17 14:36 기동, 최근 auth 수정 이전 빌드). 내 seed 가 tester 계정을 만들어 처음으로 "계정 존재" 상태 로그인 경로를 타며 표면화.
- 조치: 사용자 동의(직접 캡처 요청) 하에 pid 59109 종료 →
JAVA_HOME=/opt/homebrew/opt/openjdk@21 ./mvnw -P dev spring-boot:run재기동(현재 코드 = target/classes 재컴파일, W3-2 컨트롤러 포함). 로그: /tmp/bibimbap-app.log. 신규 pid 23318 (백그라운드). - 결과:
POST /login200,GET /game/3/reviews200(5건),GET /game/3/comments200(3건),GET /game/3200. 더미 상황 런타임 정상. → needs_user_verification 의 UI 스모크 사실상 완료.
- 발견 버그 (별도 작업단위 = W3-2 댓글기능, 내 seed 무관): 댓글 목록 author 항상 null.
- 근거: GameCommentsMapper.listGameComments 가
nickname AS authorName로 alias → 결과 컬럼authorName인데 GameCommentData 엔nickname프로퍼티만 존재 → 미매핑 → commentView(GameCommentController.java:179)getNickname()null. - 대조: 단건 getGameComment 는
nickname(alias 없음) → 정상. - 1줄 수정안: listGameComments 의
nickname AS authorName→nickname. - 처리: 사용자 요청 시에만 (in-progress 기능 코드라 무단 수정 보류).
- 근거: GameCommentsMapper.listGameComments 가
open_items
- 미커밋 신규 파일: db/seed-dev.sql, db/seed-dev-teardown.sql (작업단위 산출물). 프로젝트/하니스 커밋정책 = 사용자 요청 시에만 커밋 → 커밋 보류, 사용자 확인 대기.
- (별도 작업단위) W3-2 댓글/리뷰 기능 코드 커밋 시
/graphify src/재생성 + docs/graph/index.md frontmatter(source_commit, last_generated_at) + Scopes 표 src 행 갱신 권고. 본 더미데이터 task 범위 밖.
Retrospective
Retrospective:
signals:
positive:
- quote_or_paraphrase: "추천 옵션 전부 수락 (seed 적용방식·자격·규모 plan-gate 선택지 그대로 채택)"
about: "orchestrator 의 plan-gate(AskUserQuestion) 추천값 + research 선행으로 advisor 다수 스킵한 경량 경로"
- quote_or_paraphrase: "재지시·재호출 없이 단일 패스로 수렴 (부정 시그널 0)"
about: "research 1회로 컬럼·계약·제약을 전부 확정 → design/impl/verification advisor 스킵한 판단이 검증됨"
negative: []
what_went_well:
- "research-advisor 선행 1회로 인증 메커니즘(PBKDF2)·유저귀속·seed 적용경로를 모두 확정해, design/implementation/verification advisor 3종을 근거 있게 스킵하고 orchestrator 직접 구현으로 수렴. advisor invocation decision log 에 skip rationale 가 항목별로 남아 사후 추적 가능."
- "호스트에 JDK 가 없는 제약에도 password_hash 를 추정·방치하지 않고 eclipse-temurin:21-jdk 컨테이너에서 실제 verifyPassword 코드 경로로 교차 실행(positive=true / negative=false)해 '로그인 가능' AC 를 자기검증으로 닫음. self-report 가 아닌 실행 증거."
- "schema.sql 이 '비권위 복원본'이라는 메타 한계를 research concerns 에 보존하고, 컬럼명은 매퍼로 교차확인하되 제약·타입은 추정으로 표기해 신뢰도 과대평가를 회피."
- "seed SQL 을 멱등 + teardown 쌍으로 작성하고 재실행 후 카운트 불변을 실증해 반복 적용 안전성을 확보."
- "graph staleness 를 partial-stale 로 정직하게 판정하되, 본 세션 변경(데이터 픽스처)은 graph scope 밖임을 구분해 불필요한 재생성을 회피하고 잔여 stale 은 별도 작업단위로 정확히 귀속."
what_to_improve:
- "런타임 UI 스모크는 호스트 환경 제약(JDK 없음 + 앱 미가동)으로 자동 불가 → needs_user_verification 으로 정확히 이월됨. 개선이라기보다 환경 한계의 정직한 핸드오프. (구조적 결함 아님)"
- "seed SQL 의 제약/타입/default 는 schema.sql 비권위 유래라 실 DB \\d 대조까지는 미수행(행수·테이블존재·매퍼 동등쿼리로만 검증). 운영 DB 와 default 가 다르면 재현 시 불일치 여지 — 현 dev 스키마에선 무영향이나 운영 적용 시 유의."
memory_candidates:
- name: bibimbap-auth-pbkdf2-not-bcrypt
type: reference
description: "bibimbap 로그인 해시는 BCrypt 가 아닌 자체 PBKDF2 — 로그인 가능 더미/테스트 계정 seed 시 이 포맷으로 직접 생성해야 함"
body_draft: |
# bibimbap 인증: PBKDF2 자체 해시 (BCrypt 아님)
Spring Security 미사용. 로그인은 UserController 자체 구현 password 검증.
password_hash 포맷: `pbkdf2_sha256$210000$<base64(salt)>$<base64(hash)>` ($ 4필드)
- 알고리즘 PBKDF2WithHmacSHA256, iterations=210000, keyLength=256bit, salt=16byte SecureRandom
- 검증 경로: UserController.verifyPassword (parts[0]=="pbkdf2_sha256" && len==4 확인 후 동일 iter/salt 재계산, MessageDigest.isEqual 상수시간 비교)
## Why
외부 BCrypt 생성기로 만든 해시는 무효 — 형식 자체가 다름. 향후 로그인 가능 더미/테스트/관리자 계정을
seed 할 때마다 이 함정에 반복적으로 부딪힌다. 코드로 유도는 가능하나 "BCrypt 일 것"이라는 기본 가정이
강해 매번 재확인 비용이 든다.
## How to apply
- 로그인 가능 계정 seed 시 위 PBKDF2 스펙으로 해시 문자열을 직접 생성.
- 로그인 동작 보장은 실제 verifyPassword 코드 경로(JDK 컨테이너 교차 실행 등)로 positive/negative 둘 다 확인.
- 로그인 필수 조건 동봉: users.status='ACTIVE', user_auth_identities.provider='email',
provider_user_id=정규화(trim+lowercase) 이메일, 양쪽 is_delete=false.
rationale_for_saving: "코드로만 드러나는 비자명 사실(BCrypt 아님)이고, 테스트/더미 계정 seed 마다 재발하는 함정. schema/git log 로는 '자체 PBKDF2 라서 외부 생성기 무효'라는 함의가 드러나지 않음."
signal_source: observation
docs_sync_target: /Users/wemadeplay/workspace/stz/bibimbap/CLAUDE.md
- name: bibimbap-seed-blueprint-fk-and-unique
type: reference
description: "dev 스키마 더미 seed 청사진 — FK 순서 + game_reviews active-unique 제약(게임당 user 1리뷰)"
body_draft: |
# bibimbap dev 더미 seed 청사진
현실적 경로 = dev 스키마에 psql 직접 INSERT (UI 경유는 CSRF+세션+WebGL 업로드 강제로 고비용).
DB 직삽은 CSRF·세션·중복선검사를 우회하되 FK·CHECK·유니크idx 는 그대로 적용.
INSERT 순서(FK 의존):
1. users (status='ACTIVE' 필수, role='USER', is_delete=false, display_name 권장)
2. user_auth_identities (PBKDF2 password_hash — 별도 memory 참조; provider='email')
3. games (user_id FK, name; is_visible/is_delete default 로 목록노출 충족; webgl/thumbnail NULL 가능)
4. game_reviews (game_id, user_id, rating 1~5, body)
5. game_comments (game_id, user_id, nickname[직접 채움 — 조회가 users JOIN 안 함], content)
## 핵심 제약
- game_reviews 부분 유니크 idx `(game_id, user_id) WHERE is_delete IS NOT TRUE`
→ 한 게임에 더미 리뷰 N개 = 더미 유저 N명 필요 (한 user 는 게임당 활성 1리뷰).
- game_comments 는 유니크 없음 → 자유 다수. 작성자명 보이려면 nickname 직접 채움(비정규화 저장).
- 게임 목록+상세 노출 = games.is_visible=true, games.is_delete=false, 연결 users.is_delete=false.
## Why
리뷰 N개를 같은 유저로 넣으려다 유니크 위반으로 막히는 게 첫 시도의 흔한 실패. schema.sql 이
'비권위 복원본'이라 제약을 코드에서 직접 읽기 전엔 드러나지 않음.
## How to apply
- seed SQL 확정 직전 `\d dev.<table>` 로 제약/타입/default 운영 대조 권장(schema.sql 비권위).
- 리뷰 다양화가 목표면 더미 유저를 리뷰 수만큼 선행 INSERT.
rationale_for_saving: "seed 설계 시 반복되는 유니크-위반 함정 + FK 순서. schema.sql 비권위라 코드 교차확인 없이는 유도 불가하고, 더미/픽스처 작업마다 재사용되는 청사진."
signal_source: observation
docs_sync_target: null
- name: java-crypto-verify-via-jdk-container-when-no-host-jdk
type: feedback
description: "호스트에 JDK 없을 때 Java 암호/검증 로직을 eclipse-temurin:21-jdk 컨테이너 single-file 실행으로 교차검증"
body_draft: |
# 호스트 JDK 부재 시 Java 로직 교차검증 패턴
호스트에 JDK 가 없고 앱도 미가동인 환경에서, password_hash 같은 Java 암호/검증 로직의
정합성을 추정으로 닫지 않고 `eclipse-temurin:21-jdk` 컨테이너에 single-file/javac 로
실제 코드 경로(예: verifyPassword)를 옮겨 실행해 positive+negative 케이스를 모두 확인.
## Why
seed 한 해시가 "로그인 된다"는 self-report 는 증거가 아니다. 실제 검증 함수와 동일한
알고리즘/iter/salt 로 재계산해 true/false 가 나와야 AC 가 닫힌다. 호스트 toolchain 부재는
검증 생략의 이유가 되지 않고, 컨테이너로 우회 가능하다.
## How to apply
- 검증 대상 메서드의 알고리즘 파라미터(iter/keyLength/salt/encoding)를 코드에서 그대로 추출.
- 동일 로직을 단일 .java 로 재현해 temurin 컨테이너에서 실행, 정답=true / 오답=false 둘 다 확인.
- 런타임 UI 스모크처럼 컨테이너로도 불가한 부분만 needs_user_verification 으로 이월.
rationale_for_saving: "환경 제약(호스트 JDK 없음) + Java 검증 로직이라는 비자명 조합. self-report 대신 실행 증거로 AC 를 닫는 재현성 있는 검증 워크플로우 — 단발 우발 아님."
signal_source: positive
docs_sync_target: /Users/wemadeplay/workspace/stz/bibimbap/docs/development/verification-strategies.md
protocol_feedback: [] applied_changes: []