Skip to content

[global] todo 백로그 16건 처리 (방·세션·안정성)#44

Merged
Sean-mn merged 14 commits into
developfrom
feat/todo-backlog
Jun 11, 2026
Merged

[global] todo 백로그 16건 처리 (방·세션·안정성)#44
Sean-mn merged 14 commits into
developfrom
feat/todo-backlog

Conversation

@Sean-mn

@Sean-mn Sean-mn commented Jun 11, 2026

Copy link
Copy Markdown
Member

개요

2026-06-11 코드 분석으로 정리한 todo 백로그 16건(fix 7 / feat 5 / refactor 4)을 전체 처리하였습니다. 방 생명주기 관리 기능을 확장하고, 매치메이킹 흐름의 결함을 수정하였으며, 세션 정책과 코드 정리를 함께 진행하였습니다.

변경사항

신규 기능 (feat)

  • 방 나가기(POST /leave) 및 방 닫기(POST /close) API를 추가하였습니다. 방 닫기는 호스트만 가능하도록 검증합니다.
  • 호스트 하트비트(POST /heartbeat) API와 유령 방 정리 백그라운드 잡을 추가하였습니다. 하트비트가 끊긴 방은 주기적으로 정리되며, 주기와 타임아웃은 RoomCleanup 설정으로 제어합니다.
  • 방 목록 조회에 페이지네이션을 추가하였습니다.
  • 방 조회/참가 응답에 MaxPlayers, SteamLobbyId를 포함하도록 응답 DTO를 보강하였습니다.

버그 수정 (fix)

  • 방 참가 응답에 SteamLobbyId가 반환되지 않아 P2P 연결이 불가능하던 문제를 수정하였습니다.
  • 전역 단일 버킷이던 레이트리밋을 클라이언트별 파티션 정책으로 교체하였습니다.
  • 비밀번호 검증을 IsPrivate 플래그가 아닌 PasswordHash 유무 기준으로 전환하였습니다.
  • 방 참가자(게스트)를 추적하여 중복 참가를 방지하고, 요청 DTO 입력 검증을 추가하였습니다.
  • 방 코드 유니크 충돌 시 새 코드로 재시도하도록 수정하였습니다.
  • I/O 경로 전체에 CancellationToken을 전파하였습니다.

리팩터링 (refactor)

  • 유저당 단일 세션 정책을 적용하여 재로그인 시 기존 세션을 무효화하도록 변경하였습니다.
  • 미사용 코드를 정리하고 GetAllRoomService의 응답 DTO 경계를 정비하였습니다.

기타

  • AddRoomGuestHeartbeatAndLengthLimits 마이그레이션을 추가하였습니다 (게스트/하트비트 컬럼, 문자열 길이 제한).
  • 신규 서비스 및 정책 변경에 대한 단위 테스트를 추가·갱신하였습니다.
  • 처리 완료된 todo 백로그 문서를 삭제하고 디렉터리 구조를 복원하였습니다.

참고

  • 호스트 이관(feat 05)은 별도 구현 대신 "호스트 이탈 시 방 닫힘" 정책으로 결정되었습니다.
  • 정책 변경의 상세 배경은 각 구현 커밋 메시지를 참고해 주시기 바랍니다.

Sean-mn added 13 commits June 11, 2026 14:35
- JoinRoom이 JoinRoomResult/JoinRoomResponse로 SteamLobbyId 반환 (fix 01)
- 단건/목록 조회 응답에 MaxPlayers 추가 (feat 04)
- GetAllRoomService가 응답 DTO 대신 GetRoomResult를 반환하고
  컨트롤러에서 매핑하도록 경계 정리 (refactor 03)
- IsPrivate는 방 목록 노출 여부만 의미, 비밀번호는 공개/비공개 무관 설정 가능
- join 검증을 IsPrivate에서 PasswordHash != null 기준으로 변경해
  비밀번호 없는 비공개 방 참가 시 null 해시 BCrypt 500 오류 제거
- 방 목록 조회에서 비공개 방 제외 (idx_room_status_private 활용)
- 단건/목록 조회 응답에 HasPassword 노출
- 전역 단일 카운터(AddFixedWindowLimiter)를 AddPolicy +
  RateLimitPartition.GetFixedWindowLimiter로 교체
- login은 클라이언트 IP, create_room/join_room은 Session-Id 헤더
  (없으면 IP fallback) 기준으로 파티셔닝
- 파티션 키 헬퍼 단위 테스트 추가 (InternalsVisibleTo)
- room에 guest_steam_id 추가, TryJoinAsync로 게스트 점유와 인원 증가를
  원자적으로 처리 (중복 참가·호스트 본인 참가 차단)
