Skip to content

Style: 마이페이지 사장님 화면#116

Merged
KingSeokJin merged 6 commits intodevelopfrom
style/mypage
Feb 23, 2026
Merged

Style: 마이페이지 사장님 화면#116
KingSeokJin merged 6 commits intodevelopfrom
style/mypage

Conversation

@TakioN
Copy link
Member

@TakioN TakioN commented Feb 22, 2026

📝 작업 내용

  • 마이페이지 사장님 페이지 로직 추가

📢 PR Point


이미지 첨부

image

🔧 다음 할 일

  • 사장님 마이페이지에서 콜키지 정보 등록하기

Summary by CodeRabbit

  • 새로운 기능

    • 내 가게 목록 페이지와 매장 카드 컴포넌트 추가
    • 가게 북마크/공유 아이콘 추가
    • 오늘 영업시간을 추출하는 유틸리티 추가
  • 개선 사항

    • 모바일에서 네이티브 공유 우선 사용으로 공유 경험 개선
    • 가게 인증서 업로드 시 이미지 미리보기 제공
    • 마스터 가입 초기 단계를 첫 단계로 변경
    • 로그아웃/탈퇴 시 캐시 정리 추가
    • 리뷰 페이지 헤더 고정 및 버튼 정렬/줄바꿈 방지 개선

@coderabbitai
Copy link

coderabbitai bot commented Feb 22, 2026

Walkthrough

마스터 가게 조회/관리 기능과 인증 흐름을 추가하고, 관련 API·타입·쿼리 훅·라우트·유틸리티 및 UI 컴포넌트를 도입·수정했습니다. 공유 복사 로직과 이미지 업로드/미리보기, React Query 캐시 정리, 일부 네비게이션·레이아웃 변경이 포함됩니다.

Changes

Cohort / File(s) Summary
마스터 가게 핵심 추가
src/pages/myPage/MasterStoreList.tsx, src/shared/components/myPage/MyStoreItem.tsx, src/shared/queries/user/useMasterStores.ts
마스터 가게 목록 페이지와 개별 가게 아이템 컴포넌트 추가, useMasterStores 훅 도입으로 getMasterRestaurant 호출을 React Query로 래핑.
API 및 타입
src/shared/apis/user/user.api.ts, src/shared/apis/user/user.type.ts
MasterStoreResponse 타입 추가 및 GET /ownerRestaurant/my용 getMasterRestaurant, 인증서 업로드용 submitCertificate API 추가.
인증/업로드 흐름 수정
src/shared/components/myPage/AuthMaster.tsx, src/shared/components/myPage/FindMyStore.tsx
이미지 미리보기, 비동기 submitCertificate 호출로 인증 제출 경로 변경; FindMyStore는 마운트 시 getMasterRestaurant로 데이터 로드하도록 전환.
캐시 관리 및 쿼리 정리
src/pages/myPage/MainMyPage.tsx, src/pages/myPage/ModifyInfo.tsx
로그아웃/탈퇴 후 React Query 캐시를 지우도록 queryClient.clear() 호출 추가.
라우팅·네비게이션·레이아웃
src/shared/router/Router.tsx, src/pages/add/StoreCheck.tsx, src/pages/myPage/MyReview.tsx, src/shared/components/myPage/MyPageBranch.tsx
신규 라우트 add/my-stores 추가, StoreCheck 단순화, MyReview에 고정 헤더 적용, "내 가게 확인하기" 버튼의 네비게이션 대상 변경.
아이콘·UI 마이너 개선
src/shared/icons/Bookmark.tsx, src/shared/icons/Share.tsx, src/shared/components/myPage/MyReviewItem.tsx
Bookmark/Share SVG 컴포넌트 추가 및 MyReviewItem 버튼 정렬·줄바꿈 방지 클래스 추가.
공유 동작 개선
src/shared/components/detail/DetailHeader.tsx
모바일에서 Web Share API 우선 사용, 실패 시 클립보드 복사로 폴백하도록 clipLink 비동기화 및 에러 처리 추가.
유틸리티 추가
src/shared/utils/operatingHours.ts
getTodayOperatingHours 함수 추가: 운영시간 문자열에서 오늘 요일에 해당하는 항목을 반환.
경미한 문구/주석 변경
src/shared/store/useAuthStore.ts, src/pages/myPage/MasterSignUp.tsx
주석 예시 변경 및 MasterSignUp 초깃값 변경(3→1)으로 시작 단계 조정.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant FindMyStore
    participant useMasterStores
    participant getMasterRestaurant
    participant API as BackendAPI

    User->>FindMyStore: 컴포넌트 마운트
    FindMyStore->>useMasterStores: useQuery(['masterStores'])
    useMasterStores->>getMasterRestaurant: 호출
    getMasterRestaurant->>API: GET /ownerRestaurant/my
    API-->>getMasterRestaurant: MasterStoreResponse[]
    getMasterRestaurant-->>useMasterStores: 데이터 반환
    useMasterStores-->>FindMyStore: 데이터 제공
    FindMyStore-->>User: 가게 목록 렌더링
Loading
sequenceDiagram
    participant User
    participant AuthMaster
    participant submitCertificate
    participant API as BackendAPI

    User->>AuthMaster: 이미지 선택
    AuthMaster->>AuthMaster: ObjectURL 생성 및 미리보기 표시
    User->>AuthMaster: 제출 클릭
    AuthMaster->>submitCertificate: 파일 전달
    submitCertificate->>API: PUT /users/registration (FormData)
    API-->>submitCertificate: 성공 응답
    submitCertificate-->>AuthMaster: 완료
    AuthMaster->>AuthMaster: isPending 해제 및 onNext 호출
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • KingSeokJin

Poem

🐰 새 가게들 모여 춤추네,
이미지 빛나고 링크는 날아가네.
캐시를 쓸어낸 뒤 새로고침 한 번,
오늘 영업시간만 속삭이며,
주먹 쥔 당근으로 축배를 들어요 🥕✨

🚥 Pre-merge checks | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Title check ⚠️ Warning PR 제목이 마이페이지 사장님 화면 스타일과 관련된 변경사항을 명확하게 설명하지 못하며, 실제 변경사항은 스타일뿐 아니라 로직 추가, 새로운 컴포넌트, API 통합 등 광범위한 기능 구현을 포함합니다. PR 제목을 '마이페이지 사장님 기능 추가: 가게 목록 조회 및 인증서 제출' 또는 유사한 형태로 변경하여 로직 및 기능 추가를 명확히 반영하세요.
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.
Description check ❓ Inconclusive PR 설명은 기본 템플릿 구조를 따르지만, '작업 내용' 섹션이 매우 간략하고 'PR Point'가 비어있어 구현된 주요 기능과 변경사항의 세부 내용이 부족합니다. 작업 내용에 추가된 주요 기능들(새 컴포넌트, API 함수, 라우트 등)을 구체적으로 나열하고, PR Point에 중요한 변경사항(React Query 캐시 관리, 모바일 공유 기능 등)을 설명하세요.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch style/mypage

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.

Copy link

@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: 13

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/shared/components/myPage/MyReviewItem.tsx (1)

105-105: ⚠️ Potential issue | 🟠 Major

하드코딩된 레스토랑 이름을 review.restaurantName으로 교체해야 합니다.

MyReviewResponse 타입에 restaurantName 필드가 존재하므로, 다음 위치들에서 하드코딩된 값들을 해당 필드로 교체하세요:

  • 105줄: 엔비햄버거review.restaurantName
  • 75, 76줄: 빵빵review.restaurantName
  • 191줄: restName={'빵빵'}restName={review.restaurantName}
  • 212줄: restName={'빵빵'}restName={review.restaurantName}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/components/myPage/MyReviewItem.tsx` at line 105, Replace hardcoded
restaurant names with the restaurantName field from the review object: update
the JSX in MyReviewItem.tsx to use review.restaurantName (the
MyReviewResponse.restaurantName property) where the static strings appear —
specifically change the <h3> title currently rendering "엔비햄버거", the two earlier
occurrences rendering "빵빵", and the restName props currently set as '빵빵' to
restName={review.restaurantName}; ensure the component references the existing
review variable/prop and that review.restaurantName is used consistently for
display and prop passing.
src/shared/components/myPage/AuthMaster.tsx (1)

23-29: ⚠️ Potential issue | 🟠 Major

파일을 여러 번 선택하면 이전 Object URL이 해제되지 않아 메모리 누수가 발생합니다.

새 파일을 선택할 때 이전 previewUrl에 대해 URL.revokeObjectURL을 호출해야 합니다.

🐛 수정 제안
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
+     if (previewUrl !== '') URL.revokeObjectURL(previewUrl);
      setSelectedFile(file);
      setPreviewUrl(URL.createObjectURL(file));
    }
  };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/components/myPage/AuthMaster.tsx` around lines 23 - 29, The
handleChange in AuthMaster sets a new preview URL without revoking the previous
one, causing memory leaks; update handleChange to, before calling
URL.createObjectURL(file), check the current previewUrl (state used by
setPreviewUrl) and if present call URL.revokeObjectURL(previewUrl) to release
it, then create and set the new object URL and selected file (and also ensure
any cleanup on unmount revokes the last previewUrl if still set).
🧹 Nitpick comments (14)
src/pages/add/StoreCheck.tsx (1)

4-8: 주석 처리된 코드 블록을 제거해 주세요.

전체 파일에 걸쳐 임포트, 상태 구조 분해, 핸들러, JSX 마크업 등 대량의 코드가 주석으로만 남아 있습니다. 이력이 필요하다면 Git 히스토리로 충분히 추적 가능하므로, 주석 처리된 코드를 모두 삭제하면 가독성과 유지보수성이 크게 향상됩니다.

Also applies to: 13-20, 25-36, 41-77

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/add/StoreCheck.tsx` around lines 4 - 8, Remove all commented-out
code throughout StoreCheck.tsx—this includes the commented import lines (e.g.,
the svg imports commented above Header), any commented state/destructuring,
handlers, and JSX fragments left as comments between the import block and the
component body (areas noted around the Header import and the commented blocks
spanning the rest of the file). Delete those commented lines rather than leaving
them in place; if history is needed, rely on Git history. Keep only active
imports (like Header) and the live component code to improve readability and
maintainability.
src/pages/myPage/MyReview.tsx (1)

16-24: fixed 포지셔닝에서 width: calc(100% - 32px)는 뷰포트 기준으로 계산됩니다.

position: fixed는 부모의 relative를 무시하고 뷰포트를 기준으로 배치됩니다. 따라서 width: calc(100% - 32px)에서 100%는 부모가 아닌 뷰포트 너비입니다. 모바일에서는 앱 컨테이너가 전체 화면이므로 문제없지만, 데스크톱에서 앱이 중앙 정렬될 경우 헤더가 앱 영역을 벗어날 수 있습니다.

maxWidth로 어느 정도 방어되지만, 헤더가 앱 컨테이너 내에서 중앙 정렬되지 않을 수 있습니다. sticky 포지셔닝이 이 경우 더 적합할 수 있습니다.

♻️ `sticky` 사용 제안
-    <div className="relative px-4">
+    <div className="px-4">
       <Header
         type="back"
         title="리뷰관리"
         backFn={() => navigate(-1)}
-        className="fixed top-0 z-[5] bg-white"
-        style={{ width: 'calc(100% - 32px)', maxWidth: 'calc(var(--app-width) - 32px)' }}
+        className="sticky top-0 z-[5] bg-white"
       />
-      <section className="mt-12 flex flex-col gap-5 py-2">{renderReviews()}</section>
+      <section className="flex flex-col gap-5 py-2">{renderReviews()}</section>
     </div>

sticky는 부모 컨테이너 내에서 동작하므로 별도의 width 계산이나 margin-top 보정이 불필요합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/myPage/MyReview.tsx` around lines 16 - 24, The Header is using
position: fixed with an inline style width: 'calc(100% - 32px)' which is
viewport-based and can make the header escape the centered app container on wide
screens; change the Header from fixed to sticky (remove the "fixed top-0" class
and use "sticky top-0" or equivalent) and remove the inline width calc so it
inherits the parent container width (you can keep the maxWidth prop or class for
limits); update references in this file to the Header component and its
className/style usage to ensure the header remains contained and aligned within
the parent .relative wrapper.
src/pages/myPage/MainMyPage.tsx (2)

14-15: useAuthStore()를 두 번 호출할 필요 없이 하나로 합칠 수 있습니다.

♻️ 리팩터링 제안
- const { user } = useAuthStore();
- const { logout } = useAuthStore();
+ const { user, logout } = useAuthStore();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/myPage/MainMyPage.tsx` around lines 14 - 15, Call useAuthStore()
only once and destructure both user and logout from that single call instead of
calling useAuthStore() twice; locate the two separate calls to useAuthStore in
MainMyPage.tsx and replace them with a single const { user, logout } =
useAuthStore() to avoid duplicate store subscriptions.

30-35: 로그아웃 처리 전에 navigate를 먼저 호출하면 상태 초기화 전에 라우팅이 시작됩니다.

logout()queryClient.clear() 완료 후 navigate를 호출하는 것이 의미상 더 명확합니다.

♻️ 순서 개선 제안
  onClick={() => {
-   navigate('/home');
    logout();
    queryClient.clear();
    setFooterProps(0);
+   navigate('/home');
  }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/myPage/MainMyPage.tsx` around lines 30 - 35, The current onClick
calls navigate('/home') before clearing state; change the order so logout(),
await any async logout (if logout returns a Promise), and call/await
queryClient.clear() and setFooterProps(0) first, then call navigate('/home');
reference the onClick handler and functions navigate, logout, queryClient.clear,
and setFooterProps to locate and update the sequence and add awaits if those
functions are asynchronous.
src/shared/utils/operatingHours.ts (1)

1-1: 파라미터 이름에 오타가 있습니다: opStirngopString

✏️ 수정 제안
-export const getTodayOperatingHours = (opStirng: string) => {
+export const getTodayOperatingHours = (opString: string) => {
   const todayDay = new Date().getDay();
   const dayMapper = ['일', '월', '화', '수', '목', '금', '토'];
 
-  if (!opStirng.includes(',')) return opStirng;
+  if (!opString.includes(',')) return opString;
 
-  const todayOperation = opStirng.split(',').find((x) => x.startsWith(`${dayMapper[todayDay]}:`));
+  const todayOperation = opString.split(',').find((x) => x.startsWith(`${dayMapper[todayDay]}:`));
 
   return todayOperation;
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/utils/operatingHours.ts` at line 1, The parameter name in
getTodayOperatingHours is misspelled as opStirng; rename it to opString
throughout the function signature, all internal references, and any callers to
remove the typo and keep naming consistent (update any type annotations or JSDoc
referring to opStirng as well).
src/shared/components/myPage/MyStoreItem.tsx (1)

21-39: clipLink 함수가 DetailHeader.tsx와 중복됩니다.

DetailHeader.tsx의 리뷰에서도 언급했듯이, 모바일 감지 + Web Share API + 클립보드 폴백 로직이 두 파일에 거의 동일하게 존재합니다. 공유 유틸리티로 추출하면 중복을 제거하고 일관성을 유지할 수 있습니다.

또한 Line 32의 console.logconsole.error로, Line 35의 navigator.clipboard.writeTextawait을 추가하는 것이 좋습니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/components/myPage/MyStoreItem.tsx` around lines 21 - 39, Extract
the duplicate share logic from MyStoreItem.tsx's clipLink (and the matching code
in DetailHeader.tsx) into a shared utility function (e.g., shareOrCopyUrl) that
encapsulates mobile detection, Web Share API usage, clipboard fallback, and
returns status/errors so callers can handle UI state; update MyStoreItem's
clipLink to call that util and only manage modal state, change the catch logging
from console.log to console.error, and make navigator.clipboard.writeText
awaited (i.e., await navigator.clipboard.writeText(...)) so errors propagate to
the utility's catch handling.
src/pages/myPage/MasterStoreList.tsx (1)

7-20: 로딩 및 에러 상태 처리가 없습니다.

useMasterStores()에서 data만 구조 분해하고 있어, 네트워크 오류나 로딩 중 상태에 대한 사용자 피드백이 없습니다. isLoading, isError 등을 활용해 최소한의 로딩/에러 UI를 제공하는 것을 권장합니다.

♻️ 로딩/에러 처리 예시
 const MasterStoreList = () => {
   const navigate = useNavigate();
-  const { data: stores } = useMasterStores();
+  const { data: stores, isLoading, isError } = useMasterStores();
+
+  if (isLoading) return <div className="px-4">로딩 중...</div>;
+  if (isError) return <div className="px-4">가게 목록을 불러오는데 실패했습니다.</div>;

   const renderStores = () =>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/myPage/MasterStoreList.tsx` around lines 7 - 20, MasterStoreList
currently only destructures data from useMasterStores and lacks loading/error
handling; update the component to also destructure isLoading and isError (and
error if available) from useMasterStores, render a minimal loading state (e.g.,
a spinner or "Loading..." placeholder) when isLoading is true, and render an
error message or retry UI when isError is true using the error details if
provided; ensure renderStores/MyStoreItem still handles empty arrays and keep
Header/navigation behavior unchanged.
src/shared/components/myPage/FindMyStore.tsx (4)

16-18: useEffect 의존성 배열에 getRestaurant가 누락되어 있습니다.

getRestaurant가 컴포넌트 본문에 정의되어 있어 ESLint react-hooks/exhaustive-deps 규칙 위반이 발생할 수 있습니다. useEffect 내부로 함수를 이동하거나 useCallback으로 감싸는 것을 권장합니다.

♻️ 수정 제안: useEffect 내부로 이동
-  useEffect(() => {
-    getRestaurant();
-  }, []);
-
-  const getRestaurant = async () => {
-    try {
-      const res = await getMasterRestaurant();
-      setRestaurants(res);
-      setIsComplete(true);
-    } catch (e) {
-      console.error('사장님 가게 가져오기 실패: ' + e);
-    }
-  };
+  useEffect(() => {
+    const getRestaurant = async () => {
+      try {
+        const res = await getMasterRestaurant();
+        setRestaurants(res);
+        setIsComplete(true);
+      } catch (e) {
+        console.error('사장님 가게 가져오기 실패: ' + e);
+      }
+    };
+    getRestaurant();
+  }, []);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/components/myPage/FindMyStore.tsx` around lines 16 - 18, The
useEffect in the FindMyStore component calls getRestaurant without listing it in
the dependency array, which breaks react-hooks/exhaustive-deps; fix by either
moving the getRestaurant implementation inside the useEffect so nothing external
is referenced, or wrap getRestaurant in useCallback and add getRestaurant to the
useEffect dependency array (i.e., useEffect(() => { getRestaurant(); },
[getRestaurant])); ensure the chosen approach preserves any closures/state used
by getRestaurant.

83-90: SearchInput이 렌더링되지만 기능이 없습니다.

onKeyDownonSearch 핸들러가 모두 주석 처리되어 있어 검색 입력 필드가 아무 동작도 하지 않습니다. 이제 마운트 시 자동으로 데이터를 불러오는 방식으로 변경되었으므로, 검색 입력 UI를 제거하거나 클라이언트 사이드 필터링 용도로 활용하는 것을 고려해 주세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/components/myPage/FindMyStore.tsx` around lines 83 - 90,
SearchInput is rendered but inert because onKeyDown and onSearch are commented
out; either remove the input or wire it up for client-side filtering: re-enable
or implement the event handlers in FindMyStore by connecting SearchInput's
onChange (already using setSearchQuery) to a debounced filter function that
filters the mounted data set (use the searchQuery state) or call the existing
handleKeyDown/onSearch handlers (uncomment and adapt them) to trigger the same
fetch/filter logic; ensure SearchInput's props include onKeyDown={handleKeyDown}
and/or onSearch={onSearch} and that those functions reference searchQuery and
the store list to perform filtering or re-fetching.

14-14: 주석 처리된 코드를 정리해 주세요.

isFirstSearch, handleKeyDown, onSearch 등 이전 검색 로직이 주석으로 남아 있습니다. 버전 관리 시스템에서 히스토리를 확인할 수 있으므로, 사용하지 않는 코드는 제거하는 것이 좋습니다.

Also applies to: 29-45

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/components/myPage/FindMyStore.tsx` at line 14, Remove the leftover
commented-out legacy search logic to clean up the file: delete the commented
declarations and functions including isFirstSearch (useRef), handleKeyDown,
onSearch and any other commented search-related blocks between the indicated
ranges (e.g., the commented lines around 14 and 29-45) so only active, current
search logic remains; ensure imports or references to these symbols are also
removed if they become unused (e.g., remove unused useRef import).

97-97: CSS calc() 표현식에 연산자 앞 공백이 누락되었습니다.

calc(var(--app-width)* 0.8)에서 * 앞에 공백이 없습니다. CSS 사양에서 calc()*, / 연산자 양쪽에 공백이 필요하진 않지만, +, -는 공백이 필수입니다. 다만 일관성과 가독성을 위해 calc(var(--app-width) * 0.8)로 수정하는 것을 권장합니다.

♻️ 수정 제안
-          style={{ maxWidth: 'calc(var(--app-width)* 0.8)' }}
+          style={{ maxWidth: 'calc(var(--app-width) * 0.8)' }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/components/myPage/FindMyStore.tsx` at line 97, In FindMyStore.tsx
update the inline style expression that sets maxWidth: find the JSX style prop
containing "style={{ maxWidth: 'calc(var(--app-width)* 0.8)' }}" and add spacing
around the multiplication operator so the value becomes "calc(var(--app-width) *
0.8)"; this improves readability and consistency while keeping the same
computation.
src/shared/components/detail/DetailHeader.tsx (1)

80-98: clipLink 로직이 MyStoreItem.tsx와 거의 동일하게 중복됩니다.

이 함수의 모바일 감지, Web Share API 호출, 클립보드 폴백 로직이 src/shared/components/myPage/MyStoreItem.tsx (lines 21-39)와 사실상 동일합니다. 공유 유틸리티 함수로 추출하면 유지보수가 쉬워집니다.

추가로 몇 가지 사소한 문제가 있습니다:

  1. Line 91: 에러 로깅에 console.log 대신 console.error를 사용하는 것이 적절합니다.
  2. Line 94: navigator.clipboard.writeText는 Promise를 반환하지만 await 없이 호출되어, 클립보드 쓰기 실패 시 에러가 무시됩니다.
♻️ 에러 처리 개선 예시 (최소 수정)
       } catch (err) {
-        console.log('공유 중 에러 발생 : ' + err);
+        console.error('공유 중 에러 발생 : ', err);
       }
     } else {
-      navigator.clipboard.writeText(window.location.href);
+      await navigator.clipboard.writeText(window.location.href);
       setIsShareModalOpen(false);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/components/detail/DetailHeader.tsx` around lines 80 - 98, Extract
the sharing logic from clipLink in DetailHeader (the mobile detection,
navigator.share call and clipboard fallback) into a shared utility used by both
DetailHeader.tsx and MyStoreItem.tsx to remove duplication; in that refactor,
ensure error logging uses console.error instead of console.log for the catch
branch around navigator.share, and await navigator.clipboard.writeText (with
try/catch) so clipboard write failures are handled and you can reliably call
setIsShareModalOpen(false) / setIsCopiedModalOpen(true) only after a successful
write; reference the existing symbols clipLink, navigator.share,
navigator.clipboard.writeText, setIsShareModalOpen and setIsCopiedModalOpen and
the other copy in MyStoreItem.tsx when moving the logic.
src/shared/components/myPage/AuthMaster.tsx (2)

64-68: img 태그에 alt 속성이 누락되어 있습니다.

접근성을 위해 alt 속성을 추가하세요.

♻️ 수정 제안
        {previewUrl ? (
-         <img src={previewUrl} className="size-[80%]" />
+         <img src={previewUrl} className="size-[80%]" alt="사업자 등록증 미리보기" />
        ) : (
-         <img src={upload} className="h-[35%] w-[40%]" />
+         <img src={upload} className="h-[35%] w-[40%]" alt="이미지 업로드" />
        )}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/components/myPage/AuthMaster.tsx` around lines 64 - 68, The two
<img> elements render either previewUrl or upload but are missing alt
attributes; update both <img> tags (the one using previewUrl and the fallback
using upload) to include meaningful alt text (e.g., alt describing the
uploaded/preview image or "uploaded file preview") and ensure the values are
properly passed as string literals or from a prop/variable as needed to satisfy
accessibility and linter requirements in AuthMaster.tsx.

80-87: 제출 중(isPending) 상태에서 버튼이 비활성화 표시되지 않습니다.

isPendingtrue일 때 handVerification 내부에서 early return하지만, 사용자에게는 아무런 시각적 피드백이 없습니다. disabled 속성과 스타일을 추가하는 것을 권장합니다.

♻️ 수정 제안
        <button
-         className="fixed bottom-4 left-[10%] right-[10%] mx-auto h-[48px] w-[80%] max-w-[480px] rounded-[10px] bg-[var(--primary)] font-bold text-white"
-         onClick={handVerification}
+         className="fixed bottom-4 left-[10%] right-[10%] mx-auto h-[48px] w-[80%] max-w-[480px] rounded-[10px] bg-[var(--primary)] font-bold text-white disabled:opacity-50"
+         onClick={handleVerification}
+         disabled={isPending}
        >
-         다음
+         {isPending ? '제출 중...' : '다음'}
        </button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/components/myPage/AuthMaster.tsx` around lines 80 - 87, The "다음"
button lacks disabled styling when isPending is true; update the button rendered
when selectedFile to include a disabled attribute driven by isPending (or by
(!selectedFile || isPending)) and add conditional classes on the same element
(e.g., apply opacity-50 and cursor-not-allowed when isPending) so users see it
is inactive; keep the existing handVerification early-return logic but ensure
the button cannot be clicked when disabled by binding disabled and toggling
visual styles in the JSX where selectedFile and handVerification are referenced.
🤖 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/pages/add/StoreCheck.tsx`:
- Around line 22-24: Remove the debug useEffect that calls console.log(location)
and then remove the now-unused useLocation import and the const location =
useLocation() declaration; specifically delete the useEffect block referencing
location, remove the import of useLocation at the top, and remove the location
variable (so no unused symbols remain).

In `@src/pages/myPage/MasterStoreList.tsx`:
- Line 12: The list-rendered component returned by renderStores is missing the
required React key prop; update the map in renderStores so each <MyStoreItem>
receives a stable unique key (e.g., key={store.id} or
key={`store-${store.id}`}), falling back to the array index only if no unique id
exists, ensuring the change is applied where renderStores maps over stores and
passes store into MyStoreItem.

In `@src/shared/components/myPage/AuthMaster.tsx`:
- Line 31: Rename the misspelled function handVerification to handleVerification
to match existing handler naming (like handleUpload, handleChange); update the
function declaration name and all references/call sites (e.g., the onClick
handler that currently invokes handVerification) to call handleVerification
instead so the component uses consistent names.
- Around line 13-17: The cleanup in useEffect is capturing a stale previewUrl
because its dependency array is empty; change to track the latest value via a
ref (e.g., create previewUrlRef and update previewUrlRef.current whenever
previewUrl changes or inside handleChange), then in the useEffect cleanup call
URL.revokeObjectURL(previewUrlRef.current) if it is non-empty; update
handleChange to set both previewUrl state and previewUrlRef.current so the
cleanup sees the latest URL and revokes it on unmount or replacement.

In `@src/shared/components/myPage/FindMyStore.tsx`:
- Around line 59-60: The placeholder string '주소주소주소주소' in the FindMyStore
component should be replaced with real data or removed: update the
MasterStoreResponse type to include an address field (e.g., address or
fullAddress), populate that field where the store data is constructed/fetched,
and then render it instead of the hardcoded text (replace the <p> that uses the
hardcoded value to use rest.address or rest.fullAddress); alternatively, if
address is intentionally unavailable, remove the placeholder <p> entirely from
the FindMyStore component.

In `@src/shared/components/myPage/MyStoreItem.tsx`:
- Around line 42-43: The renderImages function is missing a key on the <img>
elements; update renderImages (the urls.map callback) to add a unique, stable
key prop to each <img> (e.g., key={url} and if urls might not be unique use
key={`${url}-${index}`} or use the map index as a fallback) and also include an
appropriate alt attribute for accessibility; target the renderImages function
and the <img> elements in that map callback when making the change.
- Line 57: The component MyStoreItem currently renders a hardcoded review count
"(333)"; replace that static value with the real data by reading the
totalReviewCount field from the MasterStoreResponse prop/state passed into
MyStoreItem (refer to the prop/variable that holds MasterStoreResponse in this
file), and render it inside the span (e.g., format as `({totalReviewCount})`);
ensure you handle missing/undefined values (fallback to 0 or hide) and keep the
existing className "text-sm font-medium text-[var(--gray-5)]" on the span.
- Around line 64-66: The image gallery container is using overflow-y-auto which
prevents horizontal scrolling; update the className on the element that renders
the images (the div wrapping renderImages(store.mainImages) in MyStoreItem.tsx)
to use overflow-x-auto (and optionally keep overflow-y-hidden or remove vertical
overflow) so the flex row of images can scroll horizontally.

In `@src/shared/icons/Bookmark.tsx`:
- Line 13: In the Bookmark.tsx component replace the SVG attribute stroke-width
with the JSX/TypeScript-friendly camelCase strokeWidth on the <circle> element
(and any other SVG elements using hyphenated attributes) so the prop names match
React's expectations; also make the same replacement in Share.tsx where the same
hyphenated SVG attributes appear to eliminate the TypeScript/JSX errors.

In `@src/shared/icons/Share.tsx`:
- Line 13: The SVG circle in Share.tsx uses the kebab-case attribute
stroke-width which React ignores; update the <circle> element (the circle with
cx="12.5" cy="12.5" r="12.25" fill="white" stroke="#DBDDE1" ...) to use the
React prop name strokeWidth instead of stroke-width (same fix applied in
Bookmark.tsx) so the stroke renders correctly and React warnings are eliminated.

In `@src/shared/queries/user/useMasterStores.ts`:
- Around line 4-10: The query in useMasterStores sets staleTime to 24h and
gcTime to 1h which causes the cache to be garbage-collected before the stale
period ends; update useMasterStores so gcTime is at least as large as staleTime
(e.g., set gcTime to 24h or greater) to ensure cached data persists for the full
staleTime and the intended caching behavior works.

In `@src/shared/store/useAuthStore.ts`:
- Around line 36-37: The auth store is initialized with a hardcoded user object
(user: { userId: 1, role: 'OWNER' }) which must be removed; update the initial
state in useAuthStore (the store creator that defines user) to use null instead
of the hardcoded object so new sessions don't start as OWNER and so the persist
middleware writes a neutral auth state; also remove or replace the commented
line (// user: null) so the default is explicitly null.

In `@src/shared/utils/operatingHours.ts`:
- Around line 7-9: Fix the typo opStirng → opString and make the return explicit
and safe: ensure the variable todayOperation (and the surrounding function) uses
an explicit return type of string and when using opString.split(...).find(...)
coerce a fallback with ?? '' so find’s possible undefined becomes an empty
string; reference todayOperation, opString, and dayMapper when making the
change.

---

Outside diff comments:
In `@src/shared/components/myPage/AuthMaster.tsx`:
- Around line 23-29: The handleChange in AuthMaster sets a new preview URL
without revoking the previous one, causing memory leaks; update handleChange to,
before calling URL.createObjectURL(file), check the current previewUrl (state
used by setPreviewUrl) and if present call URL.revokeObjectURL(previewUrl) to
release it, then create and set the new object URL and selected file (and also
ensure any cleanup on unmount revokes the last previewUrl if still set).

In `@src/shared/components/myPage/MyReviewItem.tsx`:
- Line 105: Replace hardcoded restaurant names with the restaurantName field
from the review object: update the JSX in MyReviewItem.tsx to use
review.restaurantName (the MyReviewResponse.restaurantName property) where the
static strings appear — specifically change the <h3> title currently rendering
"엔비햄버거", the two earlier occurrences rendering "빵빵", and the restName props
currently set as '빵빵' to restName={review.restaurantName}; ensure the component
references the existing review variable/prop and that review.restaurantName is
used consistently for display and prop passing.

---

Nitpick comments:
In `@src/pages/add/StoreCheck.tsx`:
- Around line 4-8: Remove all commented-out code throughout StoreCheck.tsx—this
includes the commented import lines (e.g., the svg imports commented above
Header), any commented state/destructuring, handlers, and JSX fragments left as
comments between the import block and the component body (areas noted around the
Header import and the commented blocks spanning the rest of the file). Delete
those commented lines rather than leaving them in place; if history is needed,
rely on Git history. Keep only active imports (like Header) and the live
component code to improve readability and maintainability.

In `@src/pages/myPage/MainMyPage.tsx`:
- Around line 14-15: Call useAuthStore() only once and destructure both user and
logout from that single call instead of calling useAuthStore() twice; locate the
two separate calls to useAuthStore in MainMyPage.tsx and replace them with a
single const { user, logout } = useAuthStore() to avoid duplicate store
subscriptions.
- Around line 30-35: The current onClick calls navigate('/home') before clearing
state; change the order so logout(), await any async logout (if logout returns a
Promise), and call/await queryClient.clear() and setFooterProps(0) first, then
call navigate('/home'); reference the onClick handler and functions navigate,
logout, queryClient.clear, and setFooterProps to locate and update the sequence
and add awaits if those functions are asynchronous.

In `@src/pages/myPage/MasterStoreList.tsx`:
- Around line 7-20: MasterStoreList currently only destructures data from
useMasterStores and lacks loading/error handling; update the component to also
destructure isLoading and isError (and error if available) from useMasterStores,
render a minimal loading state (e.g., a spinner or "Loading..." placeholder)
when isLoading is true, and render an error message or retry UI when isError is
true using the error details if provided; ensure renderStores/MyStoreItem still
handles empty arrays and keep Header/navigation behavior unchanged.

In `@src/pages/myPage/MyReview.tsx`:
- Around line 16-24: The Header is using position: fixed with an inline style
width: 'calc(100% - 32px)' which is viewport-based and can make the header
escape the centered app container on wide screens; change the Header from fixed
to sticky (remove the "fixed top-0" class and use "sticky top-0" or equivalent)
and remove the inline width calc so it inherits the parent container width (you
can keep the maxWidth prop or class for limits); update references in this file
to the Header component and its className/style usage to ensure the header
remains contained and aligned within the parent .relative wrapper.

In `@src/shared/components/detail/DetailHeader.tsx`:
- Around line 80-98: Extract the sharing logic from clipLink in DetailHeader
(the mobile detection, navigator.share call and clipboard fallback) into a
shared utility used by both DetailHeader.tsx and MyStoreItem.tsx to remove
duplication; in that refactor, ensure error logging uses console.error instead
of console.log for the catch branch around navigator.share, and await
navigator.clipboard.writeText (with try/catch) so clipboard write failures are
handled and you can reliably call setIsShareModalOpen(false) /
setIsCopiedModalOpen(true) only after a successful write; reference the existing
symbols clipLink, navigator.share, navigator.clipboard.writeText,
setIsShareModalOpen and setIsCopiedModalOpen and the other copy in
MyStoreItem.tsx when moving the logic.

In `@src/shared/components/myPage/AuthMaster.tsx`:
- Around line 64-68: The two <img> elements render either previewUrl or upload
but are missing alt attributes; update both <img> tags (the one using previewUrl
and the fallback using upload) to include meaningful alt text (e.g., alt
describing the uploaded/preview image or "uploaded file preview") and ensure the
values are properly passed as string literals or from a prop/variable as needed
to satisfy accessibility and linter requirements in AuthMaster.tsx.
- Around line 80-87: The "다음" button lacks disabled styling when isPending is
true; update the button rendered when selectedFile to include a disabled
attribute driven by isPending (or by (!selectedFile || isPending)) and add
conditional classes on the same element (e.g., apply opacity-50 and
cursor-not-allowed when isPending) so users see it is inactive; keep the
existing handVerification early-return logic but ensure the button cannot be
clicked when disabled by binding disabled and toggling visual styles in the JSX
where selectedFile and handVerification are referenced.

In `@src/shared/components/myPage/FindMyStore.tsx`:
- Around line 16-18: The useEffect in the FindMyStore component calls
getRestaurant without listing it in the dependency array, which breaks
react-hooks/exhaustive-deps; fix by either moving the getRestaurant
implementation inside the useEffect so nothing external is referenced, or wrap
getRestaurant in useCallback and add getRestaurant to the useEffect dependency
array (i.e., useEffect(() => { getRestaurant(); }, [getRestaurant])); ensure the
chosen approach preserves any closures/state used by getRestaurant.
- Around line 83-90: SearchInput is rendered but inert because onKeyDown and
onSearch are commented out; either remove the input or wire it up for
client-side filtering: re-enable or implement the event handlers in FindMyStore
by connecting SearchInput's onChange (already using setSearchQuery) to a
debounced filter function that filters the mounted data set (use the searchQuery
state) or call the existing handleKeyDown/onSearch handlers (uncomment and adapt
them) to trigger the same fetch/filter logic; ensure SearchInput's props include
onKeyDown={handleKeyDown} and/or onSearch={onSearch} and that those functions
reference searchQuery and the store list to perform filtering or re-fetching.
- Line 14: Remove the leftover commented-out legacy search logic to clean up the
file: delete the commented declarations and functions including isFirstSearch
(useRef), handleKeyDown, onSearch and any other commented search-related blocks
between the indicated ranges (e.g., the commented lines around 14 and 29-45) so
only active, current search logic remains; ensure imports or references to these
symbols are also removed if they become unused (e.g., remove unused useRef
import).
- Line 97: In FindMyStore.tsx update the inline style expression that sets
maxWidth: find the JSX style prop containing "style={{ maxWidth:
'calc(var(--app-width)* 0.8)' }}" and add spacing around the multiplication
operator so the value becomes "calc(var(--app-width) * 0.8)"; this improves
readability and consistency while keeping the same computation.

In `@src/shared/components/myPage/MyStoreItem.tsx`:
- Around line 21-39: Extract the duplicate share logic from MyStoreItem.tsx's
clipLink (and the matching code in DetailHeader.tsx) into a shared utility
function (e.g., shareOrCopyUrl) that encapsulates mobile detection, Web Share
API usage, clipboard fallback, and returns status/errors so callers can handle
UI state; update MyStoreItem's clipLink to call that util and only manage modal
state, change the catch logging from console.log to console.error, and make
navigator.clipboard.writeText awaited (i.e., await
navigator.clipboard.writeText(...)) so errors propagate to the utility's catch
handling.

In `@src/shared/utils/operatingHours.ts`:
- Line 1: The parameter name in getTodayOperatingHours is misspelled as
opStirng; rename it to opString throughout the function signature, all internal
references, and any callers to remove the typo and keep naming consistent
(update any type annotations or JSDoc referring to opStirng as well).

Copy link

@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: 2

🧹 Nitpick comments (4)
src/shared/queries/user/useMasterStores.ts (1)

4-8: 사장님 가게 목록에 적절한 staleTime 설정을 권장합니다.

현재 staleTime이 없으면 React Query 기본값인 0이 적용되어 컴포넌트 마운트·윈도우 포커스 때마다 불필요한 API 요청이 발생합니다. /ownerRestaurant/my는 자주 바뀌지 않는 데이터이므로 적절한 캐시 유효 시간을 설정하는 것이 좋습니다.

♻️ 제안된 변경
 export const useMasterStores = () =>
   useQuery({
     queryKey: ['masterStores'],
     queryFn: getMasterRestaurant,
+    staleTime: 1000 * 60 * 5, // 5분
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/queries/user/useMasterStores.ts` around lines 4 - 8, The
useMasterStores React Query hook lacks a staleTime, causing refetches on
mount/window focus; update useMasterStores (the exported function that calls
useQuery with queryKey ['masterStores'] and queryFn getMasterRestaurant) to
include an appropriate staleTime (e.g., several minutes) in the options so the
owner restaurant list is cached and not refetched unnecessarily; add the
staleTime property to the useQuery call and consider also setting cacheTime or
refetchOnWindowFocus if further control is needed.
src/shared/utils/operatingHours.ts (1)

1-1: 명시적 반환 타입 어노테이션 추가를 권장합니다.

이전 리뷰에서 지적된 오타(opStirng)와 undefined 폴백 누락은 모두 해결되었습니다. TypeScript가 string을 정확히 추론하므로 런타임 문제는 없지만, 함수 시그니처에 : string을 명시하면 의도를 더 명확히 전달할 수 있습니다.

♻️ 제안된 변경
-export const getTodayOperatingHours = (opString: string) => {
+export const getTodayOperatingHours = (opString: string): string => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/utils/operatingHours.ts` at line 1, The function
getTodayOperatingHours currently relies on TypeScript's inferred return type—add
an explicit return type annotation to its signature (e.g.,
getTodayOperatingHours = (opString: string): string => ...) so the function
intent is clear; locate the getTodayOperatingHours declaration and append the
explicit ": string" return type to the function signature without changing
implementation logic.
src/shared/store/useAuthStore.ts (1)

36-36: 디버그용 주석을 제거하세요.

이전 리뷰에서 지적된 하드코딩된 인증 상태(user: null이 아닌 활성 값) 문제는 해결되었습니다. 다만 개발 편의를 위해 남겨진 // user: { userId: 1, role: 'OWNER' } 주석은 불필요한 코드 노이즈이므로 삭제하는 것이 좋습니다.

♻️ 제안된 변경
-       // user: { userId: 1, role: 'OWNER' },
        user: null,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/store/useAuthStore.ts` at line 36, Remove the leftover debug
comment "// user: { userId: 1, role: 'OWNER' }" from the auth store
initialization in useAuthStore (the initial state where `user` is set), so the
file no longer contains hardcoded/dev-only sample user data; update the initial
state block inside the useAuthStore definition to only include
production-relevant fields.
src/shared/components/myPage/AuthMaster.tsx (1)

80-87: isPending 상태가 버튼에 반영되지 않아 제출 중 사용자 피드백이 없습니다.

handleVerification 내부에서 isPending 시 조기 반환 처리는 되어 있으나, 버튼에 disabled 처리나 로딩 인디케이터가 없어 사용자는 제출이 진행 중인지 알 수 없습니다.

♻️ 리팩터 제안: 버튼에 pending 상태 반영
  {selectedFile && (
    <button
      className="fixed bottom-4 left-[10%] right-[10%] mx-auto h-[48px] w-[80%] max-w-[480px] rounded-[10px] bg-[var(--primary)] font-bold text-white"
+     disabled={isPending}
      onClick={handleVerification}
    >
-     다음
+     {isPending ? '제출 중...' : '다음'}
    </button>
  )}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/components/myPage/AuthMaster.tsx` around lines 80 - 87, The submit
button doesn't reflect the isPending state so users get no feedback during
submission; update the JSX around the conditional-rendered button (the element
currently using selectedFile and onClick={handleVerification}) to disable the
button when isPending is true and show a loading indicator/text (e.g., replace
"다음" with "로딩..." or a spinner) while isPending; ensure handleVerification and
the isPending state (wherever isPending is defined) remain the single source of
truth so clicks are prevented during pending by using the disabled prop and
visually indicate progress.
🤖 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/shared/components/myPage/AuthMaster.tsx`:
- Around line 64-68: The two <img> tags in AuthMaster.tsx (the conditional using
previewUrl and the fallback using upload) are missing alt attributes; update
both <img> elements to include meaningful alt text (e.g., alt describing the
previewed image when previewUrl is present and a descriptive or empty alt for
the decorative/upload placeholder) so screen readers receive appropriate
information, ensuring you reference previewUrl and upload to set
context-specific alt values.
- Around line 38-40: The catch in submitCertificate only logs to console and
loses stack trace; add a component state (e.g., const [submitError,
setSubmitError] = useState<string | null>(null)) and in the catch of
submitCertificate call setSubmitError with a user-friendly message (and any
error.message), and log the error preserving stack (console.error('사업자 등록증 등록
실패:', e)); then render submitError in the component JSX (near the submit button)
so users see feedback and clear or update submitError on retry/success.

---

Nitpick comments:
In `@src/shared/components/myPage/AuthMaster.tsx`:
- Around line 80-87: The submit button doesn't reflect the isPending state so
users get no feedback during submission; update the JSX around the
conditional-rendered button (the element currently using selectedFile and
onClick={handleVerification}) to disable the button when isPending is true and
show a loading indicator/text (e.g., replace "다음" with "로딩..." or a spinner)
while isPending; ensure handleVerification and the isPending state (wherever
isPending is defined) remain the single source of truth so clicks are prevented
during pending by using the disabled prop and visually indicate progress.

In `@src/shared/queries/user/useMasterStores.ts`:
- Around line 4-8: The useMasterStores React Query hook lacks a staleTime,
causing refetches on mount/window focus; update useMasterStores (the exported
function that calls useQuery with queryKey ['masterStores'] and queryFn
getMasterRestaurant) to include an appropriate staleTime (e.g., several minutes)
in the options so the owner restaurant list is cached and not refetched
unnecessarily; add the staleTime property to the useQuery call and consider also
setting cacheTime or refetchOnWindowFocus if further control is needed.

In `@src/shared/store/useAuthStore.ts`:
- Line 36: Remove the leftover debug comment "// user: { userId: 1, role:
'OWNER' }" from the auth store initialization in useAuthStore (the initial state
where `user` is set), so the file no longer contains hardcoded/dev-only sample
user data; update the initial state block inside the useAuthStore definition to
only include production-relevant fields.

In `@src/shared/utils/operatingHours.ts`:
- Line 1: The function getTodayOperatingHours currently relies on TypeScript's
inferred return type—add an explicit return type annotation to its signature
(e.g., getTodayOperatingHours = (opString: string): string => ...) so the
function intent is clear; locate the getTodayOperatingHours declaration and
append the explicit ": string" return type to the function signature without
changing implementation logic.

Copy link
Collaborator

@KingSeokJin KingSeokJin left a comment

Choose a reason for hiding this comment

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

고생하셨습니당

@KingSeokJin KingSeokJin merged commit 70ee2e7 into develop Feb 23, 2026
3 checks passed
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