8000 Feature/dx 3 by guesung · Pull Request #124 · guesung/Web-Memo · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Feature/dx 3 #124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Dec 19, 2024
Merged

Feature/dx 3 #124

merged 20 commits into from
Dec 19, 2024

Conversation

guesung
Copy link
Owner
@guesung guesung commented Dec 19, 2024

PR의 목적

작업 목록

PR 체크리스트

  • CI(type, lint, build)를 체크하였나요?
  • I18n으로 번역을 수행하였나요?
  • 15분 이내에 읽을 수 있는 크기의 PR을 작성하였나요?
  • 코드를 한 번씩 읽어보았나요? 가독성이 괜찮았나요? 추가 설명이 필요한 부분에 주석 및 코멘트를 달았나요?

Summary by CodeRabbit

  • New Features

    • ExtensionBridge 모듈을 통한 메모 리패치 및 사이드 패널 요청 기능 추가.
    • 새로운 table 구조를 사용하여 Supabase 클라이언트의 데이터베이스 스키마 업데이트.
  • Bug Fixes

    • ChromeSyncStorage를 사용하여 저장소 접근 방식 변경으로 인한 오류 수정.
  • Documentation

    • ESLint 구성 파일에 새로운 플러그인 추가 및 가독성 향상.
  • Chores

    • Vite 구성 파일에서 vite-plugin-svgr 플러그인 제거.
    • turbo.json에서 캐시 및 지속성 속성 제거.
  • Refactor

    • 여러 컴포넌트에서 StorageChromeSyncStorage로 변경하여 저장소 처리 방식 개선.

Copy link
coderabbitai bot commented Dec 19, 2024

개요

워크스루

이 풀 리퀘스트는 주로 CodeRabbit Inc.의 웹 메모 확장 프로그램의 모듈화와 리팩토링에 중점을 둡니다. 주요 변경 사항은 ExtensionBridge 모듈 도입, 스토리지 관리 개선, 메시징 시스템 재구성, 그리고 Turborepo 통합을 포함합니다. 이러한 변경은 코드의 모듈성, 유지보수성, 그리고 개발 워크플로우를 향상시키는 것을 목표로 합니다.

변경 사항

파일/디렉토리 변경 요약
.eslintrc "turbo" 플러그인 추가 및 포맷팅 개선
.github/workflows/cicd-web.yml Node.js 환경 설정 및 배포 워크플로우 업데이트
.gitignore .turbo 항목 추가
.nvmrc Node.js 버전 20에서 v20.17.0으로 업데이트
chrome-extension/lib/background/index.ts ExtensionBridgeChromeSyncStorage 도입
package.json Turbo 관련 스크립트 및 의존성 업데이트
packages/shared 새로운 모듈 chrome-storage, extension-bridge 추가
packages/shared/src/constants/Supabase.ts SUPABASE 상수 구조 변경
packages/shared/src/hooks/extension/index.ts useOptionQuery 함수 내보내기 제거
packages/shared/src/utils/extension/Prompt.ts 스토리지 접근 방식 변경
packages/web/src/app/[lng]/memos/components/MemoCardFooter/MemoOption.tsx 메모 삭제 후 리패치 호출 방식 변경
turbo.json readydev 작업에서 캐시 및 지속성 속성 제거
update_version.sh 한국어로 주석 번역 및 버전 업데이트 기능 개선

시퀀스 다이어그램

sequenceDiagram
    participant Client
    participant ExtensionBridge
    participant ChromeSyncStorage
    participant Runtime

    Client->>ExtensionBridge: 메시지 요청
    ExtensionBridge->>Runtime: 런타임 메시지 전송
    Runtime->>ChromeSyncStorage: 스토리지 작업
    ChromeSyncStorage-->>Runtime: 데이터 응답
    Runtime-->>ExtensionBridge: 메시지 응답
    ExtensionBridge-->>Client: 최종 응답
Loading

관련 가능성 있는 PR

시 (토끼의 관점)

🐰 코드의 숲을 달리며
모듈들은 춤을 추네
브릿지와 스토리지
새로운 길을 열어
확장의 세계가 빛나네! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 12

🔭 Outside diff range comments (4)
packages/ui/build.mjs (1)

Line range hint 48-49: CSS 파일 복사 작업에 대한 오류 처리 개선이 필요합니다.

CSS 파일 복사 과정에서 파일이 존재하지 않거나 권한 문제가 발생할 수 있습니다. 적절한 오류 처리를 추가하는 것이 좋겠습니다.

다음과 같이 개선하는 것을 제안합니다:

-    fs.copyFileSync(resolve('global.css'), resolve('dist', 'global.css'));
+    try {
+      fs.copyFileSync(resolve('global.css'), resolve('dist', 'global.css'));
+    } catch (error) {
+      console.error('❌ global.css 파일 복사 중 오류 발생:', error);
+      throw error;
+    }
packages/shared/src/utils/extension/Supabase.ts (1)

Line range hint 28-41: 쿠키 관련 오류 처리 개선 필요

쿠키 관련 오류 메시지가 너무 일반적이며, 사용자에게 더 명확한 안내가 필요합니다.

다음과 같이 수정하는 것을 제안합니다:

    const accessTokenFromWeb = await chrome.cookies.get({
      name: COOKIE_KEY.accessToken,
      url: CONFIG.webUrl,
    });
    const refreshTokenCookieFromWeb = await chrome.cookies.get({
      name: COOKIE_KEY.refreshToken,
      url: CONFIG.webUrl,
    });

-    if (!accessTokenFromWeb || !refreshTokenCookieFromWeb) throw new Error('로그인을 먼저 해주세요.');
+    if (!accessTokenFromWeb || !refreshTokenCookieFromWeb) {
+      throw new Error('웹사이트에서 로그인이 필요합니다. 로그인 후 다시 시도해주세요.');
+    }
packages/web/src/modules/guide/useGuide.ts (1)

Line range hint 34-38: setInterval 사용에 대한 개선이 필요합니다

사이드 패널 상태를 폴링하기 위해 setInterval을 사용하는 것은 리소스 효율성 측면에서 최적이 아닙니다.

다음과 같은 개선을 제안합니다:

- const interval = setInterval(() => {
-   ExtensionBridge.requestGetSidePanelOpen(() => {
-     if (driverObj.getActiveIndex() !== 0) return;
-     driverObj.moveNext();
-   });
- }, 500);
- driverObj.destroy = () => clearInterval(interval);
+ const checkSidePanel = () => {
+   ExtensionBridge.requestGetSidePanelOpen(() => {
+     if (driverObj.getActiveIndex() !== 0) return;
+     driverObj.moveNext();
+   });
+ };
+ checkSidePanel();
+ const interval = setInterval(checkSidePanel, 2000);
+ driverObj.destroy = () => clearInterval(interval);
chrome-extension/lib/background/index.ts (1)

Line range hint 72-82: OpenAI 모델명이 잘못되었습니다

gpt-4o-mini는 존재하지 않는 모델명입니다. 올바른 모델명을 사용해주세요.

다음과 같이 수정해주세요:

    const stream = await openai.chat.completions.create({
-     model: 'gpt-4o-mini',
+     model: 'gpt-4',  // 또는 'gpt-3.5-turbo'
      messages: [
        { role: 'system', content: prompt },
        { role: 'user', content: pageContent },
      ],
      stream: true,
    });
🧹 Nitpick comments (14)
packages/ui/build.mjs (1)

Line range hint 16-37: 빌드 설정의 환경 변수 처리가 필요할 수 있습니다.

현재 NODE_ENV만 하드코딩되어 있습니다. shared 패키지처럼 .env 파일을 통한 환경 변수 처리를 고려해보세요.

pages/side-panel/src/components/MemoHeader.tsx (1)

Line range hint 28-37: 접근성 관련 한글 레이블이 국제화되어야 합니다.

aria-label="새 탭 열기"가 하드코딩되어 있습니다. 다른 텍스트처럼 I18n을 사용하여 국제화해야 합니다.

다음과 같이 수정을 제안합니다:

          role="button"
          tabIndex={0}
-         aria-label="새 탭 열기"
+         aria-label={I18n.get('openInNewTab')}
           => e.key === 'Enter' && handleMemoClick()}
packages/shared/src/modules/chrome-storage/ChromeSyncStorage.ts (2)

Line range hint 5-13: 에러 처리 개선이 필요합니다.

get 메서드의 에러 처리를 더 구체적으로 개선하면 좋을 것 같습니다:

  1. 에러 타입 구체화
  2. 디버깅을 위한 원본 에러 정보 포함

