Skip to content

Comments

Revert " [release] FE v1.1.19"#1112

Merged
seongwon030 merged 1 commit intomainfrom
revert-1106-develop-fe
Jan 25, 2026
Merged

Revert " [release] FE v1.1.19"#1112
seongwon030 merged 1 commit intomainfrom
revert-1106-develop-fe

Conversation

@oesnuj
Copy link
Member

@oesnuj oesnuj commented Jan 25, 2026

Reverts #1106

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 클럽 프로필 카드에 뒤로 가기 버튼 추가
    • 카카오톡 공유 기능 통합
  • 개선사항

    • 클럽 상세 페이지 네비게이션 구조 개선
    • 모바일/태블릿 환경 사용성 최적화
    • 헤더 컴포넌트 단순화로 일관된 인터페이스 제공
    • 스크롤 기반 상호작용 제거로 직관적인 사용 환경 구현

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Jan 25, 2026

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

Project Deployment Review Updated (UTC)
moadong Ready Ready Preview, Comment Jan 25, 2026 11:41am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 25, 2026

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: Invalid regex pattern for base branch. Received: "**" at "reviews.auto_review.base_branches[0]"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

리뷰 요약

Walkthrough

프론트엔드 빌드 설정 단순화, 반응형 장치 감지 로직 제거, 웹뷰 브릿지 기능 삭제, 스크롤 훅을 네이티브 API로 대체, 클럽 상세 페이지 상단바 컴포넌트 제거, 그리고 Kakao SDK 기반 공유 기능 도입이 포함된 대규모 프론트엔드 리팩토링입니다.

Changes

