7.9 KiB
7.9 KiB
| phase | agent | agent_version | generated_at | concerns | concerns_checked | source_confidence | workers_spawned | |
|---|---|---|---|---|---|---|---|---|
| research | research-advisor | 2 | 2026-06-29T06:17:17Z |
|
true | mixed | 4 |
조사 결과 — 게임 "좋아요" 카운트 버그 근본 원인
주제
게임 상세페이지에서 좋아요를 누르면 토글은 되지만, explore(탐색) 페이지로 가면 좋아요 수가 올라가지 않는다. 코드에서 근본 원인을 확정한다.
포인트별 발견
포인트 1: 좋아요 토글 엔드포인트 — 서버 핸들러 자체가 없음
- 경로:
src/main/java/com/pandoli365/bibimbap/controller/api/GameController.java,.../mapper/GameLikesMapper.java,src/main/webapp/WEB-INF/views/game-detail.jsp - 요약: 게임 좋아요 토글을 처리하는 서버 엔드포인트가 존재하지 않는다. GameController 매핑은
/game/new(POST),/game/{id}(GET),/game/{id}/edit(GET/POST),/game/{id}(DELETE)뿐이며 좋아요용 POST/PUT/DELETE 핸들러가 없다.addGameLike/updateGameLike/getGameLike(GameLikesMapper) 매퍼 메서드는 src 전체에서 호출자 0건(dead code). 상세 JSP 의 좋아요 버튼은 완전히 클라이언트 사이드로,localStorage('bibimbap-game-liked') 만 토글하고 화면 카운트를baseLikes + (liked ? 1 : 0)로 다시 그릴 뿐 어떤 서버 fetch/ajax 도 호출하지 않는다. (advisor 직접 확인: game-detail.jsp:1480-1485 클릭 핸들러는setLiked()+syncLike()만 호출.) - 관련 파일:라인:
- GameController.java:63,132,169,196,268 (매핑 전체 — 좋아요 토글 매핑 없음)
- GameLikesMapper.java:22,34,43 (getGameLike/addGameLike(INSERT INTO game_likes)/updateGameLike — 호출자 0건)
- game-detail.jsp:1401-1408 (setLiked → localStorage 기록), :1473-1478 (syncLike → 로컬 ±1), :1480-1485 (클릭 핸들러, 서버 요청 없음)
- 신뢰도: 확인됨
포인트 1-b: GamesMapper 에 like_count 증감 UPDATE 메서드 부재
- 요약: GamesMapper 에
incrementLikeCount/updateLikeCount/SET like_count류 UPDATE 메서드가 존재하지 않는다(검색 0 hit). UPDATE games 문은updateGame(L149-164)과softDeleteGame(L192-200) 둘뿐이며 어느 것도like_count를 SET 하지 않는다. like_count 는 SELECT 절에만 등장. - 관련 파일:라인: GamesMapper.java:149-164, 192-200; increment 류 검색 0 hit
- 신뢰도: 확인됨
포인트 2: explore 목록 like 수 출처 — games.like_count 컬럼 직접 SELECT
- 요약: 목록 조회 5개 메서드(getVisibleGames, searchVisibleGames, listVisibleKeyset, searchVisibleKeyset, searchGamesAdvanced) 전부
g.like_count AS likeCount(FROM games g)로 컬럼을 직접 SELECT한다. 어느 메서드도game_likes테이블을 COUNT 조인/서브쿼리로 집계하지 않는다.game_likes가 GamesMapper 에서 참조되는 곳은 게임 삭제용deleteGameLikes(DELETE)뿐.sort='likes'정렬도ORDER BY g.like_count DESC, g.id DESC(L247)로 컬럼 사용. - 관련 파일:라인: GamesMapper.java:51 / 75 / 206 / 275 / 312 (각 메서드 SELECT 절의
g.like_count AS likeCount), :186-190 (deleteGameLikes) - 신뢰도: 확인됨
포인트 3: 상세페이지 like 수 출처 — 동일하게 games.like_count 컬럼
- 요약: 상세 페이지도 explore 와 같은 출처(games.like_count 컬럼)를 읽는다.
GET /game/{id}핸들러가gamesMapper.getGame(id)로 조회 →getGameSQL 은g.like_count AS likeCount(games g JOIN users u 만, game_likes 미참조) →addGameModel이game.getLikeCount()로 꺼내likeCount/likeCountFormatted모델 속성으로 주입 → JSP 가var baseLikes = ${likeCount};로 기준선 사용. 좋아요 클릭 후 갱신은 서버 재조회가 아니라 로컬 JS 증감(baseLikes ±1) 일 뿐이다. - 관련 파일:라인: GameController.java:132,135,138,304,309-310; GamesMapper.java:28 (getGame
g.like_count AS likeCount, JOIN users u 만); game-detail.jsp:1248(초기 표시), :1386(baseLikes), :1477(로컬 증감) - 신뢰도: 확인됨
포인트 4: DDL/스키마
- 경로:
db/schema.sql(단일 부트스트랩 파일) - 요약:
games.like_count컬럼은 존재한다 —"like_count" integer DEFAULT 0 NOT NULL(schema.sql:95).game_likes테이블은 id(bigint PK), game_id(bigint NOT NULL FK→games), user_key(varchar(200) NOT NULL), created_at(timestamptz DEFAULT now()) 4컬럼,(game_id, user_key)UNIQUE 제약 없음(검색 0 hit). 단, schema.sql 헤더(4-11행)에 games/game_likes 는 "비권위 복원본 — 매퍼/POJO 에서 역추출, 타입·기본값·제약은 추론값" 경고가 명시. - 관련 파일:라인: db/schema.sql:95(like_count), :253-261(game_likes), :4-11(비권위 경고)
- 신뢰도: 컬럼 존재 여부=확인됨 / default·NOT NULL·UNIQUE부재=추정(비권위 복원본, 운영 pg_dump 미대조)
종합 판단
네 포인트가 일관되게 수렴한다. explore 와 상세는 동일한 출처(games.like_count 컬럼)를 읽으며, 둘 다 실시간 game_likes COUNT 집계를 쓰지 않는다. 따라서 버그는 "explore 와 상세의 출처가 다르다"가 아니라 좋아요 토글이 어떤 영속 저장소(DB)에도 쓰이지 않는다는 데 있다.
근본 원인 가설
1순위 (확정에 가까움): 좋아요는 DB 에 전혀 기록되지 않고 브라우저 localStorage 에만 저장된다.
- 상세 페이지 좋아요 버튼은 서버 엔드포인트를 호출하지 않고 localStorage('bibimbap-game-liked')만 토글한다(game-detail.jsp:1480-1485, 1401-1408). 좋아요 토글 서버 핸들러가 애초에 없다(GameController 매핑 0개, GameLikesMapper 호출자 0건).
- 그 결과
games.like_count컬럼도,game_likes행도 갱신되지 않는다(GamesMapper 에 increment UPDATE 부재). explore 목록은games.like_count컬럼을 읽으므로 영원히 올라가지 않는다. - 증상 정합: 상세에서 "토글되어 보이는" 것은 같은 브라우저의 localStorage + 로컬 ±1 표시(baseLikes+1)일 뿐이고, explore(다른 페이지/다른 사용자/새로고침 후 DB값)에는 반영되지 않는다. 사용자가 보고한 "상세는 올라가 보이는데 explore 는 안 올라간다"와 정확히 일치.
- 근거: GameController.java:63/132/169/196/268, GameLikesMapper.java:22/34/43(호출자 0), GamesMapper increment 부재, game-detail.jsp:1473-1485, GamesMapper.java:51/75/206/275/312(explore=컬럼) + :28(상세=컬럼).
2순위 (1순위에 포섭되는 보조 가설): 좋아요 영속화 백엔드 배선이 미완성/dead code 로 남아있다.
- GameLikesMapper(addGameLike/updateGameLike/getGameLike)와 games.like_count 컬럼은 좋아요를 DB 에 영속화하려던 설계 흔적이지만 컨트롤러/서비스 배선이 없어 dead code 다. 즉 기능이 "절반만 구현"된 상태. 만약 과거에 배선이 있었다면 회귀로 끊겼을 가능성(git 이력 확인은 본 조사 범위 밖).
- 근거: GameLikesMapper.java:22/34/43(정의는 있으나 호출 0), GamesMapper.java:95(like_count 컬럼 존재) vs increment UPDATE 부재.
두 가설은 배타적이지 않다 — 1순위가 현상의 직접 원인이고, 2순위는 그 구조적 배경(미완성 영속화 계층)이다.
미해결
- 과거에 좋아요 영속화 배선(서버 토글 엔드포인트)이 존재했다가 제거/회귀된 것인지 여부 — git 이력 추적은 본 조사 범위 밖. (필요 시 후속 조사)
games.like_count의 운영 DB 실제 default/제약,game_likes (game_id,user_key)UNIQUE 존재 여부 — schema.sql 이 비권위 복원본이라 미확정. 운영 pg_dump 대조 전 권위 데이터로 승격 금지.- index.jsp:843, profile.jsp:509 도
game.getLikeCount()(=컬럼)를 표시하나, 이 두 화면의 like 표시 정합성은 본 조사 4포인트 밖(관찰만).