Skip to content

MSG-581 fix: [모바일] 광역 줌에서 테마 칩 미션 목록 0개 — 요청 bbox를 중심 0.5°로 클램프 - #149

Merged
s13121312 merged 1 commit into
developfrom
fix/MSG-581-mission-bbox-clamp
Sep 7, 2026
Merged

MSG-581 fix: [모바일] 광역 줌에서 테마 칩 미션 목록 0개 — 요청 bbox를 중심 0.5°로 클램프#149
s13121312 merged 1 commit into
developfrom
fix/MSG-581-mission-bbox-clamp

Conversation

@s13121312

@s13121312 s13121312 commented Sep 7, 2026

Copy link
Copy Markdown
Member

🎫 관련 티켓

📌 작업 내용

최대 줌아웃에서 경로추천 경로선이 사라지고, 팝업스토어·지역축제는 집계 마커에 16이 찍히는데 시트는 "없어요"로 0개가 뜨는 문제입니다(사용자 QA 3건). 세 칩이 같은 미션 조회를 쓰므로 원인과 수정이 하나입니다.

원인은 미션 조회가 지도 bbox1 한 변 0.5°를 넘으면 enabled=false로 닫히는 것입니다. MSG-579 전에는 직전 데이터가 남아 가려졌고, MSG-579가 비활성 쿼리의 placeholder2를 비우면서 목록이 빈 배열이 됐습니다. 경로선은 목록에서 파생되므로 함께 사라지고, 집계 마커는 별도 조회가 bbox를 잘라 보내기 때문에 살아 있어 수가 갈렸습니다. 웹은 칩을 켜면 1km 줌으로 고정해 이 경계에 닿지 않는, 앱 전용 결함입니다.

수정은 집계 조회가 이미 쓰는 클램프3를 미션 조회에도 적용한 것입니다.

  • model/mission-query-args.ts: viewportQueryArgs 대신 clampBoundsToSpan(bounds, 0.5°)로 중심 기준 0.5°×0.5°를 잘라 요청하고, 게이트는 칩·bounds null만 봅니다
  • model/mission-query-args.test.ts: 1° 뷰포트가 중심 0.5°로 잘리는 케이스 추가
  • api/active-missions-query.test.ts: MSG-579의 "0.5° 초과면 비움"을 "넓은 bbox 같은 칩이면 유지" + "bounds null이면 비움"으로 치환
  • docs: docs/spec/MSG-581.md · STATUS 2행 · DECISIONS 1행

viewportQueryArgs·canQueryGrids/api/grids·/api/hotzones가 공유하므로 건드리지 않았습니다. 웹·packages·네이티브 0줄.

✅ 체크리스트

  • pnpm lint / pnpm typecheck / pnpm --filter mobile test run 통과
  • 수용 기준 검증 완료 (검증 리포트 요약을 아래에 첨부)
  • 필요한 경우 문서(README, docs/) 업데이트

🔍 검증 요약

게이트 결과
pnpm --filter mobile test run 203 files · 1327 passed
pnpm typecheck / pnpm lint / pnpm format:check 통과
pnpm check:duplication exit 0 (0 families)
diff 범위 apps/mobile/src/features/map-home/ 3파일 + docs. web·packages·native 0
codex 리뷰(브랜치 diff) 지적 0건: "기존 클램프 헬퍼를 일관되게 적용, 칩·인증 게이트 보존"
# 기준 판정 근거
L1 1° 뷰포트 → 중심 0.5°×0.5° bbox, enabled=true 통과 vitest
L2 상한 안 bbox 그대로 · 칩/bounds null → enabled=false 통과 vitest
L3 넓은 bbox 같은 칩 → placeholder 유지 · bounds null → 비움 통과 vitest
L4 게이트 5종 + web/packages diff 0 통과 위 표
S1 최대 줌아웃 + 경로추천: 경로선·번호 마커·코스 카드 통과 스샷 ① — 코스 4개
S2 최대 줌아웃 + 팝업스토어/지역축제 목록 ≠ 0 통과 스샷 ② 16개(마커 16) · ③ 1개(마커 1)
S3 광안리 줌인 경로추천=해파랑길, 칩 전환 시 직전 카드 없음 통과 실기(해파랑길 1코스 + 경로선)
S4 logcat ReactNativeJS 에러 0 · 4xx 0 통과 실기

실기: 두 번째 AVD(FillMap_Pixel8_verify) + 워크트리 Metro 8083(런북 1-D), 번들 grep으로 이 브랜치 코드 실행 확인. iOS 미실행(환경).

📸 스크린샷 (선택)

① S1 — 최대 줌아웃(16km 단) + 경로추천: 코스 4개 + 번호 마커 ② S2 — 최대 줌아웃 + 팝업스토어: 시트 16개 = 집계 마커 "부산 16" ③ S2 — 최대 줌아웃 + 지역축제: 시트 1개 = 집계 마커 "부산 1"
route chip at max zoom-out: 4 courses with numbered markers popup chip at max zoom-out: 16 items, marker 16 festival chip at max zoom-out: 1 item, marker 1

S3(광안리 줌인 해파랑길 1코스 + 경로선) 원본 포함 4장은 _workspace/MSG-581/screenshots/(gitignore).

💡 추가 논의할 사항

  • 목록은 화면 중앙 0.5° 창, 집계 마커는 행정 단위 총계라 최대 줌아웃에서 수가 다를 수 있습니다(이번 실기에서는 16/16, 1/1로 일치). 사용자가 이를 결함으로 보면 "확대 안내" 상태(MSG-579 후속 후보)를 별도 티켓으로.
  • 경로추천 최대 줌아웃은 코스 전체 라인을 한 화면에 그립니다. 현재 서버 코스 수가 한 자리라 성능 영향은 없고, 늘어나면 클리핑이 필요합니다.

https://claude.ai/code/session_01GykigrEHEJm4Ss4jc4QJQR

Footnotes

  1. bbox: 지도에 보이는 영역의 남서·북동 좌표 사각형입니다. 서버는 한 변 0.5°(약 55km)를 넘는 요청을 거부합니다.

  2. placeholder: TanStack Query가 새 응답을 기다리는 동안 대신 보여 주는 값입니다. MSG-579에서 "같은 칩이고 활성일 때만 직전 목록"으로 좁혔습니다.

  3. 클램프: 요청 영역이 상한보다 크면 중심을 기준으로 상한 크기만큼만 잘라 보내는 처리입니다. 집계 마커 조회(grid-aggregation-query.ts)가 이미 같은 방식을 씁니다.

…5°로 클램프

활성 미션 조회가 뷰포트 한 변 0.5° 초과에서 enabled=false였고, MSG-579가 비활성 placeholder를
비우면서 최대 줌아웃에서 목록·경로선이 사라지고 집계 마커(16)와 시트(0)가 갈렸다(세 칩 공통).
mission-query-args가 viewportQueryArgs 대신 clampBoundsToSpan(bounds, 0.5°)로 잘라 요청한다
(집계 조회 선례). viewportQueryArgs·canQueryGrids는 /api/grids·/api/hotzones 공유라 무수정.
테스트: L1 클램프 케이스 신설, MSG-579 "0.5° 초과 → undefined"는 "bounds null → undefined"로 치환.
실기: 두 번째 AVD + Metro 8083, 최대 줌아웃 경로추천 4개·팝업 16/16·지역축제 1/1, logcat 에러 0.

Claude-Session: https://claude.ai/code/session_01GykigrEHEJm4Ss4jc4QJQR
@claude

claude Bot commented Sep 7, 2026

Copy link
Copy Markdown

Claude finished @s13121312's task in 2m 17s —— View job


🔍 코드 리뷰 완료 ✅