- JoinRoomCommand에 SteamId 추가, AlreadyJoinedRoomException 신설
- RoomName ≤50자, Nickname ≤32자 검증 (서비스 레벨 도메인 예외)
- room_name/nickname 컬럼 길이 제한 + last_heartbeat_at 선반영
  마이그레이션 (AddRoomGuestHeartbeatAndLengthLimits)
- POST api/v1/room/{roomCode}/leave — 게스트 퇴장(조건부 감소로 0 미만
  방지), 호스트가 나가면 방 자동 Close (호스트 이관 없음 정책 확정)
- DELETE api/v1/room/{roomCode} — 호스트만 방 Close 가능
- CloseAsync에 Active 조건 추가로 멱등 처리
- LeaveRoomService/CloseRoomService 및 단위 테스트 추가
- POST api/v1/room/{roomCode}/heartbeat — 호스트만 LastHeartbeatAt 갱신
- StaleRoomCleanupService(BackgroundService)가 주기적으로 하트비트가
  끊긴 Active 방을 set-based 쿼리로 일괄 Close (하트비트 없으면
  CreatedAt 기준)
- 주기/타임아웃은 RoomCleanup 설정 섹션으로 주입, TimeProvider 사용
- RoomRepository.CreateAsync가 PostgreSQL 23505(UniqueViolation)를
  DuplicateRoomCodeException으로 변환 (Npgsql 의존을 Repository에 격리)
- CreateRoomService가 최대 3회 새 코드로 재시도, 소진 시
  RoomCodeGenerationFailedException(500)
- GET api/v1/room/all에 page/size 쿼리 파라미터 (size 상한 50)
- size+1 조회 방식으로 count 쿼리 없이 hasNext 판별
- 응답에 page, size, hasNext 포함
- ICacheStore/CacheStore 전 메서드에 ct 추가, IDistributedCache로 전달
- ISessionService.CreateAsync/GetAsync에 ct 추가, DeleteAsync도 실제 전달
- IAuthTicketValidator.ValidateAsync에 ct 추가, Steam HTTP 호출에 전달
- LoginService·SessionAuthorizeAttribute 호출부에서 ct 전달
- CacheKey.Session.BySteamId 역인덱스 키 추가
- 재로그인 시 기존 세션을 삭제 후 새 세션 발급 (탈취된 구 세션 무효화)
- 로그아웃 시 역인덱스가 현재 세션을 가리킬 때만 함께 정리
- SessionServiceTests 신규 추가
- Room.MarkDeleting / RoomStatus.Deleting 삭제 (즉시 Close 정책 채택으로
  불필요, DB에 Deleting 값 없음)
- User.UpdateNickname / UpdateLastLogin 삭제 (set-based UpdateAsync 유지)
- 관련 RoomTests/UserTests 정리, 닉네임 검증은 생성자 테스트로 대체
- docs/todo/README.md에 전 항목 처리 결과와 정책 변경 비고 기록
전 항목이 feat/todo-backlog 브랜치에서 구현 완료되어 백로그 문서를
제거한다. 정책 변경 내역(IsPrivate=목록 노출 여부, 호스트 leave=자동
Close 등)은 각 구현 커밋 메시지에 기록되어 있다.
완료된 백로그 문서는 삭제하되 docs/todo 골격과 우선순위 범례,
처리 이력은 README로 유지한다.
@Sean-mn Sean-mn added bug:버그 Something isn't working enhancement:개선사항 New feature or request labels Jun 11, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several key features and improvements to the matchmaking backend, including room leaving, closing, and heartbeat functionalities, along with a background cleanup service (StaleRoomCleanupService) for stale rooms. It also implements single-session enforcement per user, room code collision retries, pagination for room listings, and proper CancellationToken propagation across I/O paths. Feedback on these changes highlights a security vulnerability in the rate limiter where unvalidated Session-Id headers can bypass limits, and suggests a performance optimization to initialize LastHeartbeatAt to CreatedAt to avoid index-blocking COALESCE operations during stale room cleanup queries.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread PushAndPull/PushAndPull/Global/Config/RateLimitConfig.cs Outdated
Comment thread PushAndPull/PushAndPull/Domain/Room/Entity/Room.cs
Comment thread PushAndPull/PushAndPull/Domain/Room/Repository/RoomRepository.cs
클라이언트가 Session-Id 헤더 값을 바꿔가며 요청하면 파티션이 무한히
생성되어 레이트리밋이 우회되는 문제를 수정한다. 리뷰 지적(PR #44) 반영.
@Sean-mn
Sean-mn merged commit 3e3a0cd into develop Jun 11, 2026
3 checks passed
@Sean-mn
Sean-mn deleted the feat/todo-backlog branch June 11, 2026 06:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug:버그 Something isn't working enhancement:개선사항 New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant