bibimbap/docs/work-log/2026-06-17-w3-feature-skele...

15 KiB
Raw Blame History

kind title description status source_roadmap source_session confirmed_session confirmed_at created_at owner
work-log W3 사이트 플랫폼 — 기능별 골자 카탈로그 W3(사이트 플랫폼 워크스트림) 5개 서브기능(W3-1 태그+검색 / W3-2 댓글·리뷰 / W3-3 포스팅 보드 / W3-4 메인 허브 / W3-5 Unity업로드 deferred)의 골자. 기능당 목적·핵심동작·결합/의존·미결질문·후속진입점. 윤곽 카탈로그 깊이 — 미결질문 해소 안 하고 남김. 당장 구현 아님, 착수 전 굳혀두는 기획 메모. confirmed 2026-06-17-jam-platform-roadmap.md 20260617-172407 20260617-174635 2026-06-18 2026-06-17 art

W3 사이트 플랫폼 — 기능별 골자 카탈로그

상위 로드맵: 2026-06-17-jam-platform-roadmap.md §W3.

깊이: 윤곽 카탈로그. 기능당 목적·핵심동작·결합/의존·미결질문·후속진입점만 굳혀둔다. DDL/API 계약/시퀀스는 기능별 착수(design) 단계에서. 미결질문은 해소하지 않고 남긴다 — 골자의 목적은 "무엇을/왜 + 무엇이 미결인지"를 1페이지로 굳히는 것. 당장 구현 아님.

W3 전부 잼 일정 독립(독립 출시 가능). 게임잼(W2)은 W3 기능의 소비자 중 하나일 뿐.


코드 현황 (착수 전 확인된 결합점)