작업 목록

  • 컨텍스트 파악 (PR 본문, 변경 파일 목록)
  • 변경 파일 Read로 상세 확인 (mission-query-args.ts, viewport-query.ts, aggregation-unit.ts, active-missions-query.ts, use-active-missions-query.ts, 관련 테스트·docs 전부)
  • 버그/로직 오류 검토
  • TS 베스트 프랙티스 검토
  • 성능/가독성/보안 검토
  • 인라인 코멘트 작성 (지적 사항 없어 생략)
  • 최종 요약 코멘트 게시

결론: 지적 사항 없음. 기존 grid-aggregation-query.tsclampBoundsToSpan 패턴을 미션 조회에 그대로 재사용한 작고 안전한 수정이며, 클램프 수식·게이트 축소·placeholder 분기 모두 테스트로 검증됩니다. 상세 요약은 아래 코멘트에 게시했습니다.

👉 요약 코멘트
· 브랜치 fix/MSG-581-mission-bbox-clamp

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown

React Doctor found no new issues. 🎉

Reviewed by React Doctor for commit 5634a2a.

@claude

claude Bot commented Sep 7, 2026

Copy link
Copy Markdown

🔍 코드 리뷰 요약 (MSG-581)

결론: 지적 사항 없음 — 인라인 코멘트 0건.

검토 범위

mission-query-args.ts(핵심 변경) + viewport-query.ts·aggregation-unit.ts(재사용된 헬퍼) + active-missions-query.ts·use-active-missions-query.ts(소비처) + 테스트 2파일 + docs를 diff만이 아니라 주변 코드까지 Read로 확인했습니다.

잘한 점

  • 기존 패턴 재사용: grid-aggregation-query.ts가 이미 쓰던 clampBoundsToSpan + span cap 클램프 방식을 그대로 미션 조회에 적용 — 새 추상화를 만들지 않고 검증된 선례를 따랐습니다.
  • 클램프 수식 검증: TOO_WIDE(sw 35,128 / ne 36,129, span 1.0°) → 중심(35.5, 128.5) 기준 0.5°로 자르면 (35.25, 128.25)~(35.75, 128.75)인데, 테스트 기댓값과 정확히 일치합니다.
  • 게이트 축소가 정확함: enabled = bounds !== null && chip !== null로 span 체크만 빠지고 null 가드는 그대로 유지 — viewportQueryArgs/canQueryGrids(/api/grids·/api/hotzones 공유)는 건드리지 않아 다른 조회에 영향이 없습니다(grep으로 다른 소비처 없음 확인).
  • placeholder 로직도 함께 갱신: active-missions-query.tsplaceholderData가 "넓은 bbox + 같은 type → 유지" / "bounds null → 비움"으로 정확히 분리되어 MSG-579에서 고친 "칩 전환 시 직전 카드 잔존" 회귀를 재도입하지 않습니다.
  • 테스트 커버리지: L1(클램프 계산)·L2(null 게이트)·L3(placeholder 유지/비움 분기)가 모두 케이스로 존재하고, activeMissionsQueryOptionsenabled 합성(게이트 AND 인증)도 별도 테스트로 덮여 있습니다.
  • 문서: docs/spec/MSG-581.md가 착수 실측→결정→수용 기준→작업 로그까지 자체 완결적으로 기록되어 있고, STATUS/DECISIONS 갱신도 일관됩니다.

확인했지만 문제 없다고 판단한 부분

  • 광역 줌에서 카메라가 이동할 때마다 클램프된 bbox가 매번 바뀌어 refetch가 자주 발생할 수 있는지 확인했으나, mapQueryPolicystaleTime(5s)+keepPreviousData 오버라이드가 이미 grid-aggregation-query와 동일하게 처리하고 있어 이 PR이 새로 만든 문제가 아닙니다.
  • chip === null인데 bounds가 있는 경우 enabled=false이면서도 클램프 계산이 수행되지만, 실제 요청은 나가지 않고 계산 비용도 미미해 문제로 보지 않았습니다.

확실하지 않은 부분: 없음 — 변경 범위가 작고(순수 함수 1개 + 테스트) 기존 검증된 패턴을 그대로 재사용해 리스크가 낮다고 판단했습니다.

@s13121312
s13121312 merged commit 1671ac4 into develop Sep 7, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant