Skip to content

[Feat] 기존 식당 좌표 보완과 만료 전 갱신 (#228) - #235

Open
hwistlezz wants to merge 115 commits into
developfrom
feat/#228/restaurant-location-maintenance
Open

hwistlezz wants to merge 115 commits into
developfrom
feat/#228/restaurant-location-maintenance

Conversation

@hwistlezz

@hwistlezz hwistlezz commented Sep 26, 2026 •

Copy link
Copy Markdown
Member

🔥 작업 내용 (What)

기존 식당 주소로 좌표를 채우는 backfill과, 저장한 좌표가 만료되기 전에 갱신하는 기능을 추가했습니다. 신규 식당 등록과 같은 위치 확인 로직을 사용합니다.

🧩 변경 사항 (Details)

항목 이 PR에서 추가하는 동작
기존 식당 보완 기존 주소로 위치를 조회합니다. 별도 기본 주소가 있으면 그 값을 사용하며 모든 주소를 다시 입력할 필요는 없습니다.
실행 범위 CLI로 대상 수·예상 호출량을 확인하고 지정한 범위만 실행합니다. 중단한 작업은 이어서 처리할 수 있습니다.
자동 갱신 예약 스케줄러가 만료 3일 전부터 대상을 확인합니다. 처리 중·재시도 중인 작업은 중복 등록하지 않습니다.
갱신 중 좌표 같은 주소라면 기존 좌표를 유효기간까지 유지하고, 성공한 결과로 교체합니다.
선택한 매장 갱신 Places로 확인한 식당은 같은 장소 ID로 다시 조회합니다. 재시도·만료 뒤에도 주소 조회로 돌아가지 않습니다.
만료 정리 만료된 좌표를 정리합니다. 식당 정보·컬렉션 저장 관계·진행 중 재시도는 유지합니다.
확인 대상 불명확한 주소는 사유를 남깁니다. 관리자 주소 보완과 재처리 API로 다시 확인할 수 있습니다.
운영 확인 인증 오류·반복 실패·재시도 소진·만료 임박·처리 지연 지표와 Grafana 알림 예제를 제공합니다.
실제 주소 확인 내용
대상·방법 운영 식당 71개의 주소를 읽기 전용으로 확인하고, 별도 환경에서 Geocoding 응답과 Google Maps의 매장 위치를 대조했습니다.
확인 결과 영문·일본어 원문을 처리하고, 잘못된 번지나 불명확한 후보를 보류하는 흐름을 확인했습니다.
시설 안 매장 역처럼 시설 대표 위치가 나오는 경우에는 #233의 Places 후보 선택으로 실제 매장을 확인할 수 있습니다.
적용 범위 운영 DB에 좌표를 저장하거나 backfill을 실행한 검증은 아닙니다.

📸 스크린샷

없음

⚠️ 주의 사항 (Caution)

  • 자동 처리와 운영 backfill은 아직 활성화하지 않았습니다. 실행 전 대상·호출 예산·좌표 보관 조건을 확인해야 합니다.
  • 지도 조회는 만료 즉시 제외하고 DB 정리는 스케줄러 실행 주기에 처리합니다. 보관 기간에는 정리·장애 복구 여유를 반영해야 합니다.
  • Grafana 예제는 일시정지 상태이며 기존 Discord 수신처와 알림 정책은 변경하지 않았습니다.
  • 지도 migration 순서는 V38→V39→V39.1→V39.2→V40입니다. 이미 적용한 공지·약관 파일은 수정하지 않습니다.

🔗 관련 이슈

Closes #228

✅ 체크리스트

  • 관련 테스트와 문서 확인
  • 현재 변경의 CI 확인

@coderabbitai

coderabbitai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Review skipped

We couldn't safely recover the incremental review. No full review was started, and the last reviewed checkpoint was preserved. Retry later, or explicitly request a full review by commenting @coderabbitai full review.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

식당 위치 모델과 관리자 위치 API를 추가했습니다. Google 지오코딩 작업은 lease, 재시도 및 전역 호출 예산을 사용합니다. 기존 식당을 위한 위치 유지보수 CLI와 만료 위치 정리 기능, 관련 테스트와 운영 문서도 추가했습니다.

Changes

식당 위치 처리

Layer / File(s) Summary
위치 모델과 스키마
src/main/java/org/sopt/hashi/restaurant/domain/*, src/main/resources/db/migration/V31__add_restaurant_map_location.sql, src/test/java/org/sopt/hashi/restaurant/domain/*, docs/map/location-model.md
좌표·경계·지역·식당 위치 모델을 추가했습니다. V31은 위치·지역 테이블과 식당 참조를 생성합니다. 관련 테스트는 도메인 규칙, 스키마, 마이그레이션 및 시간대 처리를 확인합니다.
식당 저장과 관리자 위치 API
src/main/java/org/sopt/hashi/admin/*, src/main/java/org/sopt/hashi/restaurant/AdminRestaurantInfo.java, src/main/java/org/sopt/hashi/restaurant/RestaurantLocationInfo.java, src/main/java/org/sopt/hashi/restaurant/RestaurantPort.java, src/main/java/org/sopt/hashi/restaurant/service/Restaurant*, src/test/java/org/sopt/hashi/admin/*, src/test/java/org/sopt/hashi/auth/internal/security/*, src/test/java/org/sopt/hashi/restaurant/service/*
식당 생성·주소 변경·삭제 흐름을 위치 작업 등록·취소와 연결했습니다. 관리자 응답에 위치 상태와 주소 revision을 추가하고 위치 조회·재시도 API를 제공합니다.
지오코딩 작업과 Google 어댑터
src/main/java/org/sopt/hashi/restaurant/domain/RestaurantLocationJob*, src/main/java/org/sopt/hashi/restaurant/domain/GeocodingBudget*, src/main/java/org/sopt/hashi/restaurant/internal/map/*, src/main/java/org/sopt/hashi/restaurant/internal/map/google/*, src/main/java/org/sopt/hashi/restaurant/service/Location*, src/main/resources/db/migration/V32__add_restaurant_location_jobs.sql, src/test/java/org/sopt/hashi/restaurant/internal/map/google/*, src/test/java/org/sopt/hashi/restaurant/service/Location*, docs/adr/0003-restaurant-location-jobs.md, docs/map/google-geocoding-adapter.md, docs/map/location-jobs.md
작업 claim·lease·완료·재시도와 전역 호출 예산을 구현했습니다. Google 어댑터는 HTTP 응답과 오류를 분류하고 호출·응답 크기를 제한합니다. 후보 채택 정책은 주소와 좌표 조건을 확인합니다.
유지보수 CLI와 실행 기록
src/main/java/org/sopt/hashi/restaurant/migration/*, src/main/resources/db/migration/V33__add_location_maintenance_runs.sql, src/test/java/org/sopt/hashi/restaurant/migration/*, src/test/java/org/sopt/hashi/dev/DevLocationJobMySqlTest.java, build.gradle, docs/map/location-maintenance-runbook.md
드라이런, 상태 조회, 시작·중지·재개를 지원하는 CLI를 추가했습니다. 실행 진행 상태와 작업 연결을 저장합니다. MySQL 통합 테스트는 체크포인트, 동시성, 호출 한도 및 배포 JAR 실행을 확인합니다.
위치 보존·정리와 운영 자료
src/main/java/org/sopt/hashi/restaurant/internal/map/LocationRetention*, src/main/java/org/sopt/hashi/restaurant/internal/map/LocationMaintenanceMetrics.java, src/test/java/org/sopt/hashi/restaurant/domain/LocationRetentionPolicyTest.java, src/test/java/org/sopt/hashi/restaurant/internal/map/LocationRetentionConfigurationTest.java, docs/adr/0002-restaurant-map-query-and-location.md, docs/map/*, docs/map/monitoring/grafana-alerts.example.json, src/main/resources/logback-spring.xml
만료된 Google 위치를 갱신·정리하는 배치 경로와 지표를 추가했습니다. 운영 문서와 지도 계약, Grafana 알림 예시를 갱신했습니다. Apache HttpClient 로그 수준은 OFF로 설정했습니다.

Priority: ➖ Normal

Estimated code review effort: 5 (Critical) | ~120 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant RestaurantService
  participant RestaurantLocationService
  participant LocationJobScheduler
  participant RestaurantLocationWorker
  participant LocationJobTransactions
  participant GoogleGeocodingProvider
  RestaurantService->>RestaurantLocationService: 위치 작업 등록
  LocationJobScheduler->>RestaurantLocationWorker: 주기 실행
  RestaurantLocationWorker->>LocationJobTransactions: 후보 조회 및 claim
  RestaurantLocationWorker->>GoogleGeocodingProvider: 주소 geocode 요청
  GoogleGeocodingProvider-->>RestaurantLocationWorker: 후보 또는 실패 결과
  RestaurantLocationWorker->>LocationJobTransactions: 결과 완료 또는 재시도 처리
Loading

Suggested reviewers: gichangim

Merge Risk: 🟠 High · up to d6b87

This change adds restaurant location storage, geocoding jobs and maintenance tooling. Its new database migration reuses version 31, which an existing migration already uses. The build check fails, and database migration would refuse to run on deployment. That would stop the application from starting. Renumber the new migrations and the matching test targets before merging. The earlier validation-message concern has been fixed.

Security Architecture Review

Security architecture risk: 🔵 Low · up to c56da

Administrator-only access, bounded calls, and stale-result checks limit exposure. No introduced security defect was established in the reviewed flows, but production credential restrictions, retention arrangements, and recovery readiness still require confirmation before live processing is enabled.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — Effective exposure spans eligible restaurants in the connected database and the configured Google account's call budget. An authorized administrator selects restaurant IDs; the CLI's authority comes from its database credentials. Per-run limits do not cover separate administrator retries or other runs, although those claims share the global budget.

Trust Boundaries and Controls

  • observed — Authorization tests exercise the real controller, administrator service, JWT filtering, and security configuration: ADMIN reaches the restaurant port, while USER, ONBOARDING, and anonymous requests are rejected before port interaction. Request IDs are generated internally rather than accepted as caller authority.
  • observed — The external-response boundary limits body size and accepted encoding before parsing. Coordinate adoption requires a single candidate, valid coordinates, supported Japanese geography, rooftop address precision, and address matching; failed checks require review rather than automatic adoption. Configuration redacts its string representation and rejects selected secret-bearing HTTP debug logging settings.

Resilience and Maintainability Implications

  • observed — Shared-budget locking and a fresh reservation count serialize paid-call admission. Attempts are bounded at eight across configuration changes, and maintenance reserves registration capacity using that ceiling. The runbook separately acknowledges that primary-database cleanup does not establish deletion from replicas, clients, or backups, and makes monitoring, recovery ownership, and retention verification launch prerequisites.
🚥 Pre-merge checks | ✅ 6 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning [ #228 ]의 backfill·좌표 갱신·만료 정리와 직접 연결되지 않는 지도 제품/API 범위가 문서에 추가됐습니다. 새 docs/adr/0002-restaurant-map-query-and-location.md, docs/map/implementation-plan.md, docs/map/map-contract-v1.md는 화면 전환과 ch… [ #228 ]에 필요한 backfill, 좌표 갱신·만료, 백업 및 운영 절차 문서만 유지하세요. 지도 UI·공개 API·Redis 세션·컬렉션 핀·지역 관리에 관한 상세 계획과 계약은 해당 작업 범위의 별도 문서 또는 변경으로 분리하세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 6.46% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 356 functions across 61 files. (10 skipped… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (6 passed)
Check name Status Explanation
Linked Issues check ✅ Passed 활성 직접 연결 이슈 [#228]의 코딩 요구사항을 충족합니다. CLI는 읽기 전용 점검, ID 범위·호출 한도, checkpoint 재개, 실행 상태를 제공하며 등록 직전에 대상 식당과 활성 작업을 다시 확인합니다. 갱신·정리 구현은 유효한 기존 좌표를 유지하고, 만료 좌표만 제거하며, 식당 원본 정보와 재시도 상태를 보존합니다. 만료 좌표의 지도 제외,…
모듈 경계 위반 확인 ✅ Passed 변경 코드에서 명시된 모듈 경계 위반을 확인하지 못했습니다. admin은 위치 조회·재시도를 RestaurantPort로 호출하고, RestaurantLocationInfo 공개 DTO를 사용합니다 (RestaurantPort.java:64-68, AdminRestaurantService.java). 새 internal.map, `do…
Shared 공유 커널 오염 확인 ✅ Passed PR diff에 shared 소스 변경이나 common, core, util, global 패키지 신규 선언이 없습니다. 추가된 도메인 관련 코드는 restaurant 하위 패키지에 있습니다. 확인된 신규 org.sopt.hashi.shared.* import는 변경된 도메인·기능 코드에서 공통 오류·저장소 타입을 가져오는 방향이며…
엔티티 노출·응답 봉투 확인 ✅ Passed 경고 조건을 도입한 변경은 없습니다. PR에서 변경된 유일한 컨트롤러인 AdminRestaurantController의 위치 조회·재시도 메서드는 SuccessResponse<RestaurantLocationResponse>를 반환하고, 기존 식당 API도 SuccessResponse로 응답합니다. 새 위치 응답은 엔티티가 아닌 DTO입니다 (`…
Title check ✅ Passed 제목이 [Feat] 작업 내용 (#이슈번호) 형식을 따릅니다. 기존 식당 좌표 보완과 만료 전 갱신이라는 주요 변경 사항을 설명하며 #228 이슈도 포함합니다.
Description check ✅ Passed 작업 내용, 세부 변경 사항, 스크린샷, 주의 사항, 관련 이슈 및 체크리스트 섹션을 포함합니다. 기본 테스트·빌드 체크 항목과 코드 리뷰 체크 항목은 템플릿과 다르지만, 설명은 주요 변경 사항과 운영 조건을 충분히 다룹니다.
Full details: Out of Scope Changes check

Explanation

[ #228 ]의 backfill·좌표 갱신·만료 정리와 직접 연결되지 않는 지도 제품/API 범위가 문서에 추가됐습니다. 새 docs/adr/0002-restaurant-map-query-and-location.md, docs/map/implementation-plan.md, docs/map/map-contract-v1.md는 화면 전환과 chip 동작, 공개 지도 endpoint, Redis 조회 세션·cursor, 컬렉션 전체 핀 및 후속 지역 관리([#219], [#216], [#242], [#251])를 상세히 규정합니다. 이는 [#228]의 유지보수·보관 절차 문서화에 필요한 범위를 넘습니다. 해당 문서의 backfill, 좌표 수명, 정리·운영 절차 부분은 이슈와 연결됩니다.

Full details: Docstring Coverage

Explanation

Docstring coverage is 6.46% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 356 functions across 61 files. (10 skipped: 10 unsupported.)

✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Comment @coderabbitai help to get the list of available commands.

@hwistlezz hwistlezz self-assigned this Sep 26, 2026
…restaurant-location-maintenance

# Conflicts:
#	src/main/java/org/sopt/hashi/restaurant/domain/Restaurant.java
@hwistlezz hwistlezz changed the title [Feat] 기존 식당 좌표 보완과 만료 정보 정리 (#228) [Feat] 기존 식당 좌표 보완과 만료 전 갱신 (#228) Oct 8, 2026

This branch has not been deployed

No deployments
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.

[Feat] 기존 식당 좌표 보완과 만료 정보 정리

2 participants