다음과 같이 개선을 제안드립니다:

  static async get<T>(key: StorageKeyType): Promise<T> {
    try {
      const storage = await chrome.storage.sync.get(key);
      return storage[key];
    } catch (error) {
-     throw new Error(I18n.get('error_get_storage'));
+     throw new Error(`${I18n.get('error_get_storage')}: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

15-17: 타입 안전성 개선이 필요합니다.

set 메서드의 value 매개변수 타입을 제네릭을 통해 더 구체적으로 지정하면 좋을 것 같습니다.

- static set(key: StorageKeyType, value: unknown) {
+ static set<T>(key: StorageKeyType, value: T) {
    return chrome.storage.sync.set({ [key]: value });
  }
packages/shared/src/utils/extension/Prompt.ts (1)

11-12: 스토리지 접근 방식이 개선되었습니다.

ChromeSyncStorage.get을 사용한 데이터 접근과 기본값 처리가 잘 구현되어 있습니다. 다만, 아래 사항들을 고려해보시면 좋겠습니다:

  1. 스토리지 접근 실패 시의 에러 처리
  2. 프롬프트 데이터의 유효성 검증
-  const youtubePrompts = (await ChromeSyncStorage.get(STORAGE_KEYS.youtubePrompts)) ?? DEFAULT_PROMPTS.youtube;
-  const webPrompts = (await ChromeSyncStorage.get(STORAGE_KEYS.webPrompts)) ?? DEFAULT_PROMPTS.web;
+  const youtubePrompts = await ChromeSyncStorage.get(STORAGE_KEYS.youtubePrompts).catch(() => DEFAULT_PROMPTS.youtube);
+  const webPrompts = await ChromeSyncStorage.get(STORAGE_KEYS.webPrompts).catch(() => DEFAULT_PROMPTS.web);
+
+  if (!isValidPrompt(youtubePrompts) || !isValidPrompt(webPrompts)) {
+    throw new Error('Invalid prompt data');
+  }
pages/side-panel/src/SidePanel.tsx (1)

1-2: 아키텍처 개선이 잘 이루어졌습니다!

ExtensionBridge를 통한 모듈화가 잘 구현되었습니다. 다른 컴포넌트들과의 일관성도 잘 유지되어 있습니다.

추가적인 개선사항으로 다음을 고려해보세요:

  • ExtensionBridge 사용에 대한 문서화
  • 에러 처리 로직 추가

Also applies to: 17-17

pages/side-panel/src/hooks/useSummary.ts (2)

Line range hint 19-24: 오류 메시지 상세화 및 카테고리 처리 개선 필요

현재 오류 메시지가 너무 일반적이며, 카테고리 상태 관리가 개선될 수 있습니다.

다음과 같이 수정하는 것을 제안합니다:

      const { content, category } = await ExtensionBridge.requestPageContent();
      pageContent = content;
-      currentCategory = category;
+      currentCategory = category || 'others';
      setCategory(category);
    } catch (e) {
-      setErrorMessage(I18n.get('error_get_page_content'));
+      setErrorMessage(I18n.get('error_get_page_content') + `: ${e.message}`);
      return;
    }

Line range hint 29-33: 요약 작업 진행 상태 표시 개선 필요

현재 구현은 요약 작업의 진행 상태를 사용자에게 충분히 알려주지 않습니다.

진행 상태를 더 자세히 표시하도록 개선하는 것을 제안합니다:

      await Runtime.connect(
        BRIDGE_MESSAGE_TYPES.GET_SUMMARY,
        { pageContent, category: currentCategory },
-        (message: string) => message && setSummary(prev => prev + message),
+        (message: string) => {
+          if (message) {
+            setSummary(prev => prev + message);
+          }
+        },
.github/workflows/cicd-web.yml (1)

16-18: Node.js 설정이 개선되었습니다!

.nvmrc 파일을 통한 Node.js 버전 관리와 pnpm 캐시 설정이 추가된 것은 좋은 개선사항입니다. 다만, 캐시 키를 더욱 세분화하여 빌드 성능을 개선할 수 있습니다.

 with:
   node-version-file: '.nvmrc'
-  cache: pnpm
+  cache: 'pnpm'
+  cache-dependency-path: '**/pnpm-lock.yaml'
packages/web/src/modules/guide/useGuide.ts (1)

72-78: 가이드 초기화 로직 개선이 필요합니다

새로운 useEffect에서 의존성 배열이 비어있어 컴포넌트 마운트 시에만 실행됩니다. 하지만 manifest 로딩 상태를 고려하지 않고 있습니다.

다음과 같은 개선을 제안합니다:

useEffect(() => {
- if (!checkLocalStorageTrue('guide')) {
+ if (manifest && !checkLocalStorageTrue('guide')) {
    ExtensionBridge.requestGetSidePanelOpen(() => {
      setLocalStorageTrue('guide');
    });
  }
- }, []);
+ }, [manifest]);
packages/shared/src/utils/Supabase.ts (2)

12-27: MemoService의 코드 중복을 줄일 수 있습니다

테이블 이름과 기본 CRUD 작업이 반복되고 있습니다. 이를 추상화하여 재사용 가능한 기본 클래스로 만들 수 있습니다.

다음과 같은 기본 서비스 클래스 구현을 제안합니다:

abstract class BaseService<T extends { id: string }> {
  protected abstract tableName: string;
  
  constructor(protected supabaseClient: MemoSupabaseClient) {}

  insert = async (request: T) =>
    this.supabaseClient.from(this.tableName).insert(request).select();

  upsert = async (request: T[]) =>
    this.supabaseClient.from(this.tableName).upsert(request).select();

  delete = async (id: string) =>
    this.supabaseClient.from(this.tableName).delete().eq('id', id).select();
}

class MemoService extends BaseService<MemoTable> {
  protected tableName = SUPABASE.table.memo;
}

38-50: CategoryService도 동일한 패턴이 반복됩니다

MemoService와 마찬가지로 CategoryService도 동일한 CRUD 패턴이 반복됩니다. 위에서 제안한 BaseService를 활용할 수 있습니다.

class CategoryService extends BaseService<CategoryTable> {
  protected tableName = SUPABASE.table.category;
}
chrome-extension/lib/background/index.ts (2)

13-15: 스토리지 초기화 로직 개선이 필요합니다

현재 각각의 스토리지 값을 개별적으로 가져오고 있습니다. 성능 향상을 위해 한 번의 호출로 모든 값을 가져오는 것이 좋습니다.

다음과 같이 수정하는 것을 추천드립니다:

-  const language = await ChromeSyncStorage.get(STORAGE_KEYS.language);
-  const youtubePrompts = await ChromeSyncStorage.get(STORAGE_KEYS.youtubePrompts);
-  const webPrompts = await ChromeSyncStorage.get(STORAGE_KEYS.webPrompts);
+  const { language, youtubePrompts, webPrompts } = await ChromeSyncStorage.get([
+    STORAGE_KEYS.language,
+    STORAGE_KEYS.youtubePrompts,
+    STORAGE_KEYS.webPrompts
+  ]);

93-97: 탭 이벤트 핸들러 중복 로직

onActivatedonUpdated 이벤트에서 동일한 로직이 중복되어 있습니다.

다음과 같이 공통 함수로 추출하는 것을 추천드립니다:

+ const handleTabChange = async () => {
+   await ExtensionBridge.requestUpdateSidePanel();
+ };
+
- chrome.tabs.onActivated.addListener(async () => {
-   ExtensionBridge.requestUpdateSidePanel();
- });
+ chrome.tabs.onActivated.addListener(handleTabChange);
- chrome.tabs.onUpdated.addListener(async () => {
-   ExtensionBridge.requestUpdateSidePanel();
- });
+ chrome.tabs.onUpdated.addListener(handleTabChange);
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8072420 and ffecc24.

⛔ Files ignored due to path filters (5)
  • pages/side-panel/public/svgs/heart.svg is excluded by !**/*.svg
  • pages/side-panel/public/svgs/option.svg is excluded by !**/*.svg
  • pages/side-panel/public/svgs/refresh.svg is excluded by !**/*.svg
  • pages/side-panel/public/svgs/top_right_arrow.svg is excluded by !**/*.svg
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (58)
  • .eslintrc (1 hunks)
  • .github/workflows/cicd-web.yml (1 hunks)
  • .gitignore (1 hunks)
  • .nvmrc (1 hunks)
  • chrome-extension/lib/background/index.ts (3 hunks)
  • package.json (3 hunks)
  • packages/shared/build.mjs (3 hunks)
  • packages/shared/package.json (1 hunks)
  • packages/shared/src/constants/Supabase.ts (1 hunks)
  • packages/shared/src/constants/index.ts (0 hunks)
  • packages/shared/src/hooks/extension/index.ts (0 hunks)
  • packages/shared/src/hooks/extension/useOptionQuery.ts (0 hunks)
  • packages/shared/src/modules/chrome-storage/ChromeSyncStorage.ts (2 hunks)
  • packages/shared/src/modules/chrome-storage/index.ts (1 hunks)
  • packages/shared/src/modules/chrome-storage/type.ts (1 hunks)
  • packages/shared/src/modules/extension-bridge/ExtensionBridge.ts (1 hunks)
  • packages/shared/src/modules/extension-bridge/constant.ts (1 hunks)
  • packages/shared/src/modules/extension-bridge/index.ts (1 hunks)
  • packages/shared/src/modules/extension-bridge/type.ts (1 hunks)
  • packages/shared/src/types/index.ts (0 hunks)
  • packages/shared/src/utils/Supabase.ts (2 hunks)
  • packages/shared/src/utils/extension/Memo.ts (1 hunks)
  • packages/shared/src/utils/extension/Prompt.ts (1 hunks)
  • packages/shared/src/utils/extension/Supabase.ts (1 hunks)
  • packages/shared/src/utils/extension/bridge/getExtensionManifest.ts (0 hunks)
  • packages/shared/src/utils/extension/bridge/getSidePanelOpen.ts (0 hunks)
  • packages/shared/src/utils/extension/bridge/getSummary.ts (0 hunks)
  • packages/shared/src/utils/extension/bridge/getTabs.ts (0 hunks)
  • packages/shared/src/utils/extension/bridge/index.ts (0 hunks)
  • packages/shared/src/utils/extension/bridge/observeMemoPage.ts (0 hunks)
  • packages/shared/src/utils/extension/bridge/openSidePanel.ts (0 hunks)
  • packages/shared/src/utils/extension/bridge/pageContent.ts (0 hunks)
  • packages/shared/src/utils/extension/bridge/refetchTheMemos.ts (0 hunks)
  • packages/shared/src/utils/extension/bridge/type.ts (0 hunks)
  • packages/shared/src/utils/extension/bridge/updateSidePanel.ts (0 hunks)
  • packages/shared/src/utils/extension/index.ts (0 hunks)
  • packages/shared/src/utils/extension/module/Runtime.ts (1 hunks)
  • packages/shared/src/utils/extension/module/Tab.ts (1 hunks)
  • packages/shared/src/utils/extension/module/index.ts (0 hunks)
  • packages/shared/src/utils/web/Supabase.ts (1 hunks)
  • packages/ui/build.mjs (3 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/web/src/app/[lng]/memos/components/MemoCardFooter/MemoOption.tsx (2 hunks)
  • packages/web/src/hooks/useGetExtensionManifest.ts (1 hunks)
  • packages/web/src/modules/guide/useGuide.ts (3 hunks)
  • packages/web/src/modules/supabase/util.server.ts (1 hunks)
  • pages/content-ui/src/components/OpenSidePanelButton.tsx (1 hunks)
  • pages/content-ui/src/index.tsx (1 hunks)
  • pages/options/src/components/Option.tsx (3 hunks)
  • pages/side-panel/src/SidePanel.tsx (2 hunks)
  • pages/side-panel/src/components/MemoForm.tsx (2 hunks)
  • pages/side-panel/src/components/MemoHeader.tsx (2 hunks)
  • pages/side-panel/src/components/ToggleTheme.tsx (2 hunks)
  • pages/side-panel/src/hooks/useSummary.ts (3 hunks)
  • pages/side-panel/vite-env.d.ts (0 hunks)
  • pages/side-panel/vite.config.mts (0 hunks)
  • turbo.json (1 hunks)
  • update_version.sh (1 hunks)
💤 Files with no reviewable changes (19)
  • packages/shared/src/utils/extension/index.ts
  • packages/shared/src/hooks/extension/index.ts
  • packages/shared/src/constants/index.ts
  • packages/shared/src/utils/extension/module/index.ts
  • packages/shared/src/utils/extension/bridge/getSummary.ts
  • pages/side-panel/vite-env.d.ts
  • packages/shared/src/types/index.ts
  • pages/side-panel/vite.config.mts
  • packages/shared/src/utils/extension/bridge/type.ts
  • packages/shared/src/hooks/extension/useOptionQuery.ts
  • packages/shared/src/utils/extension/bridge/observeMemoPage.ts
  • packages/shared/src/utils/extension/bridge/getTabs.ts
  • packages/shared/src/utils/extension/bridge/openSidePanel.ts
  • packages/shared/src/utils/extension/bridge/updateSidePanel.ts
  • packages/shared/src/utils/extension/bridge/getSidePanelOpen.ts
  • packages/shared/src/utils/extension/bridge/index.ts
  • packages/shared/src/utils/extension/bridge/getExtensionManifest.ts
  • packages/shared/src/utils/extension/bridge/refetchTheMemos.ts
  • packages/shared/src/utils/extension/bridge/pageContent.ts
✅ Files skipped from review due to trivial changes (5)
  • .nvmrc
  • packages/shared/src/modules/chrome-storage/type.ts
  • .gitignore
  • packages/shared/src/modules/chrome-storage/index.ts
  • packages/shared/src/modules/extension-bridge/index.ts
🧰 Additional context used
🪛 Biome (1.9.4)
packages/shared/src/modules/extension-bridge/ExtensionBridge.ts

[error] 7-108: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)


[error] 51-51: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 57-57: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 58-58: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 67-67: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 68-68: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (28)
packages/shared/build.mjs (2)

1-1: import 구문이 재구성되었습니다.

import 구문이 논리적으로 재구성되었으며, promisify가 추가되었습니다. 이는 비동기 exec 호출을 위한 적절한 변경사항입니다.

Also applies to: 7-7


34-35: 빌드 성능 모니터링이 추가되었습니다.

빌드 프로세스의 성능을 측정하기 위한 타이밍 로직이 추가되었습니다. 이는 빌드 최적화와 성능 모니터링에 도움이 될 것입니다.

성능 측정 방식이 packages/ui/build.mjs와 일관성 있게 구현되어 있습니다.

Also applies to: 46-48

packages/ui/build.mjs (2)

2-5: import 구문이 일관성 있게 재구성되었습니다.

shared 패키지와 동일한 패턴으로 import 구문이 재구성되었으며, 이는 코드베이스 전반의 일관성을 향상시킵니다.

Also applies to: 8-8


40-41: 빌드 성능 모니터링이 일관되게 구현되었습니다.

shared 패키지와 동일한 방식으로 빌드 성능 모니터링이 구현되었습니다. 이러한 일관성은 빌드 프로세스 전반의 성능을 비교하고 분석하는 데 도움이 됩니다.

Also applies to: 55-57

pages/side-panel/src/components/MemoHeader.tsx (2)

3-4: Import 구문이 적절하게 리팩토링되었습니다.

ExtensionBridge로의 마이그레이션이 올바르게 수행되었으며, 더 이상 사용되지 않는 responseUpdateSidePanel import가 제거되었습니다.


19-21: ExtensionBridge 사용 8000 올바르게 구현되었는지 확인이 필요합니다.

ExtensionBridge로의 마이그레이션이 일관되게 이루어졌는지 확인이 필요합니다.

다음 스크립트를 실행하여 ExtensionBridge 구현의 일관성을 확인하세요:

✅ Verification successful

ExtensionBridge가 올바르게 구현되어 있음을 확인했습니다

ExtensionBridge의 구현을 검토한 결과:

  • responseUpdateSidePanelrequestUpdateSidePanel 메서드가 일관되게 구현되어 있습니다
  • 모든 메시지 타입이 적절하게 처리되고 있습니다
  • MemoHeader.tsx의 ExtensionBridge 사용이 올바른 패턴을 따르고 있습니다

코드베이스 전반에 걸쳐 ExtensionBridge의 사용이 일관성 있게 구현되어 있어 추가적인 수정이 필요하지 않습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: ExtensionBridge 사용의 일관성 검증

# ExtensionBridge 사용 패턴 확인
echo "Checking ExtensionBridge usage patterns..."
rg -A 2 "ExtensionBridge\." --type ts --type tsx

# 이전 responseUpdateSidePanel 사용이 남아있는지 확인
echo "Checking for remaining old patterns..."
rg "responseUpdateSidePanel" --type ts --type tsx

Length of output: 338


Script:

#!/bin/bash
# Let's try without file type specifications since tsx is not recognized
echo "Checking ExtensionBridge usage patterns..."
rg -A 2 "ExtensionBridge\."

echo -e "\nChecking for responseUpdateSidePanel usage..."
rg "responseUpdateSidePanel"

echo -e "\nListing all files containing ExtensionBridge..."
fd . -t f -e ts -e tsx | xargs rg "ExtensionBridge" || true

Length of output: 6811


Script:

#!/bin/bash
# Let's check the ExtensionBridge implementation to understand the pattern
echo "Checking ExtensionBridge implementation..."
cat packages/shared/src/modules/extension-bridge/ExtensionBridge.ts

echo -e "\nChecking message types..."
cat packages/shared/src/modules/extension-bridge/types.ts || true

Length of output: 3997

packages/shared/src/constants/Supabase.ts (1)

5-8: 새로운 table 구조가 추가되었습니다.
기존 schemaMemo와 schemaCategory를 일괄 교체하여 재정의한 것으로 보입니다. 이로 인해 기존 코드에서 해당 속성을 참조하던 부분들이 모두 ‘SUPABASE.table.memo/category’로 수정되었는지 확인이 필요합니다.

다음 스크립트를 활용해 확인해 보세요:

✅ Verification successful

테이블 구조 변경이 올바르게 적용되었습니다

검증 결과:

  • 기존 schemaMemoschemaCategory 참조가 코드베이스에서 완전히 제거되었습니다.
  • 모든 관련 코드가 새로운 SUPABASE.table.memoSUPABASE.table.category 구조를 사용하도록 올바르게 업데이트되었습니다.
  • 타입 정의와 실제 사용 코드가 일관되게 새로운 테이블 구조를 따르고 있습니다.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 변경된 table 구조에 맞춰 schemaMemo, schemaCategory 사용이 남아있는지 검색
rg 'schemaMemo|schemaCategory' -A 3

Length of output: 37


Script:

#!/bin/bash
# Search for any references to SUPABASE.table.memo or SUPABASE.table.category
rg "SUPABASE\.table\.(memo|category)" -A 3

# Also search for direct string references to 'memo' or 'category' in TypeScript/JavaScript files
fd "\.(ts|js|tsx|jsx)$" --exec rg -l "'memo'|'category'" {}

Length of output: 4481


Script:

#!/bin/bash
# Let's check if there are any remaining references to old schema names
rg "schema(Memo|Category)" --type ts

# Also check the specific files that contain 'memo' or 'category' strings for any old patterns
cat ./packages/shared/src/types/supabaseCustom.ts ./packages/shared/src/types/supabase.ts

Length of output: 6733

packages/shared/src/modules/extension-bridge/type.ts (2)

1-1: 새로 도입된 BRIDGE_MESSAGE_TYPES를 잘 가져오고 있습니다.
import 경로가 명확해서 문제 없어 보입니다.


5-8: BridgeRequest 인터페이스로 타입 안정성을 높였습니다.
필요 시 확장 가능성이 높고 메시지 구조를 한눈에 파악하기 쉽습니다.

packages/shared/src/utils/extension/Memo.ts (1)

2-2: import 경로가 명확하게 수정되었습니다.
상대 경로가 불명확했던 문제를 해결하고, 모듈 구조가 직관적으로 보입니다.

pages/content-ui/src/components/OpenSidePanelButton.tsx (1)

5-9: 버튼 구현이 잘 되었습니다!

접근성과 사용자 경험을 고려한 버튼 구현이 잘 되었습니다. 타입 지정과 스타일링이 적절합니다.

pages/content-ui/src/index.tsx (1)

13-15: 프로덕션 환경 체크 구현이 잘 되었습니다

개발 환경에서만 페이지 콘텐츠 응답을 처리하도록 구현된 것이 적절합니다.

packages/web/src/hooks/useGetExtensionManifest.ts (1)

2-2: ExtensionBridge로의 마이그레이션이 올바르게 구현되었습니다.

기존의 직접 호출 방식에서 ExtensionBridge를 통한 중앙화된 통신 방식으로의 전환이 잘 이루어졌습니다. 에러 처리도 적절히 유지되었습니다.

Also applies to: 10-10

packages/shared/src/utils/extension/module/Tab.ts (1)

1-1: 타입 변경이 적절하게 이루어졌습니다.

ExtensionBridge 모듈을 통한 메시지 타입 중앙화가 잘 반영되었습니다. 기존의 에러 처리도 잘 유지되어 있습니다.

Also applies to: 9-9

packages/shared/src/utils/web/Supabase.ts (1)

20-20: 스키마 구조 변경 검증이 필요합니다.

SUPABASE.table.memo로의 스키마 경로 변경이 다른 파일들과 일관성이 있는지 확인이 필요합니다.

✅ Verification successful

Let me check the SUPABASE constant definition to ensure complete verification.


스키마 구조 변경이 일관되게 적용되었습니다

SUPABASE.table.memo 구조로의 변경이 전체 코드베이스에서 일관되게 적용되었음을 확인했습니다. 이전 스키마 참조(SUPABASE.schema)는 발견되지 않았으며, 모든 파일에서 새로운 table 구조를 올바르게 사용하고 있습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify consistent usage of new SUPABASE.table.memo structure

# Search for any remaining old schema references
rg "SUPABASE\.schema" 

# Search for new table structure usage
rg "SUPABASE\.table\.(memo|category)"

Length of output: 1722


Script:

#!/bin/bash
# Search for SUPABASE constant definition
ast-grep --pattern 'const SUPABASE = $_'

Length of output: 645

packages/shared/src/utils/extension/Prompt.ts (1)

1-3: 스토리지 모듈 변경이 적절합니다.

ChromeSyncStorage로의 마이그레이션이 잘 이루어졌으며, 필요한 상수들도 올바르게 임포트되었습니다.

.eslintrc (1)

23-32: 플러그인 구성이 잘 되어있습니다!

플러그인 목록이 알파벳 순서로 잘 정렬되어 있으며, turbo 플러그인의 추가가 적절합니다.

turbo.json (1)

4-8: ready 태스크의 캐시 설정 제거에 대한 확인이 필요합니다.

ready 태스크에서 cache 속성이 제거되었습니다. 이는 빌드 성능에 영향을 미칠 수 있습니다. 의도적인 변경인지 확인해 주시기 바랍니다.

packages/shared/src/utils/extension/module/Runtime.ts (2)

26-37: 외부 메시지 처리 로직의 일관성이 향상되었습니다.

내부 메시지 처리와 동일한 패턴을 사용하여 코드의 일관성이 개선되었습니다. 타입 안전성도 강화되었습니다.


11-22: 메시지 핸들링 로직이 개선되었습니다.

콜백 함수의 타입 안전성이 향상되었고, 응답 처리가 더 명확해졌습니다. 하지만 메시지 타입 처리에 대한 추가 검증이 필요할 수 있습니다.

✅ Verification successful

메시지 타입 처리가 정상적으로 구현되어 있음을 확인했습니다.

BRIDGE_MESSAGE_TYPE이 다음과 같이 올바르게 구현되어 있습니다:

  • constant.ts에서 메시지 타입 상수가 정의되어 있음
  • type.ts에서 타입 정의가 올바르게 되어 있음
  • ExtensionBridge.tsRuntime.ts에서 일관된 방식으로 메시지 타입을 사용하고 있음
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# BRIDGE_MESSAGE_TYPE 상수가 올바르게 사용되는지 확인
ast-grep --pattern 'BRIDGE_MESSAGE_TYPE.$_' 

Length of output: 45


Script:

#!/bin/bash
# Check the definition and usage of BRIDGE_MESSAGE_TYPE
rg "BRIDGE_MESSAGE_TYPE" -A 2

# Check message type handling in Runtime.ts
rg "type: " --type ts -A 2

Length of output: 14257

packages/web/src/modules/supabase/util.server.ts (1)

26-26: 스키마 참조 방식이 개선되었습니다.

SUPABASE.table.memo로의 변경은 데이터베이스 스키마 참조의 일관성을 높입니다. 다른 파일들에서도 동일한 방식으로 변경되었는지 확인이 필요합니다.

✅ Verification successful

스키마 참조가 일관되게 적용되었음을 확인했습니다.

코드베이스 전반에 걸쳐 SUPABASE.table.memoSUPABASE.table.category를 사용하는 일관된 패턴이 확인되었습니다. 모든 관련 파일에서 동일한 방식으로 스키마를 참조하고 있어 리팩토링이 성공적으로 완료되었습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 스키마 참조 방식의 일관성 확인
rg -A 1 "SUPABASE\.(schema|table)\."

Length of output: 2332

packages/shared/package.json (2)

54-60: 새로운 모듈 내보내기가 추가되었습니다

chrome-storageextension-bridge 모듈에 대한 내보내기가 적절하게 구성되어 있습니다. 타입 정의와 실제 구현 파일의 경로가 올바르게 매핑되어 있습니다.


65-65: 빌드 스크립트가 단순화되었습니다

ready 스크립트에서 rm -rf dist 명령이 제거되었습니다. 이 변경이 의도적인지 확인이 필요합니다. 빌드 전에 dist 디렉토리를 정리하지 않으면 이전 빌드 아티팩트가 남아있을 수 있습니다.

✅ Verification successful

clean 스크립트가 별도로 존재합니다

package.jsonclean 스크립트가 rimraf ./dist로 정의되어 있어 빌드 전 정리 작업이 가능합니다. 빌드 전에 clean 스크립트를 실행하는 것이 권장되지만, 이는 개발자의 선택사항입니다. 현재 구조에서는 다음과 같이 사용할 수 있습니다:

  • 빌드 전 정리가 필요한 경우: npm run clean && npm run ready
  • 증분 빌드가 필요한 경우: npm run ready
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if build.mjs handles dist directory cleanup

# Look for cleanup logic in build script
rg -A 5 "dist" build.mjs

Length of output: 74


Script:

#!/bin/bash
# Find build.mjs file in the repository
fd build.mjs

# Check the content of package.json to understand the build script location
cat packages/shared/package.json

Length of output: 2369


Script:

#!/bin/bash
# Check the content of build.mjs file
cat packages/shared/build.mjs

Length of output: 1492

packages/ui/package.json (1)

14-14: 빌드 프로세스 검증 필요

rimraf dist 명령어가 제거되어 이전 빌드 아티팩트가 남아있을 수 있습니다. 빌드 프로세스가 정상적으로 작동하는지 확인이 필요합니다.

✅ Verification successful

빌드 프로세스가 안전하게 구현되어 있습니다

build.mjsesbuild를 사용하여 dist 디렉토리에 새로운 파일들을 생성하며, 이 과정에서 이전 빌드의 아티팩트는 자동으로 덮어쓰기됩니다. 또한 clean 스크립트가 별도로 존재하여 필요할 때 수동으로 정리가 가능합니다.

  • esbuildoutdir: 'dist' 설정으로 출력 디렉토리를 깨끗하게 관리
  • 필요시 npm run clean 명령어로 수동 정리 가능
  • 타입스크립트 선언 파일도 dist 디렉토리에 새로 생성
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: 빌드 프로세스 검증을 위한 스크립트

# package.json에서 clean 스크립트가 사용되는 위치 확인
rg "npm.*clean" --type ts --type js

Length of output: 37


Script:

#!/bin/bash
# Check build.mjs content to understand the build process
cat packages/ui/build.mjs

# Check if there are any other cleanup mechanisms in package.json
cat packages/ui/package.json

# Look for any other build-related scripts in the repository
fd "build.*\.m?js$"

Length of output: 4235

package.json (2)

54-54: 새로운 의존성 버전 호환성 확인

eslint-config-turbo 의존성이 추가되었습니다. 프로젝트의 다른 ESLint 설정들과의 호환성 확인이 필요합니다.

다음 스크립트로 ESLint 설정 충돌을 확인해주세요:

✅ Verification successful

eslint-config-turbo 의존성 추가는 안전합니다

현재 ESLint 설정에서 이미 turbo 플러그인을 사용하고 있으며, 기존 ESLint 설정과 충돌하는 부분이 없습니다. 설정 파일에서 다음 사항을 확인했습니다:

  • plugins 배열에 turbo가 이미 포함되어 있음
  • 다른 ESLint 플러그인 및 설정들과 호환되는 구성
  • 기존 규칙들과 충돌하는 turbo 관련 규칙이 없음
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# ESLint 설정 파일들 검사
echo "ESLint 설정 파일 목록:"
fd -e .eslintrc.js -e .eslintrc.json -e .eslintrc

# ESLint 설정에서 turbo 관련 설정 확인
echo "\nturbo 관련 ESLint 설정:"
rg -l "turbo" -g ".eslintrc*"

Length of output: 187


Script:

#!/bin/bash
# ESLint 설정 파일의 내용 확인
echo "ESLint 설정 파일 내용:"
cat .eslintrc

# package.json의
8000
 ESLint 관련 의존성 확인
echo "\nESLint 관련 의존성:"
cat package.json | jq '.dependencies,.devDependencies' | rg -i "eslint"

Length of output: 1689


15-15: 빌드 스크립트 간소화 검증 필요

Turbo를 사용한 빌드 스크립트 간소화는 좋은 변경이지만, 기존 빌드 프로세스의 모든 단계가 포함되어 있는지 확인이 필요합니다.

다음 스크립트를 실행하여 빌드 설정을 확인해주세요:

Also applies to: 24-24

✅ Verification successful

빌드 스크립트 변경이 적절히 구성되어 있음을 확인했습니다

turbo.json의 빌드 파이프라인이 다음과 같이 올바르게 구성되어 있습니다:

  • 모든 워크스페이스의 빌드 의존성이 ^build로 설정되어 순차적 빌드 보장
  • 필요한 환경 변수들이 모두 포함됨
  • 각 워크스페이스의 개별 빌드 스크립트가 적절히 유지됨 (타입 체크, 정리, Vite 빌드 등)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# turbo.json 설정 확인
echo "turbo.json 빌드 파이프라인 설정 확인:"
cat turbo.json | jq '.pipeline.build'

# 기존 빌드 스크립트와 비교
echo "\n기존 빌드 관련 스크립트:"
git show HEAD^:package.json | jq '.scripts | with_entries(select(.key | contains("build")))'

Length of output: 428


Script:

#!/bin/bash
# Check if turbo.json exists and its content
echo "turbo.json 파일 확인:"
if [ -f turbo.json ]; then
    cat turbo.json
else
    echo "turbo.json 파일이 없습니다."
fi

# Check workspace configurations
echo -e "\nworkspace 설정 확인:"
if [ -f pnpm-workspace.yaml ]; then
    cat pnpm-workspace.yaml
fi

# Find all package.json files in workspaces
echo -e "\n워크스페이스의 package.json 파일들:"
fd package.json --type f --exclude node_modules

# Check build scripts in workspace packages
echo -e "\n각 워크스페이스의 build 스크립트:"
fd package.json --type f --exclude node_modules --exec sh -c 'echo "\n=== $1 ==="; cat "$1" | jq ".scripts.build"' sh {}

Length of output: 3167

packages/web/src/app/[lng]/memos/components/MemoCardFooter/MemoOption.tsx (2)

3-3: 모듈 가져오기 순서 최적화

ExtensionBridge 임포트가 적절한 위치에 있습니다. 다만, 프로젝트 전반적으로 일관된 임포트 순서를 유지하는 것이 좋습니다.


58-58: 메모 갱신 요청 처리 검증 필요

ExtensionBridge.requestRefetchTheMemos()를 호출하기 전에 쿼리 무효화가 완료되었는지 확인이 필요할 수 있습니다.

다음 스크립트로 메모 갱신 관련 코드를 검사해주세요:

✅ Verification successful

Let me gather more information about the memo refresh implementation.


쿼리 무효화와 메모 갱신 처리가 올바르게 구현되어 있습니다

코드 검토 결과, queryClient.invalidateQueries()ExtensionBridge.requestRefetchTheMemos() 호출 이전에 실행되고 있어 메모 갱신이 적절하게 처리되고 있습니다. 추가 검증이 필요하지 않습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 메모 갱신 관련 코드 검색
echo "메모 갱신 처리 패턴:"
ast-grep --pattern 'invalidateQueries({ queryKey: $_ })'

echo "\nExtensionBridge.requestRefetchTheMemos 사용 패턴:"
rg "ExtensionBridge.requestRefetchTheMemos"

Length of output: 374


Script:

#!/bin/bash
# Check memo refresh related code
echo "Checking MemoOption.tsx implementation:"
rg -A 5 "requestRefetchTheMemos" packages/web/src/app/[lng]/memos/components/MemoCardFooter/MemoOption.tsx

echo "\nChecking ExtensionBridge implementation:"
fd ExtensionBridge.ts --exec cat {}

echo "\nChecking memo query invalidation patterns:"
rg -A 5 "invalidateQueries.*memo" 

Length of output: 6079

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: 0

🧹 Nitpick comments (3)
pages/content-ui/src/index.tsx (3)

7-9: DOM 조작 시 에러 처리 추가 필요

현재 구현은 기본적인 기능은 하지만, 다음과 같은 에러 처리가 추가되면 좋을 것 같습니다:

  • 이미 같은 ID를 가진 요소가 존재하는 경우
  • document.body가 아직 로드되지 않은 경우
+const existingRoot = document.getElementById('page-summary-content-ui');
+if (existingRoot) {
+  existingRoot.remove();
+}
+
+if (!document.body) {
+  document.addEventListener('DOMContentLoaded', () => {
+    document.body.appendChild(root);
+  });
+} else {
   document.body.appendChild(root);
+}

11-11: 에러 바운더리 추가 권장

React 렌더링 시 발생할 수 있는 예외를 처리하기 위해 ErrorBoundary 컴포넌트로 감싸는 것이 좋습니다.

-createRoot(root).render(<OpenSidePanelButton />);
+createRoot(root).render(
+  <ErrorBoundary fallback={<div>오류가 발생했습니다</div>}>
+    <OpenSidePanelButton />
+  </ErrorBoundary>
+);

13-15: 디버그 로깅 추가 권장

개발 환경에서의 디버깅을 용이하게 하기 위해 로깅을 추가하면 좋을 것 같습니다.

 if (!isProduction) {
+  console.debug('Sending page content response in development environment');
   ExtensionBridge.responsePageContent();
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ffecc24 and 6abf8b0.

📒 Files selected for processing (3)
  • packages/shared/src/modules/extension-bridge/constant.ts (1 hunks)
  • pages/content-ui/src/index.tsx (1 hunks)
  • update_version.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • update_version.sh
  • packages/shared/src/modules/extension-bridge/constant.ts
🔇 Additional comments (2)
pages/content-ui/src/index.tsx (2)

1-5: 임포트 구조가 깔끔해졌습니다!

필요한 모듈만 정확하게 임포트하고 있으며, 특히 ExtensionBridge를 통한 중앙화된 통신 구조로의 전환이 잘 반영되어 있습니다.


17-21: 클린업 로직이 잘 구현되었습니다!

이전 리뷰에서 요청된 메모리 누수 방지를 위한 클린업 로직이 적절하게 구현되었습니다.

@guesung guesung merged commit 87470e5 into develop Dec 19, 2024
8 checks passed
@guesung guesung deleted the feature/dx-3 branch December 19, 2024 03:13
Copy link

개발자 경험 개선

1 similar comment
Copy link

개발자 경험 개선

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.

1 participant
0