-
Notifications
You must be signed in to change notification settings - Fork 3
feat : 패키지 매니저 마이그레이션 #347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Add .npmrc with Next.js compatibility settings (shamefully-hoist) - Generate pnpm-lock.yaml and remove package-lock.json - Update GitHub Actions workflows (ci.yml, build.yml, release.yml) to use pnpm - Update Husky git hooks (pre-push, commit-msg) to use pnpm commands - Update package.json scripts to use pnpm - Update README.md with pnpm installation and usage guide Benefits: - Faster dependency installation with hard links - Disk space savings across projects - Stricter dependency management - Future monorepo support ready 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Update verificationFile schema to remove nullable type - Change error handling to use undefined instead of null - Fix type compatibility between schema and form defaults Fixes type errors: - src/app/my/apply-mentor/_components/UniversityScreen/index.tsx - src/app/my/apply-mentor/page.tsx - src/app/my/apply-mentor/_lib/schema.ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Walkthrough이 풀 리퀘스트는 프로젝트의 패키지 매니저를 npm에서 pnpm으로 통합적으로 마이그레이션합니다. 구체적으로는 다음과 같은 변경사항들이 포함됩니다:
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
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.
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 (1)
src/app/my/apply-mentor/_lib/schema.ts (1)
10-22: 파일 검증 필드 타입 불일치로 인한 런타임 오류 가능성스키마와 폼의 상태 처리 방식이 맞지 않아 런타임에 검증 오류가 발생할 수 있습니다.
스키마의 현재 정의
z.instanceof(File)로 설정되어 null/undefined를 거부합니다.optional()이나.nullable()이 없어 필수 필드로 작동합니다폼에서 실제 동작하는 방식
page.tsx초기값:verificationFile: undefined as any로 시작UniversityScreen/index.tsx: 파일 제거/오류 시null as any로 설정- UI 버튼은 파일이 없으면 비활성화되어 선택 사항처럼 보입니다
발견된 문제점들
- 4개 위치에서
as any타입 단언이 오류를 숨기고 있습니다- 런타임 체크
if (!data.verificationFile)는 undefined/null 가능성을 의도합니다- 스키마 검증과 폼 동작이 충돌합니다
권장 조치: 파일 업로드가 선택 사항이라면 스키마에
.optional()을 추가하고as any타입 단언을 제거해주세요.제안 코드 수정
verificationFile: z .instanceof(File, { message: "증명 서류(파일)를 업로드해 주세요.", }) .refine( (file) => { const allowedTypes = ["image/png", "image/jpeg", "image/jpg", "application/pdf"]; return allowedTypes.includes(file.type); }, { message: "파일 형식은 png, jpg, pdf만 허용됩니다.", }, ) + .optional()
🤖 Fix all issues with AI Agents
In @.husky/commit-msg:
- Line 1: Replace the use of "pnpm dlx commitlint --edit ${1}" with the
equivalent local-only execution "pnpm exec commitlint --edit ${1}" in the
.husky/commit-msg hook (change the "pnpm dlx commitlint --edit ${1}"
invocation), and ensure commitlint is installed as a devDependency so the local
exec will run the local package rather than downloading from the registry.
In @.npmrc:
- Around line 1-4: The .npmrc currently weakens pnpm isolation via
shamefully-hoist=true, auto-install-peers=true, and
strict-peer-dependencies=false; remove or comment out those three lines, run rm
-rf node_modules && pnpm install then validate with pnpm run build and pnpm run
dev, and if a specific tool truly needs hoisting replace shamefully-hoist with
targeted public-hoist-pattern entries (e.g., public-hoist-pattern[]=*eslint* or
public-hoist-pattern[]=*babel-*) and fix any missing declarations discovered via
pnpm why <package> by adding them to package.json.
In @src/app/my/apply-mentor/_components/UniversityScreen/index.tsx:
- Line 63: The three uses of setValue("verificationFile", null as any) bypass
TypeScript safety because schema.ts no longer allows null for verificationFile;
update the schema to accept nullable Files (e.g., make verificationFile a
nullable File with a refine to ensure non-null on submit) and then remove the as
any casts so setValue("verificationFile", null) is type-safe; adjust any form
submit/validation logic that expects a non-null file to rely on the schema
refine (verificationFile) rather than forcing non-null types.
In @src/app/my/apply-mentor/page.tsx:
- Line 30: The verificationFile default value is being type-escaped with
"undefined as any" in page.tsx; update the schema field verificationFile in
schema.ts to be either .optional() or .nullable() (e.g., z.instanceof(File,
{...}).refine(...).optional()) so TypeScript recognizes absence, then remove the
"as any" in defaultValues in page.tsx and use plain undefined (or undefined |
File type) for verificationFile to align compile-time types with your runtime
null checks.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
package-lock.jsonis excluded by!**/package-lock.jsonpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (11)
.github/workflows/build.yml.github/workflows/ci.yml.github/workflows/release.yml.husky/commit-msg.husky/pre-push.npmrcREADME.mdpackage.jsonsrc/app/my/apply-mentor/_components/UniversityScreen/index.tsxsrc/app/my/apply-mentor/_lib/schema.tssrc/app/my/apply-mentor/page.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: manNomi
Repo: solid-connection/solid-connect-web PR: 242
File: src/components/ui/TabSelector.tsx:10-11
Timestamp: 2025-08-12T09:41:44.182Z
Learning: manNomi prefers to keep reusable UI components simple and focused on core functionality rather than adding many features. They don't want to over-engineer flexible/reusable UI components at the initial stage.
Learnt from: manNomi
Repo: solid-connection/solid-connect-web PR: 245
File: src/components/mentor/MentorChatCard/index.tsx:17-21
Timestamp: 2025-08-24T11:14:34.297Z
Learning: manNomi prefers not to receive accessibility suggestions or recommendations during code reviews.
Learnt from: manNomi
Repo: solid-connection/solid-connect-web PR: 245
File: src/api/auth/client/usePostLogout.ts:17-33
Timestamp: 2025-08-24T11:13:08.477Z
Learning: manNomi prefers to prioritize user experience over perfect state consistency in auth flows. Specifically, in logout scenarios, they prefer to keep tokens intact on API failure to avoid forcing users to re-login, even if it means temporary UI state inconsistency.
Learnt from: manNomi
Repo: solid-connection/solid-connect-web PR: 245
File: src/api/auth/client/useDeleteUserAccount.ts:17-27
Timestamp: 2025-08-24T11:11:40.758Z
Learning: manNomi prefers optimistic navigation in auth-related flows (like account deletion) to prevent race conditions where token clearing before navigation could cause intermediate redirects to login page due to pending async requests failing.
Learnt from: manNomi
Repo: solid-connection/solid-connect-web PR: 242
File: src/types/mentor.ts:70-73
Timestamp: 2025-08-12T04:07:04.134Z
Learning: manNomi prefers using Korean labels directly in enum values (e.g., MentorTab.MY_MENTEE = "나의 멘티") over separating enum keys from UI labels for efficiency and intuitiveness, considering scalability concerns as excessive for their current project needs.
📚 Learning: 2025-08-12T09:41:16.076Z
Learnt from: manNomi
Repo: solid-connection/solid-connect-web PR: 242
File: src/app/mentor/modify/_ui/ModifyContent/_hooks/useModifyHookForm.ts:16-29
Timestamp: 2025-08-12T09:41:16.076Z
Learning: In mentor profile modification pages (like src/app/mentor/modify), form reset without isDirty guard is acceptable since users are editing their own data in a dedicated editing space where overwrites are not a concern.
Applied to files:
src/app/my/apply-mentor/page.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build
🔇 Additional comments (9)
.npmrc (1)
6-9: 설정 파일이 깔끔하게 구성되었습니다.기본 레지스트리 설정과 lockfile 활성화가 적절하게 구성되어 있습니다.
.github/workflows/build.yml (1)
30-36: pnpm 설정이 올바르게 추가되었습니다.
- pnpm 버전이 명시적으로 고정되어 있어 재현 가능한 빌드가 보장됩니다 (version 9)
- Vercel CLI 설치도 pnpm 기반으로 일관되게 변경되었습니다
.husky/pre-push (1)
1-7: pre-push 훅이 pnpm으로 깔끔하게 마이그레이션되었습니다.npm 명령어들이 pnpm으로 일관되게 변경되었으며, 훅의 기능은 그대로 유지됩니다.
.github/workflows/ci.yml (2)
17-38: CI 워크플로우의 lint 작업이 완벽하게 마이그레이션되었습니다.
- pnpm 설정이 명시적 버전(9)으로 추가됨
- Node.js 캐싱이 pnpm으로 올바르게 변경됨
npm ci→pnpm install --frozen-lockfile로 정확하게 대체됨 (lockfile 무결성 보장)- 모든 스크립트 실행 명령이 pnpm으로 일관되게 변경됨
47-62: build 작업도 일관되게 pnpm으로 마이그레이션되었습니다.lint 작업과 동일한 패턴으로 pnpm 설정, 캐싱, 의존성 설치가 구성되어 있어 워크플로우 전체가 일관성을 유지합니다.
README.md (1)
12-55: pnpm 마이그레이션 문서화가 명확하고 완성도 있게 작성되었습니다!다음 내용들이 잘 반영되어 있습니다:
Prerequisites 섹션
- Node.js와 pnpm 버전 요구사항 명시
Installation 섹션
- pnpm 전역 설치 방법
- 의존성 설치 명령어
Commands 섹션
- 모든 개발 명령어를 pnpm 기반으로 업데이트
- 주석을 통한 명령어 설명 추가
Migration from npm 섹션
- 기존 프로젝트 사용자를 위한 마이그레이션 가이드 제공
- node_modules와 package-lock.json 정리 방법 안내
문서가 명확하고 실용적이어서 팀원들이 쉽게 마이그레이션할 수 있을 것 같습니다.
package.json (1)
17-18: 스크립트 변경이 올바르게 적용되었습니다!
lint:all과fix:all스크립트가 다른 스크립트를 체이닝하므로pnpm run으로 변경한 것이 정확합니다. 일관성 있는 변경입니다..github/workflows/release.yml (1)
45-51: 워크플로우가 pnpm으로 깔끔하게 전환되었습니다!변경 내용이 올바르게 적용되었습니다:
pnpm 설치 단계 추가
pnpm/action-setup@v3액션 사용- version 9 명시
Vercel CLI 설치 변경
pnpm add --global명령어로 전환워크플로우의 순서와 구성이 논리적이고 명확합니다.
src/app/my/apply-mentor/_components/UniversityScreen/index.tsx (1)
1-230: pnpm 마이그레이션 검증 완료 확인.다음 사항들이 올바르게 적용되어 있습니다:
의존성 설치 완료
- pnpm-lock.yaml 존재 확인 (410KB)
- package-lock.json 제거 완료 ✓
pnpm 구성 설정
- .npmrc 파일 적절히 구성됨 (shamefully-hoist, auto-install-peers 등)
- Next.js 호환성 설정 적용 ✓
Husky 후크 업데이트
- commit-msg:
pnpm dlx commitlint --edit적용 ✓- pre-push:
pnpm run lint,pnpm run typecheck적용 ✓GitHub Actions 워크플로우 확인
- CI: pnpm/action-setup@v3(v9) +
pnpm install --frozen-lockfile✓- Build: pnpm 기반 배포 구성 ✓
- Release: pnpm 명령어 적용 ✓
package.json 스크립트 확인
- lint:all, fix:all에서 pnpm 명령어 참조 ✓
모든 마이그레이션 항목이 검증되었으므로 별도 조치는 불필요합니다.
| @@ -1,2 +1,2 @@ | |||
| npx --no -- commitlint --edit ${1} | |||
| pnpm dlx commitlint --edit ${1} | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
pnpm dlx vs npx --no behavior commitlint
💡 Result:
Short answer: they’re different.
-
npx --no (aka --no-install) prevents npx from downloading a package; it only runs an existing local/global binary and will fail instead of installing. This is what commitlint docs use in husky hooks to avoid prompting to install. [1][3]
-
pnpm dlx always fetches a package temporarily from the registry and runs it (does not add it to package.json). It’s the pnpm equivalent of npx for one‑off remote execution. It does not implement an npx‑style “no‑install” that refuses to download. [2]
Practical guidance for commitlint + Husky:
- If commitlint is a devDependency in the repo: run the local binary via pnpm (pnpm exec commitlint or simply pnpm commitlint) in the hook. That mirrors npx --no behaviour (no remote install). [2][3]
- If you want the one‑time download/execute behaviour (like npx when it installs), use pnpm dlx commitlint ... which will fetch commitlint temporarily. [2][3]
Sources:
[1] npx docs (npm) — npx options and --no/--no-install behavior.
[2] pnpm dlx docs — dlx fetches and runs packages temporarily.
[3] commitlint local setup (Husky example uses "npx --no -- commitlint --edit $1").
🌐 Web query:
pnpm dlx automatic install prompt behavior missing package
💡 Result:
Short answer: pnpm dlx does not "automatically install" a package into your project — it fetches the requested package temporarily from the registry and runs it. If the package cannot be resolved (not published, private/unreachable, or blocked by policy like minimumReleaseAge), dlx will fail with an error (or with the same resolution behavior as normal pnpm commands) rather than silently installing something different. There are related pnpm settings that control prompts and automatic installs for other commands (e.g., verify-deps-before-run), and there are known edge-case bugs (e.g., minimumReleaseAge interactions) discussed in the pnpm issue tracker. See pnpm dlx docs and related GitHub issues for details. [1][2][3]
Sources:
- pnpm dlx documentation. [1]
- pnpm CLI docs / release notes mentioning verify-deps-before-run and dlx behavior. [2]
- GitHub issue discussing dlx / minimumReleaseAge behavior. [3]
🌐 Web query:
npx --no flag purpose prevent install prompt
💡 Result:
--no tells npx to answer the interactive "Ok to proceed?" prompt with "no" (i.e., refuse installing missing packages), so it prevents npx from prompting to download/install and causes the run to fail if the command isn’t already available. It’s the replacement for the older --no-install behavior. [1][2]
pnpm dlx에서 pnpm exec로 변경하세요.
npx --no에서 pnpm dlx로의 전환은 기능적으로 다릅니다. 다음을 확인해주세요:
-
npx --no의 역할: 원격 패키지 설치를 거부하고 로컬에 있는 패키지만 실행합니다. 패키지가 없으면 실행이 실패합니다. -
pnpm dlx의 동작: 항상 레지스트리에서 패키지를 임시로 다운로드하여 실행합니다.--no같은 플래그로 다운로드를 거부할 수 없습니다. -
올바른 대체 방법: commitlint가 devDependency로 설치되어 있다면
pnpm exec commitlint --edit ${1}을 사용하세요. 이것이npx --no동작과 동등합니다.
현재 코드는 의도하지 않은 동작 변경을 포함하고 있습니다.
🤖 Prompt for AI Agents
In @.husky/commit-msg at line 1, Replace the use of "pnpm dlx commitlint --edit
${1}" with the equivalent local-only execution "pnpm exec commitlint --edit
${1}" in the .husky/commit-msg hook (change the "pnpm dlx commitlint --edit
${1}" invocation), and ensure commitlint is installed as a devDependency so the
local exec will run the local package rather than downloading from the registry.
| # Next.js 호환성을 위한 설정 | ||
| shamefully-hoist=true | ||
| auto-install-peers=true | ||
| strict-peer-dependencies=false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
# Check if .npmrc exists and read its content
if [ -f .npmrc ]; then
echo "=== .npmrc content ==="
cat -n .npmrc
echo ""
else
echo ".npmrc not found"
fi
# Check for package.json to understand the project
if [ -f package.json ]; then
echo "=== package.json (first 50 lines) ==="
head -50 package.json
echo ""
fiRepository: solid-connection/solid-connect-web
Length of output: 2002
🏁 Script executed:
# Search for any related issues or comments about shamefully-hoist or pnpm settings
echo "=== Searching for pnpm config related comments ==="
rg -i "shamefully-hoist|auto-install-peers|strict-peer-dependencies|public-hoist" --type-list | head -20Repository: solid-connection/solid-connect-web
Length of output: 535
🏁 Script executed:
# Check for any build configuration files
echo "=== Checking for build/config files ==="
fd -e "next.config" -e "tsconfig" -e "babel.config" -e ".npmrc" -e "pnpm-workspace"Repository: solid-connection/solid-connect-web
Length of output: 117
🏁 Script executed:
# Check for pnpm-related files and search for any configuration comments
echo "=== Checking for pnpm workspace or related configs ==="
find . -maxdepth 2 -type f \( -name "pnpm-workspace.yaml" -o -name ".pnpmfile.cjs" -o -name "pnpm-lock.yaml" \) 2>/dev/null | head -10
echo ""
echo "=== Searching for peer dependency or pnpm-related issues in comments ==="
rg -i "peer.*depend|shamefully|hoist|pnpm.*config" --type ts --type tsx --type js --type json -B 1 -A 1 2>/dev/null | head -30Repository: solid-connection/solid-connect-web
Length of output: 223
🏁 Script executed:
# Check if there are any build errors or warnings documented
echo "=== Looking for any related documentation or issues ==="
find . -maxdepth 2 -type f \( -name "README.md" -o -name "CONTRIBUTING.md" -o -name ".github" \) 2>/dev/null | head -10
# Search in README if it exists
if [ -f README.md ]; then
echo ""
echo "=== Checking README for pnpm/Next.js setup info ==="
rg -i "pnpm|install|setup|next" README.md -A 2 | head -40
fiRepository: solid-connection/solid-connect-web
Length of output: 606
🌐 Web query:
Next.js pnpm shamefully-hoist configuration best practices
💡 Result:
Short answer: avoid shamefully-hoist=true for Next.js workspaces unless you must — prefer targeted hoisting (publicHoistPattern / hoistPattern) or fixing dependency declarations. Use shamefully-hoist only as a last-resort compatibility fallback.
Why:
- shamefully-hoist flattens/hoists everything to root node_modules (makes phantom deps globally available) which hides missing/incorrect dependency declarations and can cause subtle runtime/build differences and native-module resolution problems in Next.js. (pnpm.io)
Best practices
-
Prefer correctness over global hoisting
- Ensure each package declares the deps/devDeps it actually uses (fix phantom/missing deps). This avoids needing global hoisting. (pnpm.io)
-
Use targeted hoisting instead of shamefully-hoist
- publicHoistPattern (or public-hoist-pattern in .npmrc) exposes only matching packages at the root; hoistPattern controls what goes into the virtual store. Use patterns for specific tooling (e.g., eslint, babel, legacy plugins) rather than * for everything. Example: publicHoistPattern[]=plugin or hoistPattern[]=eslint. (pnpm.io)
-
Only enable shamefully-hoist as last resort
- If a third‑party tool absolutely requires classic flattened node_modules and you cannot fix it, set shamefully-hoist=true temporarily and document why. Prefer limited publicHoistPattern over a global shameful hoist. (pnpm.io)
-
Common Next.js-specific gotchas and fixes
- Native modules / compiled artifacts inside workspace packages: Next’s resolver/build may not find .node/.native builds if not hoisted; instead either (a) export/build artifacts into package’s published dist and require from that path, (b) add a narrow publicHoistPattern for that native package, or (c) fix import paths/packaging. See Next.js issues where native modules in pnpm workspaces failed to load unless hoisted. (github.com)
- SWC/webpack/loaders and plugin tooling that assume root node_modules: prefer publicHoistPattern for those specific plugins (e.g., babel, eslint, webpack plugins) rather than global hoist. (pnpm.io)
-
Recommended minimal config examples
-
Debugging checklist before enabling shamefully-hoist
- pnpm why to see where a package is installed.
- Confirm each package.json lists required deps.
- Try hoistPattern/publicHoistPattern for the offending package.
- Reproduce build locally after each change; if unresolved, enable shamefully-hoist temporarily and open an issue with the tool/maintainer. (newreleases.io)
-
Operational notes
- Pin pnpm versions across CI/dev machines because hoisting behavior and defaults have changed across pnpm releases. Test CI builds after any hoist config change. (newreleases.io)
If you want, I can:
- review your repo’s pnpm/Next.js layout and suggest a minimal hoistPattern/publicHoistPattern, or
- produce the exact .npmrc / pnpm-workspace.yaml snippets tailored to your packages.
Citations:
- 1: https://pnpm.io/9.x/npmrc?utm_source=openai
- 2: https://pnpm.io/blog/2020/10/17/node-modules-configuration-options-with-pnpm?utm_source=openai
- 3: https://pnpm.io/next/settings?utm_source=openai
- 4: https://pnpm.io/9.x/npmrc?utm_source=openai
- 5: Next.js fails to find/load native node modules compiled as a separate package in a (pnpm) workspace vercel/next.js#71630
- 6: https://pnpm.io/next/settings?utm_source=openai
- 7: https://pnpm.io/9.x/npmrc?utm_source=openai
- 8: https://pnpm.io/next/settings?utm_source=openai
- 9: https://newreleases.io/project/github/pnpm/pnpm/release/v4.0.0-7?utm_source=openai
- 10: https://newreleases.io/project/github/pnpm/pnpm/release/v4.0.0-7?utm_source=openai
pnpm 설정의 엄격함을 약화시키는 옵션들을 검토하고 개선해주세요.
현재 .npmrc의 설정들이 pnpm의 핵심 강점인 의존성 격리를 완화하고 있습니다. 다음 단계를 통해 더 나은 구성으로 개선할 수 있습니다:
-
현재 설정의 영향 파악하기
shamefully-hoist=true: 모든 패키지를 root node_modules에 호이스팅하여 누락된 의존성 선언을 숨길 수 있음auto-install-peers=true와strict-peer-dependencies=false: pnpm의 엄격한 의존성 검사를 우회
-
설정 없이 프로젝트가 정상 작동하는지 테스트
- .npmrc에서
shamefully-hoist=true주석 처리 node_modules제거 후pnpm install실행pnpm run build와pnpm run dev실행하여 에러 확인
- .npmrc에서
-
특정 패키지만 호이스팅 필요한 경우 대안 사용
- 특정 도구나 플러그인(예: eslint, babel)만 호이스팅이 필요하다면, 전역
shamefully-hoist대신public-hoist-pattern을 사용하는 것이 권장됨 - 예시:
public-hoist-pattern[]=*eslint*또는public-hoist-pattern[]=*babel-*
- 특정 도구나 플러그인(예: eslint, babel)만 호이스팅이 필요하다면, 전역
-
의존성 누락 확인
pnpm why <패키지명>명령으로 각 패키지의 설치 위치 확인- 필요한 경우
package.json의 의존성 선언을 정정
🤖 Prompt for AI Agents
In @.npmrc around lines 1 - 4, The .npmrc currently weakens pnpm isolation via
shamefully-hoist=true, auto-install-peers=true, and
strict-peer-dependencies=false; remove or comment out those three lines, run rm
-rf node_modules && pnpm install then validate with pnpm run build and pnpm run
dev, and if a specific tool truly needs hoisting replace shamefully-hoist with
targeted public-hoist-pattern entries (e.g., public-hoist-pattern[]=*eslint* or
public-hoist-pattern[]=*babel-*) and fix any missing declarations discovered via
pnpm why <package> by adding them to package.json.
| fileInputRef.current.value = ""; | ||
| } | ||
| setValue("verificationFile", null); | ||
| setValue("verificationFile", null as any); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
세 곳의 as any 타입 단언도 동일한 타입 안전성 문제가 있습니다.
파일 검증 실패 및 제거 시 null로 설정하는 것은 로직상 올바르지만, as any를 사용하여 타입 체크를 우회하고 있습니다.
문제가 발생하는 곳:
- 라인 63: 잘못된 파일 형식일 때
- 라인 73: 파일 크기 초과일 때
- 라인 82: 파일 제거 시
근본 원인:
schema.ts에서 verificationFile이 nullable을 허용하지 않도록 변경된 것으로 보이나, 실제 사용자 경험상 파일을 제거하거나 유효하지 않은 파일을 처리할 때는 null 상태가 필요합니다.
권장되는 해결 방법:
// schema.ts에서
verificationFile: z
.instanceof(File)
.nullable()
.refine((file) => file !== null, { message: "증명서 파일을 업로드해주세요." })이렇게 하면 nullable을 허용하면서도 제출 시에는 반드시 파일이 있어야 한다는 검증 규칙을 유지할 수 있습니다.
Also applies to: 73-73, 82-82
🤖 Prompt for AI Agents
In @src/app/my/apply-mentor/_components/UniversityScreen/index.tsx at line 63,
The three uses of setValue("verificationFile", null as any) bypass TypeScript
safety because schema.ts no longer allows null for verificationFile; update the
schema to accept nullable Files (e.g., make verificationFile a nullable File
with a refine to ensure non-null on submit) and then remove the as any casts so
setValue("verificationFile", null) is type-safe; adjust any form
submit/validation logic that expects a non-null file to rely on the schema
refine (verificationFile) rather than forcing non-null types.
| country: "", | ||
| universityName: "", | ||
| verificationFile: null, | ||
| verificationFile: undefined as any, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
find . -name "schema.ts" -o -name "schema.js" | head -20Repository: solid-connection/solid-connect-web
Length of output: 296
🏁 Script executed:
cat -n src/app/my/apply-mentor/page.tsx | sed -n '20,60p'Repository: solid-connection/solid-connect-web
Length of output: 1489
🏁 Script executed:
cat -n src/app/my/apply-mentor/_lib/schema.ts 2>/dev/null || find . -path "*apply-mentor*" -name "schema.ts" -exec cat -n {} \;Repository: solid-connection/solid-connect-web
Length of output: 1749
as any를 제거하고 스키마 타입을 명확히 해주세요.
verificationFile의 타입 정의가 맞지 않습니다. 다음과 같은 부분을 개선하면 좋겠습니다.
-
현재 상황
- schema.ts에서
verificationFile은z.instanceof(File)로만 정의 (선택 불가) - page.tsx의 defaultValues에서
undefined as any로 설정 (타입 우회) - 런타임에서 null 체크 수행하지만, 컴파일 타임 타입 체크 불가능
- schema.ts에서
-
권장되는 개선 방법
- schema.ts의 verificationFile 필드에
.optional()또는.nullable()추가:verificationFile: z .instanceof(File, { message: "증명 서류(파일)를 업로드해 주세요." }) .refine(...) .optional() - page.tsx에서
undefined as any제거하고 일반적인undefined사용
- schema.ts의 verificationFile 필드에
이렇게 하면 TypeScript가 초기값부터 타입을 올바르게 이해하게 되어, 컴파일 타임에 안전성을 확보할 수 있습니다.
🤖 Prompt for AI Agents
In @src/app/my/apply-mentor/page.tsx at line 30, The verificationFile default
value is being type-escaped with "undefined as any" in page.tsx; update the
schema field verificationFile in schema.ts to be either .optional() or
.nullable() (e.g., z.instanceof(File, {...}).refine(...).optional()) so
TypeScript recognizes absence, then remove the "as any" in defaultValues in
page.tsx and use plain undefined (or undefined | File type) for verificationFile
to align compile-time types with your runtime null checks.
관련 이슈
작업 내용
pnpm 마이그레이션
특이 사항
리뷰 요구사항 (선택)