Skip to content

chore: 웹 React 19 업그레이드#533

Open
manNomi wants to merge 1 commit into
mainfrom
chore/web-react-19-upgrade
Open

chore: 웹 React 19 업그레이드#533
manNomi wants to merge 1 commit into
mainfrom
chore/web-react-19-upgrade

Conversation

@manNomi
Copy link
Copy Markdown
Contributor

@manNomi manNomi commented May 26, 2026

관련 이슈

  • resolves: 없음

작업 내용

  • apps/web의 React/ReactDOM을 19.2.6으로 업그레이드했습니다.
  • React 19 peer dependency 대응을 위해 Next.js를 16.2.6으로 함께 올리고, Next 16 App Router 타입 변경에 맞춰 params, searchParams, cookies() 사용부를 정리했습니다.
  • 기존 SVG 처리(@svgr/webpack) 호환을 유지하기 위해 production build를 next build --webpack으로 고정했습니다.
  • Next 16 빌드 경고에 맞춰 middlewareproxy 컨벤션으로 이전하고, Sentry 설정을 instrumentation.ts / instrumentation-client.ts 구조로 정리했습니다.
  • 서버 프리렌더에서 FileList가 없는 환경에서도 성적 제출 스키마가 안전하게 평가되도록 보완했습니다.
  • Next 16 Turbopack/webpack 이미지 처리에서 실패하던 favicon.ico를 정상 ICO로 교체했습니다.

특이 사항

  • 현재 웹 앱은 SVG를 React 컴포넌트로 import하는 구조가 많아, Next 16 기본 Turbopack build 대신 webpack build를 명시했습니다.
  • 로컬 Node가 repo engine(22.x)과 달라 Unsupported engine warning은 계속 표시됩니다.
  • React 19 단독 업그레이드는 기존 Next 14 peer range와 충돌해서 Next 16 호환 변경이 같은 PR에 포함됐습니다.

리뷰 요구사항 (선택)

  • Next 16 전환에 따른 App Router page props 변경(params, searchParams)과 Sentry instrumentation 경로 변경을 중점적으로 봐주세요.

검증

  • pnpm --filter @solid-connect/web lint:check
  • pnpm --filter @solid-connect/web typecheck
  • pnpm --filter @solid-connect/web ci:check
  • pnpm --filter @solid-connect/web build
  • push hook CI parity checks 통과(web/admin ci:check 및 build)

@manNomi manNomi requested review from enunsnv and wibaek as code owners May 26, 2026 16:23
@vercel
Copy link
Copy Markdown

vercel Bot commented May 26, 2026

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

Project Deployment Actions Updated (UTC)
solid-connect-web-admin Ready Ready Preview, Comment May 26, 2026 4:26pm
solid-connection-web Ready Ready Preview, Comment May 26, 2026 4:26pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

Review Change Stack

전체 변경 사항 요약

이 PR은 Next.js 14에서 16으로, React 18에서 19로 업그레이드하는 대규모 마이그레이션입니다. 다음과 같은 6가지 핵심 변경이 포함됩니다:

  1. 빌드 설정 및 의존성 업그레이드 — package.json에서 Next.js 16, React 19로 버전 상향. next.config.mjs의 이미지 설정을 remotePatterns 기반으로 전환. TypeScript 설정을 bundler 모듈 해석 및 react-jsx로 조정.

  2. 동적 임포트 제거 — 15개 페이지/컴포넌트에서 next/dynamic 기반의 SSR 비활성 로더를 제거하고 정적 임포트로 통일.

  3. 비동기 params 처리 — Next.js 15+ 요구사항에 따라 10개 동적 라우트 페이지의 params 타입을 Promise로 변경하고 await로 해석.

  4. Sentry 계측 재구성 — 기존 sentry.client.config.ts 내용을 삭제하고, 새로운 instrumentation-client.ts(클라이언트 라우팅 추적)와 instrumentation.ts(서버 핸들러)로 분리. 프로덕션 환경에서만 초기화.

  5. 캐시 및 유틸리티 업데이트 — revalidateTag에 expire: 0 옵션 추가, isServerStateLogin 비동기화, proxy.ts 함수명 변경.

  6. 타입 가드 개선 — FileList 타입 판별을 위한 런타임 가드 함수 추가하여 Zod 스키마 검증 강화.

Walkthrough

이 변경사항은 Next.js 마이너 버전 업그레이드와 런타임 계측 재설계를 중심으로 진행됩니다. 주요 리뷰 지점은:

  • 빌드 설정: webpack 옵션 추가, React 19 호환 TypeScript 설정
  • 컴포넌트 로딩: 동적 임포트 제거로 더 단순한 정적 구조로 전환
  • 라우팅 시그니처: params를 Promise로 받아 처리하는 새로운 패턴 적용
  • 에러 추적: Sentry 계측을 분산된 두 개 모듈(클라이언트/서버)로 재구성
  • 캐시 정책: 즉시 무효화를 명시하는 expire 옵션 도입
  • 타입 안전: FileList 런타임 검증으로 폼 스키마 강화

예상 코드 리뷰 노력

🎯 4 (Complex) | ⏱️ ~60 minutes

추천 리뷰어

  • wibaek
  • enunsnv
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 주요 변경 사항인 React 19 업그레이드를 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명이 템플릿의 모든 필수 섹션(관련 이슈, 작업 내용, 특이 사항, 리뷰 요구사항)을 포함하고 있으며, 변경 사항을 상세하게 기술하고 있습니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/web-react-19-upgrade

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

@manNomi
Copy link
Copy Markdown
Contributor Author

manNomi commented May 26, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

ℹ️ 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".

Copy link
Copy Markdown

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/web/src/app/(home)/_ui/PopularUniversitySection/index.tsx (1)

29-45: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

아래 Suspense fallback은 현재 구조에선 사실상 안 뜹니다 — Suspense 래퍼를 제거하세요

  1. PopularUniversitySection에서 PopularUniversityCard를 정적으로 렌더링하고 있어(동기 컴포넌트) 여기서는 Suspense가 트리거될 suspend 지점이 없습니다.
  2. PopularUniversityCard가 사용하는 FallbackImageuseState로 이미지 에러 대체만 처리하며 Suspense용 동작은 하지 않습니다.
♻️ 정리 방향
-        {belowFold.map((university) => (
-          <Suspense
-            key={university.id}
-            fallback={
-              <div className="relative w-[153px]">
-                <div className="h-[120px] w-[153px] animate-pulse rounded-lg bg-gray-200" />
-              </div>
-            }
-          >
-            <PopularUniversityCard
-              university={university}
-              priority={false}
-              loading="lazy"
-              fetchPriority="low"
-              quality={50} // 동적 로딩 이미지는 50으로 최대 압축
-            />
-          </Suspense>
-        ))}
+        {belowFold.map((university) => (
+          <PopularUniversityCard
+            key={university.id}
+            university={university}
+            priority={false}
+            loading="lazy"
+            fetchPriority="low"
+            quality={50} // below-fold 이미지는 50으로 최대 압축
+          />
+        ))}

reactSuspense import도 함께 제거하는 게 좋습니다.

🤖 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/`(home)/_ui/PopularUniversitySection/index.tsx around lines
29 - 45, The Suspense wrapper around the belowFold.map items should be removed
because PopularUniversityCard is rendered synchronously and FallbackImage
doesn't suspend; delete the <Suspense ... fallback={...}> wrapper around each
PopularUniversityCard in PopularUniversitySection (the map over belowFold) and
keep the key on the PopularUniversityCard, and also remove the unused Suspense
import from the file; ensure you simply render <PopularUniversityCard
university={university} priority={false} loading="lazy" fetchPriority="low"
quality={50} /> directly for each item.
apps/web/src/app/community/[boardCode]/[postId]/modify/page.tsx (1)

19-25: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

1) 수정 페이지도 postId 숫자 검증을 넣어주세요.

  • Line 25의 Number(postId) 결과가 NaN일 때 차단 로직이 없습니다.
  • 라우트 오입력 시 하위 컴포넌트/요청이 비정상 동작할 수 있습니다.
수정 예시
 import type { Metadata } from "next";
+import { notFound } from "next/navigation";
@@
 const PostModifyPage = async ({ params }: PostModifyPageProps) => {
   const { boardCode, postId } = await params;
+  const numericPostId = Number(postId);
+  if (Number.isNaN(numericPostId)) notFound();
@@
-        <PostModifyContent boardCode={boardCode} postId={Number(postId)} />
+        <PostModifyContent boardCode={boardCode} postId={numericPostId} />
🤖 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/community/`[boardCode]/[postId]/modify/page.tsx around lines
19 - 25, Validate postId before passing to PostModifyContent: convert
params.postId to a number (e.g., const id = Number(postId)) and if
Number.isNaN(id) short-circuit (for example call notFound() or render an
error/redirect) so the component PostModifyContent and subsequent requests never
receive NaN; update the code around params, postId, and the PostModifyContent
invocation to use the validated id.
🤖 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/community/`[boardCode]/[postId]/page.tsx:
- Around line 17-18: params.postIdParam을 Number로 변환만 하고 검증하지 않아 postId가 NaN으로
PostPageContent에 전달될 수 있으니, params와 postIdParam을 사용해 변환 후
Number.isInteger/!Number.isNaN 검사로 유효성 확인하고 유효하지 않을 경우 PostPageContent로 NaN을 넘기지
말고 적절히 처리(예: next/navigation의 notFound() 호출 또는 400 응답/리다이렉트)하도록 변경하세요; 수정 대상
식별자: params, postIdParam, postId, PostPageContent.

In `@apps/web/src/app/mentor/`[id]/page.tsx:
- Around line 16-17: Validate the parsed mentorId after converting from params:
check that Number(id) is a finite integer (not NaN) before passing it to
MentorDetialContent; if validation fails, handle the bad route by returning or
throwing an appropriate response (e.g., invoke notFound() or redirect) so
MentorDetialContent never receives NaN. Update the logic around const mentorId =
Number(id) to perform this check and early-return/route-fail when id is invalid.

In `@apps/web/src/instrumentation-client.ts`:
- Line 10: The configuration currently hardcodes sendDefaultPii: true in
instrumentation-client.ts which risks sending identifiers before user consent;
change the default to sendDefaultPii: false and add a controlled mechanism to
enable it only after explicit consent (e.g., expose a method like
enablePiiCollection or accept a runtime flag in the initialization function used
by the app) so the setting is toggled when the consent signal is received;
update any initialization calls that construct the instrumentation client to
respect this default and call the new enable path after consent.
- Around line 25-32: The lazy-load promise from
Sentry.lazyLoadIntegration("replayIntegration") currently only uses .then(...)
and lacks failure handling; update that chain to append a .catch(...) that
absorbs and logs errors (use Sentry.captureException(error) and/or console.error
with contextual message) so failures to load the replay integration don’t
produce unhandled rejections; ensure the .catch references the same Sentry
symbol and includes enough context (e.g., "replayIntegration lazy load failed")
for debugging.

---

Outside diff comments:
In `@apps/web/src/app/`(home)/_ui/PopularUniversitySection/index.tsx:
- Around line 29-45: The Suspense wrapper around the belowFold.map items should
be removed because PopularUniversityCard is rendered synchronously and
FallbackImage doesn't suspend; delete the <Suspense ... fallback={...}> wrapper
around each PopularUniversityCard in PopularUniversitySection (the map over
belowFold) and keep the key on the PopularUniversityCard, and also remove the
unused Suspense import from the file; ensure you simply render
<PopularUniversityCard university={university} priority={false} loading="lazy"
fetchPriority="low" quality={50} /> directly for each item.

In `@apps/web/src/app/community/`[boardCode]/[postId]/modify/page.tsx:
- Around line 19-25: Validate postId before passing to PostModifyContent:
convert params.postId to a number (e.g., const id = Number(postId)) and if
Number.isNaN(id) short-circuit (for example call notFound() or render an
error/redirect) so the component PostModifyContent and subsequent requests never
receive NaN; update the code around params, postId, and the PostModifyContent
invocation to use the validated id.
🪄 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: 83c18adc-cfc3-4520-9be3-9458f2994a33

📥 Commits

Reviewing files that changed from the base of the PR and between 4351ca9 and e6815ec.

⛔ Files ignored due to path filters (2)
  • apps/web/src/app/favicon.ico is excluded by !**/*.ico
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (28)
  • apps/web/next.config.mjs
  • apps/web/package.json
  • apps/web/sentry.client.config.ts
  • apps/web/src/app/(home)/_ui/PopularUniversitySection/index.tsx
  • apps/web/src/app/(home)/page.tsx
  • apps/web/src/app/api/revalidate/route.ts
  • apps/web/src/app/community/[boardCode]/[postId]/modify/page.tsx
  • apps/web/src/app/community/[boardCode]/[postId]/page.tsx
  • apps/web/src/app/community/[boardCode]/create/page.tsx
  • apps/web/src/app/community/[boardCode]/page.tsx
  • apps/web/src/app/layout.tsx
  • apps/web/src/app/login/page.tsx
  • apps/web/src/app/mentor/[id]/page.tsx
  • apps/web/src/app/mentor/chat/[chatId]/page.tsx
  • apps/web/src/app/university/[homeUniversity]/page.tsx
  • apps/web/src/app/university/application/apply/page.tsx
  • apps/web/src/app/university/score/page.tsx
  • apps/web/src/app/university/score/submit/gpa/_lib/schema.ts
  • apps/web/src/app/university/score/submit/gpa/page.tsx
  • apps/web/src/app/university/score/submit/language-test/_lib/schema.ts
  • apps/web/src/app/university/score/submit/language-test/page.tsx
  • apps/web/src/app/university/search/page.tsx
  • apps/web/src/components/layout/GlobalLayout/index.tsx
  • apps/web/src/instrumentation-client.ts
  • apps/web/src/instrumentation.ts
  • apps/web/src/proxy.ts
  • apps/web/src/utils/isServerStateLogin.ts
  • apps/web/tsconfig.json
💤 Files with no reviewable changes (1)
  • apps/web/sentry.client.config.ts

Comment on lines +17 to +18
const { boardCode, postId: postIdParam } = await params;
const postId = Number(postIdParam);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

1) 숫자 파라미터 검증이 빠져서 NaN이 그대로 내려갈 수 있어요.

- Line 18에서 `Number(postIdParam)`만 수행하고 검증이 없습니다.
- 잘못된 URL 입력 시 `PostPageContent`로 `NaN` 전달되어 500/잘못된 요청으로 이어질 수 있습니다.
수정 예시
 import type { Metadata } from "next";
+import { notFound } from "next/navigation";
@@
 const PostPage = async ({ params }: PostPageProps) => {
   const { boardCode, postId: postIdParam } = await params;
   const postId = Number(postIdParam);
+  if (Number.isNaN(postId)) notFound();
📝 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
const { boardCode, postId: postIdParam } = await params;
const postId = Number(postIdParam);
import type { Metadata } from "next";
import { notFound } from "next/navigation";
const PostPage = async ({ params }: PostPageProps) => {
const { boardCode, postId: postIdParam } = await params;
const postId = Number(postIdParam);
if (Number.isNaN(postId)) notFound();
🤖 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/community/`[boardCode]/[postId]/page.tsx around lines 17 -
18, params.postIdParam을 Number로 변환만 하고 검증하지 않아 postId가 NaN으로 PostPageContent에
전달될 수 있으니, params와 postIdParam을 사용해 변환 후 Number.isInteger/!Number.isNaN 검사로 유효성
확인하고 유효하지 않을 경우 PostPageContent로 NaN을 넘기지 말고 적절히 처리(예: next/navigation의
notFound() 호출 또는 400 응답/리다이렉트)하도록 변경하세요; 수정 대상 식별자: params, postIdParam, postId,
PostPageContent.

Comment on lines +16 to +17
const { id } = await params;
const mentorId = Number(id);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

1) mentorIdNaN 방어가 필요합니다.

- Line 17에서 숫자 변환만 하고 유효성 체크가 없습니다.
- 비정상 경로 입력이 들어오면 `MentorDetialContent`로 `NaN`이 전달될 수 있습니다.
수정 예시
 import type { Metadata } from "next";
+import { notFound } from "next/navigation";
@@
 const MentorDetailPage = async ({ params }: MentorDetailPageProps) => {
   const { id } = await params;
   const mentorId = Number(id);
+  if (Number.isNaN(mentorId)) notFound();
📝 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
const { id } = await params;
const mentorId = Number(id);
import type { Metadata } from "next";
import { notFound } from "next/navigation";
// ... other imports
const MentorDetailPage = async ({ params }: MentorDetailPageProps) => {
const { id } = await params;
const mentorId = Number(id);
if (Number.isNaN(mentorId)) notFound();
🤖 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/mentor/`[id]/page.tsx around lines 16 - 17, Validate the
parsed mentorId after converting from params: check that Number(id) is a finite
integer (not NaN) before passing it to MentorDetialContent; if validation fails,
handle the bad route by returning or throwing an appropriate response (e.g.,
invoke notFound() or redirect) so MentorDetialContent never receives NaN. Update
the logic around const mentorId = Number(id) to perform this check and
early-return/route-fail when id is invalid.

dsn: process.env.NEXT_PUBLIC_SENTRY_DSN || process.env.SENTRY_DSN || "",
environment: process.env.NEXT_PUBLIC_SENTRY_ENVIRONMENT || process.env.SENTRY_ENVIRONMENT || "production",

sendDefaultPii: true,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

  1. sendDefaultPii를 기본 활성화하면 개인정보 수집 리스크가 큽니다.

Line 10에서 sendDefaultPii: true가 고정되어 있어, 동의 이전에도 식별 정보가 전송될 수 있습니다. 기본값을 false로 두고 동의 신호가 있을 때만 켜는 방식이 안전합니다.

변경 제안
-    sendDefaultPii: true,
+    sendDefaultPii: false,
📝 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
sendDefaultPii: true,
sendDefaultPii: false,
🤖 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/instrumentation-client.ts` at line 10, The configuration
currently hardcodes sendDefaultPii: true in instrumentation-client.ts which
risks sending identifiers before user consent; change the default to
sendDefaultPii: false and add a controlled mechanism to enable it only after
explicit consent (e.g., expose a method like enablePiiCollection or accept a
runtime flag in the initialization function used by the app) so the setting is
toggled when the consent signal is received; update any initialization calls
that construct the instrumentation client to respect this default and call the
new enable path after consent.

Comment on lines +25 to +32
Sentry.lazyLoadIntegration("replayIntegration").then((replay) => {
Sentry.addIntegration(
replay({
maskAllText: true,
blockAllMedia: true,
}),
);
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

  1. Replay 지연 로딩 Promise에 실패 처리가 없어 관측이 조용히 깨질 수 있습니다.

Line 25-32는 .then(...)만 있어 로딩 실패 시 unhandled rejection이 발생할 수 있습니다. .catch(...)를 추가해 오류를 흡수/로깅해 주세요.

변경 제안
-  Sentry.lazyLoadIntegration("replayIntegration").then((replay) => {
-    Sentry.addIntegration(
-      replay({
-        maskAllText: true,
-        blockAllMedia: true,
-      }),
-    );
-  });
+  Sentry.lazyLoadIntegration("replayIntegration")
+    .then((replay) => {
+      Sentry.addIntegration(
+        replay({
+          maskAllText: true,
+          blockAllMedia: true,
+        }),
+      );
+    })
+    .catch(() => {
+      // replay integration load failure should not break runtime
+    });
📝 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
Sentry.lazyLoadIntegration("replayIntegration").then((replay) => {
Sentry.addIntegration(
replay({
maskAllText: true,
blockAllMedia: true,
}),
);
});
Sentry.lazyLoadIntegration("replayIntegration")
.then((replay) => {
Sentry.addIntegration(
replay({
maskAllText: true,
blockAllMedia: true,
}),
);
})
.catch(() => {
// replay integration load failure should not break runtime
});
🤖 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/instrumentation-client.ts` around lines 25 - 32, The lazy-load
promise from Sentry.lazyLoadIntegration("replayIntegration") currently only uses
.then(...) and lacks failure handling; update that chain to append a .catch(...)
that absorbs and logs errors (use Sentry.captureException(error) and/or
console.error with contextual message) so failures to load the replay
integration don’t produce unhandled rejections; ensure the .catch references the
same Sentry symbol and includes enough context (e.g., "replayIntegration lazy
load failed") for debugging.

@manNomi
Copy link
Copy Markdown
Contributor Author

manNomi commented May 26, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e6815eca1f

ℹ️ 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".

Comment thread apps/web/package.json
"linkifyjs": "^4.3.2",
"lucide-react": "^0.479.0",
"next": "^14.2.35",
"next": "^16.2.6",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge 웹팩 기반 SVG 로더를 dev 실행에도 강제하세요

Next를 ^16.2.6로 올리면 next dev의 기본 번들러가 Turbopack으로 바뀌는데, 현재 설정은 build--webpack으로 고정되어 있어 개발 서버에서는 next.config.mjswebpack()(여기서 @svgr/webpack을 등록) 구성이 적용되지 않습니다. 이 저장소는 public/svgs/*.svg를 React 컴포넌트로 광범위하게 import하므로, pnpm dev에서 SVG import가 깨지거나 런타임 렌더링 오류가 발생할 수 있습니다.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant