MSG-356 feat: 지도 축소 시 행정 단위 격자 집계 조회 추가 - #144
Merged
Merged
Conversation
Codex 커밋 리뷰 반영. 시도 무상한은 NaN·무한대 fail-open이라 10도 유한 상한+유한성 검증(4401 선행)으로 교체. required=false 근거를 실제 핸들러 동작(누락은 이미 400, 문제는 4405와의 비대칭)으로 정정. 성능은 유계 논증 단정 대신 EXPLAIN(ANALYZE)+1만 행 시드 실측을 완료 조건으로 명시.
동/구/시 단위로 행정동 코드 접두를 잘라 GROUP BY 집계, 좌표 검증(WGS84 범위, NaN·무한대 포함)을 공통 지점으로 승격. 1만 행 시드 전국 시도 집계 EXPLAIN ANALYZE 실행 10.9ms (SLO 300ms 대비 27배 여유).
|
Claude finished @s13121312's task in 5m 8s —— View job 리뷰 완료
확인 범위: 발견
이 외에 P1/P2급 문제는 찾지 못했습니다. 근거:
|
테스트 커버리지
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🎫 관련 티켓
작업 내용
GET /api/grids/aggregation?swLat&swLng&neLat&neLng&unit=DONG|SIGUNGU|SIDO(내 도감)GET /api/friends/{userId}/grids/aggregation(친구 도감, 관계 검증 후 위임)regionCode), 이름, 마커 좌표, 격자 수입니다. 행정동 미판정 격자(격자 중심이 바다에 떨어진 경우 등)는 이름 없는 항목 하나로 포함해, 어느 단위로 세어도 합이 개별 조회 총수와 일치합니다 (프론트가 마커를 더 병합해도 count 합산이 어긋나지 않음).GridQueryService에 4번째 메서드getOccupiedAggregatesInViewport(userId, bounds, unit)를 추가했습니다 (기존 3메서드 불변). 동반 신설:RegionUnit(단위별 코드 접두 길이/이름 토큰/뷰포트 상한 보유),RegionAggregateView,RegionAggregateResponseDto, 에러코드4405 INVALID_AGGREGATION_UNIT.grids.region_code(V5),grids.center_geom(V1),regions.region_name재료만 씁니다.🤔 고민한 내용
묶음 단위: 행정 단위 vs H32/geohash 격자 묶음. 도감은 "어느 동네에 몇 칸"이 곧 정보라 이름 마커("부전2동 31")가 화면 요구인데, 육각형 타일에는 행정 이름을 붙일 수 없습니다(경계에 걸친 타일에 이름을 붙이면 숫자가 거짓이 됨). 다방·직방 등 국내 부동산 지도들의 표준 패턴이 행정 사다리인 것도 실물로 확인했습니다. 격자에 이미 저장된 행정동 코드3의 계층성(앞 2자리 시도, 앞 5자리 시군구) 덕에 매핑 테이블 없이 성립합니다.
핵심 쿼리 (
GridRepository.aggregateOccupiedInRange, native 원문):기존 개별 조회와 FROM·WHERE 술어가 글자 그대로 같아 합산 정합이 구조로 보장됩니다. GROUP BY가 식이 아니라 출력 컬럼 번호(1)인 이유: 같은 substring 식을 두 자리에 쓰면
:codeLen바인딩이 서로 다른 파라미터 자리($1, $6)가 되어 PostgreSQL이 "must appear in the GROUP BY clause"로 거절합니다(실측). regions가 LEFT JOIN인 것도 의도입니다 — INNER면 미판정 격자가 총합에서 사라집니다.성능: 유계 논증(스캔 행이 사용자 점령 격자 수로 제한)에 실측을 더했습니다. 사용자 1인 1만 행 시드, 전국 시야 시도 집계 EXPLAIN ANALYZE4 실행 10.9ms로 기존 뷰포트 SLO(p95 300ms) 대비 27배 여유입니다. 재실측은
GRID_BENCHMARK=true로 벤치 테스트를 실행하면 됩니다.시도 단위 상한을 무상한 대신 10도로: 상한이 없으면 NaN이 모든 비교에서 false라 검증이 fail-open5 됩니다. 마커 대표 좌표는 지역 경계 중심이 아니라 그룹 점령 격자 중심의 평균입니다 — 부산 전체에서 해운대만 채운 사용자의 시 마커가 바다(도시 기하 중심)가 아니라 점령 지점 근처에 서고, 경계 도형이 없는 미판정 버킷에도 같은 규칙이 성립합니다.
👀 리뷰 포인트
validateBounds공통화로 기존 개별·페이지 조회도 NaN 같은 미정의 입력을 빈 결과 대신 4401로 명시 거절하게 됩니다. 정상 입력 계약은 불변임을 기존 회귀 테스트(MSG-73/90 계열 전건 green)로 확인했지만, 소급이 부담스러우면 집계 경로 한정으로 좁힐 수 있습니다.requireFriend후 위임 한 줄이고, 실패는 기존 9424 단일 응답 재사용입니다(신규 에러코드 없음). 이 형태 유지가 맞는지 봐 주세요.regionCode는 있고name만 null인 항목이 나올 수 있습니다. 현 시딩 체계에선 발생하지 않아 코드로 막지 않고 작업 로그에 기록만 했습니다.Footnotes
WGS84: GPS가 쓰는 세계 표준 위경도 좌표계. 위도 -90
90, 경도 -180180이 정의역이다. ↩H3: 우버가 만든 육각형 격자 인덱스. 지구를 크기별 육각형 타일로 나눠 위치 데이터를 묶는 데 쓴다. ↩
행정동 코드: 행정안전부의 10자리 행정동 식별 코드. 앞자리가 상위 행정 단위를 가리켜 코드만 잘라도 시도/시군구로 묶을 수 있다. ↩
EXPLAIN ANALYZE: PostgreSQL이 쿼리를 실제로 실행하면서 실행 계획과 단계별 소요 시간을 보여주는 명령. ↩
fail-open: 검증이 이상 입력을 잡지 못하고 통과시키는 방향으로 뚫리는 것. NaN은 모든 비교가 거짓이라 "상한보다 크지 않다" 검사를 전부 통과한다. ↩