[Setting/#131] ESLint 추가 규칙 및 코드 스타일 정리#138
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (14)
📝 WalkthroughWalkthrough이 PR은 ESLint와 자동 포매팅 규칙을 기반으로 100개 이상의 파일에 걸쳐 import 순서 정렬, 다중 라인 코드를 단일 라인으로 압축하는 등의 포맷팅을 일관되게 적용한 변경사항입니다. 기능적 로직은 변경되지 않았습니다. Changes
🎯 Review Effort🎯 2 (Simple) | ⏱️ ~20 minutes
Possibly Related PRs
Suggested Reviewers
🔍 추가 코멘트이 PR은 코드 일관성 개선을 목표로 한 대규모 포매팅 작업입니다. 몇 가지 확인 사항이 있습니다: ✅ 긍정적 요소
📝 체크포인트대규모 파일 변경이므로 머지 전 다음을 확인하면 좋겠습니다:
이 작업 덕분에 앞으로 코드 리뷰와 유지보수가 훨씬 수월해질 것 같습니다! 🚀 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Review rate limit: 0/1 reviews remaining, refill in 15 minutes and 31 seconds.Comment |
There was a problem hiding this comment.
Actionable comments posted: 14
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (7)
src/pages/myPage/subscriptionPage.tsx (1)
140-205:⚠️ Potential issue | 🟡 Minor플랜 목록 empty 상태 UX를 하나 추가해두면 좋아요
plans가 비는 경우 현재는 영역이 통째로 비어 보여서 사용자 입장에서 상태 파악이 어렵습니다. 페이지 컴포넌트라 empty fallback 한 줄만 있어도 UX가 훨씬 좋아집니다.예시 코드
- <div className="grid grid-cols-1 md:grid-cols-2 gap-6"> - {plans.map((plan) => { + {plans.length === 0 ? ( + <div className="rounded-xl border border-gray-100 bg-white p-6 text-sm text-gray-500"> + 현재 선택 가능한 구독 플랜이 없습니다. + </div> + ) : ( + <div className="grid grid-cols-1 md:grid-cols-2 gap-6"> + {plans.map((plan) => { const isCurrent = selectedPlan === plan.name; const isRecommended = plan.name === "프리미엄"; return ( ... ); - })} - </div> + })} + </div> + )}As per coding guidelines
src/pages/**: 라우팅/레이아웃 영향, 로딩/에러/empty 상태 UX 확인.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/myPage/subscriptionPage.tsx` around lines 140 - 205, Add an explicit empty-state fallback when the plans list is empty so the UI doesn't render a blank area: in the component that maps over plans (the block using plans.map and referencing selectedPlan, billingCycle, handlePlanChange), check if plans.length === 0 and render a concise placeholder (e.g., a centered message and optional CTA) instead of the grid; ensure the fallback matches existing styling and accessibility patterns and disables plan-interaction UI when shown.src/pages/myPage/settingPage.tsx (1)
40-46:⚠️ Potential issue | 🟠 Major스위치에 접근 가능한 이름이 필요해요.
현재
role="switch"는 있지만 이름이 없어 보조기기에서 “무슨 스위치인지” 읽히지 않습니다.aria-label(또는aria-labelledby)을Switch에 전달해 주세요.예시 수정 코드
-function Switch({ enabled, onClick }: { enabled: boolean; onClick: () => void }) { +function Switch({ + enabled, + onClick, + ariaLabel, +}: { + enabled: boolean; + onClick: () => void; + ariaLabel: string; +}) { return ( <button type="button" role="switch" aria-checked={enabled} + aria-label={ariaLabel} onClick={onClick}-<Switch enabled={enabled} onClick={onClick} /> +<Switch enabled={enabled} onClick={onClick} ariaLabel={label} />-<Switch enabled={notifications.email} onClick={() => toggleNotification("email")} /> +<Switch + enabled={notifications.email} + onClick={() => toggleNotification("email")} + ariaLabel="이메일 알림 수신" +/> ... -<Switch enabled={notifications.sms} onClick={() => toggleNotification("sms")} /> +<Switch + enabled={notifications.sms} + onClick={() => toggleNotification("sms")} + ariaLabel="SMS 알림 수신" +/>Also applies to: 160-162
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/myPage/settingPage.tsx` around lines 40 - 46, The Switch component lacks an accessible name; update the Switch signature to accept an ariaLabel (or labelledBy) prop (e.g., add parameter ariaLabel?: string) and pass it through to the rendered button as aria-label (or aria-labelledby) so assistive tech can announce which switch it is; then update all call sites (including the other Switch usage around the 160-162 area) to provide a suitable aria-label or aria-labelledby string/ID.src/components/main/StateSection.tsx (1)
21-25:⚠️ Potential issue | 🟠 Major접근성 개선 제안: 애니메이션 모션 제어 필요
현재 애니메이션이
prefers-reduced-motion설정을 고려하지 않아 전정기관 장애가 있는 사용자에게 불편하거나 위험할 수 있습니다. Tailwind의motion-reduce:유틸리티를 활용해 개선할 수 있습니다.As per coding guidelines: "컴포넌트는 단일 책임, props 타입/네이밍 명확히, 접근성(aria) 체크."
♿ 접근성 개선 예시
<div className={cn( "flex flex-col items-center space-y-10 tracking-tight mb-20", - "transition-all duration-900 ease-out", + "motion-reduce:transition-none transition-all duration-900 ease-out", inView ? "opacity-100 translate-y-0" : "opacity-0 translate-y-20", )} >라인 34-38의 stats 아이템들도 동일하게 적용:
<div key={s.label} className={cn( "text-center", - "transition-all duration-900 ease-out", + "motion-reduce:transition-none transition-all duration-900 ease-out", inView ? "opacity-100 translate-y-0" : "opacity-0 translate-y-20", )}이렇게 하면 사용자가 시스템 설정에서 "모션 줄이기"를 활성화했을 때 애니메이션이 비활성화됩니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/main/StateSection.tsx` around lines 21 - 25, The animated container's className (the JSX using cn(...) with inView) doesn't honor users' prefers-reduced-motion; update the className expression for the StateSection container and for the stats item elements to include Tailwind motion-reduce utilities (e.g. motion-reduce:transition-none and motion-reduce:transform-none or motion-reduce:opacity-100/motion-reduce:translate-y-0) so that when prefers-reduced-motion is enabled the component skips transitions/transform effects; apply the same change to the stats items' className(s) that use inView-driven opacity/translate classes to ensure all motion is suppressed for assistive users.src/components/store-registration/StepBusinessAuth.tsx (2)
213-223:⚠️ Potential issue | 🟠 Major개업일자 변경 분기에서도
businessNumber/startDate전달이 서로 바뀌어 있습니다.이 상태면 인증 완료 후 개업일자 수정 시 사업자번호가 오염됩니다.
수정 예시
{...register("startDate", { onChange: (e) => { if (isVerified) { - const { name, startDate } = getValues(); + const { name, businessNumber } = getValues(); setIsVerified(false); onComplete({ name, - businessNumber: e.target.value, - startDate, + businessNumber, + startDate: e.target.value, isVerified: false, }); } }, })}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/store-registration/StepBusinessAuth.tsx` around lines 213 - 223, 현재 register("startDate")의 onChange 블록이 getValues()에서 { name, startDate }를 받아와 e.target.value를 businessNumber로 넘기고 있어 businessNumber와 startDate가 뒤바뀌고 있습니다; onChange 핸들러(등록된 register("startDate") 블록)에서 const { name, businessNumber } = getValues()로 올바른 값을 읽고 setIsVerified(false) 후 onComplete에 businessNumber: businessNumber (또는 getValues().businessNumber)와 startDate: e.target.value를 넘기도록 수정하세요 (참조: isVerified, getValues, setIsVerified, onComplete, register("startDate")).
168-184:⚠️ Potential issue | 🟠 Major사업자등록번호 변경 시
onComplete필드 매핑이 뒤바뀌어 있어요.현재 분기에서
e.target.value를startDate로 전달하고 있어, 인증 후 값 수정 시 부모 상태가 잘못 저장됩니다.수정 예시
{...register("businessNumber", { onChange: (e) => { if (isVerified) { - const { name, businessNumber } = getValues(); + const { name, startDate } = getValues(); setIsVerified(false); onComplete({ name, - businessNumber, - startDate: e.target.value, + businessNumber: e.target.value, + startDate, isVerified: false, }); } }, })}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/store-registration/StepBusinessAuth.tsx` around lines 168 - 184, The onChange handler for the businessNumber input is passing e.target.value into startDate, causing parent state to get wrong fields when a verified business number is edited; update the handler in the register call for "businessNumber" (the onChange inside register), so it reads const { name, startDate } = getValues(); then setIsVerified(false); and call onComplete({ name, businessNumber: e.target.value, startDate, isVerified: false }) — i.e., map e.target.value to businessNumber and preserve startDate.src/components/owner/tableDashboard.tsx (1)
244-257:⚠️ Potential issue | 🔴 Critical
fetchLayout이펙트가tableData의존성 때문에 반복 호출 루프를 만들 수 있어요.이펙트 내부에서
setTableData(...)를 수행하면서 의존성에tableData가 포함되어 있어, 레이아웃 재조회가 연쇄적으로 반복될 수 있습니다.수정 예시
- setTableData(mapTablesFromApi(layout.tables, layout.gridInfo.gridCol, tableData)); + setTableData((prev) => + mapTablesFromApi(layout.tables, layout.gridInfo.gridCol, prev), + ); setCreateModalOpen(false); @@ - }, [storeId, tableData]); + }, [storeId]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/owner/tableDashboard.tsx` around lines 244 - 257, The useEffect that defines and calls fetchLayout is currently depending on tableData which causes a re-render loop because fetchLayout calls setTableData; remove tableData from the dependency array and instead depend only on storeId (or other true external deps), or if you must react to tableData changes, use a ref or a separate effect; specifically update the useEffect containing fetchLayout (the function named fetchLayout and the calls to setTableData and setCreateModalOpen) to not include tableData in its dependency array to prevent repeated fetches.src/api/bookings.ts (1)
43-48:⚠️ Potential issue | 🟠 Major
cancelBooking응답 타입이 열려 있어 타입 안정성이 깨질 수 있습니다현재
response.data가 사실상any로 흐를 수 있어 호출부에서 런타임 오류를 숨길 가능성이 있습니다. 반환 타입과 axios 제네릭을 명시해 주세요.예시 수정안
+ interface CancelBookingResponse { + result: { + bookingId: number; + status: "CANCELED"; + }; + } -export const cancelBooking = async (bookingId: number, reason: string = "사용자 취소") => { - const response = await api.patch(`/api/v1/bookings/${bookingId}/cancel`, { +export const cancelBooking = async ( + bookingId: number, + reason: string = "사용자 취소", +): Promise<CancelBookingResponse> => { + const response = await api.patch<CancelBookingResponse>(`/api/v1/bookings/${bookingId}/cancel`, { reason, }); return response.data; };As per coding guidelines,
src/api/**: 에러 처리/타임아웃/리트라이 전략 확인, 응답 타입 안전성 유지.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/api/bookings.ts` around lines 43 - 48, The cancelBooking function returns an untyped response which breaks type safety; define a specific response interface (e.g., CancelBookingResponse) that models the API payload, annotate api.patch with the axios generic (api.patch<CancelBookingResponse>(...)) and set the cancelBooking signature to return Promise<CancelBookingResponse>; while here you update types, also ensure the request uses existing shared axios options (timeout/retry/interceptor) rather than raw calls so error/timeout/retry behavior is preserved.
🧹 Nitpick comments (10)
src/pages/myPage/subscriptionPage.tsx (1)
181-181: 리스트 key는 문자열 단독보다 복합 key가 더 안전해요
key={feature}는 문구 중복 시 충돌 가능성이 있습니다.plan.name+ index 등으로 조합하면 안정적입니다.예시 코드
- {plan.features.map((feature) => ( - <li key={feature} className="flex items-center gap-3 text-sm text-gray-600"> + {plan.features.map((feature, idx) => ( + <li key={`${plan.name}-${idx}`} className="flex items-center gap-3 text-sm text-gray-600"> <Check size={18} className="text-blue-500" /> {feature} </li> ))}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/myPage/subscriptionPage.tsx` at line 181, The list item key currently uses only feature (key={feature}), which can collide for duplicate feature strings; update the map creating the <li> in subscriptionPage.tsx to use a composite key that includes the plan identity and the item index (e.g., combine plan.name and the map index and feature) so each key is unique across plans and repeated feature labels; locate the map that renders the feature variable inside the component and replace key={feature} with a concatenation like `${plan.name}-${index}-${feature}` (or equivalent) to ensure stable, unique keys.src/components/customer-support/SupportFAQ.tsx (2)
96-116: FAQ 토글 버튼에 aria-expanded 속성 추가를 권장합니다.FAQ 아코디언 버튼에
aria-expanded속성을 추가하면, 스크린 리더 사용자가 현재 항목의 펼쳐짐/접힘 상태를 명확히 인지할 수 있습니다.♻️ 접근성 개선 제안
<button onClick={() => toggleFaq(faq.id)} + aria-expanded={openFaqId === faq.id} className="w-full p-4 md:px-6 md:py-5 flex items-center justify-between text-left hover:bg-gray-100 transition-colors cursor-pointer" >As per coding guidelines:
src/components/**: 컴포넌트는 접근성(aria) 체크.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/customer-support/SupportFAQ.tsx` around lines 96 - 116, The FAQ toggle button lacks an aria-expanded attribute which impairs screen-reader feedback; update the button in SupportFAQ (the element using onClick={() => toggleFaq(faq.id)} and checking openFaqId === faq.id) to set aria-expanded={openFaqId === faq.id} so the button reflects expanded/collapsed state for assistive tech, and ensure the value updates alongside the existing toggleFaq logic (no other changes to toggleFaq necessary).
46-52: 검색 입력창에 접근성 레이블 추가를 권장합니다.검색 입력창에 시각적 placeholder는 있지만, 스크린 리더 사용자를 위한 명시적 레이블이 없습니다. 접근성 개선을 위해
aria-label을 추가하면 좋겠습니다.♻️ 접근성 개선 제안
<input type="text" placeholder="궁금한 내용을 검색해보세요" + aria-label="FAQ 검색" value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} className="w-full pl-12 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none" />As per coding guidelines:
src/components/**: 컴포넌트는 접근성(aria) 체크.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/customer-support/SupportFAQ.tsx` around lines 46 - 52, The search input in SupportFAQ (the <input> that uses value={searchTerm} and onChange={(e) => setSearchTerm(e.target.value)}) lacks an explicit accessibility label; add an aria-label (for example "검색어 입력" or "Search FAQs") to that input element so screen readers can identify its purpose, ensuring it remains in sync with the existing placeholder and state handling.src/pages/myPage/settingPage.tsx (1)
80-81: 초기 알림 상태의 타입 안전성 검증을 추가하면 더 안정적입니다.
localStorage값이 깨졌거나 구버전 포맷이면 boolean이 아닌 값이 상태로 들어올 수 있습니다. 초기화 시점에 스키마/가드로 한 번 검증해 두는 게 안전합니다.예시 수정 코드
+const isNotificationSettings = (value: unknown): value is NotificationSettings => { + if (!value || typeof value !== "object") return false; + const v = value as Record<string, unknown>; + return ["reservation", "promotion", "review", "email", "sms"].every( + (k) => typeof v[k] === "boolean", + ); +}; const getInitialNotifications = () => { if (typeof window === "undefined") return defaultNotifications; try { const raw = localStorage.getItem(STORAGE_KEY); if (!raw) return defaultNotifications; const parsed = JSON.parse(raw); - return { ...defaultNotifications, ...parsed }; + if (!isNotificationSettings(parsed)) return defaultNotifications; + return { ...defaultNotifications, ...parsed }; } catch (e) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/myPage/settingPage.tsx` around lines 80 - 81, The initial notification state may contain malformed values from localStorage; add a runtime validator (e.g. isValidNotificationSettings) that checks the NotificationSettings shape and boolean types, use it inside getInitialNotifications (or immediately after parsing) to return either the parsed value or a safe defaultNotifications object, and initialize both notifications and savedNotifications with the validated result (replace direct use of getInitialNotifications return for setSavedNotifications as well) so only type-safe NotificationSettings enter state.src/pages/LoginErrorPage.tsx (1)
5-38: 접근성 개선 제안 (선택사항)현재 에러 페이지는 시각적으로 에러 상태를 잘 표현하고 있지만, 스크린 리더 사용자를 위한 추가 개선이 가능합니다. 에러 발생 시 보조 기술이 자동으로 안내할 수 있도록 ARIA live region을 추가하면 UX가 더 향상될 것 같아요.
♿ 접근성 개선 예시
const LoginErrorPage: React.FC = () => { const navigate = useNavigate(); return ( <div className="min-h-screen bg-gray-50 flex items-center justify-center px-6"> - <div className="max-w-md w-full text-center"> + <div className="max-w-md w-full text-center" role="alert" aria-live="assertive"> <div className="relative mb-8"> <div className="absolute inset-0 flex items-center justify-center animate-pulse"> <div className="w-32 h-32 bg-red-100 rounded-full"></div> </div> <div className="relative flex justify-center"> - <AlertCircle size={60} className="text-red-600" /> + <AlertCircle size={60} className="text-red-600" aria-hidden="true" /> </div> </div> - <h1 className="text-5xl font-bold text-red-600 mb-4">Error</h1> + <h1 className="text-5xl font-bold text-red-600 mb-4" id="error-title">Error</h1> <h2 className="text-2xl font-semibold text-gray-900 mb-3">로그인에 실패했습니다</h2>
role="alert"와aria-live="assertive"를 추가하면 스크린 리더가 에러 발생을 즉시 알려줍니다.As per coding guidelines: src/pages/** 경로의 파일은 에러 상태 UX 확인이 필요하며, 접근성 개선은 사용자 경험 향상에 도움이 됩니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/LoginErrorPage.tsx` around lines 5 - 38, The LoginErrorPage component lacks an ARIA live region to announce the error to screen readers; update the component (e.g., the outer container inside LoginErrorPage or the error message element rendered by the JSX) to include an accessible live region such as adding role="alert" and aria-live="assertive" (or create a dedicated visually-present but screen-reader-first live region) so that assistive technologies immediately announce the error state; ensure the attributes are applied to the element that contains the error heading/description (the h1/h2 or the wrapping div in LoginErrorPage) and keep visual layout unchanged.src/components/map/KakaoMap.tsx (1)
185-185: CSS 문자열 포맷팅을 일관되게 맞춰주면 좋을 것 같아요.현재 CSS 속성 간 공백이 일관되지 않아서 가독성이 조금 떨어져요:
padding뒤에는 공백이 있는데font-size,line-height뒤에는 공백이 없음- 속성 사이 세미콜론 뒤 공백도 누락
기능상 문제는 없지만, 통일하면 더 깔끔할 것 같습니다!
✨ 포맷팅 개선 제안
- el.style.cssText = "padding: 6px 8px; font-size:12px;line-height:1.2;"; + el.style.cssText = "padding: 6px 8px; font-size: 12px; line-height: 1.2;";🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/map/KakaoMap.tsx` at line 185, The CSS string assigned to el.style.cssText is inconsistently spaced; update the assignment in the KakaoMap component so property names and values use consistent spacing and include a space after each semicolon (e.g., "padding: 6px 8px; font-size: 12px; line-height: 1.2;") to improve readability—locate the el.style.cssText assignment and normalize spacing around colons and semicolons accordingly.src/api/dto/store.dto.ts (1)
3-10: 선택적 제안: DayDTO도 단일 라인 고려해볼까요?CategoryDTO는 단일 라인으로 압축했는데, DayDTO는 여전히 멀티라인이네요. 일관성 측면에서 DayDTO도 다음처럼 단일 라인으로 정리하면 더 깔끔할 수 있어요:
선택적 제안
-export type DayDTO = - | "MONDAY" - | "TUESDAY" - | "WEDNESDAY" - | "THURSDAY" - | "FRIDAY" - | "SATURDAY" - | "SUNDAY"; +export type DayDTO = "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY";다만 가독성 차이는 선호도 문제라서 현재 상태도 괜찮습니다!
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/api/dto/store.dto.ts` around lines 3 - 10, The DayDTO union is formatted across multiple lines while CategoryDTO is a single-line union; to make formatting consistent, collapse DayDTO into a single-line union (replace the multiline union declaration for DayDTO with a compact single-line form) ensuring the exported type name DayDTO and its string members ("MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY") remain unchanged and keep the export modifier intact.src/hooks/queries/useAuth.ts (1)
44-44:alert대신 비차단형 알림(토스트)으로 바꾸는 걸 권장합니다.Line 44의
alert는 UI를 멈추게 해서 사용자 흐름이 끊길 수 있어요. 같은 메시지는 토스트/스낵바로 처리하면 UX가 더 안정적입니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/hooks/queries/useAuth.ts` at line 44, Replace the blocking browser alert used in useAuth.ts (the alert("사업자 인증이 완료되었습니다. \n사장님 권한 적용을 위해 반드시 재로그인해주세요."); call) with a non-blocking toast/snackbar: import and use your app's notification utility (eg. showToast, enqueueSnackbar, or NotificationService) inside the same function so the same message is shown asynchronously; ensure the toast variant/severity (info/success) and any required options (autoHideDuration, multi-line support) are set and remove the alert call.src/pages/myPage/storePage.tsx (1)
99-100: 로딩 상태 문구에aria-live를 추가해 접근성을 보완해주세요.Line 99의 로딩 메시지는 시각적으로는 충분하지만, 스크린리더 사용자에게 상태 변경이 자동 전달되지 않을 수 있어요.
aria-live="polite"를 붙이면 로딩/에러/empty UX 완성도가 더 좋아집니다.예시 코드
- <div className="py-14 text-center text-gray-400">가게 정보를 불러오는 중입니다...</div> + <div className="py-14 text-center text-gray-400" aria-live="polite"> + 가게 정보를 불러오는 중입니다... + </div>As per coding guidelines,
src/pages/**: 라우팅/레이아웃 영향, 로딩/에러/empty 상태 UX 확인.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/myPage/storePage.tsx` around lines 99 - 100, The loading message div (the element with className "py-14 text-center text-gray-400") should include accessibility attributes so screen readers announce state changes; add aria-live="polite" to that div (and optionally role="status") so the loading/empty/error text is announced automatically to assistive technologies.src/api/bookings.ts (1)
39-40: 중복 타입 캐스팅은 제거해도 됩니다
api.get<{ result: BookingResponse }>로 이미 타입이 보장돼서as BookingResponse는 불필요합니다. 제거하면 타입 신뢰성이 더 명확해져요.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/api/bookings.ts` around lines 39 - 40, The code redundantly casts the result despite api.get already typing the shape; remove the unnecessary "as BookingResponse" and return response.data.result directly. Locate the call to api.get<{ result: BookingResponse }>(), the response variable (response.data.result) and the BookingResponse type, then change the function to return response.data.result without the type assertion so the declared generic is the single source of type truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/api/endpoints/member.ts`:
- Around line 58-59: The change password call currently returns res.data.result
without verifying the API success flag; update the handler that calls
api.put<ApiEnvelope<ChangePasswordResponse>> (the ChangePassword endpoint in
src/api/endpoints/member.ts) to follow the same success-validation pattern used
by other endpoints: verify res.data.success (or the project’s ApiEnvelope
success indicator) and throw a descriptive error (or return a typed failure)
when it’s false, otherwise return res.data.result; ensure you also null-check
res.data and preserve ApiEnvelope/ChangePasswordResponse typings for type
safety.
In `@src/api/endpoints/payments.ts`:
- Around line 47-48: The confirmPayment call currently returns res.data.result
without checking the ApiEnvelope success/failure, so update the confirmPayment
implementation (the api.post call that returns
ApiEnvelope<PaymentConfirmResult>) to validate the envelope: check the
envelope's status/success flag and presence of result, and if the envelope
indicates failure or result is missing throw a descriptive error (including the
server message from the envelope) or return a rejected Promise; ensure any
thrown error includes the envelope.message and relevant metadata so callers can
handle failures safely.
In `@src/components/auth/SignupDialog.tsx`:
- Around line 130-131: The error message <p> elements in SignupDialog.tsx (e.g.,
the block rendering {errors.name && <p ...>{errors.name.message}</p>}) lack
accessibility attributes; update each field's input and its corresponding error
node so the input has an id and aria-describedby pointing to the error element,
and the error <p> uses role="alert" and/or aria-live="assertive" (or "polite" as
appropriate) with a unique id (e.g., nameError) so screen readers announce
validation messages; apply the same modification pattern to the other error
render sites mentioned (lines around the other {errors.*} usages) to ensure
consistent ARIA linking and live region announcements.
In `@src/components/customer-support/support.schema.ts`:
- Line 20: Update the Zod error message usage in the support schema to avoid the
deprecated `{ message: "..." }` pattern: replace occurrences on the `title` and
`content` fields (and any other z.string().min/max calls using `{ message: ...
}`) with the modern form—pass the error message string directly (e.g.,
z.string().min(1, "...").max(100, "...")) or use `{ error: "..." }` if you need
an object—so all validations in the schema (the `title` and `content` keys in
the exported schema object) use a consistent, non-deprecated error format.
In `@src/components/customer-support/SupportModal.tsx`:
- Around line 119-120: The form error messages in SupportModal lack ARIA linking
and live-region semantics; update the error <p> elements (e.g., the one rendered
for errors.name) to include role="alert" or aria-live="assertive" and give each
error a unique id (e.g., `${fieldName}-error`) and then ensure the corresponding
input element (in SupportModal) has aria-describedby pointing to that id so
screen readers detect changes; apply the same pattern for the other error
renders referenced (around lines handling errors at 135-136, 151-153, 169-170,
185-186) and keep error ids unique per field.
In `@src/components/owner/menuFormModal.tsx`:
- Around line 4-5: Combine the duplicate imports from the same module: replace
the two separate imports in menuFormModal.tsx that pull createMenus,
MenuUpdateItem, updateMenu, uploadMenuImage and deleteMenuImage from
"@/api/owner/menus" with a single consolidated import statement that imports all
those symbols together (createMenus, type MenuUpdateItem, updateMenu,
uploadMenuImage, deleteMenuImage).
In `@src/components/owner/MenuManagement.tsx`:
- Around line 51-53: The temporary ID generation in mapServerToLocal (returning
id: String(s.menuId ?? `MENU_${Date.now()}`)) can collide when multiple items
are created in the same millisecond; replace the Date.now()-only fallback with a
collision-resistant generator (e.g., use crypto.randomUUID() or a UUIDv4
library) so the id for MenuItem is unique (e.g., id: s.menuId ? String(s.menuId)
: `MENU_${<uuid>}`), ensuring mapServerToLocal and any consumers of MenuItem get
a stable, unique identifier.
In `@src/components/owner/StoreSettings.tsx`:
- Line 399: The alert message in StoreSettings.tsx currently lists "가게 이름, 설명,
전화번호, 이메일, 주소" as required but the validation only checks for 가게 이름, 설명, 전화번호;
update the message to match the actual validation or expand the validation to
include 이메일 and 주소. Locate the validation/submit handler in the StoreSettings
component (the function that triggers alert(...) at the shown diff) and either
change the alert text to "가게 이름, 설명, 전화번호는 필수 입력 항목입니다." or add checks for email
and address (and include those fields in the required validation) so the
displayed message matches the enforced rules.
In `@src/components/owner/tableDashboard.tsx`:
- Around line 685-695: Replace the clickable Pencil SVG usage with a native
interactive element: wrap or replace the Pencil component with a <button
type="button"> that carries the onClick handler (which calls
e.stopPropagation(); updateTable(id, { isEditingNum: true })), preserves the
aria-label ("테이블 번호 수정") and the visual classes (text-orange-400 fill-orange-400
cursor-pointer opacity-0 group-hover:opacity-100 transition-opacity); remove
role="button" and tabIndex since the native button provides correct keyboard
activation and semantics. Ensure any focus/visual styles remain consistent and
that tests/linters still pass after moving the onClick from the SVG to the
button.
In `@src/components/reservation/modals/PaymentModal.tsx`:
- Around line 77-80: The UI is still rendering booking.totalDeposit directly
instead of the state variable _payAmount, so updates via setPayAmount(...) never
appear; update the component to read and render the state (_payAmount)
everywhere you currently use booking.totalDeposit (and ensure the same fix at
the other occurrence around line 237), and also synchronize _payAmount with
incoming payOrder.amount (and booking?.totalDeposit) in the useEffect(s) that
currently call setPayAmount to guarantee the displayed amount matches
server-provided payOrder.amount.
In `@src/components/reservation/modals/ReservationConfirmModal.tsx`:
- Line 168: In ReservationConfirmModal, fix the user-facing spacing/ellipsis in
the two places that render the deposit text (where isCalculating, depositAmount
and formatKrw are used): replace the awkward "계산중 .." with a consistent,
user-friendly string like "계산 중…" (space between 계산 and 중 and a single ellipsis)
and ensure the rendered amount string is spaced consistently (update the
`${formatKrw(depositAmount)}원` occurrence(s) to match your UI convention, e.g.,
`${formatKrw(depositAmount)} 원` or keep it attached if that’s the project style)
in both locations so both lines show consistent punctuation and spacing.
In `@src/components/reservation/modals/ReservationMenuModal.tsx`:
- Around line 183-188: The render loop currently maps over
(["MAIN","SIDE","BEVERAGE","ALCOHOL"] as MenuCategory[]) and therefore never
renders items categorized as "OTHER" by mapMenuCategory; update the iteration to
include the OTHER category (or iterate keys from grouped) so grouped["OTHER"] is
checked and rendered; adjust the mapped array or replace it with
Object.keys(grouped) (or a typed equivalent) and continue to use
MenuCategoryLabel and grouped to derive safeLabel and list so no "OTHER" menus
are dropped.
In `@src/layouts/PublicLayout.tsx`:
- Around line 29-30: The current parse of rawId assigns parsedId = Number(rawId)
and then checks Number.isFinite(parsedId), which still allows integers >
Number.MAX_SAFE_INTEGER; update the validation so you only accept safe integers:
after converting rawId to a number (rawId -> parsedId) check
Number.isSafeInteger(parsedId) instead of Number.isFinite(parsedId) (use the
existing rawId and parsedId variables/logic in PublicLayout.tsx) so only safe
integer member IDs are accepted.
In `@src/pages/payment/FailPage.tsx`:
- Line 74: The JSX in FailPage currently renders literal semicolons between
error fragments (the expression with {code ? `code: ${code}` : null};{message ?
`message: ${message}` : null};) causing stray ";" characters; update FailPage to
avoid printing semicolons by either rendering code and message as separate
elements (e.g., render a <div> or <span> for each of the code and message when
present) or build a single string that joins non-empty parts with a separator
only when both exist (e.g., conditionally join ["code: …", "message: …"] with "
• " or similar), ensuring the unique expression currently producing semicolons
is replaced accordingly.
---
Outside diff comments:
In `@src/api/bookings.ts`:
- Around line 43-48: The cancelBooking function returns an untyped response
which breaks type safety; define a specific response interface (e.g.,
CancelBookingResponse) that models the API payload, annotate api.patch with the
axios generic (api.patch<CancelBookingResponse>(...)) and set the cancelBooking
signature to return Promise<CancelBookingResponse>; while here you update types,
also ensure the request uses existing shared axios options
(timeout/retry/interceptor) rather than raw calls so error/timeout/retry
behavior is preserved.
In `@src/components/main/StateSection.tsx`:
- Around line 21-25: The animated container's className (the JSX using cn(...)
with inView) doesn't honor users' prefers-reduced-motion; update the className
expression for the StateSection container and for the stats item elements to
include Tailwind motion-reduce utilities (e.g. motion-reduce:transition-none and
motion-reduce:transform-none or
motion-reduce:opacity-100/motion-reduce:translate-y-0) so that when
prefers-reduced-motion is enabled the component skips transitions/transform
effects; apply the same change to the stats items' className(s) that use
inView-driven opacity/translate classes to ensure all motion is suppressed for
assistive users.
In `@src/components/owner/tableDashboard.tsx`:
- Around line 244-257: The useEffect that defines and calls fetchLayout is
currently depending on tableData which causes a re-render loop because
fetchLayout calls setTableData; remove tableData from the dependency array and
instead depend only on storeId (or other true external deps), or if you must
react to tableData changes, use a ref or a separate effect; specifically update
the useEffect containing fetchLayout (the function named fetchLayout and the
calls to setTableData and setCreateModalOpen) to not include tableData in its
dependency array to prevent repeated fetches.
In `@src/components/store-registration/StepBusinessAuth.tsx`:
- Around line 213-223: 현재 register("startDate")의 onChange 블록이 getValues()에서 {
name, startDate }를 받아와 e.target.value를 businessNumber로 넘기고 있어 businessNumber와
startDate가 뒤바뀌고 있습니다; onChange 핸들러(등록된 register("startDate") 블록)에서 const { name,
businessNumber } = getValues()로 올바른 값을 읽고 setIsVerified(false) 후 onComplete에
businessNumber: businessNumber (또는 getValues().businessNumber)와 startDate:
e.target.value를 넘기도록 수정하세요 (참조: isVerified, getValues, setIsVerified,
onComplete, register("startDate")).
- Around line 168-184: The onChange handler for the businessNumber input is
passing e.target.value into startDate, causing parent state to get wrong fields
when a verified business number is edited; update the handler in the register
call for "businessNumber" (the onChange inside register), so it reads const {
name, startDate } = getValues(); then setIsVerified(false); and call
onComplete({ name, businessNumber: e.target.value, startDate, isVerified: false
}) — i.e., map e.target.value to businessNumber and preserve startDate.
In `@src/pages/myPage/settingPage.tsx`:
- Around line 40-46: The Switch component lacks an accessible name; update the
Switch signature to accept an ariaLabel (or labelledBy) prop (e.g., add
parameter ariaLabel?: string) and pass it through to the rendered button as
aria-label (or aria-labelledby) so assistive tech can announce which switch it
is; then update all call sites (including the other Switch usage around the
160-162 area) to provide a suitable aria-label or aria-labelledby string/ID.
In `@src/pages/myPage/subscriptionPage.tsx`:
- Around line 140-205: Add an explicit empty-state fallback when the plans list
is empty so the UI doesn't render a blank area: in the component that maps over
plans (the block using plans.map and referencing selectedPlan, billingCycle,
handlePlanChange), check if plans.length === 0 and render a concise placeholder
(e.g., a centered message and optional CTA) instead of the grid; ensure the
fallback matches existing styling and accessibility patterns and disables
plan-interaction UI when shown.
---
Nitpick comments:
In `@src/api/bookings.ts`:
- Around line 39-40: The code redundantly casts the result despite api.get
already typing the shape; remove the unnecessary "as BookingResponse" and return
response.data.result directly. Locate the call to api.get<{ result:
BookingResponse }>(), the response variable (response.data.result) and the
BookingResponse type, then change the function to return response.data.result
without the type assertion so the declared generic is the single source of type
truth.
In `@src/api/dto/store.dto.ts`:
- Around line 3-10: The DayDTO union is formatted across multiple lines while
CategoryDTO is a single-line union; to make formatting consistent, collapse
DayDTO into a single-line union (replace the multiline union declaration for
DayDTO with a compact single-line form) ensuring the exported type name DayDTO
and its string members ("MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY",
"SATURDAY", "SUNDAY") remain unchanged and keep the export modifier intact.
In `@src/components/customer-support/SupportFAQ.tsx`:
- Around line 96-116: The FAQ toggle button lacks an aria-expanded attribute
which impairs screen-reader feedback; update the button in SupportFAQ (the
element using onClick={() => toggleFaq(faq.id)} and checking openFaqId ===
faq.id) to set aria-expanded={openFaqId === faq.id} so the button reflects
expanded/collapsed state for assistive tech, and ensure the value updates
alongside the existing toggleFaq logic (no other changes to toggleFaq
necessary).
- Around line 46-52: The search input in SupportFAQ (the <input> that uses
value={searchTerm} and onChange={(e) => setSearchTerm(e.target.value)}) lacks an
explicit accessibility label; add an aria-label (for example "검색어 입력" or "Search
FAQs") to that input element so screen readers can identify its purpose,
ensuring it remains in sync with the existing placeholder and state handling.
In `@src/components/map/KakaoMap.tsx`:
- Line 185: The CSS string assigned to el.style.cssText is inconsistently
spaced; update the assignment in the KakaoMap component so property names and
values use consistent spacing and include a space after each semicolon (e.g.,
"padding: 6px 8px; font-size: 12px; line-height: 1.2;") to improve
readability—locate the el.style.cssText assignment and normalize spacing around
colons and semicolons accordingly.
In `@src/hooks/queries/useAuth.ts`:
- Line 44: Replace the blocking browser alert used in useAuth.ts (the alert("사업자
인증이 완료되었습니다. \n사장님 권한 적용을 위해 반드시 재로그인해주세요."); call) with a non-blocking
toast/snackbar: import and use your app's notification utility (eg. showToast,
enqueueSnackbar, or NotificationService) inside the same function so the same
message is shown asynchronously; ensure the toast variant/severity
(info/success) and any required options (autoHideDuration, multi-line support)
are set and remove the alert call.
In `@src/pages/LoginErrorPage.tsx`:
- Around line 5-38: The LoginErrorPage component lacks an ARIA live region to
announce the error to screen readers; update the component (e.g., the outer
container inside LoginErrorPage or the error message element rendered by the
JSX) to include an accessible live region such as adding role="alert" and
aria-live="assertive" (or create a dedicated visually-present but
screen-reader-first live region) so that assistive technologies immediately
announce the error state; ensure the attributes are applied to the element that
contains the error heading/description (the h1/h2 or the wrapping div in
LoginErrorPage) and keep visual layout unchanged.
In `@src/pages/myPage/settingPage.tsx`:
- Around line 80-81: The initial notification state may contain malformed values
from localStorage; add a runtime validator (e.g. isValidNotificationSettings)
that checks the NotificationSettings shape and boolean types, use it inside
getInitialNotifications (or immediately after parsing) to return either the
parsed value or a safe defaultNotifications object, and initialize both
notifications and savedNotifications with the validated result (replace direct
use of getInitialNotifications return for setSavedNotifications as well) so only
type-safe NotificationSettings enter state.
In `@src/pages/myPage/storePage.tsx`:
- Around line 99-100: The loading message div (the element with className "py-14
text-center text-gray-400") should include accessibility attributes so screen
readers announce state changes; add aria-live="polite" to that div (and
optionally role="status") so the loading/empty/error text is announced
automatically to assistive technologies.
In `@src/pages/myPage/subscriptionPage.tsx`:
- Line 181: The list item key currently uses only feature (key={feature}), which
can collide for duplicate feature strings; update the map creating the <li> in
subscriptionPage.tsx to use a composite key that includes the plan identity and
the item index (e.g., combine plan.name and the map index and feature) so each
key is unique across plans and repeated feature labels; locate the map that
renders the feature variable inside the component and replace key={feature} with
a concatenation like `${plan.name}-${index}-${feature}` (or equivalent) to
ensure stable, unique keys.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8900fcbf-e4d2-477f-b6cd-a5e1b45c638a
⛔ Files ignored due to path filters (7)
.prettierrcis excluded by none and included by noneeslint.config.jsis excluded by none and included by noneindex.htmlis excluded by none and included by nonepackage.jsonis excluded by none and included by nonepnpm-lock.yamlis excluded by!**/pnpm-lock.yaml,!pnpm-lock.yamland included by nonetsconfig.jsonis excluded by none and included by nonevite.config.tsis excluded by none and included by none
📒 Files selected for processing (116)
src/App.tsxsrc/api/adapters/store.adapter.tssrc/api/api.error.tssrc/api/auth.tssrc/api/axios.tssrc/api/bookings.tssrc/api/dto/store.dto.tssrc/api/endpoints/bookings.tssrc/api/endpoints/member.tssrc/api/endpoints/menus.tssrc/api/endpoints/payments.tssrc/api/endpoints/reservations.tssrc/api/inquiry.tssrc/api/menu.tssrc/api/owner/menus.tssrc/api/owner/reservation.tssrc/api/owner/storeLayout.tssrc/api/owner/stores.tssrc/api/owner/table.tssrc/api/store.tssrc/components/RouteGuards.tsxsrc/components/auth/ChangePasswordDiaLog.tsxsrc/components/auth/LoginDialog.tsxsrc/components/auth/Signup.schema.tssrc/components/auth/SignupDialog.tsxsrc/components/auth/WithdrawDialog.tsxsrc/components/customer-support/SupportCompleteModal.tsxsrc/components/customer-support/SupportFAQ.tsxsrc/components/customer-support/SupportHero.tsxsrc/components/customer-support/SupportModal.tsxsrc/components/customer-support/support.schema.tssrc/components/main/CtaSection.tsxsrc/components/main/FeatureCard.tsxsrc/components/main/FeatureSection.tsxsrc/components/main/Footer.tsxsrc/components/main/ForOwnerSection.tsxsrc/components/main/ForUserSection.tsxsrc/components/main/Header.tsxsrc/components/main/Hero.tsxsrc/components/main/ProblemSection.tsxsrc/components/main/StateSection.tsxsrc/components/map/KakaoMap.tsxsrc/components/owner/AddTableModal.tsxsrc/components/owner/BreakTimeModal.tsxsrc/components/owner/MenuManagement.tsxsrc/components/owner/StoreSettings.tsxsrc/components/owner/TableCreateModal.tsxsrc/components/owner/menuFormModal.tsxsrc/components/owner/tableDashboard.tsxsrc/components/owner/tableDetailModal.tsxsrc/components/reservation/modals/PaymentModal.tsxsrc/components/reservation/modals/ReservationCompleteModal.tsxsrc/components/reservation/modals/ReservationConfirmModal.tsxsrc/components/reservation/modals/ReservationMenuModal.tsxsrc/components/reservation/modals/ReservationModal.tsxsrc/components/reservation/parts/TableMap.tsxsrc/components/restaurant/RestaurantCard.tsxsrc/components/restaurant/RestaurantDetailModal.tsxsrc/components/restaurant/RestaurantList.tsxsrc/components/restaurant/RestaurantListSkeleton.tsxsrc/components/store-registration/CompleteModal.tsxsrc/components/store-registration/ConfirmModal.tsxsrc/components/store-registration/Menu.schema.tssrc/components/store-registration/MenuItemInput.tsxsrc/components/store-registration/RegistrationStepper.tsxsrc/components/store-registration/StepBusinessAuth.tsxsrc/components/store-registration/StepMenuRegistration.tsxsrc/components/store-registration/StepStoreInfo.tsxsrc/components/store-registration/StoreInfo.schema.tssrc/components/store-registration/StoreTransform.utils.tssrc/components/ui/button.tsxsrc/components/ui/calendar.tsxsrc/components/ui/checkbox.tsxsrc/components/ui/dialog.tsxsrc/components/ui/label.tsxsrc/components/ui/popover.tsxsrc/components/ui/separator.tsxsrc/hooks/common/useConfirmClose.tssrc/hooks/queries/useAuth.tssrc/hooks/queries/useMenu.tssrc/hooks/queries/useStore.tssrc/hooks/reservation/useAvailableTables.tssrc/hooks/reservation/useAvailableTimes.tssrc/hooks/reservation/useCreateBooking.tssrc/hooks/reservation/useMenus.tssrc/hooks/store/useRestaurantDetail.tssrc/hooks/store/useSearchStores.tssrc/layouts/PublicLayout.tsxsrc/layouts/myPageLayout.tsxsrc/lib/kakao.tssrc/lib/utils.tssrc/main.tsxsrc/pages/CustomerSupportPage.tsxsrc/pages/LoginErrorPage.tsxsrc/pages/NotFound.tsxsrc/pages/OAuthCallbackPage.tsxsrc/pages/ReservationCompletePage.tsxsrc/pages/SearchPage.tsxsrc/pages/myPage/MyInfoPage.tsxsrc/pages/myPage/StoreRegistrationPage.tsxsrc/pages/myPage/reservationPage.tsxsrc/pages/myPage/settingPage.tsxsrc/pages/myPage/storePage.tsxsrc/pages/myPage/subscriptionPage.tsxsrc/pages/ownerPage.tsxsrc/pages/payment/FailPage.tsxsrc/pages/payment/SuccessPage.tsxsrc/query/keys.tssrc/stores/useAuthStore.tssrc/types/booking.tssrc/types/kakao.d.tssrc/types/restaurant.tssrc/utils/menu.tssrc/utils/phoneNumber.tssrc/utils/reservation.tssrc/utils/time.ts
🔢 관련 이슈 링크
📌 변경사항PR
💻 작업내용
코드 일관성 향상을 위해 ESLint 추가 규칙과 Prettier 포맷 규칙 정리.
기존에는 기본 설정만 되어있는 상태였고, 추가로 import 구조와 자동정렬 중심으로 개선진행.
"semi": true,//문장끝 세미콜론 붙이기"singleQuote": false,//문자열에 ""사용"trailingComma": "all",//마지막요소뒤에도 쉼표붙임"printWidth": 100,//한줄 최대글자 100자"tabWidth": 2,//들여쓰기 공백 2칸"useTabs": false,//탭 문자대신 스페이스 사용"bracketSpacing": true,//중괄호 양끝에 공백넣기"bracketSameLine": false,// 닫는괄호 줄바꿈 관련"endOfLine": "auto",//파일줄바꿈방식 OS에 맞게 자동유지-
"quoteProps": "consistent",//객체속성에 따옴표 일관성유지"arrowParens": "always",//매개변수1개여도 괄호 붙이기"proseWrap": "preserve"//README 자동 줄바꿈 방지+)추가로 import 규칙 추가 코드
"simple-import-sort/imports": "warn", // import 구문 정렬 검사"simple-import-sort/exports": "warn", // export 구문 순서 정리"import/newline-after-import": "warn", // import 구문 다음에 코드 한줄 띄워줌(빈 줄 추가)"import/no-duplicates": "warn", // 중복된 import 구문 있으면 하나로 합쳐줌(중복제거)import 작성 방식을 통일했고, 파일 저장하면 바로 코드 스타일 자동적용되도록 수정했습니다.
🪧 미완성 작업
N/A
🤔 논의 사항 및 참고 사항
pnpm lint 명령어로 lint 규칙 어긋났는지 사전점검가능하고,
import 정렬 관련 warn이 발생한 경우에는
pnpm eslint . --fix명령어 사용해서 import구문정렬 자동수정이 가능합니다!현재 파일 저장시 ESLint와 Prettier 자동 정렬이 적용되도록 설정되어있어서 일반적인 정렬및 규칙은 저장으로 정리되도록 설정했습니다.
✅ 체크리스트
Summary by CodeRabbit
릴리스 노트