Skip to content

Comments

[Feat/analytics-102] ✨ feat: Analytics 추가 & 시리즈 수 집계 로직 수정#103

Merged
swallowedB merged 2 commits intodevfrom
feat/analytics-102
Jan 14, 2026
Merged

[Feat/analytics-102] ✨ feat: Analytics 추가 & 시리즈 수 집계 로직 수정#103
swallowedB merged 2 commits intodevfrom
feat/analytics-102

Conversation

@swallowedB
Copy link
Owner

@swallowedB swallowedB commented Jan 14, 2026

요약

  • 변경 목적(왜?): Vercel Analytics 연동 및 시리즈 수 집계 로직 정확도 확보
  • 주요 변경(무엇을?): Analytics 추가 + series 집계 로직 레지스트리 기반으로 수정

변경 내용

  • Analytics 연동: layout에 <Analytics /> 삽입
  • series 집계 로직 수정: SERIRES_META_BY_CATEGORY 기반으로 계산되도록 변경
  • 문서/설정 변경 없음

테스트

  • 로컬 테스트 정상
  • 타입체크/린트 통과
  • 빌드 정상

관련 이슈

close #102

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 사이트 방문 및 사용자 활동에 대한 분석 데이터 수집 기능이 추가되었습니다.
  • 스타일

    • 카테고리별 통계 위젯의 월간 통계 레이블 텍스트가 개선되었습니다.

✏️ Tip: You can customize this high-level summary in your review settings.

@swallowedB swallowedB linked an issue Jan 14, 2026 that may be closed by this pull request
3 tasks
@vercel
Copy link

vercel bot commented Jan 14, 2026

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

Project Deployment Review Updated (UTC)
b0o0a Ready Ready Preview, Comment Jan 14, 2026 3:59pm

@coderabbitai
Copy link

coderabbitai bot commented Jan 14, 2026

📝 Walkthrough

📋 Walkthrough

Vercel Analytics 의존성을 추가하고 레이아웃에 Analytics 컴포넌트를 통합했습니다. 동시에 시리즈 개수 계산 로직을 메타데이터 조회로 단순화하고 UI 텍스트를 업데이트했습니다.

📊 Changes

Cohort / File(s) 요약
Analytics 통합
package.json, src/app/layout.tsx
@vercel/analytics 의존성 추가 및 Analytics 컴포넌트를 root layout에 마운트하여 페이지 방문 데이터 수집 활성화
시리즈 계산 최적화
src/lib/posts/stats.ts
seriesCount 계산을 Set 기반 중복 제거에서 SERIES_META_BY_CATEGORY 직접 조회로 변경. 더 이상 포스트 매핑/필터링 불필요
UI 텍스트 & 정리
src/app/(layout)/(shell)/(category)/[category]/_components/CategoryWidget.tsx
두 번째 StatWidget 레이블을 "New This Month"에서 "This Month"로 변경, 레이아웃 주석 제거

🎯 Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

📌 Possibly related PRs

🎭 Poem

📈 분석의 눈을 열고
스탯도 깔끔하게 재계산하니
데이터는 흐르고, 코드는 맑아지고
이제 우린 더 잘 알게 되겠지
사용자들이 어디서 머무르는지 ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 3
❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning CategoryWidget.tsx에서 UI 텍스트 변경('New This Month' → 'This Month')이 이루어졌는데, 이는 linked issue #102의 명시된 요구사항에 포함되지 않았습니다. CategoryWidget의 UI 텍스트 변경이 issue #102의 요구사항과 관련이 있는지 확인하고, 불필요하다면 별도 PR로 분리하거나 이슈를 업데이트하세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive PR이 issue #102의 주요 목표인 Vercel Analytics 추가와 시리즈 집계 로직 수정을 구현했습니다. 다만 cmdk 자동저장 기능 비활성화는 포함되지 않았습니다. cmdk 자동저장 기능 비활성화 관련 변경사항이 누락된 것 같습니다. 이것이 별도 PR에서 처리될 예정인지 확인이 필요합니다.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 PR의 주요 변경사항(Analytics 추가 및 시리즈 집계 로직 수정)을 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명이 템플릿 구조를 따르고 변경 목적, 주요 변경사항, 테스트 완료 상태를 포함하고 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@swallowedB swallowedB merged commit 8d40ac0 into dev Jan 14, 2026
3 of 4 checks passed
@swallowedB swallowedB deleted the feat/analytics-102 branch January 14, 2026 16:01
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/app/layout.tsx`:
- Around line 46-48: The <Analytics /> component is currently rendered outside
the ThemeProvider which breaks component hierarchy consistency; move the
<Analytics /> JSX so it is rendered inside the ThemeProvider (e.g., after
{children} but before closing ThemeProvider) to keep component structure
consistent while leaving functionality unchanged; update the render in
layout.tsx so ThemeProvider wraps children and <Analytics /> together.

In `@src/lib/posts/stats.ts`:
- Around line 71-72: The series lookup is failing due to case mismatch between
registry IDs and post-config transformed IDs: normalize casing during lookup
instead of relying on registry changes; update getSeriesMeta (and any code
referencing SERIES_META_BY_CATEGORY or the s.id === seriesId comparison) to
compare a normalized form (e.g., convert both s.id and seriesId to toLowerCase()
or apply a shared normalize function) so seriesCount and series-based filtering
use the same canonical casing as capitalizeFirst in velite.config.ts.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc876c3 and 54477c3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • package.json
  • src/app/(layout)/(shell)/(category)/[category]/_components/CategoryWidget.tsx
  • src/app/layout.tsx
  • src/lib/posts/stats.ts
🧰 Additional context used
🧬 Code graph analysis (2)
src/lib/posts/stats.ts (3)
src/lib/posts/registry/series.registry.ts (1)
  • SERIES_META_BY_CATEGORY (4-60)
src/app/(layout)/(shell)/(category)/[category]/_components/CategorySeries.tsx (4)
  • acc (38-42)
  • CategorySeries (26-70)
  • m (44-51)
  • p (35-35)
src/lib/posts/queries.ts (1)
  • getSeriesListByCategory (68-70)
src/app/(layout)/(shell)/(category)/[category]/_components/CategoryWidget.tsx (2)
src/app/(layout)/(shell)/(category)/[category]/_components/widget/MissionWidget.tsx (2)
  • MissionWidget (7-49)
  • MissionWidgetProps (1-5)
src/app/(layout)/(shell)/(category)/[category]/_components/widget/StatWidget.tsx (2)
  • StatWidget (8-24)
  • StatWidgetProps (2-6)
🔇 Additional comments (4)
src/app/(layout)/(shell)/(category)/[category]/_components/CategoryWidget.tsx (1)

37-41: LGTM!

라벨이 "New This Month"에서 "This Month"으로 간결하게 변경되었고, caption "이번 달 업데이트"와 잘 어울립니다. value에 이미 + 접두사가 있어 "신규" 의미가 충분히 전달됩니다.

src/app/layout.tsx (1)

5-5: LGTM!

@vercel/analytics/react에서 올바르게 import 되었습니다.

src/lib/posts/stats.ts (1)

4-4: LGTM!

시리즈 메타데이터 레지스트리를 import하여 중앙 집중화된 데이터 소스를 활용합니다.

package.json (1)

22-22: @vercel/analytics 의존성 추가 확인됨.

@vercel/analytics@^1.6.1dependencies에 올바르게 추가되었으며, 현재 npm의 최신 안정 버전(1.6.1)입니다. src/app/layout.tsx에서 Analytics 컴포넌트로 정상 임포트되어 Vercel 배포 환경에서 자동으로 연동됩니다. 버전 범위 ^1.6.1은 마이너/패치 업데이트는 허용하고 메이저 버전 변경은 제한하는 보수적인 설정이므로 문제없습니다.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines 46 to +48
{children}
</ThemeProvider>
<Analytics />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

<Analytics /> 배치 위치 확인 필요.

현재 <Analytics />ThemeProvider 바깥에 위치해 있습니다. 기능상 문제는 없지만, 일반적으로 컴포넌트 계층 구조의 일관성을 위해 ThemeProvider 내부에 배치하는 것이 더 자연스럽습니다.

다만, Vercel Analytics는 테마 컨텍스트가 필요 없으므로 현재 위치도 정상 동작합니다.

♻️ (선택사항) ThemeProvider 내부로 이동
         <ThemeProvider
           attribute="class"
           defaultTheme="system"
           enableSystem={true}
           storageKey="theme"
         >
           {children}
+          <Analytics />
         </ThemeProvider>
-        <Analytics />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{children}
</ThemeProvider>
<Analytics />
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem={true}
storageKey="theme"
>
{children}
<Analytics />
</ThemeProvider>
🤖 Prompt for AI Agents
In `@src/app/layout.tsx` around lines 46 - 48, The <Analytics /> component is
currently rendered outside the ThemeProvider which breaks component hierarchy
consistency; move the <Analytics /> JSX so it is rendered inside the
ThemeProvider (e.g., after {children} but before closing ThemeProvider) to keep
component structure consistent while leaving functionality unchanged; update the
render in layout.tsx so ThemeProvider wraps children and <Analytics /> together.

Comment on lines +71 to +72
const seriesMeta = SERIES_META_BY_CATEGORY[category] ?? [];
const seriesCount = seriesMeta.length;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

find . -type f -name "*.ts" -o -name "*.tsx" | grep -E "(registry|series)" | head -20

Repository: swallowedB/b-log

Length of output: 490


🏁 Script executed:

# SERIES_META_BY_CATEGORY 정의 찾기
rg "SERIES_META_BY_CATEGORY" --type ts -B 2 -A 5

Repository: swallowedB/b-log

Length of output: 2900


🏁 Script executed:

# stats.ts의 해당 부분 확인
cat -n src/lib/posts/stats.ts | sed -n '60,85p'

Repository: swallowedB/b-log

Length of output: 961


🏁 Script executed:

# 레지스트리 전체 내용 확인
cat -n src/lib/posts/registry/series.registry.ts

Repository: swallowedB/b-log

Length of output: 1750


🏁 Script executed:

# 포스트 구조에서 series 필드 확인
rg "series" src/lib/posts/source.ts -B 2 -A 2

Repository: swallowedB/b-log

Length of output: 42


🏁 Script executed:

# 실제 포스트 파일에서 series id 사용 확인 (샘플 포스트 찾기)
fd "\.mdx?$" --max-results 10 | head -1 | xargs head -30

Repository: swallowedB/b-log

Length of output: 1121


🏁 Script executed:

# velite 설정이나 포스트 스키마 확인
rg "series" src/lib/posts -B 2 -A 2 --type ts | head -40

Repository: swallowedB/b-log

Length of output: 2005


🏁 Script executed:

# 포스트 저장 위치 찾기
fd -t f -e md -e mdx | head -5

Repository: swallowedB/b-log

Length of output: 107


🏁 Script executed:

# 포스트 메타데이터 스키마 확인 (velite)
rg "schema\|collection" velite.config -A 5 -B 2 2>/dev/null || rg "export.*Post" src/lib/posts -A 10 | head -50

Repository: swallowedB/b-log

Length of output: 2676


🏁 Script executed:

# VelitePost 타입 정의 확인
rg "VelitePost\|posts:\|collection" -A 15 | grep -A 15 "posts\|VelitePost" | head -60

Repository: swallowedB/b-log

Length of output: 42


🏁 Script executed:

# velite.config 파일 찾기
fd "velite" -name "*.config.*" -o -name "velite.ts" -o -name "velite.js"

Repository: swallowedB/b-log

Length of output: 290


🏁 Script executed:

# 실제 포스트 파일 확인 (frontmatter에 series 있는지)
cat content/posts/INSIGHT/velite-test.mdx | head -30

Repository: swallowedB/b-log

Length of output: 700


🏁 Script executed:

# getSeriesByIdAndCategory 함수 확인 - 대소문자 처리 확인
rg "getSeriesBy\|seriesId" src/lib/posts -B 3 -A 8 | head -60

Repository: swallowedB/b-log

Length of output: 42


🏁 Script executed:

# 모든 포스트에서 사용된 series 값 추출 (대소문자 확인)
rg "^series:" content/posts -h | sort | uniq -c

Repository: swallowedB/b-log

Length of output: 10375


🏁 Script executed:

# 레지스트리의 모든 series id 확인
rg "id:" src/lib/posts/registry/series.registry.ts | grep -o '"[^"]*"' | sort | uniq

Repository: swallowedB/b-log

Length of output: 119


🏁 Script executed:

# posts 폴더의 모든 .mdx 파일에서 series 필드 확인
find content/posts -name "*.mdx" -exec grep -h "^series:" {} \; | sort | uniq -c

Repository: swallowedB/b-log

Length of output: 84


🏁 Script executed:

# 쿼리에서 series 필터링 로직 확인
rg "filterByS\|filterSeries\|series.*filter" src/lib/posts -B 2 -A 8

Repository: swallowedB/b-log

Length of output: 42


🏁 Script executed:

# queries.ts에서 시리즈 필터링 로직 전체 확인
cat -n src/lib/posts/queries.ts | sed -n '1,150p'

Repository: swallowedB/b-log

Length of output: 2483


🏁 Script executed:

# 포스트 소스 정의 및 시리즈 필드 정규화 확인
cat src/lib/posts/source.ts

Repository: swallowedB/b-log

Length of output: 181


🏁 Script executed:

# velite config 또는 post schema 확인
fd -type f \( -name "*.config.ts" -o -name "*.config.js" \) | xargs grep -l "posts\|velite" 2>/dev/null

Repository: swallowedB/b-log

Length of output: 232


🏁 Script executed:

# 시리즈 관련 모든 대소문자 처리 확인
rg "toLowerCase\|toUpperCase\|series" src/lib/posts -i -B 2 -A 2 | grep -A 5 -B 5 "series"

Repository: swallowedB/b-log

Length of output: 42


🏁 Script executed:

# velite 설정 파일 찾기
find . -name "velite.config.*" -o -name "velite.ts"

Repository: swallowedB/b-log

Length of output: 78


🏁 Script executed:

# 포스트 schema 정의 확인 (# site prefix 찾기)
rg "#site" src -B 3 -A 3 | head -40

Repository: swallowedB/b-log

Length of output: 277


🏁 Script executed:

# 포스트 필드 검사 (series 포함)
rg "series\|category\|draft" src/lib/posts/source.ts -B 1 -A 1

Repository: swallowedB/b-log

Length of output: 42


🏁 Script executed:

# velite.config.ts 파일 확인
cat velite.config.ts

Repository: swallowedB/b-log

Length of output: 2005


🏁 Script executed:

# 모든 포스트 파일에서 series 필드값 추출 (확인)
find content/posts -name "*.mdx" -exec grep -h "^series:" {} \;

Repository: swallowedB/b-log

Length of output: 76


시리즈 ID 대소문자 불일치로 인한 조회 실패 발생

현재 코드에서 발견된 문제들:

  1. 레지스트리 등록 누락 시 카운트 제외 (의도된 동작): seriesCount = SERIES_META_BY_CATEGORY[category].length는 레지스트리 기반 카운트이므로, 포스트에 있지만 레지스트리에 미등록된 시리즈는 집계되지 않습니다. 이것이 의도된 설계라면 명확히 문서화하면 좋겠습니다.

  2. 긴급: 시리즈 ID 매칭 실패: velite.config.ts에서 series 필드를 capitalizeFirst() 변환하므로 포스트는 "Nextjs"(대문자)가 되지만, 레지스트리는 id: "nextjs"(소문자)로 정의되어 있습니다. 결과적으로 getSeriesMeta()s.id === seriesId 비교가 실패하며, series 기반 포스트 필터링 및 조회가 정상 작동하지 않습니다.

레지스트리의 모든 시리즈 ID를 capitalizeFirst() 형식으로 통일하거나, 조회 시 toLowerCase()를 적용하여 대소문자를 정규화해야 합니다.

🤖 Prompt for AI Agents
In `@src/lib/posts/stats.ts` around lines 71 - 72, The series lookup is failing
due to case mismatch between registry IDs and post-config transformed IDs:
normalize casing during lookup instead of relying on registry changes; update
getSeriesMeta (and any code referencing SERIES_META_BY_CATEGORY or the s.id ===
seriesId comparison) to compare a normalized form (e.g., convert both s.id and
seriesId to toLowerCase() or apply a shared normalize function) so seriesCount
and series-based filtering use the same canonical casing as capitalizeFirst in
velite.config.ts.

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: 애널리틱스 추가 및 오류 수정

1 participant