Skip to content

release: dev → main (i18n 서피스 확장 + decode 태그 파리티)#892

Merged
cocoyoon merged 19 commits into
mainfrom
dev
Jul 11, 2026
Merged

release: dev → main (i18n 서피스 확장 + decode 태그 파리티)#892
cocoyoon merged 19 commits into
mainfrom
dev

Conversation

@cocoyoon

Copy link
Copy Markdown
Member

dev → main 릴리스. dev에서 이미 CI 통과·머지된 미배포분을 prod로 승격.

포함 (실질 변경 8)

배포 후 (env)

  • 신규 env 변경 없음 — #891은 proto/OpenAPI/env 변경 없이 기존 컬럼(context/style_tags) 재사용.

후속 (non-blocking)

🤖 Generated with Claude Code

thxforall and others added 19 commits July 11, 2026 01:38
* fix(web): 공개 프로필 강제 다크 해제·더블 크롬 제거 (#839)

공개 프로필 /profile/[userId]가 강제 다크(`<div className="dark">`)로 뷰어
테마를 무시하고, 자체 모바일/데스크톱 헤더를 렌더해 AppShell 크롬과 더블
크롬이 됐다.

- page.tsx: 강제 다크 래퍼 제거 → 뷰어 라이트/다크 테마 인식(클라이언트는
  semantic 토큰만 사용). 전면 3-zone V2 rebuild는 #809.
- PublicProfileClient.tsx: 자체 헤더(모바일 `<header>` + 데스크톱 `<Header/>`)를
  main/not-found/skeleton/error 4개 렌더 경로 전부 제거하고 AppShell 크롬에
  위임. 헤더 잔재였던 pt-16(전 (shell) 페이지 중 유일 outlier)도 제거해 시각
  일관성 복원. 미사용 import(Header/ArrowLeft/Share2)·shareProfile 정리.

모바일 공유 버튼(URL 복사)이 제거된 헤더와 함께 사라지는 기능 손실은 quickfix
범위상 수용, 재배치는 #809/후속으로 이관.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(web): 공개 프로필 단일 크롬·테마 인식 회귀 가드 추가 (#839)

#839 회귀 가드.

- PublicProfileClient.test.tsx: 4개 렌더 상태(main/not-found/skeleton/error)가
  자체 `<header>`·`<Header/>`를 렌더하지 않음을 검증. 기존 #669 Style DNA
  privacy 테스트는 유지.
- page-theme.test.tsx: 서버 컴포넌트 트리에 강제 `dark` 클래스가 없음을 검증
  (뷰어 테마 인식). node 환경에서 async 서버 컴포넌트를 직접 호출해 element
  트리를 검사.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
드롭다운 엔티티 히트(brand/artist/group)를 일반 텍스트 히트와 시각적으로
구분하고, 클릭 시 막다른 길이 아니라 canonical 텍스트 검색으로 브리지한다.

- entityHit.ts: 엔티티 히트 → 검색어 브리지 seam(entityHitToCanonicalQuery).
  raw alias가 아닌 resolved 엔티티 name으로 검색. posts는 locale-blind
  (고유명사)라 name_en override 없이 localized name 유지 → 한글 기반 엔티티
  회귀 방지. entity_id는 interim에서 미소비(엔티티 페이지=후속 #799).
- SearchSuggestions.tsx: 클릭·키보드 Enter 모두 seam 경유로 일관화.
  kind 라벨을 semantic token pill로 승격 + data-hit-type 구분 훅 추가.
- search-locale-behavior.md: posts locale-blind 검색 동작 문서화(#796 D-SEARCH).

D-SEARCH 결정 #796: interim=alias→canonical 텍스트검색 유지 + 히트 시각 구분.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
프로필 자체 화면(ProfileClient·ProfileHeaderCardV2·ProfileRightRail)의
하드코딩 문자열을 Home 베이스라인(#838, i18n-surface-pattern) 그대로
next-intl로 배선. Profile 네임스페이스를 ko/en 1:1로 추가(한국어 실초안),
parity 테스트 + render-seam 테스트 추가.

- Profile은 CSR(shell 내부, provider 하위)이라 RSC locale 전달은 불필요.
- 공개 프로필([userId]) 문자열은 미머지 PR #860(#839)과의 파일 겹침을
  피하려 이번 슬라이스에서 제외 → #860 머지 후 별도 배선.
- auth 폼(Login/Signup) i18n은 non-[locale] 라우트라 provider 부재 →
  별도 결정 필요, 이번 커밋 미포함(PR 본문 참조).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
라이브러리 surface(LibraryShell, LikedItemsGrid, LikesGrid)를 Home #838
패턴대로 `Library` 네임스페이스로 ko/en 배선하고, LikesGrid의 영/한 혼용
문구와 `ko-KR` 하드코딩 날짜 포맷을 로케일-어웨어로 정리한다.

- messages/{ko,en}.json에 `Library` 네임스페이스 1:1 추가 (실제 한국어 초안)
- LikesGrid 날짜: `toLocaleDateString("ko-KR", …)` → Home ICU-plural 상대시간
  (ko "N일 전" / en "N days ago", ko=other만). >30일 fallback도 활성 로케일
  소비 (하드코딩 ko-KR 제거)
- LikesGrid 영/한 혼용(error/retry/untitled/postAlt/empty) 전부 t() 배선
- 테스트: library-messages-parity(Home 복제) + LikedItemsGrid.locale +
  LikesGrid.timeAgo. tsc 0 · 신규 7 + 기존 i18n 그린

Note: LikesGrid는 profile 디렉터리 컴포넌트지만 Library 탭에서 렌더되므로
#846 소유로 `Library` 네임스페이스를 읽는다. 향후 Profile 슬라이스는
LikesGrid를 재배선하지 말 것 (공유 문구 경계).

Closes #846

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…배선·드롭다운 크롬 (#843) (#880)

BE 비종속 FE 정직화 (PRD #825 / D-EXPLORE #797). 서버 facet 소비는 graduated(#799/#851/#842).

- 정렬(crit1): mode-aware 옵션 — browse는 solution_count 숨김(useInfinitePosts 미지원, 무성 no-op),
  search만 노출(service.rs가 실제 지원). search→browse 전환 시 coerceSortForMode로 표시값 정합.
- 스타일 칩 desync(crit2): activeStyle을 query에서 파생(단일 소스). 자유 입력·서제스천 선택으로
  query가 갈라지면 하이라이트 자동 해제 → stale-highlight 제거.
- CategoryFilter(crit3): 아무도 안 읽던 useFilterStore write(죽은 컴포넌트)를 controlled
  canned-query 팔레트로 재배선 + 마운트. 파생 하이라이트, 빈 결과는 기존 recovery 상태로.
- editorial 칩(crit4): 라벨=canned query 유지, 파생 하이라이트로 dead-end 구조적 제거.
- 검색 드롭다운(crit5): ExploreClient wrapper 카드 + SearchSuggestions 자체 카드 이중크롬 제거
  (단일 크롬). input을 combobox(aria-expanded/controls/autocomplete)로, listbox에 id/aria-label.

canned query 값은 product/editorial 결정(라벨=title/artist/group 텍스트 검색, 결과 충만도는
라이브 인덱스 콘텐츠 의존). TDD: exploreFilters 순수 로직 15 케이스.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
explore surface의 하드코딩 영문을 useTranslations("Explore")로 배선
(#838 홈 baseline 패턴 복제). messages/{ko,en}.json에 Explore 네임스페이스
신설(ko는 실제 한국어 초안), 키셋 1:1 파리티 + ICU 보간 정적 테스트를
i18n/__tests__에 추가. explore는 CSR(client mutator가 URL locale 추종)
이라 RSC serverApiGet locale 전달 스텝은 불필요(홈 전용 갭).

배선: ExploreClient(헤더/검색/에러·엠프티 상태/로딩), EntityTabBar(탭
라벨+aria), ComingSoonState(타이틀/설명/배지), SortDropdown(정렬 라벨),
ExploreCardCell(alt/스팟 aria, ICU plural). 엠프티 상태 동적 카피는 ICU
이스케이프 함정을 피해 곡선따옴표(‘{query}’) 사용 + 보간 테스트로 가드.

스코프 결정:
- STYLE_TAXONOMY 스타일칩/POPULAR_SEARCH_TAGS는 미번역 — 라벨이 검색
  쿼리로 그대로 주입(setQuery)되는 검색 토큰/고유명사라 번역 시 백엔드
  검색 동작이 바뀜.
- SearchSuggestions(전역 검색 드롭다운)는 이번 스코프 제외 — 비지역화
  루트 레이아웃 Header에도 마운트되어 NextIntlClientProvider 밖이라
  useTranslations 배선 시 전역 크래시. 셸 프로바이더 커버리지 후속 필요.

#880(#843 explore 필터 interim)과 ExploreClient.tsx·SortDropdown.tsx
공유 — 문자열만 t() 교체, 필터 로직/SORT_OPTIONS 상수 shape 미변경
(나중 머지 rebase 최소화).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
decode_look(#746)이 CodyDescribeParser만 돌려 style_tags/context/
style_formula가 배치 파이프라인과 달리 비어 있던 문제 수정.

- LookDecoder: SubjectParser(context/style_tags, Stage1과 동시 실행) +
  CodyFormulaParser(style_formula, 텍스트-only) optional 배선, 둘 다
  soft-fail. artist/group은 의도적으로 버림(유저 본인 업로드).
- api-server: DecodeResult에 context/style_tags 필드 추가해 post
  ActiveModel에 반영 (proto/OpenAPI 변경 불필요 — opaque result_json +
  기존 DTO 컬럼 재사용).
`[locale]/(shell)/profile/[userId]` 라우트의 params 타입은 `{ userId, locale }`
인데 #839 page-theme 테스트가 `{ userId }`만 mock 하여 tsc 타입 불일치(TS2322)
가 발생했다. 로컬 tsc / next build 에서만 드러나던 것(web typecheck CI 부재).
mock 에 `locale: "en"` 추가로 해소. 런타임 동작·단언 불변.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
look_decoder.py 에 subject/formula 배선(#891) 이전에 생성된 post_type='decode'
포스트는 이 세 필드가 비어 있었다. SubjectParser/CodyFormulaParser 를 직접
호출해 소급 적용하는 일회성 스크립트 추가 — idempotent(이미 채워진 값은
COALESCE/조건절로 보존), dry-run 지원.

prod 3건(87b3425a, 3a6a48b6, c9c71b15) 적용 완료 — session-mode pooler(5432,
15 slot) 가 상시 포화 상태라 transaction-mode pooler(6543)로 접속해 처리.
* feat(web): 언어 전환을 Settings 페이지로 이동, 셸 로케일 토글 제거

사이드바(AppSidebar)와 모바일 상단바(MobileTopAppBar)의 LocaleSwitcher pill
토글을 제거하고, /settings 의 APPEARANCE 섹션과 동일한 라디오 행 스타일로
LANGUAGE 섹션을 추가한다. 전환은 기존 메커니즘 그대로 next-intl navigation
으로 로케일 프리픽스만 교체하고 현재 pathname 을 유지한다.

- SettingsClient: LANGUAGE 라디오그룹(LIVE_LOCALES 기반, 한국어/English)
- AppSidebar/MobileTopAppBar: LocaleSwitcher 렌더 제거
- LocaleSwitcher.tsx + 테스트 삭제(소비처 0), switch 커버리지는
  SettingsClient 테스트로 이관

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* style(web): SettingsClient LANGUAGE_LABELS prettier 포맷 정리

Record<> 타입 어노테이션 줄바꿈을 prettier 규칙에 맞춰 정리(eslint
prettier/prettier 4건 해소). 순수 포맷팅 변경으로 동작·타입 무변.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
decoded-app Ready Ready Preview, Comment Jul 11, 2026 10:15am

@cocoyoon
cocoyoon merged commit 16cfcc3 into main Jul 11, 2026
4 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in decoded-monorepo Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants