Skip to content

chore: Next.js 14.2.35 → 15.5.25 + React 19 업그레이드 - #45

Closed
Smartnewb wants to merge 1 commit into
codex/security-hardeningfrom
codex/next-15-upgrade
Closed

Smartnewb wants to merge 1 commit into
codex/security-hardeningfrom
codex/next-15-upgrade

Conversation

@Smartnewb

Copy link
Copy Markdown
Owner

Summary

H1 항목: EOL인 Next.js 14.2.35에 누적된 미해결 Critical/High CVE(RSC DoS GHSA-5j59-xgg2-r9c4 등)를 정리하기 위해 15.x 최신 안정판(15.5.25)으로 업그레이드. #44(security-hardening) 위에 쌓인 PR — next.config.js를 양쪽에서 건드려서 base를 해당 브랜치로 지정. #44 머지 후 자동으로 main으로 리타겟됩니다.

의존성:

  • next 14.2.35 → 15.5.25, eslint-config-next 동일 버전
  • react/react-dom → 19.2.8 핀(@react-three/fiber peer가 >=19 <19.3이라 캐럿 범위가 19.3.0을 잡으면 충돌), @types/react(-dom) 19
  • react-quill → react-quill-new@3.8.3 — react-quill은 React 19에서 제거된 findDOMNode를 써서 마운트 시 크래시; 유지 fork로 교체(임포트/CSS 경로만 변경, API 동일)
  • react-leaflet 4 → 5(React 19 지원), @hello-pangea/dnd 16 → 18, @testing-library/react 16 + @testing-library/dom 10(devDep)

코드 변경(Next 15 async request APIs):

  • shared/auth/cookies.ts: cookies() → await cookies() (7곳; 호출자는 이미 모두 async wrapper await)
  • 페이지 params/searchParams Promise화: ai-profiles/generator/[id], ai-profiles/ghosts/users/[userId], push-groups/[id]/edit — 라우트 핸들러(kb-candidates 등)는 이미 Promise<params> 형태였음
  • admin-proxy 컨텍스트 타입을 params: Promise<AdminProxyRouteParams>로 확정(기존 union은 Next 15 타입 검증 실패)
  • next.config.js: experimental.serverComponentsExternalPackages → serverExternalPackages
  • review-inbox-v2: React 19에서 제거된 글로벌 JSX 네임스페이스 → import type { JSX } from 'react'

Checks: pnpm typecheck:admin-v2 ✓, pnpm lint:admin-v2 ✓(0 errors), pnpm test:admin ✓ 123/123, pnpm build ✓ (Next 15.5.25)

Material limits: 브라우저 E2E 미실행 — react-quill-new/리플릿 지도 등 마이그레이션된 컴포넌트의 실제 렌더링은 배포 전 스테이징 확인 권장. experimental.serverActions 키는 15에서도 유효(빌드 로그에 experiments 표기만).

Link to Devin session: https://app.devin.ai/sessions/28aeed4402ec4a02a3f6a6138f4899d0
Open in Devin Desktop: https://app.devin.ai/desktop/session/28aeed4402ec4a02a3f6a6138f4899d0?variant=devin
Requested by: @Smartnewb

- next 15.5.25, eslint-config-next 15.5.25 (EOL 14.x line CVEs)
- react/react-dom 19.2.8 pinned, @types/react(-dom) 19
- react-quill -> react-quill-new 3.8.3 (react-quill uses findDOMNode,
  removed in React 19); react-leaflet 5; @hello-pangea/dnd 18;
  @testing-library/react 16 + @testing-library/dom 10
- async request APIs: await cookies() in shared/auth/cookies.ts;
  params/searchParams as Promise in pages and admin-proxy route context
- next.config.js: serverComponentsExternalPackages -> serverExternalPackages
- review-inbox-v2: JSX namespace via react import

Co-Authored-By: Newbie Smart <smartnewb2@gmail.com>
@Smartnewb Smartnewb self-assigned this Sep 21, 2026
@vercel

vercel Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
project-solo Ready Ready Preview Sep 21, 2026 2:18am UTC

Request Review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-21T02:18:53.459595Z 406d542 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@sonarqubecloud

Copy link
Copy Markdown

@Smartnewb

Copy link
Copy Markdown
Owner Author

E2E test — security hardening + Next.js 15 upgrade

Tested locally (pnpm dev + pnpm build/pnpm start) against the remote backend with a real admin account; recorded walkthrough available in the Devin session.

Verified

  • Security checks pass: unauth /admin/* → 307; proxy/session/token → 401/403; refresh + session/country [REDACTED SECRET] same-origin (missing/evil Origin → 403); country xx normalizes to kr; kb-candidates path-injection id → 400; login JSON drops accessToken; rate-limit trips 429 + Retry-After after the limit.
  • Prod headers (pnpm start): CSP has no unsafe-eval, connect-src restricted to 'self' + API origin, frame-ancestors 'none', HSTS, XFO DENY, Permissions-Policy all present.
  • React 19 render: dashboard, react-quill-new editor (typed text → live preview), react-leaflet cluster map (tiles + circles), country switch KR→JP — all working. No JSX crashes.

Pre-existing bug (not introduced here)

/admin/scheduled-matching region map never mounts: getMatchingPoolStats types the {data:{...}} envelope as the payload, so mapStats.scheduled is undefined → always "데이터가 없습니다" even though the API returns 43 regions for KR. Fix: unwrap .data in the service or read mapStats.data[matchingType].

Minor

  • React 19 hydration error in country modal: <h6> nested inside <h2> (MUI DialogTitle pattern).
  • Quill logs Cannot register "bullet" in formats ×2 (react-quill-new quirk; editor functional).
Dashboard Quill editor (React 19) Cluster map
dashboard quill map

Smartnewb pushed a commit that referenced this pull request Sep 21, 2026
@Smartnewb
Smartnewb deleted the branch codex/security-hardening September 21, 2026 04:02
@Smartnewb Smartnewb closed this Sep 21, 2026
@Smartnewb

Copy link
Copy Markdown
Owner Author

이 PR의 커밋은 main에 머지 커밋 7a91281(Merge PR #45)로 이미 반영됐습니다. 직접 푸시 방식으로 머지해 GitHub이 자동으로 'Merged' 대신 base 브랜치 삭제 시 'Closed'로 표시한 상태입니다 — 실제 코드는 main에 들어가 있습니다.

This branch was successfully deployed

1 active deployment
Preview — 406d5425 Deployed Sep 21, 2026 by vercel[bot]
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.

1 participant