Skip to content

[S15P11A705-307] 지도 마커 latestCollectionId 정정과 재발급 크로스탭 직렬화, 참조 문서 동기화 - #100

Merged
TrossYou merged 6 commits into
devfrom
fix/S15P11A705-307-map-latest-collection-id
Aug 4, 2026
Merged

[S15P11A705-307] 지도 마커 latestCollectionId 정정과 재발급 크로스탭 직렬화, 참조 문서 동기화#100
TrossYou merged 6 commits into
devfrom
fix/S15P11A705-307-map-latest-collection-id

Conversation

@TrossYou

@TrossYou TrossYou commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

관련 이슈

S15P11A705-307

작업 내용

doc-syncer로 docs/reference/를 원본(Team-PinLog/docs HEAD 8b1d3b6, PR #48 docs/map-latest-collection-id)에 맞춰 동기화하고, 그 결과 드러난 계약 불일치를 코드·문서에 반영했다.

버그 수정 — 지도 마커가 전부 "미분류" 색으로 떨어지던 문제

  • 마커 응답 필드 확정 명칭이 collectionId가 아니라 **latestCollectionId**였다. 프론트 Zod 스키마가 optional로 받고 있어 파싱 오류 없이 조용히 undefined가 되고, 모든 마커가 미분류 색(slate) 하나로 렌더됐다.
  • 의미도 좁아졌다 — "속한 Collection"이 아니라 "가장 최근에 담긴" Collection(담은 시각 기준, 뺀 연결 제외)이다.

재발급 크로스탭 직렬화

  • 11_인증_설계.md 4.4가 single-flight를 탭·창 간에도 묶으라고 확장했다. 인증 쿠키는 오리진 단위로 탭이 공유하므로, 탭마다 따로 묶으면 두 탭이 같은 Refresh 토큰을 동시에 회전시켜 늦게 도착한 쪽이 401을 받고 사용자가 로그아웃된다.
  • 수단은 Web Locks(navigator.locks.request). BroadcastChannel은 메시지 전달 수단이라 리더 선출·타임아웃을 직접 구현해야 하고 락을 쥔 탭이 닫히면 남은 탭이 영구 대기하는 반면, Web Locks는 브라우저가 상호배제를 보장하고 탭이 죽으면 락을 자동 회수한다.
  • 락은 동시 호출만 막고 중복 호출은 막지 않는다 — 두 번째 탭은 이미 회전된 새 쿠키로 재발급하므로 성공한다. navigator.locks가 없으면 기존 탭 내 single-flight로 폴백한다.

문서 반영 (docs/api-contract.md, docs/architecture.md)

  • 상태 코드에 500·503 추가. 503은 재발급 대상이 아니다 — 자격증명 거절이 아니라 인증 여부를 확인하지 못한 상태라, 401과 같은 분기로 묶으면 일시적 장애가 전체 로그아웃으로 번진다.
  • 커서-정렬 방향 제약 신설. 서버가 커서와 정렬 방향의 불일치를 검증하지 않으므로(back BD-46) 정렬 파라미터는 상수로 고정하고 정렬 토글 UI는 BD-46 해소 전까지 만들지 않는다.
  • Collection 내부 Record 정렬을 [협의 필요] → [확정]으로 이동(담은 순 오름차순 기본, recordSort=ADDED_AT_DESC로 최신순).
  • "장소 검색"이 가리키는 세 가지(카카오 로컬 / GET /records/map?keyword= / POST /search/records)를 표로 분리. 내 기록 안의 장소 검색은 카카오가 아니라 서버이며, 컬렉션 만들기의 장소 선택도 이 엔드포인트를 재사용한다.
  • GET /followscollectionSize·collectionSort(1+N 제거), PlaceSummary.thumbnailUrl(4:3, null 폴백), 회원 탈퇴 2단계 절 신설.
  • 잔여 모순이던 [협의 필요] "카카오 검색 프록시 API(BFF 경유)" 항목 삭제 — 같은 문서 [확정]의 "프론트가 직접 호출"과 이미 어긋나 있었다.

변경 유형

  • feat (기능)
  • fix (버그)
  • refactor / chore / docs / style / test

확인 방법

  • npx tsc --noEmit / npx eslint src / npx vitest run(78 passed) / npx vite build 모두 통과.
  • 지도 마커 색: Home 지도에서 서로 다른 Collection에 담긴 기록들이 각각 다른 색 마커로 뜨는지 확인한다. 수정 전에는 전부 같은 slate 색이었다. 단, 백엔드가 latestCollectionId를 아직 배포하지 않았다면 여전히 전부 미분류이며 이는 정상이다(스키마가 optional).
  • 재발급 직렬화: 탭 두 개를 열고 Access 만료 후 양쪽에서 동시에 API를 호출했을 때 로그아웃되지 않는지 확인한다. DevTools Application → Web Locks에서 pinlog:auth-refresh 락이 잡히는 것을 볼 수 있다.

체크리스트

  • 공개 화면(Feed, 타인 Shelf, Collection 상세)에 Context 원문·신원 정보를 노출하지 않았다
  • member.id(내부 사용자 ID)를 URL·요청·응답에 사용하지 않았다 (진입점은 Collection id)
  • Keyword는 label만 사용하고 code를 노출하지 않았다
  • Context 수정 후 새 contextId로 쿼리 키·URL·선택 상태를 교체했다 (이번 변경 범위에 Context 수정 없음)
  • keywords: [] 등 빈 결과를 오류로 처리하지 않았고 로딩·오류·401 상태를 처리했다
  • docs/conventions.md(용어·any·컴포넌트 직접 API 호출 금지)를 지켰다

리뷰어가 알아야 할 점

dev를 머지해 충돌을 해소했다(8f4def2). 이 브랜치의 앞 커밋 4개는 그 사이 #98로 dev에 squash 머지됐고, #97(회원 탈퇴 2단계 구현)이 그 위에 얹혔다. 그래서 dev 대비 실제 변경은 아래 파일뿐이다 — 지도 배경 레이어·SVG 마커·줌 제한은 이미 dev에 있다.

  • docs/api-contract.md, docs/architecture.md, docs/reference/ 4개(doc-sync)
  • src/features/map/api/getRecordMapMarkers.ts, src/features/map/components/RecordMapView.tsx, src/shared/lib/getRecordMarkerAsset.ts (collectionIdlatestCollectionId)
  • src/shared/http/client.ts (Web Locks 재발급 직렬화)

충돌 해결 방향:

파일 채택 이유
getRecordMapMarkers.ts · RecordMapView.tsx · getRecordMarkerAsset.ts 이 브랜치 dev(#98) 쪽은 정정 전 명칭 collectionId뿐이고 나머지는 동일하다
deleteAccount.ts dev #97이 2단계 흐름을 실제로 구현했다. "옛 계약이라 손대지 않는다"는 이 브랜치의 경고 주석은 폐기했다
docs/api-contract.md 이 브랜치 collectionId 절을 삭제하고 latestCollectionId 절로 대체. 더불어 "회원 탈퇴 — 2단계" 제목의 ⚠️ 현재 프론트 구현이 옛 계약 기준이다 경고를 뗐다 — #97로 사실이 아니게 됐다

후속 티켓이 필요한 항목 (이 PR 범위 밖, 문서에만 기록):

  • PlaceSummary.thumbnailUrl — 필드가 아직 서버에 없어 스키마에 추가하지 않았다. 계약만 문서화했다.

(원래 여기 있던 "회원 탈퇴 2단계화" 항목은 dev #97로 해소되어 제거했다.)

🤖 Generated with Claude Code

TrossYou and others added 6 commits August 4, 2026 17:54
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
지도 마커는 latestCollectionId(수정된 계약)를 채택하고, dev PR #97이 구현한
회원 탈퇴 2단계 흐름은 dev 쪽을 그대로 받는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@TrossYou
TrossYou merged commit fad88e2 into dev Aug 4, 2026
1 check passed
@TrossYou
TrossYou deleted the fix/S15P11A705-307-map-latest-collection-id branch August 4, 2026 14:46
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