골자의 "결합/의존" 정확도를 위해 현 코드베이스를 대조했다. file 근거:

  1. games 테이블 (GamesMapper.java) — id, user_id, name, creator_note, git_url, webgl_path, thumbnail_url, like_count, is_visible, sort_order, created_at, updated_at. 태그 컬럼 없음. 검색은 name/creator_note ILIKE 방식만.
  2. game_comments (GameCommentsMapper.java) — id, game_id, nickname(자유입력), content, created_at, deleted_at, is_delete. 로그인 연동 없음. content 길이 제한 없음. review 테이블·tag 테이블 모두 없음 → W3-1·W3-2 구조 전부 신규.
  3. 권한 인프라UserData.role 필드 존재, UserControllerROLE_USER="USER" 상수만. Interceptor 클래스 없음 (WebMvcConfigurer 구현체에 addInterceptors 없음). W3-3 포스터 게이트가 얹힐 자리 미비 → W1 의존 강화.
  4. index.jsp — 게임 카드 그리드 + 텍스트 검색(ILIKE) 단일 섹션. 잼 출품작 노출 없음.
  5. WebGL 업로드 (GameUploadController.java) — /api/game-files/webgl-zip 이미 구현. zip-slip 방어·엔트리 수 상한(8000)·압축 해제 크기 상한(512MB)·UUID 기반 /game/{uuid}/ 배치 적용. 단 (a) 로그인 체크만, 권한 체크 없음 (b) /game/** 정적 핸들러가 UploadResourceConfig.java 에 미등록/profile/** 만 등록. → 서빙 경로 동작 미보장(QG-3, 의도/버그 미확인).

기능별 골자

W3-1 — 태그 + 검색

  • 목적: 일반 게임 발견성 향상이 1차. 잼 용도(진행 회차 강조, 이전 회차 검색)는 부수.
  • 핵심 동작: 게임/잼에 태그를 붙이고 태그로 필터 검색(기존 텍스트 검색과 병행). 개발자(제작자) 검색 지원. 정렬은 태그 일치도 가중 × 2차 정렬키(좋아요/최신/방문수/리뷰수/점수).
  • 결합/의존:
    • C1: 신규 tags + 조인테이블 필요(현 코드에 태그 구조 없음). — 코드사실
    • C2: 잼 전용 태그 연결은 W2 게임잼 엔티티 선행 의존.
    • C3: 게임 태그 기본 기능은 W2 무관 독립 착수 가능. 단 정렬 일부는 의존 — 리뷰수·점수 정렬은 W3-2, 방문수 정렬은 신규 조회수 인프라.
    • C4: GamesMapper.searchVisibleGames ILIKE 쿼리 확장 필요. — 코드사실
    • C5: 방문수 정렬 → 신규 조회수 카운터 필요(games 에 like_count만, 조회수 컬럼 없음). — 코드사실
    • C6: 리뷰수·점수 정렬 → W3-2(game_reviews) 의존. 정렬 점수의 정확한 의미(단일 평점 vs 다축)는 W3-2 설계 종속.
    • C7: 개발자 검색 → games.user_id ↔ user 조인 확장.
    • 태그 테이블 구조: 통합 1테이블 + 용도 구분(게임 공용/잼 전용) 권장. 잼 태그 요건(W2) 확정 시 분리 재검토.
  • 미결질문 (합의된 방향 + 잔여):
    • Q1 태그 관리: 출시는 운영자 사전정의, 구조는 혼합(운영자 사전정의 + 사용자 생성) 지원. 잔여: 사용자 생성 태그 개방 시점·승인 흐름.
    • Q2 제한·허용: 태그당 게임 수·게임당 태그 수 제한 없음. 허용 조건은 보안(주입·XSS sanitize) + 욕설/금칙어 필터 통과. 잔여: 태그명 길이·허용 문자셋 구체값, 금칙어 사전 출처.
    • Q3 테이블 구조: 통합 1테이블 채택(위 결합/의존). 잔여: 잼 태그 요건 확정 시 분리 여부.
    • Q4 정렬: 태그 미선택=최신순(기본), 태그 미선택+좋아요=전체 좋아요순, 태그 선택=태그 일치도 가중+2차키(최신/좋아요/방문수/리뷰수/점수). 잔여: 태그 일치도 가중 계산·동률 처리는 design 단계.
    • Q5 다중 태그·개발자 검색: 다중 태그 AND/OR 지원 + 개발자(제작자) 검색 추가. 잔여: AND/OR 노출·입력 방식은 design 단계.
  • 후속 진입점: design-advisor

W3-2 — 댓글 / 리뷰 분리

  • 목적: 모든 게임 페이지 일반 기능. 잼 평가기간 게이트 없음, 잼 독립.
  • 핵심 동작: 기존 game_comments(닉네임 자유입력)를 로그인 사용자 연동 댓글로 전환 + 별도 리뷰(게임당 1회) 신설. 리뷰 = 별점 5점 평점 + 서술 평가, 다축(육각형 레이더)은 후속 확장 여지. W2-6 시상이 리뷰 평점을 단방향 집계. 댓글 content 200자 제한 신규.
  • 결합/의존:
    • ①: game_comments 기존 존재 — 닉네임 자유입력, 로그인 연동 없음 → 로그인 연동 전환 시 기존 데이터 처리 결정 필요. — 코드사실
    • ②: game_reviews 신규 (review 테이블 없음). — 코드사실
    • ③: W2-6 시상이 리뷰 평점을 단방향 집계 → W2-3(평가 통합설계) 동결과 정합 필요. — 해석
    • ④: 댓글 content 200자 제한 신규 (현 game_comments content 길이 제한 없음). — 코드사실
    • ⑤: W3-1 의 리뷰수·점수 정렬이 W3-2(평점·리뷰수)에 의존 — W3-1 C6 의 역방향. — 신규
  • 미결질문 (합의된 방향 + 잔여):
    • Q1 기존 닉네임 레코드 처리: 미결로 유지 (전체수준 QG-2 사안 — 골자 단계 해소 보류).
    • Q2 댓글 수정·삭제 권한: 작성자 본인 + 운영자. 잔여: updateGameComment 권한 체크 신규 적용 범위는 design.
    • Q3 평점 척도: 별점 5점(초기 단일), 다축(육각형) 후속 확장 여지. 잔여: 다축 시 축 구성·완성도/종합 분리 여부는 design.
    • Q4 리뷰 수정: 수정 가능 + 이력 보존, 노출은 "수정됨" 마커만 표시. 잔여: 이력 열람 권한은 design.
    • Q5 W2-3 평점 집계 계약: W2-3 동결 후 정합 (W3-2 선확정 안 함).
    • Q6 (신규) 리뷰 단위: 업데이트 단위 분리 여부 + 나눠도 통합 평점 여부 — 미결 유지.
  • 후속 진입점: design-advisor (W2-3 진행 연계 확인 후)

W3-3 — 포스팅 보드

  • 목적: 사이트 공지·블로그 + 외부링크 큐레이션. 별도 메뉴, 잼 무관 독립 채널.
  • 핵심 동작: 포스터 권한자(W1 RBAC 부여)만 작성, 일반 유저 읽기만(댓글 없음). 카테고리는 운영자가 추가/수정/삭제 가능(DB 저장). 본문은 마크다운 류 여러 서식(sanitize). 외부링크 큐레이션은 OG 미리보기 포함. 유니티블로그는 고정 카테고리가 아니라 외부 피드(레퍼런스) 감시 — 새 글 게시 감지 후 알림 형태로 별도 취급.
  • 결합/의존:
    • C1: W1 선행 필요UserData.role 존재하나 Interceptor 미구현. 권한 게이트 인프라가 W1 에서 구현돼야 함. — 코드사실
    • C2: posts/board_posts 신규.
    • C3: RecruitPostsMapper/RecruitController 유사 게시판 패턴 참고 가능. — 코드사실(참고)
    • C4: (신규) 외부 fetch 인프라 — OG 미리보기 + 유니티블로그 피드 감시 → SSRF 방어·캐싱·실패처리·폴링 필요. — 신규
  • 미결질문 (합의된 방향 + 잔여):
    • Q1 착수 시점: W1 완료 후 착수 (임시 role 직접 체크 안 함). → 전체수준 QG-1 의 W3-3 부분 결정. (W3-5 권한 부분은 여전히 미결)
    • Q2 카테고리 저장: DB 저장 (운영자 추가/수정/삭제 가능).
    • Q3 외부링크: OG 미리보기 포함. 잔여: SSRF 방어·캐싱·실패처리 방식은 design.
    • Q4 본문 형식: 마크다운 류 여러 서식(sanitize). 잔여: 허용 서식 범위·sanitize 정책은 design.
    • Q5 댓글 부착: 붙이지 않음 (읽기 전용 채널). → W3-2 결합 없음.
    • Q6 (신규) 유니티블로그 외부 피드 감시: 새 글 게시 감지 → 알림 형태. 미결: 확인 방식(RSS/폴링)·알림 표면·갱신 주기.
  • 후속 진입점: design-advisor (W1 진행 확인 선행)

W3-4 — 메인페이지 (게임 허브)

  • 목적: index.jsp 를 게임 허브로 확장 + 진행 중 잼 안내. 포스팅은 별도 메뉴(메인 통합 아님).
  • 핵심 동작: 평소엔 현 게임 카드 그리드 전체 노출(현 정렬 유지). 진행 중 잼 있을 때만 검색창 아래에 "게임잼 진행 중" 안내 + 신규 출품작 강조, 클릭 시 게임잼 태그 검색(W3-1)으로 이동. (별도 잼 섹션 그리드 아님.) 페이지네이션/무한스크롤 도입.
  • 결합/의존:
    • C1: 현 index.jspGamesMapper.getVisibleGames()/searchVisibleGames() 단일 소스. — 코드사실
    • C2: 잼 노출(검색창 아래 안내·신규작 강조·클릭 라우팅) = W2(잼 엔티티·진행 상태) + W3-1(잼 태그 검색) 의존. — 신규/해석
    • C3: 일반 게임 허브 개선(페이지네이션·그리드)은 W2/W3-1 무관 독립.
  • 미결질문 (합의된 방향 + 잔여):
    • Q1 잼 노출 조건: 진행 중 잼 있을 때만.
    • Q2 노출 형태: 별도 그리드 섹션 대신 검색창 아래 안내 배너 + 신규작 강조 → 클릭 시 잼 태그 검색. 평소 전체 게임 그대로. (별도 그리드 없어 중복 노출 문제 해소)
    • Q3 정렬·추천: 현 정렬 유지(sort_order ASC + created_at DESC). 인기순은 후속.
    • Q4 페이지네이션: 도입. 잔여: 페이지네이션 vs 무한스크롤 택은 design.
    • Q5 단계 착수: 단계 착수 가능 — 일반 허브(페이지네이션·그리드) 먼저, 잼 안내는 W2+W3-1 후.
  • 후속 진입점: design-advisor

W3-5 — Unity WebGL 빌드 업로드 자동화 ⏸ deferred

골자 아님 — 선행 조사 스텁. 조사 완료 후 골자/설계 진입.

  • 목적: 일반 게임 호스팅 자동화. 현 수동 호스팅 대체. 게임잼 무관 인프라.
  • 현황: 업로드 로직 부분 구현 존재(위 코드현황 5). zip-slip·크기상한·UUID 배치 됨. 권한 체크 없음 + /game/** 정적 핸들러 미등록.
  • 선행 조사 항목:
    • zip-slip 방어 충분성 — 현 target.startsWith(targetDir) 외 심볼릭 링크·인코딩 우회 케이스.
    • WebGL 빌드 포맷 검증 범위 — index.html 외 필수 파일(Build/*.data, *.wasm, *.js) 존재 검증.
    • 업로드 크기/타입 — zip 원본 크기 상한, Content-Type MIME+확장자 이중 체크 여부.
    • 저장 경로 boundary — app.upload.game-storage-path 외부 주입 시 경계 검증.
    • /game/** 정적 핸들러 미등록 — 서빙 동작 미보장(QG-3).
    • 업로드 권한 게이트 — 현 로그인만, 권한 제한 없음.
    • UUID 재사용 시 기존 레코드 덮어쓰기/삭제 정책.
  • 착수 전 합의(이번 세션): 조사 항목 7개 그대로 유지. 업로드 권한 게이트는 QG-1 미결로 유지(조사 단계 확정). QG-3(/game/** 핸들러)는 코드 확인을 조사 단계로 미룸.
  • 후속 진입점: research-advisor → (조사 후) design-advisor

워크스트림 결합 요약

기능 결합 대상 결합 방식 독립 출시
W3-1 태그+검색 W2(잼 태그) + W3-2(리뷰수·점수 정렬) + 조회수 인프라(방문수 정렬) 잼 태그·정렬 일부 의존, 게임 태그 코어는 독립 부분 (게임 태그 코어 먼저)
W3-2 댓글/리뷰 W2-6(시상 집계) + W2-3(평점 계약 정합) + W3-1(정렬이 평점·리뷰수 소비) 리뷰 평점을 W2-6 단방향 집계, W3-1 정렬이 역참조 가능 (댓글·리뷰 코어 독립, 평점 집계 계약은 W2-3 동결 후)
W3-3 포스팅 보드 W1(포스터 권한/인터셉터) + 외부 fetch 인프라(OG·유니티블로그 피드) 권한 게이트 의존, W1 완료 후 착수(임시 체크 안 함) W1 선행
W3-4 메인 허브 W2(잼 엔티티·진행 상태) + W3-1(잼 태그 검색 라우팅) 잼 안내·신규작 강조→잼 태그 검색 의존, 일반 허브는 독립 부분 (일반 허브 먼저, 잼 안내는 W2+W3-1 후)
W3-5 WebGL 자동화 없음 (일반 인프라) 독립 deferred (조사 선행)

착수 순서 제언 (단정 아님 — 이번 세션 합의)

의존 사슬: W3-2(평점 공급) → W3-1(정렬이 평점 소비) → W3-4(잼 안내가 잼 태그 검색으로 라우팅). W3-3·W3-5 는 W1 권한 게이트 선행.

  1. W3-2 댓글/리뷰 — 기존 game_comments 확장, 코어 완전 독립, 착수 비용 최소. 다른 기능의 평점 공급원. 평점 집계 계약만 W2-3 동결 후 정합.
  2. W3-1 태그+검색 — W3-2 뒤에 오면 리뷰수·점수 정렬까지 완성. 게임 태그 코어는 독립, 정렬 일부는 W3-2·조회수 인프라 의존.
  3. W3-4 메인 허브 (일반 부분 먼저) — 페이지네이션·그리드 개선은 독립 선착수. 잼 안내(검색창 아래 배너→잼 태그 검색)는 W2+W3-1 후.
  4. W3-3 포스팅 — W1 Interceptor 선행(임시 체크 안 함 확정). OG·유니티블로그 외부 fetch 인프라 동반.
  5. W3-5 WebGL 자동화 — deferred, 선행 조사 완료 후.

전체 수준 미결질문 (착수 전 확정 필요)

  • QG-1: W1 인터셉터 완료 시점과 권한 게이트 착수. W3-3 은 W1 완료 후 착수(임시 role 직접 체크 안 함)로 확정. W3-5 업로드 권한은 미결 유지(조사 단계 확정). 잔여: W1 지연 시 W3-5 임시 체크 허용 여부.
  • QG-2: W3-2 기존 닉네임 자유입력 레코드 처리 — 마이그레이션/유지/레거시 표시. 미결 유지 확정(골자 단계 해소 보류).
  • QG-3: W3-5 /game/** 정적 핸들러 미등록이 의도인지 버그인지 — 현 WebGL 서빙 실제 동작 확인 필요. 코드 확인을 조사 단계로 미룸 확정.

다음 단계

골자 합의 완료(이번 세션 — 5기능 + 착수 순서). 각 기능을 실제 착수할 때 위 "후속 진입점" advisor 로 진입한다. 착수 전 해당 기능의 잔여 미결 + 관련 QG 를 먼저 확정한다. 착수 1순위 = W3-2 로 확정.