MSG-600 feat: 행사 위치 영역 상한을 81칸에서 2,500칸으로 올린다 - #286
Merged
Merged
Conversation
|
Claude finished @s13121312's task in 2m 13s —— View job 리뷰 완료
확인한 범위
발견된 P1/P2/P3 이슈 없음. |
테스트 커버리지
|
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.
🎫 관련 티켓
작업 내용
행사 운영자가 등재 신청에서 위치 하나에 그릴 수 있는 격자 칸1 수 상한을 81칸에서 2,500칸으로 올렸다. 판정 방식(사각형 합집합2)과 에러 응답(developCode 13432, HTTP 400)은 그대로이고 값과 안내 문구만 바뀐다. 스키마, API 표면, 에러코드 변경은 없다.
RepresentativeGridResolver.MAX_CELLS_PER_LOCATION(2,500) 한 곳으로 모았다. 행사 위치 시더와 신청 접수 검증이 각자 들고 있던 상수(2,500과 81)를 지우고 이 값을 참조한다. 위치당 사각형 개수 상한도 같은 상수에 묶여 함께 오른다.Math.multiplyExact와Math.addExact로 바꿨다. 넘치면 조용한 오답이 아니라ArithmeticException으로 드러난다(아래 고민한 내용).docs/prd/event-submission.mdv2.4(FR-24 개정, 결정 기록), 스펙docs/spec/MSG-600.md신규,docs/spec/MSG-498.md의 현행 계약 서술 갱신, SRS FR-EVENT-13 구현됨, RTM 재생성,.claude/docs/status.md.변경 파일 22개(문서 7, main 11, test 4). 테스트는 검증 경계값과 재제출, 겹침, 사각형 2,500개, 이벤트 참여형 위치, 위치 20개 접수, 컨트롤러 2,501칸, 리졸버 2건(5만 칸 결정성, 오버플로 예외), 승인 통합 1건(mission_grids 50,000행과 대표 격자)을 추가하거나 고쳤다. 마커는
// 검증: FR-EVENT-13, AC-600-NN이다../gradlew build(CI와 같은 이미지의 임시 PostGIS)flowchart LR A[행사 운영자 신청<br/>사각형 목록] --> B{사각형 하나가<br/>2,500칸 초과?} B -- 예 --> X1[13432 거부<br/>전개 없이] B -- 아니오 --> C[Set으로 전개<br/>겹침은 한 번만] C --> D{합집합 > 2,500?} D -- 예 --> X1 D -- 아니오 --> E[접수, 대표 격자 계산] E --> F[관리자 승인] F --> G[전 위치 합집합<br/>최대 20 × 2,500 = 50,000칸] G --> H[대표 격자 재계산<br/>exact 산술, 넘치면 예외] H --> I[mission_grids 저장]PRD 결정 기록 발췌(v2.4 §8):
🤔 고민한 내용
왜 81이었고 왜 2,500인가. 81은 피그마 댓글의 "1km로 합의"에서 온 디자인 값이지 기술 제약이 아니다. 청계천 경계 기술검증(
docs/reports/2026-09-13-event-tour-additive-poc.md)에서 중심선에 편측 20m 경계만 줘도 면적은 33칸 상당인데 걸치는 격자가 135칸이라 신청 자체가 안 됐다. 값을 조금만 올리는 안(예: 300)은 상한이 두 벌로 남고 다음 선형 행사장에서 반복되므로 기각했고, 시더가 이미 쓰던 2,500과 통일했다. 사각형 대신 경계 도형을 입력받는 안은 상한이 아니라 입력 계약 문제라 별도 PRD로 넘겼다. 이 PR만으로 청계천을 신청하려면 사각형을 여러 개 그려야 하는 불편은 남는다.상수를 왜
global.geo에 뒀나. 대표 격자 계산기의 long 오버플로4 안전 논증이 "셀 수 상한" 위에 서 있어서, 셀 집합을 만드는 쪽(시딩, 접수)이 계산기 옆의 값을 보게 하는 편이 사본 두 벌보다 낫다. MSG-498이 격자 인덱스 상한을 같은 자리로 승격한 선례를 따랐다.승인 경로에서 논증이 깨진다. 스펙 교차 리뷰(Codex 1라운드)가 잡은 것으로, 승인은 위치 20개의 전 셀 합집합으로 대표 격자를 다시 계산한다. 위치당 2,500이면 합집합은 최대 50,000칸이고, 기존 자바독의 "인덱스 100,000 × 셀 수 2,500 → 2.5e17" 논증은 이 n에서 long 범위를 넘을 수 있다(5e9의 제곱). 실제 한국 좌표는 인덱스 폭이 1만 셀 안팎이라 5e17에 그쳐 열 배 넘게 여유가 있지만, 문서화된 전제가 무너지는 것은 그대로 둘 수 없었다. 부동소수점 전환은 동률 결정성(남서 우선)을 깨서 기각했고, exact 연산으로 바꿔 넘치면 예외가 나게 했다. 이 예외는
ApiException이 아니라 핸들러의 공통 500으로 떨어진다. 도달 불가 조건이라 수용했다.심사가 실질 방어선이 된다. 5km 사방을 한 위치로 신청하는 것은 형식 검증을 통과한다. FE 티켓 MSG-547이 "한 변 10칸 경고, 확정은 허용, 관리자 심사가 최종 판단"으로 이미 같은 구도를 택한 상태라 서버도 그 위에 선다.
전체 빌드를 임시 DB로 돌린 이유. 로컬 공유 DB에 MSG-596 부하 데이터(videos 135만 건)가 남아 있어
GridEpsg5179MigrationTest의 V28 재생이 videos 잠금을 쥔 채 9분 넘게 돌고 다른 세션 96개가 대기했다. CI와 같은 이미지(postgis 16-3.4-alpine)를 5433에 띄워 빌드했고 컨테이너는 지웠다. 실패 2건(VideoEncodingJobRepositoryTest시각 창,MissionVideoUploadRollbackTest예외 기대)은 1시간 46분짜리 빌드의 순서·시각 플레이크로 판정했고 공유 DB 단독 재실행에서 통과했다.👀 리뷰 포인트
RepresentativeGridResolver.nearestToCentroid의 exact 연산 전환과 자바독 논증. 폭 기준 논증(폭 × n ≤ 약 3e9)이 맞는지 봐 주시면 좋겠다.15525:8840) 갱신. 한 변 10칸 경고는 유지를 권한다.Footnotes
칸: 국토 평면 좌표계 위 100m×100m 격자 하나. 2,500칸은 50×50이라 한 변 5km 정사각형 상당이다. ↩
합집합 판정: 사각형들이 덮는 칸을 Set으로 전개해 겹치는 칸을 한 번만 세는 방식. 같은 영역을 어떤 사각형 조합으로 그렸든 결과가 같아 그리는 방식에 따라 거부되는 비결정성이 없다. ↩
대표 격자: 위치의 영상이 실제로 연결되는 격자 하나. 홀수 행렬 직사각형이면 정중앙, 아니면 영역 중심에 가장 가까운 포함 격자를 정수 산술로 고른다. ↩
long 오버플로: 64비트 정수 범위(약 9.2×10¹⁸)를 넘는 곱셈이 조용히 엉뚱한 값으로 감기는 현상. 거리 제곱 비교에서 일어나면 예외 없이 잘못된 격자가 대표로 저장된다.
multiplyExact는 그 순간 예외를 던진다. ↩