Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning
|
| 타입 | 파일 | 변경 내용 |
|---|---|---|
| 빌드 설정 | frontend/config/vite.config.ts |
SVGR 플러그인 제거 |
frontend/package.json |
Webpack 관련 스크립트 및 의존성 제거 | |
frontend/public/index.html |
메타 viewport에서 viewport-fit=cover 제거 |
|
frontend/src/vite-env.d.ts |
Vite 및 SVGR 관련 타입 참조 제거 | |
| 헤더/네비게이션 | frontend/src/components/common/Header/Header.tsx |
디바이스 감지 로직(showOn, hideOn props) 제거, 컴포넌트 시그니처 단순화 |
frontend/src/pages/ApplicationFormPage/ApplicationFormPage.tsx |
Header의 showOn={['desktop']} prop 제거 |
|
frontend/src/pages/ClubUnionPage/ClubUnionPage.tsx |
Header 렌더링을 isInAppWebView() 조건문으로 변경 |
|
frontend/src/pages/IntroducePage/IntroducePage.tsx |
조건부 Header 렌더링 추가 |
|
| 클럽 상세 페이지 | frontend/src/pages/ClubDetailPage/ClubDetailPage.tsx |
TOP_BAR 기반 네비게이션 제거, 탭 핸들러 명시화, Header 조건부 렌더링 |
frontend/src/pages/ClubDetailPage/ClubDetailPage.styles.ts |
태블릿 padding 및 TabButton height 제거 | |
frontend/src/pages/ClubDetailPage/components/ClubDetailTopBar/* |
클럽 상세 상단바 컴포넌트 및 스타일 전체 삭제 | |
frontend/src/pages/ClubDetailPage/components/ClubFeed/ClubFeed.tsx |
디바이스 기반 eager 로딩 로직 제거, 모든 이미지를 lazy loading으로 통일 | |
frontend/src/pages/ClubDetailPage/components/ClubProfileCard/ClubProfileCard.* |
백 버튼 추가, useNavigate 통합, 스타일 확장 |
|
frontend/src/pages/ClubDetailPage/components/ShareButton/ShareButton.tsx |
웹뷰 공유 경로 제거, Kakao SDK 기반 공유로 변경 | |
| 스크롤/UI 유틸 | frontend/src/hooks/Scroll/useScrollTo.ts |
스크롤 훅 파일 전체 삭제 |
frontend/src/hooks/Scroll/ScrollToTop.tsx |
useScrollTo 제거, window.scrollTo 직접 호출로 변경 |
|
frontend/src/components/common/ScrollToTopButton/ScrollToTopButton.tsx |
useScrollTo 의존성 제거, 네이티브 window.scrollTo 호출 추가 |
|
| API/타입 단순화 | frontend/src/apis/applicants.ts |
함수 반환 타입 명시 제거 (타입 추론 사용) |
frontend/src/apis/application.ts |
ApplicationListResponse 인터페이스 제거, 반환 타입 일반화 |
|
frontend/src/pages/AdminPage/auth/LoginTab/LoginTab.tsx |
로그인 응답 null 체크 제거, 직접 destructuring | |
| 스타일 업데이트 | frontend/src/components/application/modals/ApplicationSelectModal.styles.ts |
OptionButton의 color: black 제거 |
frontend/src/pages/AdminPage/tabs/ApplicantsTab/* |
CSS URL 따옴표 제거 (cleaner syntax) | |
frontend/src/pages/ClubDetailPage/components/ClubProfileCard/ClubProfileCard.styles.ts |
BackButton 스타일 추가, IntroDescription 모바일 폰트 크기 추가 |
|
frontend/src/styles/zIndex.ts |
Z_INDEX.modal 속성 제거 |
|
frontend/src/styles/styled.d.ts |
styled-components DefaultTheme 선언 제거 |
|
| 기타 | README.md |
프로젝트 소개 및 구성 대규모 리구성 (기술 스택, 팀 정보 추가) |
frontend/src/index.tsx |
Kakao SDK 초기화 함수 추가 및 호출 | |
frontend/src/mocks/mswDevSetup.ts |
MSW handler 타입 캐스팅 추가 | |
frontend/src/utils/webviewBridge.ts |
웹뷰 브릿지 유틸 전체 삭제 | |
frontend/src/hooks/Queries/useClubCover.ts, useClubImages.ts |
URL 데이터 null 체크 제거, 직접 destructuring | |
frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx |
queryClient.invalidateQueries() 호출 제거 |
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
- [feature] 상세 페이지 모바일 탑바 웹뷰로 이관 및 리액트 네이티브 API 연동 구조 도입 #1090: 메인 PR에서 제거된 ClubDetailTopBar, webviewBridge, useScrollTo 등 SVGR 통합을 이전에 추가했던 PR이므로 직접 관련
- [chore] Vite 전환 이후 남아있던 Webpack 패키지 정리 #1098: Webpack 설정 파일 및 의존성을 추가했던 PR과 반대 방향의 변경으로 직접 충돌 가능성 있음
- [release] v1.0.8 #595: ShareButton 컴포넌트의 Kakao 공유 로직 변경과 직접 관련
Suggested labels
⚙ Setting, 🔄 Refactor, 📃 Docs
Suggested reviewers
- lepitaaar
- suhyun113
- seongwon030
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | 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. |
✅ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | PR 제목이 변경 내용의 주요 목적을 정확하게 반영하고 있습니다. 이전 릴리스를 되돌리는 작업이며, PR 설명에서도 '#1106을 되돌린다'고 명시되어 있습니다. |
✏️ 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.
Comment @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
frontend/src/hooks/Queries/useClubImages.ts (2)
31-37:feedResArrundefined/길이 불일치 시 런타임 오류 위험
feedApi.getUploadUrls가undefined를 반환하거나 길이가files와 다르면feedResArr[i]접근에서 즉시 실패합니다. 최소한의 가드가 필요합니다.🛠️ 제안 수정안
- const feedResArr = await feedApi.getUploadUrls(clubId, uploadRequests); + const feedResArr = await feedApi.getUploadUrls(clubId, uploadRequests); + if (!feedResArr || feedResArr.length !== files.length) { + throw new Error('업로드 URL 생성에 실패했습니다.'); + }Also applies to: 44-48
103-113:logoApi.getUploadUrl결과가 undefined면 구조 분해에서 터짐
logoApi.getUploadUrl는Promise<PresignedData | undefined>타입입니다. 현재처럼 바로 구조 분해하면undefined일 때 런타임 예외가 발생합니다.🛠️ 제안 수정안
- const { presignedUrl, finalUrl } = await logoApi.getUploadUrl( + const uploadUrlData = await logoApi.getUploadUrl( clubId, file.name, file.type, ); + if (!uploadUrlData) { + throw new Error('로고 업로드 URL 생성에 실패했습니다.'); + } + const { presignedUrl, finalUrl } = uploadUrlData;
🤖 Fix all issues with AI agents
In `@frontend/config/webpack.dev.ts`:
- Around line 19-35: The build success logging uses stats.toJson() and then
calls .assets.map(...) which can throw because webpack is configured with stats:
{ all: false } and assets may be omitted; update the compiler.hooks.done.tap
handler to call stats.toJson with explicit fields (e.g. stats.toJson({ assets:
true, errors: true, warnings: true })) and guard access to assets (e.g., use
(json.assets ?? []) before mapping) so the Assets listing and error/warning
logging cannot cause a runtime exception.
In `@frontend/package.json`:
- Around line 27-32: Move the build-only packages out of runtime dependencies:
remove "@sentry/webpack-plugin" and "dotenv-webpack" from the dependencies
section of package.json and add them to devDependencies instead; update
package.json entries accordingly, run your package manager (npm/yarn/pnpm
install) to update lockfile, and verify webpack.common.ts still imports/uses
"dotenv-webpack" for build-time only without requiring it at runtime.
In `@frontend/src/hooks/Queries/useClubCover.ts`:
- Around line 15-23: coverApi.getUploadUrl returns Promise<PresignedData |
undefined>, so don’t destructure its result immediately; call const data = await
coverApi.getUploadUrl(...), check if data is undefined and handle the failure
(throw an error, return early, or log and surface a user-facing error) before
using uploadToStorage or calling coverApi.completeUpload; reference the call to
coverApi.getUploadUrl and the variables presignedUrl/finalUrl (now accessed from
data) and ensure uploadToStorage and coverApi.completeUpload are only invoked
when data is present.
In `@frontend/src/pages/AdminPage/auth/LoginTab/LoginTab.tsx`:
- Around line 35-36: The call to login() in LoginTab.tsx can return undefined,
so avoid destructuring directly; instead capture the result (e.g., const result
= await login(userId, password)), check if result is falsy, handle the error
path (show validation/error message and return) and only then read
result.accessToken and call localStorage.setItem('accessToken', accessToken);
update any references to accessToken in the function to use the validated result
to prevent the runtime TypeError when login() returns undefined.
In `@frontend/src/pages/ClubDetailPage/components/ShareButton/ShareButton.tsx`:
- Around line 14-15: The current check only uses Kakao.isInitialized(), which
doesn't guarantee the Share API exists; update the ShareButton logic to
additionally verify the Share API is available (e.g., check window.Kakao &&
typeof window.Kakao.Share !== 'undefined' and that the specific method you call
exists like sendDefault or sendCustom) before attempting to call it; modify the
event handler in ShareButton (and any init/ready guards referencing
isInitialized()) to bail out gracefully (disable the button, show an
error/toast, or log) when the Share API/method is missing, and keep
DEFAULT_IMAGE_URL usage unchanged.
In `@frontend/src/pages/MainPage/components/Popup/Popup.styles.ts`:
- Line 2: Remove the unused Theme type import from the top of Popup.styles.ts:
only the theme object is used in this file (referenced as theme on multiple
lines), so delete the named Theme import from the import statement and keep the
theme import only; ensure no other references to Theme remain and run a quick
typecheck to confirm the unused-import warning is gone.
In `@README.md`:
- Around line 68-92: Add descriptive alt attributes to each <img> element in the
contributor grid to resolve accessibility warnings: for each <img> (the ones
paired with links labeled Pororo, Zepelown, FhRh, lepitaaar, alsdddk) add a
concise alt string like "Pororo avatar" / "Zepelown avatar" etc. Ensure alt text
describes the image/purpose (not empty) and matches the corresponding
contributor name so screen readers convey the contributor identity.
- Around line 29-48: The contributor table has an <img> tag with an empty src
and missing alt text and a corresponding <a> whose link text is empty; update
every <img> in that contributor cells block to include meaningful alt attributes
(e.g., alt="Avatar of <username>"), remove or replace src="" with a valid image
URL or omit the entire <td> if no avatar is available, and ensure each <a>
contains non-empty visible text (e.g., the GitHub username) so anchors are
accessible and render properly.
- Around line 113-120: Add descriptive alt attributes to every raw HTML <img
src="..."> badge in README.md (for example the <img> tags for React, TypeScript,
styled--components, Prettier, Google_Cloud, docker, etc.) so they provide
concise accessible text (e.g., "React logo", "TypeScript logo", "Google Cloud
logo"); alternatively replace the raw <img> with markdown image syntax
 that already includes alt text—ensure all <img src="...">
occurrences are updated to include meaningful alt attributes.
🧹 Nitpick comments (5)
frontend/src/apis/applicants.ts (1)
5-11: 명시적 반환 타입 및 제네릭 타입 파라미터 제거로 인한 타입 안전성 저하
getClubApplicants함수에서 명시적 반환 타입과handleResponse의 제네릭 타입 파라미터가 제거되었습니다. 이로 인해 반환 타입이Promise<ApplicantsInfo | undefined>대신Promise<unknown | undefined>로 추론되어, 호출하는 측에서 타입 추론이 제대로 작동하지 않을 수 있습니다.리버트 PR이므로 의도된 롤백이라면 이해하지만, 향후 타입 안전성을 위해 명시적 타입 지정을 고려해 주세요.
🔧 타입 안전성을 위한 제안
+import { ApplicantsInfo } from '@/types/applicants'; + -export const getClubApplicants = async (applicationFormId: string) => { +export const getClubApplicants = async (applicationFormId: string): Promise<ApplicantsInfo | undefined> => { return withErrorHandling(async () => { const response = await secureFetch( `${API_BASE_URL}/api/club/apply/info/${applicationFormId}`, ); - return handleResponse(response, '지원자 목록을 불러오는데 실패했습니다.'); + return handleResponse<ApplicantsInfo>(response, '지원자 목록을 불러오는데 실패했습니다.'); }, 'Error fetching club applicants'); };frontend/src/apis/application.ts (1)
73-78:getAllApplicationForms의 타입 정의 누락으로 인한 일관성 저하동일 파일 내 다른 함수들(
getApplication,getApplicationOptions)은 명시적 반환 타입과 제네릭 타입 파라미터를 사용하는 반면,getAllApplicationForms는 타입 정의가 없습니다. 이로 인해 API 함수 간 일관성이 떨어지고, 호출하는 측에서 응답 타입을 알 수 없게 됩니다.리버트 PR의 맥락을 이해하지만, 코드베이스 전반의 타입 일관성을 위해 적절한 응답 타입 정의를 권장합니다.
frontend/src/mocks/mswDevSetup.ts (1)
2-5: MSW 내부 경로 import 및 double cast 제거 권장
msw/lib/core/...는 MSW의 내부 경로로, 버전 업그레이드 시 예고 없이 변경될 수 있습니다. MSW v2의 공식 공개 API는import { RequestHandler } from 'msw'입니다. 또한handlers as unknown as RequestHandler[]형태의 이중 타입 캐스팅은 실제 타입 오류를 숨길 수 있으므로,frontend/src/mocks/api/index.ts에서handlers를RequestHandler[]로 명확히 선언하면 이곳에서 캐스팅을 완전히 제거할 수 있습니다.♻️ 제안 수정 (mswDevSetup.ts)
-import { RequestHandler } from 'msw/lib/core/handlers/RequestHandler.mjs'; +import type { RequestHandler } from 'msw'; -export const worker = setupWorker(...(handlers as unknown as RequestHandler[])); +export const worker = setupWorker(...handlers);♻️ 제안 수정 (frontend/src/mocks/api/index.ts)
+import type { RequestHandler } from 'msw'; import { applyHandlers } from './apply'; -export const handlers = [...applyHandlers]; +export const handlers: RequestHandler[] = [...applyHandlers];frontend/src/pages/ClubDetailPage/components/ClubProfileCard/ClubProfileCard.tsx (1)
1-2: BackButton에type="button"지정 권장버튼이 폼 내부에 배치될 가능성을 고려하면 기본 submit 동작을 방지하는 편이 안전합니다.
♻️ 제안 수정안
- <Styled.BackButton onClick={handleBackClick} aria-label='뒤로가기'> + <Styled.BackButton + type='button' + onClick={handleBackClick} + aria-label='뒤로가기' + > <img src={PrevButton} alt='' /> </Styled.BackButton>Also applies to: 31-35, 63-65
frontend/config/webpack.prod.ts (1)
26-26: 프로덕션 CSS 파일명에 contenthash 추가 권장JS는
[name].[contenthash].js로 설정되어 있는데 CSS는 기본 파일명이라 캐시 갱신이 어려울 수 있습니다.MiniCssExtractPlugin에filename/chunkFilename을 지정하는 편이 안전합니다.♻️ 제안 수정
- plugins: [new MiniCssExtractPlugin()], + plugins: [ + new MiniCssExtractPlugin({ + filename: '[name].[contenthash].css', + chunkFilename: '[id].[contenthash].css', + }), + ],
| compiler.hooks.done.tap('done', (stats) => { | ||
| if (stats.hasErrors()) { | ||
| console.error('❌ Webpack Build Failed! Please check errors above.'); | ||
| console.error(stats.toJson().errors); | ||
| } else if (stats.hasWarnings()) { | ||
| console.warn('⚠️ Webpack Build Completed with Warnings.'); | ||
| } else { | ||
| console.log(` | ||
| -------------------------------------------------------- | ||
| 🎉 WEBPACK BUILD SUCCESSFULLY COMPLETED! | ||
| ✅ Files Generated: ${stats | ||
| .toJson() | ||
| .assets.map((asset) => asset.name) | ||
| .join(', ')} | ||
| ⏱️ Build Time: ${stats.endTime - stats.startTime} ms | ||
| 🌐 Server Running at: http://localhost:${port} | ||
| -------------------------------------------------------- |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
webpack stats.toJson default options assets when stats.all false
💡 Result:
In webpack’s stats.toJson() options, all is a fallback: it applies to any stats option you didn’t explicitly set, and it overrides webpack’s built-in defaults (like assets: true). So if you call:
stats.toJson({ all: false })then assets becomes false (because it’s “not defined”, so it falls back to all: false), and the assets list won’t be included. Webpack documents stats.all as the fallback and stats.assets as boolean = true by default. [1]
If you want “everything off by default, but still include assets”, do:
stats.toJson({ all: false, assets: true })(toJson accepts either a preset string or an options object). [2]
Sources: [1] [2]
🏁 Script executed:
# Find and examine the webpack.dev.ts file
find . -name "webpack.dev.ts" -type fRepository: Moadong/moadong
Length of output: 91
🏁 Script executed:
# Search for stats configuration in webpack config files
rg "stats\s*:" frontend/ -A 5 -B 2Repository: Moadong/moadong
Length of output: 427
🏁 Script executed:
# Verify the exact problematic code at lines 19-35
sed -n '19,35p' frontend/config/webpack.dev.tsRepository: Moadong/moadong
Length of output: 801
🏁 Script executed:
# Check if there are other calls to stats.toJson() in the file (mentioned "Also applies to: 80-82")
sed -n '75,85p' frontend/config/webpack.dev.tsRepository: Moadong/moadong
Length of output: 238
stats: { all: false } 설정으로 인해 .assets 필드 누락 시 런타임 오류 발생
현재 코드는 stats: { all: false } 설정으로 인해 stats.toJson()이 기본값에서 assets 필드를 포함하지 않습니다. 26-29번 줄의 .assets.map() 호출이 undefined에서 실행되어 런타임 오류를 발생시킵니다. stats.toJson({ assets: true, errors: true, warnings: true })로 명시하거나, 다음과 같이 가드 로직을 추가하세요:
const json = stats.toJson({ assets: true, errors: true, warnings: true });
const assetNames = (json.assets ?? []).map((asset) => asset.name).join(', ');
console.log(`✅ Files Generated: ${assetNames}`);🤖 Prompt for AI Agents
In `@frontend/config/webpack.dev.ts` around lines 19 - 35, The build success
logging uses stats.toJson() and then calls .assets.map(...) which can throw
because webpack is configured with stats: { all: false } and assets may be
omitted; update the compiler.hooks.done.tap handler to call stats.toJson with
explicit fields (e.g. stats.toJson({ assets: true, errors: true, warnings: true
})) and guard access to assets (e.g., use (json.assets ?? []) before mapping) so
the Assets listing and error/warning logging cannot cause a runtime exception.
| "@sentry/react": "^9.18.0", | ||
| "@sentry/webpack-plugin": "^3.4.0", | ||
| "@tanstack/react-query": "^5.66.0", | ||
| "date-fns": "^4.1.0", | ||
| "dotenv-webpack": "^8.1.0", | ||
| "eventsource": "^4.1.0", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, let's examine the frontend/package.json structure
echo "=== Examining frontend/package.json dependencies section ==="
cat -n frontend/package.json | head -100Repository: Moadong/moadong
Length of output: 4400
🏁 Script executed:
#!/bin/bash
# Check webpack config files for plugin usage
echo "=== Checking webpack config files for plugin usage ==="
find frontend -name "webpack*.ts" -o -name "webpack*.js" | head -20Repository: Moadong/moadong
Length of output: 210
🏁 Script executed:
#!/bin/bash
# Examine webpack config files for `@sentry/webpack-plugin` and dotenv-webpack usage
echo "=== webpack.common.ts ==="
cat -n frontend/config/webpack.common.ts | grep -E "(sentry|dotenv)" -B 2 -A 2
echo -e "\n=== webpack.dev.ts ==="
cat -n frontend/config/webpack.dev.ts | grep -E "(sentry|dotenv)" -B 2 -A 2
echo -e "\n=== webpack.prod.ts ==="
cat -n frontend/config/webpack.prod.ts | grep -E "(sentry|dotenv)" -B 2 -A 2
# Also check if these are imported in any of these files
echo -e "\n=== Checking for imports in webpack configs ==="
rg -n "import.*sentry|require.*sentry|import.*dotenv|require.*dotenv" frontend/config/Repository: Moadong/moadong
Length of output: 532
🏁 Script executed:
#!/bin/bash
# Check the full webpack.common.ts for plugin instantiation
echo "=== Full webpack.common.ts to see plugin usage ==="
wc -l frontend/config/webpack.common.ts
# Read relevant sections
echo -e "\n=== Webpack common config (first 100 lines) ==="
cat -n frontend/config/webpack.common.ts | head -100Repository: Moadong/moadong
Length of output: 2263
🏁 Script executed:
#!/bin/bash
# Search for `@sentry/webpack-plugin` usage in the entire project
echo "=== Searching for `@sentry/webpack-plugin` usage ==="
rg -n "@sentry/webpack-plugin|sentry.*webpack|SentryWebpackPlugin" frontend/
# Also check package.json to see if it's actually used
echo -e "\n=== Checking if `@sentry/webpack-plugin` is imported anywhere ==="
rg -n "sentry.*webpack|SentryWebpackPlugin" frontend/ --type ts --type tsx --type js --type jsonRepository: Moadong/moadong
Length of output: 992
🏁 Script executed:
#!/bin/bash
# Search for actual usage of sentry/webpack plugin and dotenv-webpack in source code
echo "=== Searching for SentryWebpackPlugin usage in source ==="
rg -n "SentryWebpackPlugin|require.*sentry.*webpack|import.*sentry.*webpack" frontend/src/ frontend/config/
echo -e "\n=== Checking webpack.prod.ts for Sentry plugin ==="
cat -n frontend/config/webpack.prod.ts
echo -e "\n=== Checking webpack.dev.ts for Sentry plugin ==="
cat -n frontend/config/webpack.dev.ts
echo -e "\n=== Checking if dotenv-webpack is used at runtime ==="
rg -n "process\.env|dotenv" frontend/src/ | head -20Repository: Moadong/moadong
Length of output: 4458
🏁 Script executed:
#!/bin/bash
# Check vite config since there are vite build scripts
echo "=== Checking vite config files ==="
find frontend/config -name "*vite*" -type f
echo -e "\n=== Checking if `@sentry/webpack-plugin` is used in vite configs ==="
rg -n "sentry|Sentry" frontend/config/ || echo "No Sentry usage found in config"
# Check CI configuration
echo -e "\n=== Looking for CI configuration ==="
find . -maxdepth 2 -name "*.yml" -o -name "*.yaml" | grep -E "(github|gitlab|circleci|jenkins|workflow)" | head -10Repository: Moadong/moadong
Length of output: 319
🏁 Script executed:
#!/bin/bash
# Check the vite config to see Sentry usage
echo "=== Checking vite.config.ts for Sentry configuration ==="
cat -n frontend/config/vite.config.ts
echo -e "\n=== Looking for GitHub Actions or other CI files ==="
find . -path ./.git -prune -o -name "*.yml" -o -name "*.yaml" | grep -v node_modules | grep -v ".git" | head -20
echo -e "\n=== Check deployment/GitHub workflows ==="
find .github -name "*.yml" -o -name "*.yaml" 2>/dev/null | head -10Repository: Moadong/moadong
Length of output: 2663
🏁 Script executed:
#!/bin/bash
# Check the key CI workflows for how dependencies are installed
echo "=== Checking pr-test.yml workflow ==="
cat -n .github/workflows/pr-test.yml
echo -e "\n=== Checking deployment workflows for dependency installation ==="
rg -n "npm install|npm ci|yarn install|pnpm install|--production|--omit" .github/workflows/ | head -30Repository: Moadong/moadong
Length of output: 2564
🏁 Script executed:
#!/bin/bash
# Check other deployment workflows that might handle frontend
echo "=== Checking oracle_server_cd_develop.yml ==="
cat -n .github/workflows/oracle_server_cd_develop.yml | head -100
echo -e "\n=== Checking server_cd_release.yml ==="
cat -n .github/workflows/server_cd_release.yml | head -100Repository: Moadong/moadong
Length of output: 7210
🏁 Script executed:
#!/bin/bash
# Let me verify if `@sentry/webpack-plugin` is actually imported anywhere else
echo "=== Complete search for `@sentry/webpack-plugin` usage ==="
rg -n "@sentry" frontend/ --type-add 'ts:*.ts' --type-add 'tsx:*.tsx' | grep -v "package-lock" | head -30
echo -e "\n=== Checking src directory for any Sentry usage ==="
find frontend/src -type f \( -name "*.ts" -o -name "*.tsx" \) -exec grep -l "sentry" {} \;
echo -e "\n=== Checking if Sentry is initialized in the app ==="
rg -n "Sentry\.|@sentry" frontend/src/ | head -20Repository: Moadong/moadong
Length of output: 658
🏁 Script executed:
#!/bin/bash
# Check if there are frontend-specific deployment or build configurations
echo "=== Searching for frontend-specific deployments or docker ==="
find . -name "Dockerfile" -o -name "docker-compose*" | grep -i frontend
echo -e "\n=== Checking root level Dockerfile ==="
cat -n ./Dockerfile 2>/dev/null | head -50 || echo "No root Dockerfile found"
echo -e "\n=== Checking if frontend is built in backend Dockerfile ==="
cat -n ./backend/Dockerfile | head -100Repository: Moadong/moadong
Length of output: 680
🏁 Script executed:
#!/bin/bash
# Check git history or comments about `@sentry/webpack-plugin`
echo "=== Checking for any comments or notes about `@sentry/webpack-plugin` ==="
rg -n "sentry.*webpack|SentryWebpackPlugin" frontend/ --context 5
echo -e "\n=== Checking if there are any TODO or FIXME comments related to Sentry ==="
rg -n "TODO|FIXME|XXX" frontend/ | grep -i sentry
echo -e "\n=== Final verification - checking all webpack config plugins instantiation ==="
cat frontend/config/webpack.common.ts | grep -A 20 "plugins:"Repository: Moadong/moadong
Length of output: 6322
빌드 전용 플러그인을 devDependencies로 이동하세요
@sentry/webpack-plugin과 dotenv-webpack은 빌드 단계에서만 사용되므로 devDependencies로 옮겨야 합니다. dotenv-webpack은 webpack.common.ts에서 플러그인으로 사용 중이며, 두 패키지 모두 런타임에는 필요하지 않습니다.
♻️ 수정 제안
"dependencies": {
"@channel.io/channel-web-sdk-loader": "^2.0.0",
"@sentry/react": "^9.18.0",
- "@sentry/webpack-plugin": "^3.4.0",
"@tanstack/react-query": "^5.66.0",
"date-fns": "^4.1.0",
- "dotenv-webpack": "^8.1.0",
"eventsource": "^4.1.0", "devDependencies": {
"@chromatic-com/storybook": "^4.1.3",
"@eslint/js": "^9.17.0",
"@ianvs/prettier-plugin-sort-imports": "^4.7.0",
+ "@sentry/webpack-plugin": "^3.4.0",
...
+ "dotenv-webpack": "^8.1.0",📝 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.
| "@sentry/react": "^9.18.0", | |
| "@sentry/webpack-plugin": "^3.4.0", | |
| "@tanstack/react-query": "^5.66.0", | |
| "date-fns": "^4.1.0", | |
| "dotenv-webpack": "^8.1.0", | |
| "eventsource": "^4.1.0", | |
| "@sentry/react": "^9.18.0", | |
| "@tanstack/react-query": "^5.66.0", | |
| "date-fns": "^4.1.0", | |
| "eventsource": "^4.1.0", |
🤖 Prompt for AI Agents
In `@frontend/package.json` around lines 27 - 32, Move the build-only packages out
of runtime dependencies: remove "@sentry/webpack-plugin" and "dotenv-webpack"
from the dependencies section of package.json and add them to devDependencies
instead; update package.json entries accordingly, run your package manager
(npm/yarn/pnpm install) to update lockfile, and verify webpack.common.ts still
imports/uses "dotenv-webpack" for build-time only without requiring it at
runtime.
| const { presignedUrl, finalUrl } = await coverApi.getUploadUrl( | ||
| clubId, | ||
| file.name, | ||
| file.type, | ||
| ); | ||
|
|
||
| if (!uploadUrlData) { | ||
| throw new Error('커버 업로드 URL 생성 실패'); | ||
| } | ||
|
|
||
| const { presignedUrl, finalUrl } = uploadUrlData; | ||
|
|
||
| await uploadToStorage(presignedUrl, file); | ||
|
|
||
| await coverApi.completeUpload(clubId, finalUrl); |
There was a problem hiding this comment.
coverApi.getUploadUrl undefined 처리 누락
반환 타입이 Promise<PresignedData | undefined>인데 바로 구조 분해하면 실패 케이스에서 런타임 예외가 납니다. 가드를 추가하세요.
🛠️ 제안 수정안
- const { presignedUrl, finalUrl } = await coverApi.getUploadUrl(
+ const uploadUrlData = await coverApi.getUploadUrl(
clubId,
file.name,
file.type,
);
+ if (!uploadUrlData) {
+ throw new Error('커버 업로드 URL 생성에 실패했습니다.');
+ }
+ const { presignedUrl, finalUrl } = uploadUrlData;📝 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.
| const { presignedUrl, finalUrl } = await coverApi.getUploadUrl( | |
| clubId, | |
| file.name, | |
| file.type, | |
| ); | |
| if (!uploadUrlData) { | |
| throw new Error('커버 업로드 URL 생성 실패'); | |
| } | |
| const { presignedUrl, finalUrl } = uploadUrlData; | |
| await uploadToStorage(presignedUrl, file); | |
| await coverApi.completeUpload(clubId, finalUrl); | |
| const uploadUrlData = await coverApi.getUploadUrl( | |
| clubId, | |
| file.name, | |
| file.type, | |
| ); | |
| if (!uploadUrlData) { | |
| throw new Error('커버 업로드 URL 생성에 실패했습니다.'); | |
| } | |
| const { presignedUrl, finalUrl } = uploadUrlData; | |
| await uploadToStorage(presignedUrl, file); | |
| await coverApi.completeUpload(clubId, finalUrl); |
🤖 Prompt for AI Agents
In `@frontend/src/hooks/Queries/useClubCover.ts` around lines 15 - 23,
coverApi.getUploadUrl returns Promise<PresignedData | undefined>, so don’t
destructure its result immediately; call const data = await
coverApi.getUploadUrl(...), check if data is undefined and handle the failure
(throw an error, return early, or log and surface a user-facing error) before
using uploadToStorage or calling coverApi.completeUpload; reference the call to
coverApi.getUploadUrl and the variables presignedUrl/finalUrl (now accessed from
data) and ensure uploadToStorage and coverApi.completeUpload are only invoked
when data is present.
| const { accessToken } = await login(userId, password); | ||
| localStorage.setItem('accessToken', accessToken); |
There was a problem hiding this comment.
login() 함수가 undefined를 반환할 수 있어 런타임 오류 위험이 있습니다.
frontend/src/apis/auth.ts에서 login() 함수는 Promise<LoginResponseData | undefined>를 반환합니다. 현재 코드는 undefined 반환 시 구조 분해 할당에서 TypeError가 발생합니다.
🐛 null 체크 추가 제안
- const { accessToken } = await login(userId, password);
- localStorage.setItem('accessToken', accessToken);
+ const loginData = await login(userId, password);
+ if (!loginData) {
+ throw new Error('로그인 응답이 없습니다.');
+ }
+ localStorage.setItem('accessToken', loginData.accessToken);📝 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.
| const { accessToken } = await login(userId, password); | |
| localStorage.setItem('accessToken', accessToken); | |
| const loginData = await login(userId, password); | |
| if (!loginData) { | |
| throw new Error('로그인 응답이 없습니다.'); | |
| } | |
| localStorage.setItem('accessToken', loginData.accessToken); |
🤖 Prompt for AI Agents
In `@frontend/src/pages/AdminPage/auth/LoginTab/LoginTab.tsx` around lines 35 -
36, The call to login() in LoginTab.tsx can return undefined, so avoid
destructuring directly; instead capture the result (e.g., const result = await
login(userId, password)), check if result is falsy, handle the error path (show
validation/error message and return) and only then read result.accessToken and
call localStorage.setItem('accessToken', accessToken); update any references to
accessToken in the function to use the validated result to prevent the runtime
TypeError when login() returns undefined.
| const DEFAULT_IMAGE_URL = | ||
| 'https://avatars.githubusercontent.com/u/200371900?s=200&v=4'; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "ShareButton.tsx" -type fRepository: Moadong/moadong
Length of output: 133
🏁 Script executed:
# Once file is found, examine the relevant code section
cat -n frontend/src/pages/ClubDetailPage/components/ShareButton/ShareButton.tsx | head -65Repository: Moadong/moadong
Length of output: 2508
🌐 Web query:
Kakao JavaScript SDK Share API isInitialized() guarantee and sendDefault requirements
💡 Result:
Kakao.isInitialized() — what it does (and doesn’t) guarantee
Kakao.isInitialized()only indicates whetherKakao.init(appKey)has been called successfully in the current page context (returns boolean). It’s essentially a “did we initialize the SDK?” flag. [1][2]- It does not guarantee that:
- your JavaScript SDK domain is registered correctly in Kakao Developers,
- the Product Link product is enabled for the app,
- your share template object is valid,
- sharing will succeed at runtime (e.g., due to configuration/permission issues). [3]
Practical pattern:
- Call
Kakao.init('JAVASCRIPT_KEY')once after the SDK script is loaded, and useKakao.isInitialized()to guard against missing/double init. [1][2]
Kakao.Share.sendDefault() — requirements (what must be set up)
To use Kakao.Share.sendDefault() (default-template sharing), Kakao’s docs list these prerequisites/app settings:
- Install the Kakao JavaScript SDK on the page.
- Initialize the SDK with your JavaScript key (
Kakao.init('JAVASCRIPT_KEY')). - Register your site in JavaScript SDK domain.
- Enable Product Link for the app. [3]
Runtime/input requirements:
- You must pass a default-template object matching one of the supported template types (Feed/List/Location/Commerce/Text, etc.). [3]
- Optional: configuring the share target picker with
shareType/limitrequires additional permission. [3]
Sources: [1] https://developers.kakao.com/docs/latest/en/javascript/getting-started, [2] https://developers.kakao.com/sdk/reference/js, [3] https://developers.kakao.com/docs/latest/en/kakaotalk-share/js-link
Kakao Share API 존재 여부까지 방어 필요
isInitialized()는 Kakao.init() 호출 여부만 확인하며, Kakao JavaScript SDK 문서에 따르면 이것이 Share API의 가용성을 보장하지 않습니다. 도메인 등록, Product Link 활성화 등의 설정에 따라 Share API가 없을 수 있으므로, Share 메서드 존재 여부도 함께 확인해주세요.
제안 수정안
const handleShare = () => {
if (
!window.Kakao ||
!window.Kakao.isInitialized() ||
!window.Kakao.Share?.sendDefault
) {
alert('카카오 SDK가 아직 준비되지 않았습니다.');
return;
}🤖 Prompt for AI Agents
In `@frontend/src/pages/ClubDetailPage/components/ShareButton/ShareButton.tsx`
around lines 14 - 15, The current check only uses Kakao.isInitialized(), which
doesn't guarantee the Share API exists; update the ShareButton logic to
additionally verify the Share API is available (e.g., check window.Kakao &&
typeof window.Kakao.Share !== 'undefined' and that the specific method you call
exists like sendDefault or sendCustom) before attempting to call it; modify the
event handler in ShareButton (and any init/ready guards referencing
isInitialized()) to bail out gracefully (disable the button, show an
error/toast, or log) when the Share API/method is missing, and keep
DEFAULT_IMAGE_URL usage unchanged.
| @@ -1,5 +1,5 @@ | |||
| import styled from 'styled-components'; | |||
| import { theme } from '@/styles/theme'; | |||
| import { theme, Theme } from '@/styles/theme'; | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n frontend/src/pages/MainPage/components/Popup/Popup.styles.tsRepository: Moadong/moadong
Length of output: 2425
🏁 Script executed:
# Check if Theme is used anywhere in the file (excluding the import line)
rg -n "Theme" frontend/src/pages/MainPage/components/Popup/Popup.styles.tsRepository: Moadong/moadong
Length of output: 107
🏁 Script executed:
# Check the git diff to understand what changed in this revert PR
cd frontend/src/pages/MainPage/components/Popup && git diff HEAD^ HEAD Popup.styles.ts 2>/dev/null || echo "Git diff not available"Repository: Moadong/moadong
Length of output: 81
Theme 타입 import는 사용되지 않으므로 제거하세요.
파일에서 Theme 타입이 어디에도 사용되지 않습니다. 오직 theme 객체만 라인 59, 66, 67, 82에서 사용되고 있습니다.
-import { theme, Theme } from '@/styles/theme';
+import { theme } from '@/styles/theme';📝 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.
| import { theme, Theme } from '@/styles/theme'; | |
| import { theme } from '@/styles/theme'; |
🤖 Prompt for AI Agents
In `@frontend/src/pages/MainPage/components/Popup/Popup.styles.ts` at line 2,
Remove the unused Theme type import from the top of Popup.styles.ts: only the
theme object is used in this file (referenced as theme on multiple lines), so
delete the named Theme import from the import statement and keep the theme
import only; ensure no other references to Theme remain and run a quick
typecheck to confirm the unused-import warning is gone.
| <td align="center"> | ||
| <img src="https://avatars.githubusercontent.com/u/105052068?v=4" width="120px;"/> | ||
| <br /> | ||
| <a href="https://github.com/seongwon030" title="Code"><b>seongwon030</b></a> | ||
| </td> | ||
| <td> | ||
| <img width="2218" alt="모아동 지원서2" src="https://github.com/user-attachments/assets/bc7006cc-ed82-4a88-822d-d583e8efecb6" /> | ||
| <td align="center"> | ||
| <img src="https://avatars.githubusercontent.com/u/112786665?v=4" width="120px;"/> | ||
| <br /> | ||
| <a href="https://github.com/oesnuj" title="Code"><b>oesnuj</b></a> | ||
| </td> | ||
| <td align="center"> | ||
| <img src="https://avatars.githubusercontent.com/u/163711629?v=4" width="120px;"/> | ||
| <br /> | ||
| <a href="https://github.com/suhyun113" title="Code"><b>suhyun113</b></a> | ||
| </td> | ||
| <td align="center"> | ||
| <img src="" width="120px;"/> | ||
| <br /> | ||
| <a href="https://github.com/newdesigner" title="Code"><b></b></a> | ||
| </td> |
There was a problem hiding this comment.
프론트 기여자 이미지 alt 누락 및 빈 src 처리 필요
<img>에 alt가 없고 src=""/빈 링크 텍스트가 있어 접근성과 렌더링에 문제가 생깁니다. alt 추가 및 빈 항목 보완이 필요합니다.
🛠️ 제안 수정
- <img src="https://avatars.githubusercontent.com/u/105052068?v=4" width="120px;"/>
+ <img src="https://avatars.githubusercontent.com/u/105052068?v=4" alt="seongwon030" width="120px;" />
...
- <img src="https://avatars.githubusercontent.com/u/112786665?v=4" width="120px;"/>
+ <img src="https://avatars.githubusercontent.com/u/112786665?v=4" alt="oesnuj" width="120px;" />
...
- <img src="https://avatars.githubusercontent.com/u/163711629?v=4" width="120px;"/>
+ <img src="https://avatars.githubusercontent.com/u/163711629?v=4" alt="suhyun113" width="120px;" />
...
- <img src="" width="120px;"/>
+ <img src="https://github.com/newdesigner.png?size=120" alt="newdesigner" width="120px;" />
...
- <a href="https://github.com/newdesigner" title="Code"><b></b></a>
+ <a href="https://github.com/newdesigner" title="Code"><b>newdesigner</b></a>🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
30-30: Images should have alternate text (alt text)
(MD045, no-alt-text)
35-35: Images should have alternate text (alt text)
(MD045, no-alt-text)
40-40: Images should have alternate text (alt text)
(MD045, no-alt-text)
45-45: Images should have alternate text (alt text)
(MD045, no-alt-text)
🤖 Prompt for AI Agents
In `@README.md` around lines 29 - 48, The contributor table has an <img> tag with
an empty src and missing alt text and a corresponding <a> whose link text is
empty; update every <img> in that contributor cells block to include meaningful
alt attributes (e.g., alt="Avatar of <username>"), remove or replace src="" with
a valid image URL or omit the entire <td> if no avatar is available, and ensure
each <a> contains non-empty visible text (e.g., the GitHub username) so anchors
are accessible and render properly.
| <td align="center"> | ||
| <img src="https://avatars.githubusercontent.com/u/130421104?v=4" width="120px;"/> | ||
| <br /> | ||
| <a href="https://github.com/PororoAndFriends" title="Code"><b>Pororo</b></a> | ||
| </td> | ||
| <td align="center"> | ||
| <img src="https://avatars.githubusercontent.com/u/49135677?v=4" width="120px;"/> | ||
| <br /> | ||
| <a href="https://github.com/Zepelown" title="Code"><b>Zepelown</b></a> | ||
| </td> | ||
| <td align="center"> | ||
| <img src="https://avatars.githubusercontent.com/u/48638700?v=4" width="120px;"/> | ||
| <br /> | ||
| <a href="https://github.com/FhRh" title="Code"><b>FhRh</b></a> | ||
| </td> | ||
| <td align="center"> | ||
| <img src="https://avatars.githubusercontent.com/u/66681282?v=4" width="120px;"/> | ||
| <br /> | ||
| <a href="https://github.com/lepitaaar" title="Code"><b>lepitaaar</b></a> | ||
| </td> | ||
| <td align="center"> | ||
| <img src="https://avatars.githubusercontent.com/u/143075401?v=4" width="120px;"/> | ||
| <br /> | ||
| <a href="https://github.com/alsdddk" title="Code"><b>alsdddk</b></a> | ||
| </td> |
There was a problem hiding this comment.
백엔드 기여자 이미지 alt 추가 필요
접근성 경고가 발생하므로 각 <img>에 alt를 추가해 주세요.
🛠️ 제안 수정
- <img src="https://avatars.githubusercontent.com/u/130421104?v=4" width="120px;"/>
+ <img src="https://avatars.githubusercontent.com/u/130421104?v=4" alt="Pororo" width="120px;" />
...
- <img src="https://avatars.githubusercontent.com/u/49135677?v=4" width="120px;"/>
+ <img src="https://avatars.githubusercontent.com/u/49135677?v=4" alt="Zepelown" width="120px;" />
...
- <img src="https://avatars.githubusercontent.com/u/48638700?v=4" width="120px;"/>
+ <img src="https://avatars.githubusercontent.com/u/48638700?v=4" alt="FhRh" width="120px;" />
...
- <img src="https://avatars.githubusercontent.com/u/66681282?v=4" width="120px;"/>
+ <img src="https://avatars.githubusercontent.com/u/66681282?v=4" alt="lepitaaar" width="120px;" />
...
- <img src="https://avatars.githubusercontent.com/u/143075401?v=4" width="120px;"/>
+ <img src="https://avatars.githubusercontent.com/u/143075401?v=4" alt="alsdddk" width="120px;" />📝 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.
| <td align="center"> | |
| <img src="https://avatars.githubusercontent.com/u/130421104?v=4" width="120px;"/> | |
| <br /> | |
| <a href="https://github.com/PororoAndFriends" title="Code"><b>Pororo</b></a> | |
| </td> | |
| <td align="center"> | |
| <img src="https://avatars.githubusercontent.com/u/49135677?v=4" width="120px;"/> | |
| <br /> | |
| <a href="https://github.com/Zepelown" title="Code"><b>Zepelown</b></a> | |
| </td> | |
| <td align="center"> | |
| <img src="https://avatars.githubusercontent.com/u/48638700?v=4" width="120px;"/> | |
| <br /> | |
| <a href="https://github.com/FhRh" title="Code"><b>FhRh</b></a> | |
| </td> | |
| <td align="center"> | |
| <img src="https://avatars.githubusercontent.com/u/66681282?v=4" width="120px;"/> | |
| <br /> | |
| <a href="https://github.com/lepitaaar" title="Code"><b>lepitaaar</b></a> | |
| </td> | |
| <td align="center"> | |
| <img src="https://avatars.githubusercontent.com/u/143075401?v=4" width="120px;"/> | |
| <br /> | |
| <a href="https://github.com/alsdddk" title="Code"><b>alsdddk</b></a> | |
| </td> | |
| <td align="center"> | |
| <img src="https://avatars.githubusercontent.com/u/130421104?v=4" alt="Pororo" width="120px;" /> | |
| <br /> | |
| <a href="https://github.com/PororoAndFriends" title="Code"><b>Pororo</b></a> | |
| </td> | |
| <td align="center"> | |
| <img src="https://avatars.githubusercontent.com/u/49135677?v=4" alt="Zepelown" width="120px;" /> | |
| <br /> | |
| <a href="https://github.com/Zepelown" title="Code"><b>Zepelown</b></a> | |
| </td> | |
| <td align="center"> | |
| <img src="https://avatars.githubusercontent.com/u/48638700?v=4" alt="FhRh" width="120px;" /> | |
| <br /> | |
| <a href="https://github.com/FhRh" title="Code"><b>FhRh</b></a> | |
| </td> | |
| <td align="center"> | |
| <img src="https://avatars.githubusercontent.com/u/66681282?v=4" alt="lepitaaar" width="120px;" /> | |
| <br /> | |
| <a href="https://github.com/lepitaaar" title="Code"><b>lepitaaar</b></a> | |
| </td> | |
| <td align="center"> | |
| <img src="https://avatars.githubusercontent.com/u/143075401?v=4" alt="alsdddk" width="120px;" /> | |
| <br /> | |
| <a href="https://github.com/alsdddk" title="Code"><b>alsdddk</b></a> | |
| </td> |
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
69-69: Images should have alternate text (alt text)
(MD045, no-alt-text)
74-74: Images should have alternate text (alt text)
(MD045, no-alt-text)
79-79: Images should have alternate text (alt text)
(MD045, no-alt-text)
84-84: Images should have alternate text (alt text)
(MD045, no-alt-text)
89-89: Images should have alternate text (alt text)
(MD045, no-alt-text)
🤖 Prompt for AI Agents
In `@README.md` around lines 68 - 92, Add descriptive alt attributes to each <img>
element in the contributor grid to resolve accessibility warnings: for each
<img> (the ones paired with links labeled Pororo, Zepelown, FhRh, lepitaaar,
alsdddk) add a concise alt string like "Pororo avatar" / "Zepelown avatar" etc.
Ensure alt text describes the image/purpose (not empty) and matches the
corresponding contributor name so screen readers convey the contributor
identity.
| <img src="https://img.shields.io/badge/react-61DAFB?style=for-the-badge&logo=react&logoColor=white"> <img src="https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white">  | ||
| <img src="https://img.shields.io/badge/styled--components-DB7093?style=for-the-badge&logo=styled-components&logoColor=white"> <img src="https://img.shields.io/badge/Prettier-F7B93E?style=for-the-badge&logo=prettier&logoColor=white"> | ||
| <img src="https://img.shields.io/badge/ESLint-4B32C3?style=for-the-badge&logo=eslint&logoColor=white"> <br/>    <img src="https://img.shields.io/badge/Jest-323330?style=for-the-badge&logo=Jest&logoColor=white"/> <img src="https://img.shields.io/badge/testing%20library-323330?style=for-the-badge&logo=testing-library&logoColor=red"/> | ||
|
|
||
| 지원서 응답을 개별로 확인하며 서류검토/면접대기/합격/불합격 상태로 관리할 수 있어요. | ||
| <br/> | ||
|
|
||
| <img width="1200" alt="지원서 폼 응답 확인" src="https://github.com/user-attachments/assets/9ab91736-c639-47d7-b3e6-190aaafbc202" /> | ||
| ### 백엔드 | ||
|    <img src="https://img.shields.io/badge/Google_Cloud-4285F4?style=for-the-badge&logo=google-cloud&logoColor=white"/> <img src="https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white"/>    |
There was a problem hiding this comment.
Tech Stack 배지 이미지에 alt 추가 필요
여러 <img> 배지에 alt가 없어 접근성 경고가 발생합니다. alt 추가를 권장합니다.
🛠️ 제안 수정
-<img src="https://img.shields.io/badge/react-61DAFB?style=for-the-badge&logo=react&logoColor=white"> <img src="https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white"> 
+<img src="https://img.shields.io/badge/react-61DAFB?style=for-the-badge&logo=react&logoColor=white" alt="React"> <img src="https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript"> 
...
- <img src="https://img.shields.io/badge/styled--components-DB7093?style=for-the-badge&logo=styled-components&logoColor=white"> <img src="https://img.shields.io/badge/Prettier-F7B93E?style=for-the-badge&logo=prettier&logoColor=white">
+ <img src="https://img.shields.io/badge/styled--components-DB7093?style=for-the-badge&logo=styled-components&logoColor=white" alt="styled-components"> <img src="https://img.shields.io/badge/Prettier-F7B93E?style=for-the-badge&logo=prettier&logoColor=white" alt="Prettier">
...
-<img src="https://img.shields.io/badge/ESLint-4B32C3?style=for-the-badge&logo=eslint&logoColor=white"> <br/>    <img src="https://img.shields.io/badge/Jest-323330?style=for-the-badge&logo=Jest&logoColor=white"/> <img src="https://img.shields.io/badge/testing%20library-323330?style=for-the-badge&logo=testing-library&logoColor=red"/>
+<img src="https://img.shields.io/badge/ESLint-4B32C3?style=for-the-badge&logo=eslint&logoColor=white" alt="ESLint"> <br/>    <img src="https://img.shields.io/badge/Jest-323330?style=for-the-badge&logo=Jest&logoColor=white" alt="Jest"/> <img src="https://img.shields.io/badge/testing%20library-323330?style=for-the-badge&logo=testing-library&logoColor=red" alt="Testing Library"/>
...
-   <img src="https://img.shields.io/badge/Google_Cloud-4285F4?style=for-the-badge&logo=google-cloud&logoColor=white"/> <img src="https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white"/>   
+   <img src="https://img.shields.io/badge/Google_Cloud-4285F4?style=for-the-badge&logo=google-cloud&logoColor=white" alt="Google Cloud"/> <img src="https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white" alt="Docker"/>   🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
113-113: Images should have alternate text (alt text)
(MD045, no-alt-text)
113-113: Images should have alternate text (alt text)
(MD045, no-alt-text)
114-114: Images should have alternate text (alt text)
(MD045, no-alt-text)
114-114: Images should have alternate text (alt text)
(MD045, no-alt-text)
115-115: Images should have alternate text (alt text)
(MD045, no-alt-text)
115-115: Images should have alternate text (alt text)
(MD045, no-alt-text)
115-115: Images should have alternate text (alt text)
(MD045, no-alt-text)
120-120: Images should have alternate text (alt text)
(MD045, no-alt-text)
120-120: Images should have alternate text (alt text)
(MD045, no-alt-text)
🤖 Prompt for AI Agents
In `@README.md` around lines 113 - 120, Add descriptive alt attributes to every
raw HTML <img src="..."> badge in README.md (for example the <img> tags for
React, TypeScript, styled--components, Prettier, Google_Cloud, docker, etc.) so
they provide concise accessible text (e.g., "React logo", "TypeScript logo",
"Google Cloud logo"); alternatively replace the raw <img> with markdown image
syntax  that already includes alt text—ensure all <img src="...">
occurrences are updated to include meaningful alt attributes.
Reverts #1106
Summary by CodeRabbit
릴리스 노트
새로운 기능
개선사항
✏️ Tip: You can customize this high-level summary in your review settings.