diff --git a/docs/api-contract.md b/docs/api-contract.md index 8efa155..7152456 100644 --- a/docs/api-contract.md +++ b/docs/api-contract.md @@ -88,7 +88,7 @@ > ⚠️ **이 절의 근거는 원본 `08_API_명세`가 아니라 front#109다.** Collection 표지 생성 절(§"Collection 표지 생성")과 같은 패턴 — 원본 문서에 이 엔드포인트가 아직 없고, 스키마가 바뀌면 이 문서가 아니라 그 이슈가 기준이다. 이 엔드포인트는 Core API 소속이라(`/image/api/*`와 달리) `httpClient`를 그대로 쓴다. - + - **목적**: 대화 캡처 이미지 1장에서 장소명 후보를 AI가 추출하고, 후보마다 카카오 로컬 검색 결과를 붙여 함께 내려준다. 위 "세 가지 장소 검색" 표에는 없는 **네 번째 경로**다 — 카카오도 `GET /records/map`도 아니고, 이미지 한 장에서 장소를 **발견**하는 용도다. 사용자가 최종 확인·수정한 뒤 기존 `POST /records`로 저장한다. **AI 결과만으로 자동 저장되지 않는다.** - **요청**: `multipart/form-data`, 필드명 `image`, 이미지 **1장만**, **JPEG/PNG만**, **최대 5 MiB**(front#109). 기존 로그인 쿠키+CSRF 흐름을 그대로 쓴다 — 별도 인증 방식이 없다. @@ -135,8 +135,8 @@ - 추가 필드: **`latestCollectionId`**(`number | null`) — 그 Record가 **가장 최근에 담긴** Collection의 id. "가장 최근"의 기준은 컬렉션 내부 정렬과 같은 **담은 시각**이며, 컬렉션에서 **뺀(삭제된) 연결은 판단에서 제외**된다. 어느 Collection에도 담기지 않은 Record는 `null`이다. - ⚠️ 필드명은 `collectionId`가 **아니다.** 2026-08-04 doc-sync 이전 이 문서와 프론트 Zod 스키마가 `collectionId`로 적혀 있었고, 그대로면 파싱이 조용히 `undefined`가 되어 모든 마커가 "미분류" 색으로 떨어진다. - 한 Record가 여러 Collection에 담길 수 있으나 이 필드는 **단일 값**이다. 마커 색은 "그 Record가 속한 모든 Collection"이 아니라 "가장 최근 것 하나"를 나타낸다. -- 프론트 처리: `latestCollectionId` 기반 해시로 마커 asset(색) 결정, `null`이면 별도 고정 asset(미분류) 적용. 구현은 `getRecordMarkerAsset`(S15P11A705-307). -- **back 구현은 아직 머지되지 않았다** — back PR #191(`S15P11A705-308`)이 2026-08-04 기준 **OPEN**이다. 그래서 프론트 Zod 스키마는 이 필드를 **optional로 받는다**(필드가 없거나 명시적 `null`이면 동일하게 "미분류"로 취급). 현재 지도 마커가 전부 미분류 색으로 보이는 것은 **정상**이며, #191이 머지·배포된 뒤에야 색이 갈린다. 그 시점에 optional 제거를 검토한다. +- 프론트 처리: `latestCollectionId` 기반 해시로 마커 asset(색) 결정, `null`이면 별도 고정 asset(미분류) 적용. 구현은 `getRecordMarkerAsset`(Jira 작업). +- **back 구현은 아직 머지되지 않았다** — back PR #191(`Jira 작업`)이 2026-08-04 기준 **OPEN**이다. 그래서 프론트 Zod 스키마는 이 필드를 **optional로 받는다**(필드가 없거나 명시적 `null`이면 동일하게 "미분류"로 취급). 현재 지도 마커가 전부 미분류 색으로 보이는 것은 **정상**이며, #191이 머지·배포된 뒤에야 색이 갈린다. 그 시점에 optional 제거를 검토한다. ### [확정] 지도 키워드 칩 (`GET /records/map/keywords`) @@ -156,7 +156,7 @@ > **`DELETE /me`는 더 이상 "탈퇴 완료"가 아니다.** `204`(완료) → **`200` + 이동할 곳**으로 바뀌었다. 엔드포인트·메서드는 그대로다. > -> **프론트 대응 완료** — front #97, back #181(`S15P11A705-285`, 머지됨). `deleteAccount` 응답 파싱 · `WithdrawConfirmDialog` 페이지 이동 · `handleOAuthCallback`의 `WITHDRAWAL_*` 분기까지 반영돼 있다. +> **프론트 대응 완료** — front #97, back #181(`Jira 작업`, 머지됨). `deleteAccount` 응답 파싱 · `WithdrawConfirmDialog` 페이지 이동 · `handleOAuthCallback`의 `WITHDRAWAL_*` 분기까지 반영돼 있다. 탈퇴는 두 단계이며, **공급자 연결 해제가 선행되고 그것이 성공한 경우에만** 데이터가 삭제된다. @@ -224,7 +224,7 @@ type PlaceSummary = { }; ``` -- back 구현 **머지 완료**(back #184 `S15P11A705-305`, 2026-08-04). `PlaceSummaryResponse`를 쓰는 **모든 응답**에 실린다 — Record 상세뿐 아니라 Collection 상세도 포함이다. +- back 구현 **머지 완료**(back #184 `Jira 작업`, 2026-08-04). `PlaceSummaryResponse`를 쓰는 **모든 응답**에 실린다 — Record 상세뿐 아니라 Collection 상세도 포함이다. - **`thumbnailUrl`은 `null`일 수 있으나 필드가 생략되지는 않는다.** `null`이거나 이미지 로드에 실패하면 기본 이미지로 폴백한다. - **4:3 비율**로 제공된다. `aspect-ratio: 4 / 3` + `object-fit: cover`로 표시하면 로딩 전 영역이 확보되고 폭에 적응한다. - 현 단계 값은 같은 오리진의 절대 경로(`/api/core/images/places/…`)다. 이후 카카오 이미지 검색 API 전환 시 같은 필드에 외부 절대 URL이 들어가며 **프론트 계약은 바뀌지 않는다**. **`VITE_API_BASE_URL`(`/api/core/v1`)을 앞에 붙이지 않는다** — 이 경로는 `v1` 밖이다. @@ -371,8 +371,8 @@ type PlaceSummary = { 1. **provider 대소문자** — 경로는 소문자(`kakao`), 응답은 대문자(`KAKAO`). 타입은 대문자로 두고 경로 조립 시 `toLowerCase()`로 매핑한다. 2. **표지 생성 요청의 인증·rate limit** — `POST /image/api/covers`는 GPU 비용이 발생하는데 front#99 예제에 인증 헤더가 없다. 비로그인 허용 여부와 남용 방지 정책이 미확정이다(`05-1_파트간_요구사항.md` §3.2). - **구현은 막지 않는다** — 가이드대로 인증 없이 호출한다. 다만 인증이 붙으면 요청 헤더가 바뀌므로, 이미지 서비스 호출부를 전용 클라이언트 한 곳에 모아 그 변경이 한 파일에서 끝나게 한다. -3. **이미지 기반 장소 제안(`POST /places/suggestions`)의 rate limit 구체값** — Gemini Vision 등 분석 비용이 발생하는 경로다. front#109가 `503 PLACE_SUGGESTION_BUSY`(동시 분석 제한)의 **존재**는 명시하지만 임계값(동시 요청 수·시간당 횟수 등)은 없다. 표지 생성(위 2번)과 같은 이유로 협의 필요. -4. **`kakaoSearch.status`(`NO_RESULTS`/`FAILED`)가 오류인지 정상 응답 안의 상태 표시인지** — 200 응답 안에 후보별로 내려오는 필드라는 스키마 형태로 미루어 보면 "정상 응답, 개별 후보 실패"에 가깝지만, front#109 본문에는 이 필드명 자체가 없다(이슈는 `warnings[].code`로만 부분 실패를 표현한다). 확정 전까지 프론트는 후보별 안내로만 처리하고 전체 요청 실패로 승격하지 않는다(`PlaceRecordSheet.tsx`, S15P11A705-343). +3. **이미지 기반 장소 제안(`POST /places/suggestions`)의 rate limit 구체값** — Gemini Vision 등 분석 비용이 발생하는 경로다. front#109가 `503 PLACE_SUGGESTION_BUSY`(동시 분석 제한)의 **존재**는 명시하지만 임계값(동시 요청 수·시간당 횟수 등)은 없다. 표지 생성(위 2번)과 같은 이유로 협의 필요. +4. **`kakaoSearch.status`(`NO_RESULTS`/`FAILED`)가 오류인지 정상 응답 안의 상태 표시인지** — 200 응답 안에 후보별로 내려오는 필드라는 스키마 형태로 미루어 보면 "정상 응답, 개별 후보 실패"에 가깝지만, front#109 본문에는 이 필드명 자체가 없다(이슈는 `warnings[].code`로만 부분 실패를 표현한다). 확정 전까지 프론트는 후보별 안내로만 처리하고 전체 요청 실패로 승격하지 않는다(`PlaceRecordSheet.tsx`, Jira 작업). ### 이번에 [협의 필요]에서 제거(확정으로 흡수)됨 diff --git a/docs/conventions.md b/docs/conventions.md index edb1860..84b4116 100644 --- a/docs/conventions.md +++ b/docs/conventions.md @@ -17,10 +17,10 @@ - **컴포넌트에서 API를 직접 호출하지 않는다.** 데이터 흐름은 `docs/architecture.md`를 따른다(화면 → Hook → API 함수 → HTTP Client). - 서버 상태(TanStack Query)와 UI 상태(Context API)를 한 곳에 섞지 않는다. - 검증 스키마는 Zod로 정의하고 API 경계에서 파싱한다. -- **하나의 사실을 두 변수가 나눠 들지 않는다.** 특히 외부 라이브러리 인스턴스의 준비 여부가 렌더에 영향을 준다면 ref가 아니라 state로 든다 — ref는 갱신해도 리렌더가 없어 effect가 다시 돌지 않는다(`docs/troubleshooting/2026-08-06-map-remount-ref-state-race.md`, S15P11A705-346). +- **하나의 사실을 두 변수가 나눠 들지 않는다.** 특히 외부 라이브러리 인스턴스의 준비 여부가 렌더에 영향을 준다면 ref가 아니라 state로 든다 — ref는 갱신해도 리렌더가 없어 effect가 다시 돌지 않는다(`docs/troubleshooting/2026-08-06-map-remount-ref-state-race.md`, Jira 작업). - **Tailwind 클래스는 리터럴로만 쓴다.** Tailwind는 소스를 원시 텍스트로 스캔해 양방향으로 조용히 틀린다 — 문자열 조작으로 만든 클래스는 스캔되지 않아 **스타일이 없고**, 주석에 클래스처럼 생긴 문자열을 적으면 스캔돼 **없는 규칙이 생긴다**. 조건부는 완성된 리터럴 중 하나를 고르는 형태로 쓰고, 주석에서 클래스를 언급할 때 대괄호 arbitrary value를 그대로 적지 않는다(`docs/troubleshooting/2026-08-06-collection-spread-redesign-lessons.md`·`2026-08-06-silent-css-traps-nav-shell.md`). -- **새 컴포넌트를 만들기 전에 기존 구현을 먼저 찾는다.** 병렬 작업에서 배정받은 "내 파일 목록"은 쓰기 권한의 경계이지 **탐색 범위의 경계가 아니다**. 배정 밖 파일을 고쳐야 하면 우회해서 새로 만들지 말고 보고한다(S15P11A705-332). -- **모듈 스코프 플래그·전역 상태의 소비자를 지울 때 생산자도 함께 확인한다.** 타입으로 이어지지 않아 컴파일러가 알려주지 않는다 — 읽는 쪽을 지우면 쓰는 쪽이 아무도 안 보는 값을 계속 쓴다. 당장 지울 수 없으면 후속 정리 대상으로 명시한다(S15P11A705-332 → 350). +- **새 컴포넌트를 만들기 전에 기존 구현을 먼저 찾는다.** 병렬 작업에서 배정받은 "내 파일 목록"은 쓰기 권한의 경계이지 **탐색 범위의 경계가 아니다**. 배정 밖 파일을 고쳐야 하면 우회해서 새로 만들지 말고 보고한다(Jira 작업). +- **모듈 스코프 플래그·전역 상태의 소비자를 지울 때 생산자도 함께 확인한다.** 타입으로 이어지지 않아 컴파일러가 알려주지 않는다 — 읽는 쪽을 지우면 쓰는 쪽이 아무도 안 보는 값을 계속 쓴다. 당장 지울 수 없으면 후속 정리 대상으로 명시한다(Jira 작업 → 350). - **`httpClient`로 `FormData`(multipart) 요청을 보낼 때는 `Content-Type` 헤더를 지운다.** `httpClient`가 기본 헤더로 `Content-Type: application/json`을 고정하고 있어서, 그대로 두면 브라우저가 multipart boundary를 붙이지 못해 요청이 깨진다(서버가 `image/jpeg` 등을 JSON으로 파싱하려다 실패). ```typescript @@ -32,18 +32,18 @@ }); ``` - `'multipart/form-data'`를 직접 지정하지 않는다 — boundary 값을 브라우저가 요청 생성 시점에 채워야 하므로, 헤더를 아예 비워(`undefined`) 브라우저가 자동으로 채우게 한다. 예시: `suggestPlacesFromImage.ts`(S15P11A705-345). + `'multipart/form-data'`를 직접 지정하지 않는다 — boundary 값을 브라우저가 요청 생성 시점에 채워야 하므로, 헤더를 아예 비워(`undefined`) 브라우저가 자동으로 채우게 한다. 예시: `suggestPlacesFromImage.ts`(Jira 작업). ## 3. Git - 브랜치: `main`(배포), `dev`(통합). 기능은 항상 `dev`에서 분기한다. -- Jira 이슈키 형식: `S15P11A705-숫자` (예: `S15P11A705-42`). +- Jira 이슈키 형식: `Jira-숫자` (예: `Jira 작업`). | 대상 | 형식 | 예시 | | ------- | ---------------------------------- | ------------------------------------- | -| 브랜치 | `feature/S15P11A705-<번호>-<설명>` | `feature/S15P11A705-42-record-map` | -| 커밋 | `type(S15P11A705-<번호>): 설명` | `feat(S15P11A705-42): 지도 마커 조회` | -| PR 제목 | `[S15P11A705-<번호>] 설명` | `[S15P11A705-42] 지도 마커 조회` | +| 브랜치 | `feature/-<설명>` | `feature/-record-map` | +| 커밋 | `type(Jira-<번호>): 설명` | `feat(Jira 작업): 지도 마커 조회` | +| PR 제목 | `[Jira-<번호>] 설명` | `[Jira 작업] 지도 마커 조회` | - 커밋 `type`: `feat`, `fix`, `refactor`, `docs`, `chore`, `test`, `style` 등 Conventional Commits. - 설명은 한국어로 간결하게 쓴다. @@ -89,4 +89,4 @@ - `/dev/*` 등 개발·QA 전용 라우트는 `router.tsx`에서 `import.meta.env.DEV` 조건으로 라우트 트리 등록 자체를 감싼다(예시: `placeRecordPreviewRoute`). Vite가 빌드 타임에 상수로 치환해 프로덕션 빌드에서는 조건이 `false`로 굳어지므로 라우트가 등록되지 않아 해당 경로는 `NotFoundPage`로 떨어진다 — URL을 알아도 접근할 수 없다. (페이지 컴포넌트 자체는 모듈 그래프에서 정적으로 참조되므로 번들에는 남지만, 라우터가 마운트하지 않아 실행되지는 않는다.) - `beforeLoad` 인증 가드(`requireLoggedIn` 등)로는 대체하지 않는다. 개발 전용 라우트는 종종 "로그인 없이 테스트 세션을 발급"하는 등 인증 가드와 목적이 상충하는 기능을 담기 때문이다. -- 개발 전용 라우트가 호출하는 API가 있다면, 그 API가 운영 백엔드에도 노출되어 있는지 별도로 확인한다. 프론트에서 라우트를 숨겨도 백엔드 엔드포인트 자체가 운영에 살아 있으면 URL을 아는 누구나 호출할 수 있다 — 이건 프론트만으로는 막을 수 없는 백엔드 이슈다(S15P11A705-342). +- 개발 전용 라우트가 호출하는 API가 있다면, 그 API가 운영 백엔드에도 노출되어 있는지 별도로 확인한다. 프론트에서 라우트를 숨겨도 백엔드 엔드포인트 자체가 운영에 살아 있으면 URL을 아는 누구나 호출할 수 있다 — 이건 프론트만으로는 막을 수 없는 백엔드 이슈다(Jira 작업). diff --git "a/docs/reference/05-1_\355\214\214\355\212\270\352\260\204_\354\232\224\352\265\254\354\202\254\355\225\255.md" "b/docs/reference/05-1_\355\214\214\355\212\270\352\260\204_\354\232\224\352\265\254\354\202\254\355\225\255.md" index 7343e92..2835f2c 100644 --- "a/docs/reference/05-1_\355\214\214\355\212\270\352\260\204_\354\232\224\352\265\254\354\202\254\355\225\255.md" +++ "b/docs/reference/05-1_\355\214\214\355\212\270\352\260\204_\354\232\224\352\265\254\354\202\254\355\225\255.md" @@ -159,6 +159,6 @@ front#99 가이드의 호출 예제에는 인증 헤더가 없습니다. `POST / | 1.3 Feed 이벤트 | Front | Feed 동작 | | 1.4 등급 표시 | Front | 제품 결정 | | 1.5 입력 크기 상한 | Front | UX — 서버만 막으면 사용자가 다 쓴 뒤 거절당한다 | -| 1.6 표지 생성 플로우 | Front | 구현 정합성 + UX — back은 구현 완료(S15P11A705-322), 프론트 연결만 남음 | +| 1.6 표지 생성 플로우 | Front | 구현 정합성 + UX — back은 구현 완료(Jira 작업), 프론트 연결만 남음 | | 3.2 생성 요청 인증 | 이미지 서비스(INFRA) | 보안·비용 | | 3.1 표지 파일 보존 | 이미지 서비스(INFRA) | 확인 완료 — 정리 배치 도입 시 사전 통보 | diff --git "a/docs/reference/05_AI_\354\204\244\352\263\204.md" "b/docs/reference/05_AI_\354\204\244\352\263\204.md" index 3d62700..7fdb90d 100644 --- "a/docs/reference/05_AI_\354\204\244\352\263\204.md" +++ "b/docs/reference/05_AI_\354\204\244\352\263\204.md" @@ -442,7 +442,7 @@ openai-text-embedding-3-small-1536-cosine-v1 - Context와 Keyword Preset은 같은 Embedding Profile을 사용합니다. - **Profile의 정본은 FastAPI 설정의 기본값입니다**(`ai` 레포 `app/core/config.py`). 배포 환경변수 주입은 실험·롤백을 위한 **덮어쓰기**이며 필수가 아닙니다. - Spring과 FastAPI가 서로 다른 Profile을 갖는 것은 **런타임 대조**로 막습니다. Spring이 검색 요청에 실어 보낸 `embeddingProfile`이 FastAPI 설정과 다르면 요청을 거부하며, 빈 결과를 돌려주지 않습니다 — 빈 결과는 "일치하는 기록이 없음"으로 보여 설정 오류를 숨깁니다. 처리 상세는 `ai` 레포 `docs/spec/model-profile.md` 3.1. -- Spring이 그 값을 어디서 얻는지는 **검색 연동 시점에 정합니다**(`S15P11A705-135`). 소비자가 없는 상태에서 정하면 붙일 때 다시 뒤집힙니다. +- Spring이 그 값을 어디서 얻는지는 **검색 연동 시점에 정합니다**(`Jira 작업`). 소비자가 없는 상태에서 정하면 붙일 때 다시 뒤집힙니다. Profile 문자열의 버전 표기는 모델·전처리 구성을 식별하는 값이며 Context와 무관합니다. diff --git a/docs/troubleshooting/2026-08-06-background-polling-provider-lifetime.md b/docs/troubleshooting/2026-08-06-background-polling-provider-lifetime.md index e584dbb..10e565f 100644 --- a/docs/troubleshooting/2026-08-06-background-polling-provider-lifetime.md +++ b/docs/troubleshooting/2026-08-06-background-polling-provider-lifetime.md @@ -1,7 +1,7 @@ # 백그라운드 폴링이 화면을 옮기면 취소된다 — 구독자 수명과 Provider 위치 - 날짜: 2026-08-06 -- 관련 이슈키: S15P11A705-326 +- 관련 이슈키: Jira 작업 ## 증상 @@ -66,9 +66,9 @@ Provider가 하는 일은 잡 목록 관리뿐이고, 폴링·저장은 잡마 ## 관련 이슈키 -- S15P11A705-326 (PR #125) — 이 문서 -- S15P11A705-318 — 표지 선택 모달(`CollectionCoverModal`), "나중에 하기"를 두지 않기로 한 결정 -- S15P11A705-327 (PR #131) — 장소 추가로 만든 새 컬렉션도 표지 선택을 거치게 함 +- Jira 작업 (PR #125) — 이 문서 +- Jira 작업 — 표지 선택 모달(`CollectionCoverModal`), "나중에 하기"를 두지 않기로 한 결정 +- Jira 작업 (PR #131) — 장소 추가로 만든 새 컬렉션도 표지 선택을 거치게 함 --- diff --git a/docs/troubleshooting/2026-08-06-collection-spread-redesign-lessons.md b/docs/troubleshooting/2026-08-06-collection-spread-redesign-lessons.md index 0dddf3c..231e7cb 100644 --- a/docs/troubleshooting/2026-08-06-collection-spread-redesign-lessons.md +++ b/docs/troubleshooting/2026-08-06-collection-spread-redesign-lessons.md @@ -1,9 +1,9 @@ # 컬렉션 펼친 화면 재설계에서 반복된 함정들 (레인 시야·죽은 소비자·Tailwind·지도) - 날짜: 2026-08-06 -- 관련 이슈키: S15P11A705-332 +- 관련 이슈키: Jira 작업 -여러 세션이 worktree를 나눠(L1 상세 / L2 표지 / L3 책장) 동시에 작업하는 중에 S15P11A705-332를 +여러 세션이 worktree를 나눠(L1 상세 / L2 표지 / L3 책장) 동시에 작업하는 중에 Jira 작업를 진행하며 겪은 문제를 모았다. 개별 버그보다 **반복된 패턴**이 남길 가치가 있어 한 문서로 묶는다. --- @@ -185,11 +185,11 @@ record 장의 확대 레벨을 6 → 3으로 당기면서 발견했다. 기존 ## 관련 이슈키 -- S15P11A705-332 (컬렉션 펼친 화면 재설계) -- S15P11A705-207 (오버레이 진입 구분 — `collectionOverlayIntent` 도입) -- S15P11A705-143 (`ShelfExploreSection` 원본) -- S15P11A705-307 (마커 SVG asset·`RecordMapView` 마커 처리) -- S15P11A705-245 / -246 / -171 (목차 fitBounds · 인덱스 레일 · 지도 고정 레벨) +- Jira 작업 (컬렉션 펼친 화면 재설계) +- Jira 작업 (오버레이 진입 구분 — `collectionOverlayIntent` 도입) +- Jira 작업 (`ShelfExploreSection` 원본) +- Jira 작업 (마커 SVG asset·`RecordMapView` 마커 처리) +- Jira 작업 / -246 / -171 (목차 fitBounds · 인덱스 레일 · 지도 고정 레벨) --- diff --git a/docs/troubleshooting/2026-08-06-dev-auth-login-prod-check.md b/docs/troubleshooting/2026-08-06-dev-auth-login-prod-check.md index 371f2dc..ee41bcf 100644 --- a/docs/troubleshooting/2026-08-06-dev-auth-login-prod-check.md +++ b/docs/troubleshooting/2026-08-06-dev-auth-login-prod-check.md @@ -1,7 +1,7 @@ # 운영 백엔드 /dev/auth/login 노출 여부 확인 - 날짜: 2026-08-06 -- 관련 이슈키: S15P11A705-342 +- 관련 이슈키: Jira 작업 ## 증상 @@ -33,9 +33,9 @@ $ curl -s https://pin-log.com/api/core/v1/dev/auth/login ## 재발 방지 -- 프론트: 라우트 자체를 `import.meta.env.DEV`로 감싸 프로덕션 번들에서 제외(S15P11A705-342, `docs/conventions.md` 7장에 규칙 추가). +- 프론트: 라우트 자체를 `import.meta.env.DEV`로 감싸 프로덕션 번들에서 제외(Jira 작업, `docs/conventions.md` 7장에 규칙 추가). - 백엔드: dev 프로파일 전용 컨트롤러가 prod 프로파일 빌드/설정에 포함되지 않는지는 백엔드 팀 확인이 필요하다. 이번 실측상 운영에서 열려 있지 않음이 확인됐으므로 별도 이슈 승격은 하지 않는다. ## 관련 이슈키 -S15P11A705-342 +Jira 작업 diff --git a/docs/troubleshooting/2026-08-06-map-remount-ref-state-race.md b/docs/troubleshooting/2026-08-06-map-remount-ref-state-race.md index 2ee604f..71fb3b7 100644 --- a/docs/troubleshooting/2026-08-06-map-remount-ref-state-race.md +++ b/docs/troubleshooting/2026-08-06-map-remount-ref-state-race.md @@ -1,7 +1,7 @@ # 화면을 다녀오면 지도 마커가 다시 그려지지 않는다 — ref와 state의 이중 관리 - 날짜: 2026-08-06 -- 관련 이슈키: S15P11A705-346 +- 관련 이슈키: Jira 작업 ## 증상 @@ -54,9 +54,9 @@ Error: Calling setState synchronously within an effect can trigger cascading ren ## 관련 이슈키 -- S15P11A705-346 (GitHub front#128) — 이 문서 -- S15P11A705-307 — SDK 재로드 깜빡임 제거(`isKakaoMapsSdkReady` 초기화), StrictMode 이중 Map 생성 가드, `isolate` stacking context -- S15P11A705-325 — 가시 영역 보정(`topObstructionPx`, `readInsets`, 저장 후 `focusRecordId` `panTo`) +- Jira 작업 (GitHub front#128) — 이 문서 +- Jira 작업 — SDK 재로드 깜빡임 제거(`isKakaoMapsSdkReady` 초기화), StrictMode 이중 Map 생성 가드, `isolate` stacking context +- Jira 작업 — 가시 영역 보정(`topObstructionPx`, `readInsets`, 저장 후 `focusRecordId` `panTo`) --- diff --git a/docs/troubleshooting/2026-08-06-overflow-y-auto-clips-horizontally.md b/docs/troubleshooting/2026-08-06-overflow-y-auto-clips-horizontally.md index c74d075..e166e61 100644 --- a/docs/troubleshooting/2026-08-06-overflow-y-auto-clips-horizontally.md +++ b/docs/troubleshooting/2026-08-06-overflow-y-auto-clips-horizontally.md @@ -1,7 +1,7 @@ # `overflow-y-auto`가 가로도 클리핑한다 — 선반 판 그림자가 잘리던 원인 - 날짜: 2026-08-06 -- 관련 이슈키: S15P11A705-328 +- 관련 이슈키: Jira 작업 ## 증상 @@ -61,4 +61,4 @@ box-shadow: 0 10px 16px rgba(4,33,66,.13) ## 관련 이슈키 -S15P11A705-328 (315·319의 후속) +Jira 작업 (315·319의 후속) diff --git a/docs/troubleshooting/2026-08-06-parallel-worktree-sessions.md b/docs/troubleshooting/2026-08-06-parallel-worktree-sessions.md index df6eda5..2747dde 100644 --- a/docs/troubleshooting/2026-08-06-parallel-worktree-sessions.md +++ b/docs/troubleshooting/2026-08-06-parallel-worktree-sessions.md @@ -42,7 +42,7 @@ PinLog/ git은 같은 브랜치를 두 worktree에서 체크아웃하지 못하게 막는다. 조율 세션이 `front/`에서 `dev`를 잡고 있으므로 **레인은 `dev`를 건드릴 수 없다.** - 최신화: `git fetch origin && git rebase origin/dev` -- 다음 티켓 브랜치: `git checkout -b feature/S15P11A705-XXX-... origin/dev` +- 다음 티켓 브랜치: `git checkout -b feature/Jira-XXX-... origin/dev` - ❌ `git pull` / ❌ `git checkout dev` **재발 방지**: worktree 브리프에 이 세 줄을 명시한다. 모르면 레인이 `git checkout dev`에서 막히고 원인을 못 찾는다. @@ -50,7 +50,7 @@ git은 같은 브랜치를 두 worktree에서 체크아웃하지 못하게 막 ## 3. `git worktree add -b`가 upstream을 `origin/dev`로 잡는다 ```bash -git worktree add ../front-cover -b feature/S15P11A705-326-... origin/dev +git worktree add ../front-cover -b feature/-... origin/dev # → branch '...' set up to track 'origin/dev' ``` @@ -109,8 +109,8 @@ gitignore라 당연히 안 따라오는데, 없으면 앱이 **에러 없이 반 ## 재발 방지 — 세팅 체크리스트 ```bash -git worktree add ../front- -b feature/S15P11A705-XXX- origin/dev -git branch --unset-upstream feature/S15P11A705-XXX- # 3번 +git worktree add ../front- -b feature/Jira-XXX- origin/dev +git branch --unset-upstream feature/Jira-XXX- # 3번 cp .env ../front-/.env # 5번 (cd ../front- && npm ci) # 4번 # CLAUDE.local.md 작성 (2번 규칙 + 담당 파일 목록 포함) # 6번 @@ -124,4 +124,4 @@ git worktree remove ../front- && git worktree prune ## 관련 이슈키 -- S15P11A705-326·327·328·329·330·332·346·347 (이 방식으로 진행) +- Jira 작업·327·328·329·330·332·346·347 (이 방식으로 진행) diff --git a/docs/troubleshooting/2026-08-06-sessionstorage-across-oauth-roundtrip.md b/docs/troubleshooting/2026-08-06-sessionstorage-across-oauth-roundtrip.md index c592263..3dac3e8 100644 --- a/docs/troubleshooting/2026-08-06-sessionstorage-across-oauth-roundtrip.md +++ b/docs/troubleshooting/2026-08-06-sessionstorage-across-oauth-roundtrip.md @@ -1,7 +1,7 @@ # OAuth 왕복을 건너 사실을 전달한다 — sessionStorage 패턴과 그 함정 - 날짜: 2026-08-06 -- 관련 이슈키: S15P11A705-347 +- 관련 이슈키: Jira 작업 ## 증상 @@ -51,6 +51,6 @@ TTL 값에 대해서는 판단이 하나 필요했다. 이슈는 "인가 요청 ## 관련 이슈키 -- S15P11A705-347 (GitHub front#105) — 이 문서 -- S15P11A705-99 — `preLoginPath` 패턴의 출처(콜백 성공 시 복귀 경로) -- S15P11A705-162 — 탈퇴 확인 다이얼로그 +- Jira 작업 (GitHub front#105) — 이 문서 +- Jira 작업 — `preLoginPath` 패턴의 출처(콜백 성공 시 복귀 경로) +- Jira 작업 — 탈퇴 확인 다이얼로그 diff --git a/docs/troubleshooting/2026-08-06-shelf-column-header-height-coupling.md b/docs/troubleshooting/2026-08-06-shelf-column-header-height-coupling.md index 49d341d..f344c92 100644 --- a/docs/troubleshooting/2026-08-06-shelf-column-header-height-coupling.md +++ b/docs/troubleshooting/2026-08-06-shelf-column-header-height-coupling.md @@ -1,7 +1,7 @@ # 책장 열 헤더 행 높이(`h-7`)가 행 수·선반 위치를 좌우한다 - 날짜: 2026-08-06 -- 관련 이슈키: S15P11A705-329 +- 관련 이슈키: Jira 작업 ## 증상 @@ -48,4 +48,4 @@ ## 관련 이슈키 -S15P11A705-329 (295 추가 수정 이슈 4의 재발 방지) +Jira 작업 (295 추가 수정 이슈 4의 재발 방지) diff --git a/docs/troubleshooting/2026-08-06-silent-css-traps-nav-shell.md b/docs/troubleshooting/2026-08-06-silent-css-traps-nav-shell.md index d9d8dc1..cc25636 100644 --- a/docs/troubleshooting/2026-08-06-silent-css-traps-nav-shell.md +++ b/docs/troubleshooting/2026-08-06-silent-css-traps-nav-shell.md @@ -1,7 +1,7 @@ # 조용히 잘못되는 CSS 셋 — safe-area·:focus-within·Tailwind가 주석을 읽는다 - 날짜: 2026-08-06 -- 관련 이슈키: S15P11A705-330 +- 관련 이슈키: Jira 작업 ## 배경 @@ -130,4 +130,4 @@ grep -oE "[^{},]*focus-visible[^{}]*\{[^}]*\}" dist/assets/*.css ## 관련 이슈키 -- S15P11A705-330 +- Jira 작업 diff --git a/docs/troubleshooting/2026-08-07-content-layer-swallows-map-clicks.md b/docs/troubleshooting/2026-08-07-content-layer-swallows-map-clicks.md index 6006f4f..0e1f5dc 100644 --- a/docs/troubleshooting/2026-08-07-content-layer-swallows-map-clicks.md +++ b/docs/troubleshooting/2026-08-07-content-layer-swallows-map-clicks.md @@ -1,7 +1,7 @@ # Home 컨텐츠 레이어가 지도·지역 클릭을 통째로 삼켰다 - 날짜: 2026-08-07 -- 관련 이슈키: S15P11A705-376, S15P11A705-377 +- 관련 이슈: Jira 작업 ## 증상 @@ -30,4 +30,4 @@ ## 관련 이슈키 -S15P11A705-376(지역 뷰 도입 — 버그 유입), S15P11A705-377(원인 규명·수정, PR #160) +Jira 작업(지역 뷰 도입 — 버그 유입), Jira 작업(원인 규명·수정, PR #160) diff --git a/docs/troubleshooting/2026-08-07-free-font-license-blocks-subset-pipeline.md b/docs/troubleshooting/2026-08-07-free-font-license-blocks-subset-pipeline.md index 3a5f6fd..4850d15 100644 --- a/docs/troubleshooting/2026-08-07-free-font-license-blocks-subset-pipeline.md +++ b/docs/troubleshooting/2026-08-07-free-font-license-blocks-subset-pipeline.md @@ -1,7 +1,7 @@ # "무료 폰트"여도 서브셋·WOFF2 변환이 라이선스 위반일 수 있다 - 날짜: 2026-08-07 -- 관련 이슈키: S15P11A705-380 +- 관련 이슈키: Jira 작업 ## 증상 @@ -33,4 +33,4 @@ ## 관련 이슈키 -S15P11A705-380(PR #162), S15P11A705-357(서브셋 파이프라인·외부 폰트 0건 정책), S15P11A705-375(Gaegu CDN 제거) +Jira 작업(PR #162), Jira 작업(서브셋 파이프라인·외부 폰트 0건 정책), Jira 작업(Gaegu CDN 제거) diff --git a/docs/troubleshooting/2026-08-07-squash-merge-stacked-branch-rebase.md b/docs/troubleshooting/2026-08-07-squash-merge-stacked-branch-rebase.md index 2edccf0..4a289e4 100644 --- a/docs/troubleshooting/2026-08-07-squash-merge-stacked-branch-rebase.md +++ b/docs/troubleshooting/2026-08-07-squash-merge-stacked-branch-rebase.md @@ -1,7 +1,7 @@ # 스택 브랜치가 부모 squash 머지 후 CONFLICTING이 된다 — `--onto` 재배치로 해소 - 날짜: 2026-08-07 -- 관련 이슈키: S15P11A705-374 (외 371·376·377·378·379·386·389 동일 패턴) +- 관련 이슈키: Jira 작업 (외 371·376·377·378·379·386·389 동일 패턴) ## 증상 @@ -32,4 +32,4 @@ git push --force-with-lease origin ## 관련 이슈키 -S15P11A705-374(PR #157 — 최초 발생·해법 확립), 이후 371/376/377/378/379/386/389 스택 정리에 동일 적용 +Jira 작업(PR #157 — 최초 발생·해법 확립), 이후 371/376/377/378/379/386/389 스택 정리에 동일 적용 diff --git a/docs/troubleshooting/README.md b/docs/troubleshooting/README.md index 9e7b10f..2f15465 100644 --- a/docs/troubleshooting/README.md +++ b/docs/troubleshooting/README.md @@ -14,7 +14,7 @@ # <제목> - 날짜: YYYY-MM-DD -- 관련 이슈키: S15P11A705-<번호> +- 관련 이슈키: Jira-<번호> ## 증상 diff --git a/fonts-src/README.md b/fonts-src/README.md index 42d3d9b..61e4e8b 100644 --- a/fonts-src/README.md +++ b/fonts-src/README.md @@ -3,7 +3,7 @@ 이 디렉터리는 **웹에 서빙되지 않는다.** 원본 TTF와 변환 스크립트만 들어 있다. 실제로 브라우저가 받는 파일은 `public/fonts/*.woff2` 이고, 그건 여기서 만들어 낸 산출물이다. -근거: Jira S15P11A705-357 +근거: Jira 작업 ## 왜 원본을 그대로 쓰지 않나