콘텐츠로 이동

MSG-388 행정동 내 격자 카드 조회 신설 (지도 홈 패널을 내 것 기준으로)

티켓: MSG-388 · 작성일: 2026-08-15 · 작성: prd-writer 상태: 검토됨 (2026-08-15 사용자 승인, 같은 날 사실 정정과 미해결 질문 3건 확정 반영 후 재승인. 임시 전역 조회의 타인 격자 노출은 dev 실측으로 확인: 부전2동 카드 8장 중 본인 격자 2장)

1. 문제 상황

지도 홈 기본 화면의 사이드 패널에는 격자 카드 목록이 뜬다. 2026-08-13에 "상단 칩을 켜지 않는 한 지도 홈은 전부 내 격자 기준"이 확정되면서(SRS FR-MAP-07, FR-MAP-10) 이 카드도 내 격자를 보여줘야 하는데, 한 행정동 안에서 내 격자를 카드(썸네일과 영상 수)로 주는 조회가 서버에 없다. 그래서 FE는 전역 공개 콘텐츠[^1] 조회 GET /api/regions/{regionCode}/gridssort=LATEST&limit=20으로 임시 사용 중이고, 이 상태로는 남의 영상이 섞인 카드가 내 격자 자리에 노출된다. 결정은 이미 났고(MSG-387 PRD 승인 과정, 2026-08-13 팀원 K) 구현만 남았다.

비슷한 조회 두 개가 이미 있지만 어느 쪽도 요구를 채우지 못한다. GET /api/collections/grids는 내 격자 카드를 주지만 전국 대상에 수집 시각순 최대 30개 고정이고, GET /api/collections/videos?regionCode=는 행정동 필터가 있지만 격자 카드가 아니라 영상 목록이다.

2. 목적 · 목표

  • 목적: 지도 홈 패널이 "내 격자 기준" 확정(FR-MAP-07)대로 동작하도록, 한 행정동에서 내 격자를 카드로 주는 서버 조회를 만든다.
  • 목표:
  • FE가 행정동 코드 하나로 그 동네의 내 격자 카드를 최신 업로드순 최대 20장으로 받을 수 있다.
  • FE 연동 가이드의 "전역 조회 임시 사용" 안내가 새 조회로 교체된다.
  • 비목표(스코프 제외):
  • 패널 헤더의 재료 변경. 헤더는 지금처럼 지도 집계 응답의 currentRegion[^2]이 채운다 (MSG-374, FR-MAP-06). 헤더의 카운트 줄("이 지역 격자 N개 · 영상 M개")은 2026-08-15에 폐기돼 동 이름만 남았다.
  • 전역 조회 GET /api/regions/{regionCode}/grids의 계약 변경. 상단 칩 활성 화면과 전역 탐색이 계속 쓴다.
  • 칩 활성 상태의 패널(미션 목록, MSG-383)과 친구 도감 카드.

3. 엔드포인트 형태 결정

티켓이 PRD에서 정하기로 한 항목이다. 기존 내 도감 갤러리 조회 GET /api/collections/grids에 선택 파라미터를 더하는 확장으로 간다.

  • 새 조회가 주는 카드의 재료(격자 ID, 썸네일, 영상 수, 격자 표시명)와 응답 모양이 기존 갤러리 카드와 같다. 필터(행정동)와 정렬(최신 업로드순)만 다르다.
  • 행정동 필터를 쿼리 파라미터로 받는 선례가 같은 컨트롤러에 이미 있다 (GET /api/collections/videos?regionCode=).
  • 신규 엔드포인트로 가면 같은 재료를 다른 경로 두 곳에서 반환하게 되어 응답 모양이 갈라질 위험만 생긴다.

파라미터 없는 기존 호출(도감 갤러리)의 동작은 그대로 두는 것이 이 결정의 전제다 (FR-7).

4. 기능 요구사항

ID 요구사항 우선순위
FR-1 로그인 사용자는 행정동 코드로 그 행정동에 속한 내 격자를 카드 목록으로 조회할 수 있다. 카드에는 격자 ID, 격자 인덱스, 영상 수, 커버 썸네일, 커버 영상 길이(패널 카드의 재생 시간 뱃지 재료), 격자 표시명 재료(zoneName, zoneCell, regionName)가 담긴다 (SRS FR-MAP-07, FR-MAP-10 상세화) Must
FR-2 정렬은 내 영상이 가장 최근에 올라온 격자 순(최신 업로드순)을 지원한다. 지도 홈 패널이 이 정렬로 20장을 요청한다 Must
FR-3 장수 상한(20)과 정렬은 클라이언트가 조회 파라미터로 정한다. 서버는 상한을 강제하지 않는다 (FR-MAP-10, MSG-387 FR-3 승계) Must
FR-4 세는 대상은 내 도감 관례를 따른다. 삭제되지 않은 내 영상은 비공개(PRIVATE)든 인코딩 중이든 블라인드 상태든 전부 포함한다(영상 수 차감은 삭제만, 블라인드는 유지가 기존 모더레이션 정책). currentRegion 집계(MSG-374)와 같은 기준이라 지도 홈 안의 숫자들이 서로 어긋나지 않는다 Must
FR-5 격자의 행정동 귀속은 격자 축(격자 소속 행정동)이다. 영상 좌표가 옆 동이어도 격자 소속 동 기준으로 잡힌다. 같은 화면의 동 단위 내 영상 조회(/api/collections/videos)와 같은 기준이다 Must
FR-6 그 행정동에 내 격자가 없거나 존재하지 않는 행정동 코드면 404가 아니라 200에 빈 배열이다. 패널은 빈 상태 UI를 그린다 (MSG-387 FR-6 승계) Must
FR-7 파라미터 없는 기존 호출(도감 갤러리, 수집 시각순 최대 30개)의 동작이 바뀌지 않는다. 기존 응답 필드의 의미, 정렬, 상한은 불변이고, 새 필드를 더하는 것(FR-1의 커버 영상 길이)만 허용한다 Must
FR-8 커버 썸네일이 아직 없는 격자(인코딩 완료 전)는 카드에서 빠지지 않고 썸네일만 null로 온다 (도감 갤러리와 같은 동작) Must

5. 비기능 요구사항

분류 요구사항
성능 패널 기본 호출(20장)은 격자당 커버 1건 조회와 썸네일 presigned URL[^3] 발급 20회 수준이다. 전국 30장을 주는 기존 갤러리 조회와 같은 구조라 새 병목이 없어야 한다
보안/인가 토큰 필수. 본인 것만 조회된다. 다른 사용자의 격자나 비공개 영상 존재가 이 응답으로 새지 않는다
데이터 정합 영상을 모두 지워 점령 롤백[^4]된 격자는 카드에서 즉시 사라진다 (user_grids 행 삭제로 자연 보장, glossary 규칙)
운영 읽기 전용 조회라 마이그레이션이 없다

6. 시퀀스 다이어그램

시퀀스 다이어그램
시퀀스 다이어그램

7. 클래스 다이어그램

신규 타입 없이 기존 조회 계열의 시그니처만 확장된다. 응답 DTO는 기존 CollectionGridResponseDto를 그대로 쓴다.

클래스 다이어그램
클래스 다이어그램

8. 변경 파일 목록

파일 변경 Owner
src/main/java/com/msg/fillmap/usergrid/controller/CollectionController.java getCollectionGrids에 선택 파라미터(regionCode, sort, limit) 추가, 스웨거 설명 갱신 B
src/main/java/com/msg/fillmap/usergrid/service/UserGridQueryService.java 조회 시그니처 확장 B
src/main/java/com/msg/fillmap/usergrid/service/impl/UserGridQueryServiceImpl.java 필터·정렬 분기 구현 B
src/main/java/com/msg/fillmap/usergrid/repository/UserGridRepository.java 행정동 필터 + 최신 업로드순 native 조회 추가 B
docs/srs.md 구현 완료 시 FR-MAP-10 비고의 "임시 사용" 서술 갱신 (마무리 단계) -
위키 03-specs/지도 홈 API 연동 가이드 FE.md 패널 카드 안내를 전역 조회에서 새 조회로 교체 (레포 밖) -
컨플루언스 cf-32636957 위키와 같은 내용으로 갱신 (FE가 보는 원본) -

Owner 판정: 조회 축이 user_grids와 videos(커버)라 구현 주도는 Owner B다. 행정동 귀속은 grids.region_code를 같은 쿼리에서 읽는 기존 B 내부 선례(/api/collections/videos, MSG-167)를 따르므로 새 경계 설계는 필요 없다. 다만 UserGridQueryService는 계약 인터페이스라 시그니처 확장에 상대 팀원 확인이 필요하다(스펙에서 공동으로 분류).

9. 미해결 질문

작성 시점의 3건이 모두 해소됐다.

  • [x] 카드 커버는 도감 갤러리와 같은 user_grids 커버로 확정 (2026-08-15 사용자 확정. 격자의 첫 내 영상이 유지되고, 삭제나 블라인드로 사라지면 재선정되며, 블라인드 해제 시 원복은 없다. 재선정 대상이 없으면 커버 없이 카드만 남는다).
  • [x] regionCode를 지정하고 limit을 생략한 호출은 그 동네의 내 격자 전부를 반환한다 (2026-08-15 사용자 확정. 전역 조회의 "전체 보기" 계약 승계, MSG-387 FR-4. 웹, 앱 디자인 모두 전체 보기 링크 실재 확인).
  • [x] sort 파라미터는 스펙에서 확정했다: COLLECTED(수집 시각순, 생략 기본값)와 UPLOADED(최신 업로드순).

[^1]: 전역 공개 콘텐츠: 살아 있고(삭제, 블라인드 아님) 전체 공개(PUBLIC)이며 인코딩까지 끝난 영상. 전역 노출 경로가 세는 대상이라 남의 영상이 포함된다. [^2]: currentRegion: 지도 집계 응답(MSG-374)에 실리는 뷰포트 중심 행정동 정보. 동 이름과 그 동 전체의 내 점령 격자 수, 내 영상 수를 담아 패널 헤더를 채운다. [^3]: presigned URL: S3 객체를 일정 시간 동안만 열 수 있게 서명한 임시 URL. 썸네일 원본 키를 그대로 노출하지 않기 위해 서버가 발급한다. [^4]: 점령 롤백: 한 격자의 내 영상이 모두 삭제되면 점령(user_grids 행)도 자동 취소되는 규칙. 시간 제한이 없다.