타입 파일 변경 내용
빌드 설정 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 HeadershowOn={['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 OptionButtoncolor: 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

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 ⚠️ Warning 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@seongwon030 seongwon030 merged commit fefc3ff into main Jan 25, 2026
2 of 3 checks passed
Copy link
Contributor

@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: 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: feedResArr undefined/길이 불일치 시 런타임 오류 위험

feedApi.getUploadUrlsundefined를 반환하거나 길이가 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.getUploadUrlPromise<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
![React](url) 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에서 handlersRequestHandler[]로 명확히 선언하면 이곳에서 캐스팅을 완전히 제거할 수 있습니다.

♻️ 제안 수정 (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는 기본 파일명이라 캐시 갱신이 어려울 수 있습니다. MiniCssExtractPluginfilename/chunkFilename을 지정하는 편이 안전합니다.

♻️ 제안 수정
-  plugins: [new MiniCssExtractPlugin()],
+  plugins: [
+    new MiniCssExtractPlugin({
+      filename: '[name].[contenthash].css',
+      chunkFilename: '[id].[contenthash].css',
+    }),
+  ],

Comment on lines +19 to +35
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}
--------------------------------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 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 f

Repository: Moadong/moadong

Length of output: 91


🏁 Script executed:

# Search for stats configuration in webpack config files
rg "stats\s*:" frontend/ -A 5 -B 2

Repository: 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.ts

Repository: 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.ts

Repository: 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.

Comment on lines 27 to 32
"@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",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 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 -100

Repository: 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 -20

Repository: 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 -100

Repository: 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 json

Repository: 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 -20

Repository: 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 -10

Repository: 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 -10

Repository: 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 -30

Repository: 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 -100

Repository: 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 -20

Repository: 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 -100

Repository: 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-plugindotenv-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.

Suggested change
"@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.

Comment on lines +15 to 23
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);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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.

Comment on lines +35 to +36
const { accessToken } = await login(userId, password);
localStorage.setItem('accessToken', accessToken);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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.

Comment on lines +14 to +15
const DEFAULT_IMAGE_URL =
'https://avatars.githubusercontent.com/u/200371900?s=200&v=4';
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -name "ShareButton.tsx" -type f

Repository: 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 -65

Repository: 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 whether Kakao.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 use Kakao.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 / limit requires 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';
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n frontend/src/pages/MainPage/components/Popup/Popup.styles.ts

Repository: 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.ts

Repository: 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.

Suggested change
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.

Comment on lines +29 to +48
<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>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

프론트 기여자 이미지 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.

Comment on lines +68 to +92
<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>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

백엔드 기여자 이미지 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.

Suggested change
<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.

Comment on lines +113 to +120
<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"> ![React Query](https://img.shields.io/badge/-React%20Query-FF4154?style=for-the-badge&logo=react%20query&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/> ![Esbuild](https://img.shields.io/badge/esbuild-%23FFCF00.svg?style=for-the-badge&logo=esbuild&logoColor=black) ![Webpack](https://img.shields.io/badge/webpack-%238DD6F9.svg?style=for-the-badge&logo=webpack&logoColor=black) ![NPM](https://img.shields.io/badge/NPM-%23CB3837.svg?style=for-the-badge&logo=npm&logoColor=white) <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" />
### 백엔드
![Java](https://img.shields.io/badge/java-%23ED8B00.svg?style=for-the-badge&logo=openjdk&logoColor=white) ![Spring](https://img.shields.io/badge/spring-%236DB33F.svg?style=for-the-badge&logo=spring&logoColor=white) ![MongoDB](https://img.shields.io/badge/MongoDB-%234ea94b.svg?style=for-the-badge&logo=mongodb&logoColor=white) <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"/> ![Nginx](https://img.shields.io/badge/nginx-%23009639.svg?style=for-the-badge&logo=nginx&logoColor=white) ![GitHub Actions](https://img.shields.io/badge/github%20actions-%232671E5.svg?style=for-the-badge&logo=githubactions&logoColor=white) ![Cloudflare](https://img.shields.io/badge/Cloudflare-F38020?style=for-the-badge&logo=Cloudflare&logoColor=white)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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"> ![React Query](https://img.shields.io/badge/-React%20Query-FF4154?style=for-the-badge&logo=react%20query&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"> ![React Query](https://img.shields.io/badge/-React%20Query-FF4154?style=for-the-badge&logo=react%20query&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/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/> ![Esbuild](https://img.shields.io/badge/esbuild-%23FFCF00.svg?style=for-the-badge&logo=esbuild&logoColor=black) ![Webpack](https://img.shields.io/badge/webpack-%238DD6F9.svg?style=for-the-badge&logo=webpack&logoColor=black) ![NPM](https://img.shields.io/badge/NPM-%23CB3837.svg?style=for-the-badge&logo=npm&logoColor=white) <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/> ![Esbuild](https://img.shields.io/badge/esbuild-%23FFCF00.svg?style=for-the-badge&logo=esbuild&logoColor=black) ![Webpack](https://img.shields.io/badge/webpack-%238DD6F9.svg?style=for-the-badge&logo=webpack&logoColor=black) ![NPM](https://img.shields.io/badge/NPM-%23CB3837.svg?style=for-the-badge&logo=npm&logoColor=white) <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"/> 
 ...
-![Java](https://img.shields.io/badge/java-%23ED8B00.svg?style=for-the-badge&logo=openjdk&logoColor=white) ![Spring](https://img.shields.io/badge/spring-%236DB33F.svg?style=for-the-badge&logo=spring&logoColor=white) ![MongoDB](https://img.shields.io/badge/MongoDB-%234ea94b.svg?style=for-the-badge&logo=mongodb&logoColor=white) <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"/> ![Nginx](https://img.shields.io/badge/nginx-%23009639.svg?style=for-the-badge&logo=nginx&logoColor=white) ![GitHub Actions](https://img.shields.io/badge/github%20actions-%232671E5.svg?style=for-the-badge&logo=githubactions&logoColor=white) ![Cloudflare](https://img.shields.io/badge/Cloudflare-F38020?style=for-the-badge&logo=Cloudflare&logoColor=white)
+![Java](https://img.shields.io/badge/java-%23ED8B00.svg?style=for-the-badge&logo=openjdk&logoColor=white) ![Spring](https://img.shields.io/badge/spring-%236DB33F.svg?style=for-the-badge&logo=spring&logoColor=white) ![MongoDB](https://img.shields.io/badge/MongoDB-%234ea94b.svg?style=for-the-badge&logo=mongodb&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"/> ![Nginx](https://img.shields.io/badge/nginx-%23009639.svg?style=for-the-badge&logo=nginx&logoColor=white) ![GitHub Actions](https://img.shields.io/badge/github%20actions-%232671E5.svg?style=for-the-badge&logo=githubactions&logoColor=white) ![Cloudflare](https://img.shields.io/badge/Cloudflare-F38020?style=for-the-badge&logo=Cloudflare&logoColor=white)
🧰 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 ![React](url) that already includes alt text—ensure all <img src="...">
occurrences are updated to include meaningful alt attributes.

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.

2 participants