feat: 검색 최적화 기반 정비#538
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
|
Warning Review limit reached
More reviews will be available in 52 minutes and 58 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
Walkthrough이 PR은 SEO 메타데이터 관리를 체계화하고 검색 엔진 인덱싱 정책을 통합하는 작업입니다. 주요 변경사항은 다음과 같습니다:
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9a527d7693
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (boardCode) { | ||
| revalidatePath(`/community/${boardCode}`); | ||
| revalidateTag(`posts-${boardCode}`, { expire: 0 }); | ||
| revalidateTag(`posts-${boardCode}`); |
There was a problem hiding this comment.
Restore the required revalidateTag profile
With this repo on Next 16.2.6, the official API docs define revalidateTag(tag: string, profile: string | { expire?: number }) and note that the single-argument form is deprecated and a TypeScript error (docs); because the root workflow asks for pnpm typecheck, this route will fail type checking for both this board invalidation and the generic tag branch unless the second argument is kept, e.g. { expire: 0 } or an appropriate cache profile.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
apps/web/src/app/sitemap.ts (1)
29-49: ⚡ Quick win1. 대학 데이터 패치 실패 시에도 정적 경로는 살려두면 어떨까요?
getAllUniversities()가 거절(reject)되면 sitemap 생성 전체가 실패해서, 안전한 정적 경로(/,/university,/terms, 홈 대학 목록)까지 함께 사라지게 됩니다. PR 설명에도 prerender 단계 불안정이 언급되어 있으니, 동적 경로만 실패하도록 감싸두면 검색 노출의 핵심 경로를 지킬 수 있어요.♻️ 동적 경로 실패를 흡수하는 제안
const getUniversityDetailRoutes = async (): Promise<MetadataRoute.Sitemap> => { - const universities = await getAllUniversities(); + let universities; + try { + universities = await getAllUniversities(); + } catch { + return []; + } const seenUrls = new Set<string>();🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/app/sitemap.ts` around lines 29 - 49, The getUniversityDetailRoutes function currently lets getAllUniversities rejection bubble up and break sitemap generation; wrap the await getAllUniversities() call in a try/catch inside getUniversityDetailRoutes (or handle its Promise rejection) so that on error you log the failure and return an empty array (i.e., no dynamic university entries) instead of throwing, preserving the static routes; reference getUniversityDetailRoutes, getAllUniversities, seenUrls, and toSitemapEntry when making the change.apps/web/src/app/university/[homeUniversity]/[id]/page.tsx (1)
126-144: 💤 Low value1. 404 분기 이후 남은 삼항 조건은 이제 죽은 코드예요.
isNotFoundError가true면 위에서notFound()가 즉시 throw하기 때문에, 아래 fallback 렌더는 항상 404가 아닌 경우(준비 중)에만 도달합니다. 그래서title/description의isNotFoundError ? ... : undefined삼항은 늘undefined로만 평가되는 죽은 분기가 되었어요. 의도는 정확하니 가독성 차원에서 정리해두면 다음 사람이 헷갈리지 않습니다.♻️ 불필요해진 조건 정리 제안
- const isNotFoundError = universityDetailResult.status === 404; - - if (isNotFoundError) { + if (universityDetailResult.status === 404) { notFound(); } return ( <> <TopDetailNavigation title="파견 학교 상세" backHref={`/university/${homeUniversity}`} /> - <UniversityDetailPreparingFallback - backHref={`/university/${homeUniversity}`} - title={isNotFoundError ? "해당 대학 정보를 찾을 수 없어요." : undefined} - description={ - isNotFoundError ? "요청하신 파견학교를 찾지 못했습니다. 목록에서 다른 학교를 선택해 주세요." : undefined - } - /> + <UniversityDetailPreparingFallback backHref={`/university/${homeUniversity}`} /> </> );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/app/university/`[homeUniversity]/[id]/page.tsx around lines 126 - 144, The ternary checks using isNotFoundError are dead code because notFound() short-circuits when isNotFoundError is true; remove the redundant conditionals in the UniversityDetailPreparingFallback props (title and description) and simplify them to their preparing-state values or omit them (i.e., pass undefined directly or remove the props) so the component only reflects the “preparing” state; update references to isNotFoundError, notFound(), and UniversityDetailPreparingFallback to ensure clarity.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/src/app/api/revalidate/route.ts`:
- Line 60: The call to revalidateTag(`posts-${boardCode}`) is missing the
required second argument causing TS2554; restore the profile argument (either
"max" or the original object like { expire: 0 }) to match the intended cache
behavior. Update both calls of revalidateTag (the one at
revalidateTag(`posts-${boardCode}`) and the other similar call at line 81) to
pass the appropriate profile as the second parameter so the function signature
for revalidateTag(tag, profile) is satisfied and the desired revalidation policy
(e.g., "max" or { expire: 0 }) is preserved.
In `@apps/web/src/app/my/match/page.tsx`:
- Line 9: The page metadata title ("metadata.title") currently reads "프로필 수정"
but the rendered header uses TopDetailNavigation with the label "매칭 멘토"; update
the metadata to match the visible header by changing metadata.title to "매칭 멘토"
(or alternatively make TopDetailNavigation read from metadata.title) in the
page.tsx so the browser tab and page header show the same title; locate the
export/const named metadata and the TopDetailNavigation usage in this file and
ensure they use the identical string.
---
Nitpick comments:
In `@apps/web/src/app/sitemap.ts`:
- Around line 29-49: The getUniversityDetailRoutes function currently lets
getAllUniversities rejection bubble up and break sitemap generation; wrap the
await getAllUniversities() call in a try/catch inside getUniversityDetailRoutes
(or handle its Promise rejection) so that on error you log the failure and
return an empty array (i.e., no dynamic university entries) instead of throwing,
preserving the static routes; reference getUniversityDetailRoutes,
getAllUniversities, seenUrls, and toSitemapEntry when making the change.
In `@apps/web/src/app/university/`[homeUniversity]/[id]/page.tsx:
- Around line 126-144: The ternary checks using isNotFoundError are dead code
because notFound() short-circuits when isNotFoundError is true; remove the
redundant conditionals in the UniversityDetailPreparingFallback props (title and
description) and simplify them to their preparing-state values or omit them
(i.e., pass undefined directly or remove the props) so the component only
reflects the “preparing” state; update references to isNotFoundError,
notFound(), and UniversityDetailPreparingFallback to ensure clarity.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 20373075-2365-4913-8ada-a5ebcdf992e6
📒 Files selected for processing (41)
apps/web/src/app/(home)/page.tsxapps/web/src/app/api/revalidate/route.tsapps/web/src/app/community/[boardCode]/[postId]/modify/page.tsxapps/web/src/app/community/[boardCode]/[postId]/page.tsxapps/web/src/app/community/[boardCode]/create/page.tsxapps/web/src/app/community/[boardCode]/page.tsxapps/web/src/app/community/page.tsxapps/web/src/app/layout.tsxapps/web/src/app/login/apple/callback/page.tsxapps/web/src/app/login/kakao/callback/page.tsxapps/web/src/app/login/page.tsxapps/web/src/app/mentor/[id]/page.tsxapps/web/src/app/mentor/chat/[chatId]/page.tsxapps/web/src/app/mentor/chat/page.tsxapps/web/src/app/mentor/modify/page.tsxapps/web/src/app/mentor/page.tsxapps/web/src/app/mentor/waiting/page.tsxapps/web/src/app/my/apply-mentor/layout.tsxapps/web/src/app/my/favorite/page.tsxapps/web/src/app/my/match/page.tsxapps/web/src/app/my/modify/page.tsxapps/web/src/app/my/page.tsxapps/web/src/app/my/password/page.tsxapps/web/src/app/robots.tsapps/web/src/app/sign-up/email/page.tsxapps/web/src/app/sign-up/page.tsxapps/web/src/app/sitemap.tsapps/web/src/app/terms/page.tsxapps/web/src/app/university/(home)/page.tsxapps/web/src/app/university/[homeUniversity]/[id]/page.tsxapps/web/src/app/university/[homeUniversity]/page.tsxapps/web/src/app/university/[homeUniversity]/search/page.tsxapps/web/src/app/university/application/apply/page.tsxapps/web/src/app/university/application/page.tsxapps/web/src/app/university/list/[homeUniversityName]/page.tsxapps/web/src/app/university/score/example/layout.tsxapps/web/src/app/university/score/page.tsxapps/web/src/app/university/score/submit/gpa/page.tsxapps/web/src/app/university/score/submit/language-test/page.tsxapps/web/src/app/university/search/page.tsxapps/web/src/utils/seo.ts
| import MatchContent from "./_ui/MatchContent"; | ||
|
|
||
| export const metadata: Metadata = { | ||
| title: "프로필 수정", |
There was a problem hiding this comment.
메타데이터 제목이 페이지 네비게이션 제목과 일치하지 않습니다.
메타데이터의 title이 "프로필 수정"으로 설정되어 있지만, 16번 줄의 TopDetailNavigation은 "매칭 멘토"를 표시합니다. 브라우저 탭과 페이지 헤더의 제목이 일치하도록 수정해주세요.
🔧 제안하는 수정
export const metadata: Metadata = {
- title: "프로필 수정",
+ title: "매칭 멘토",
robots: NO_INDEX_ROBOTS,
};📝 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.
| title: "프로필 수정", | |
| export const metadata: Metadata = { | |
| title: "매칭 멘토", | |
| robots: NO_INDEX_ROBOTS, | |
| }; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/app/my/match/page.tsx` at line 9, The page metadata title
("metadata.title") currently reads "프로필 수정" but the rendered header uses
TopDetailNavigation with the label "매칭 멘토"; update the metadata to match the
visible header by changing metadata.title to "매칭 멘토" (or alternatively make
TopDetailNavigation read from metadata.title) in the page.tsx so the browser tab
and page header show the same title; locate the export/const named metadata and
the TopDetailNavigation usage in this file and ensure they use the identical
string.
관련 이슈
작업 내용
https://www.solid-connection.com으로 맞췄습니다.noindex로 정리했습니다.SearchAction을 제거하고, 대학 상세 404는notFound()로 처리하도록 정리했습니다.revalidateTag호출 시그니처를 현재 타입에 맞게 수정했습니다.특이 사항
noindex로 두었습니다.pnpm --filter @solid-connect/web run build는 컴파일 성공 후 static prerender 단계에서Unsupported Server Component type: {...}오류로 실패합니다. 오류는 루트, 로그인, 마이페이지, 대학 상세 등 다수 기존 라우트에 걸쳐 발생하며, 빌드 중 Next가tsconfig.json의jsx를 자동 변경하려 해 해당 변경은 원복했습니다.v23.10.0이고 패키지 요구 버전은 Node22.x라 검증 시 경고가 출력됩니다.리뷰 요구사항 (선택)
검증
pnpm --filter @solid-connect/web run lint:check통과pnpm --filter @solid-connect/web run typecheck:ci통과ci:check통과ci:check통과 후next buildprerender 오류로 실패하여, 위 특이 사항을 남기고 훅을 우회해 브랜치를 푸시했습니다.