-
Notifications
You must be signed in to change notification settings - Fork 0
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
Feature/dx search params #103
Conversation
Walkthrough이 풀 리퀘스트는 여러 파일에 대한 변경 사항을 포함하며, 주요 변경 사항은 Changes
Possibly related PRs
Warning There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure. 🔧 eslint
packages/web/src/app/auth/callback/route.tsOops! Something went wrong! :( ESLint: 8.57.0 ESLint couldn't find the config "next/core-web-vitals" to extend from. Please check that the name of the config is correct. The config "next/core-web-vitals" was referenced from the config file in "/packages/web/.eslintrc.json". If you still have problems, please stop by https://eslint.org/chat/help to chat with the team. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
Documentation and Community
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 35
🧹 Outside diff range and nitpick comments (97)
packages/web/src/modules/search-params/constant.ts (1)
1-1
: 각 검색 매개변수의 용도를 문서화하는 것이 좋겠습니다.각 검색 매개변수(
id
,isWish
,category
)의 목적과 사용 사례를 설명하는 JSDoc 주석을 추가하면 코드의 유지보수성이 향상될 것 같습니다.다음과 같이 문서화를 추가해보세요:
+/** + * 검색 매개변수 키 상수 + * @constant + * @description + * - id: 메모의 고유 식별자 + * - isWish: 찜 목록 여부 + * - category: 메모의 카테고리 + */ export const SEARCH_PARAMS_KEYS = ['id', 'isWish', 'category'] as const;pages/side-panel/src/types/Input.ts (1)
1-4
: 인터페이스에 문서화 추가 필요인터페이스의 구조와 타입은 적절하게 정의되어 있습니다. 하지만 더 나은 개발자 경험을 위해 JSDoc 주석을 추가하는 것이 좋겠습니다.
다음과 같이 문서화를 추가해보세요:
+/** + * 메모 입력을 위한 인터페이스 + * @property memo - 메모 내용 + * @property isWish - 위시리스트 여부 + */ export interface MemoInput { memo: string; isWish: boolean; }packages/shared/src/utils/Environment.ts (1)
1-3
: 코드는 간단하고 명확해 보입니다.중앙 집중식 설정 관리로의 전환이 잘 이루어졌습니다. 코드가 간단하면서도 목적이 명확합니다.
이러한 중앙 집중식 설정 관리 방식은 다음과 같은 이점이 있습니다:
- 설정 값의 일관성 유지
- 타입 안정성 향상
- 설정 변경 시 유지보수 용이성
packages/web/src/app/[lng]/memos/types/Input.ts (2)
1-3
: 타입 정의가 명확하고 간단합니다!인터페이스가 잘 정의되어 있습니다. 다만, 카테고리 값의 유효성을 보장하기 위해 문자열 리터럴 유니온 타입 사용을 고려해보시는 것은 어떨까요?
예시:
export interface CategoryInput { - category: string; + category: 'work' | 'personal' | 'shopping' | 'etc'; // 실제 사용되는 카테고리 값으로 대체 }
5-7
: 메모 입력 타입이 잘 정의되어 있습니다!타입 정의가 명확하고 재사용 가능하도록 잘 설계되어 있습니다. 보안과 데이터 무결성을 위해 몇 가지 제안사항이 있습니다:
다음과 같은 개선사항을 고려해보세요:
export type MemoInput = { - memo: string; + memo: string & { length: 1 } | { maxLength: 1000 }; // 메모 길이 제한 추가 + createdAt?: Date; // 선택적으로 생성 시간 추가 };packages/shared/src/constants/Cookie.ts (1)
1-5
: 문서화 개선을 제안합니다.각 쿠키 키의 용도와 예상되는 값 형식을 설명하는 JSDoc 주석을 추가하면 좋을 것 같습니다.
다음과 같이 문서화를 추가해보세요:
+/** + * 애플리케이션에서 사용되는 쿠키 키 상수들 + * @property {string} accessToken - 사용자 인증 액세스 토큰을 위한 쿠키 키 + * @property {string} refreshToken - 토큰 갱신을 위한 리프레시 토큰 쿠키 키 + * @property {string} sideBarState - 사이드바 상태 저장을 위한 쿠키 키 + */ export const COOKIE_KEY = { accessToken: 'access_token', refreshToken: 'refresh_token', sideBarState: 'sidebar_state', };chrome-extension/utils/openai.ts (1)
Line range hint
1-7
: 환경 변수 사용을 고려해보세요.프로덕션 환경에서는 API 키를 환경 변수로 관리하는 것을 권장드립니다. 이는 보안을 강화하고 다양한 환경에서의 설정 관리를 용이하게 만들 것입니다.
다음과 같은 방식을 고려해보세요:
import { CONFIG } from '@extension/shared/constants'; import OpenAI from 'openai'; export const openai = new OpenAI({ - apiKey: CONFIG.openApiKey, + apiKey: process.env.OPENAI_API_KEY || CONFIG.openApiKey, });packages/shared/src/utils/String.ts (1)
1-4
: 함수 이름 변경이 적절합니다만, 코드를 더 간결하게 만들 수 있습니다.
isStringArray
에서checkStringArray
로의 이름 변경은 함수의 목적을 더 명확하게 표현합니다.다음과 같이 코드를 더 간결하게 작성할 수 있습니다:
-export const checkStringArray = (value: unknown): value is string[] => { - if (Array.isArray(value) && value.every(item => typeof item === 'string')) return true; - return false; -}; +export const checkStringArray = (value: unknown): value is string[] => + Array.isArray(value) && value.every(item => typeof item === 'string');packages/shared/src/constants/Supabase.ts (2)
5-5
: 타입 안정성 개선 제안
schemaMemo
속성에만as const
를 적용하는 것보다, 객체 전체에 적용하는 것이 더 일관성 있습니다.
1-1
: 상수 이름 컨벤션 제안상수 객체의 이름이
SUPABASE
인데, 일반적으로 타입스크립트에서는 이런 설정 객체의 경우SupabaseConfig
와 같은 명명이 더 일반적입니다.packages/web/src/modules/local-storage/type.ts (1)
3-5
: 타입 정의가 명확하고 잘 구조화되어 있습니다.
UpdateVersionType
은 시맨틱 버저닝 패턴을 잘 따르고 있습니다.LocalStorageKeyType
은 기존 키들과 버전 타입을 효과적으로 통합했습니다.다만, 각 타입의 용도와 예시를 JSDoc 주석으로 추가하면 더 좋을 것 같습니다.
다음과 같이 문서화를 추가해보세요:
+/** + * 업데이트 버전을 나타내는 문자열 타입 + * @example 'updateVersion1.0.0', 'updateVersion2.1.3' + */ export type UpdateVersionType = `updateVersion${number}.${number}.${number}`; +/** + * 로컬 스토리지에서 사용되는 모든 키 타입 + * @example 'guide', 'install', 'updateVersion1.0.0' + */ export type LocalStorageKeyType = (typeof LOCAL_STORAGE_KEY)[number] | UpdateVersionType;vitest.config.ts (2)
7-7
: 테스트 파일 패턴을 더 포괄적으로 확장하는 것을 고려해보세요.현재
*.test.ts
파일만 포함하고 있어, TypeScript와 JavaScript 테스트 파일을 모두 지원하도록 패턴을 확장하는 것이 좋습니다.다음과 같이 수정하는 것을 제안합니다:
- include: ['**/*.test.ts'], + include: ['**/*.test.{js,jsx,ts,tsx}'],
4-10
: 설정이 기본적인 테스트 환경을 적절히 구성하고 있습니다.기본적인 Vitest 설정이 잘 구성되어 있습니다. 하지만 다음 설정들을 추가로 고려해보시기 바랍니다:
- 테스트 환경 설정 (node/jsdom)
- 코드 커버리지 리포트 설정
- 테스트 타임아웃 설정
다음과 같은 추가 설정을 제안합니다:
export default defineConfig({ plugins: [react()], test: { include: ['**/*.test.ts'], globals: true, + environment: 'jsdom', + coverage: { + reporter: ['text', 'json', 'html'], + }, + testTimeout: 10000, }, });packages/web/src/modules/search-params/type.ts (1)
4-5
: 타입 안전성 개선을 위한 제안SearchParamValueType을 키에 따라 더 구체적으로 정의하고, 튜플 대신 Record 타입을 사용하는 것을 고려해보세요.
-export type SearchParamValueType = string; -export type SearchParamType = [SearchParamKeyType, SearchParamValueType]; +export type SearchParamValueType<T extends SearchParamKeyType> = + T extends 'isWish' ? 'true' | 'false' : + T extends 'category' ? 'work' | 'personal' | 'shopping' : + string; +export type SearchParamType = Record<SearchParamKeyType, string>;packages/shared/src/constants/Url.ts (2)
1-6
: URL 상수들의 구조화가 잘 되었습니다!타입 안정성을 더욱 강화하기 위해 TypeScript의 const assertion을 사용하는 것을 추천드립니다.
-export const URL = { +export const URL = { guideKo: 'https://guesung.notion.site/8a740938aa6547b88d09dbab7cb2222b', guideEn: 'https://guesung.notion.site/10d89de02fde803c99c9e3027c2d10d5', googleForm: 'https://forms.gle/qHkL7PeknaCy5QfY6', chromeStore: 'https://chromewebstore.google.com/detail/web-memo/eaiojpmgklfngpjddhoalgcpkepgkclh', -}; +} as const;
1-6
: URL 상수들에 대한 문서화를 추가하면 좋을 것 같습니다.각 URL의 용도와 목적을 명확히 하기 위해 JSDoc 주석을 추가하는 것을 제안드립니다.
+/** + * 애플리케이션에서 사용되는 외부 URL 상수들 + * @property {string} guideKo - 한국어 가이드 문서 URL + * @property {string} guideEn - 영어 가이드 문서 URL + * @property {string} googleForm - 사용자 피드백 폼 URL + * @property {string} chromeStore - Chrome 웹 스토어 확장 프로그램 페이지 URL + */ export const URL = { guideKo: 'https://guesung.notion.site/8a740938aa6547b88d09dbab7cb2222b', guideEn: 'https://guesung.notion.site/10d89de02fde803c99c9e3027c2d10d5', googleForm: 'https://forms.gle/qHkL7PeknaCy5QfY6', chromeStore: 'https://chromewebstore.google.com/detail/web-memo/eaiojpmgklfngpjddhoalgcpkepgkclh', };packages/web/tsconfig.json (1)
15-15
: 더 최신 버전의 ECMAScript 타겟 사용을 고려해보세요ES2015는 상대적으로 오래된 버전입니다. 최신 브라우저들은 더 새로운 ECMAScript 버전을 지원하므로, 다음 사항들을 고려해보시기 바랍니다:
ES2020
또는 그 이상의 버전을 타겟으로 설정하면 더 현대적인 JavaScript 기능들을 활용할 수 있습니다.- 프로젝트의 브라우저 지원 요구사항을 확인하고, 그에 맞는 적절한 타겟을 선택하세요.
다음과 같이 수정하는 것을 제안드립니다:
- "target": "ES2015" + "target": "ES2020"pages/side-panel/src/utils/Url.ts (1)
1-10
: URL 생성 로직 중복을 제거하는 것이 좋겠습니다.두 함수가 비슷한 URL 생성 로직을 공유하고 있습니다. 이를 하나의 유틸리티 함수로 추출하면 코드 재사용성이 향상될 것 같습니다.
다음과 같은 리팩토링을 제안드립니다:
const createMemoUrl = (params: { id?: number; wish?: boolean }) => { const searchParams = new URLSearchParams(); if (params.wish) searchParams.append('wish', 'true'); if (params.id) searchParams.append('id', String(params.id)); const query = searchParams.toString(); return `${CONFIG.webUrl}/memos${query ? `?${query}` : ''}`; }; export const getMemoUrl = (id?: number) => createMemoUrl({ id }); export const getMemoWishListUrl = (id?: number) => createMemoUrl({ id, wish: true });packages/shared/src/hooks/extension/useSupabaseClientQuery.ts (1)
5-11
: Suspense 동작에 대한 문서화가 필요합니다.useSuspenseQuery를 사용함으로써 발생하는 Suspense 동작과 에러 처리 방식에 대한 주석 설명이 필요합니다.
다음과 같이 문서화를 추가하는 것을 제안드립니다:
+/** + * Supabase 클라이언트를 가져오는 훅입니다. + * + * @remarks + * - Suspense를 사용하므로 상위에 Suspense 바운더리가 필요합니다. + * - 실패 시 1회 재시도합니다. + * - 에러 발생 시 ErrorBoundary로 처리되어야 합니다. + */ export default function useSupabaseClientQuery() {packages/web/src/modules/local-storage/util.ts (2)
3-5
: 에러 처리와 반환 타입을 개선하면 좋을 것 같습니다.localStorage 작업은 실패할 수 있으므로, 에러 처리를 추가하고 반환 타입을 명시하는 것이 좋습니다.
다음과 같이 개선해보세요:
-export const setLocalStorageTrue = (key: LocalStorageKeyType) => { +export const setLocalStorageTrue = (key: LocalStorageKeyType): boolean => { + try { LocalStorage.set(key, LOCAL_STORAGE_VALUE_MAP.true); + return true; + } catch (error) { + console.error(`로컬 스토리지 설정 실패: ${key}`, error); + return false; + } };
1-9
: 전체적인 모듈 구조에 대한 제안
- 로컬 스토리지 작업에 대한 통합된 에러 처리 전략을 수립하는 것이 좋습니다.
- 이러한 유틸리티 함수들에 대한 단위 테스트 추가를 고려해주세요.
- 로컬 스토리지 키와 값에 대한 상수를 별도의 설정 파일로 분리하는 것을 추천드립니다.
단위 테스트 코드 작성에 도움이 필요하시다면 말씀해 주세요.
packages/web/src/modules/local-storage/LocalStorage.ts (1)
8-10
: 값 유효성 검사 및 에러 처리가 필요합니다.
JSON.stringify
과정에서 발생할 수 있는 순환 참조나 기타 에러에 대한 처리가 필요합니다.다음과 같이 개선하는 것을 제안합니다:
- static set(key: LocalStorageKeyType, value: unknown) { - localStorage.setItem(key, JSON.stringify(value)); - } + static set(key: LocalStorageKeyType, value: unknown): boolean { + try { + if (value === undefined) { + console.warn('undefined 값은 저장할 수 없습니다.'); + return false; + } + localStorage.setItem(key, JSON.stringify(value)); + return true; + } catch (error) { + console.error(`로컬 스토리지에 데이터 저장 중 오류 발생: ${key}`, error); + return false; + } + }packages/web/src/constants/Config.ts (1)
3-7
: 타입 정의와 문서화를 추가하면 좋을 것 같습니다.다음과 같이 TypeScript 인터페이스와 JSDoc 주석을 추가하는 것을 제안드립니다:
+/** 애플리케이션 설정 값들을 정의하는 인터페이스 */ +interface AppConfig { + /** 웹 애플리케이션의 기본 URL */ + webUrl: string; + /** Supabase 서비스 URL */ + supabaseUrl: string; + /** Supabase 익명 인증 키 */ + supabaseAnonKey: string; +} +/** 애플리케이션 전역 설정 */ -export const CONFIG = { +export const CONFIG: AppConfig = { webUrl: getSafeConfig('NEXT_PUBLIC_WEB_URL', process.env.NEXT_PUBLIC_WEB_URL), supabaseUrl: getSafeConfig('NEXT_PUBLIC_SUPABASE_URL', process.env.NEXT_PUBLIC_SUPABASE_URL), supabaseAnonKey: getSafeConfig('NEXT_PUBLIC_SUPABASE_ANON_KEY', process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY), };packages/web/src/hooks/useSupabaseClient.ts (2)
7-10
: 에러 처리 및 타입 안전성 개선 필요
getSupabaseClientBrowser
함수의 안정성을 높이기 위한 개선사항을 제안드립니다:다음과 같이 수정하는 것을 고려해보세요:
-function getSupabaseClientBrowser() { +function getSupabaseClientBrowser(): MemoSupabaseClient { if (client) return client; - return getSupabaseClient(); + try { + client = getSupabaseClient(); + return client; + } catch (error) { + console.error('Supabase 클라이언트 초기화 실패:', error); + throw error; + } }
12-14
: 구현이 적절하나, 정리(cleanup) 로직 추가 고려현재 구현은 적절하지만, 컴포넌트 언마운트 시 클라이언트 연결을 정리하는 것이 좋을 수 있습니다.
다음과 같은 개선을 고려해보세요:
function useSupabaseClient() { - return useMemo(getSupabaseClientBrowser, []); + const supabase = useMemo(getSupabaseClientBrowser, []); + useEffect(() => { + return () => { + // 필요한 경우 클라이언트 정리 로직 추가 + if (client) { + client = undefined; + } + }; + }, []); + return supabase; }packages/shared/src/utils/extension/Storage.ts (1)
16-17
: 쿠키 관리 로직 개선 제안현재 구현은 잘 되어있지만, 다음과 같은 개선사항을 고려해보시면 좋을 것 같습니다:
- 쿠키 관련 작업을 위한 전용 훅이나 유틸리티 클래스 생성
- 에러 처리 로직 추가
- 타입 안전성을 위한 상수 타입 정의
이러한 개선사항들은 코드의 재사용성과 안정성을 높일 수 있습니다.
pages/content-ui/src/index.tsx (1)
Line range hint
1-15
: 아키텍처 변경에 대한 제안코드가 상당히 간소화되었으나, 개발 환경에서만 작동하는 기능(
isProduction
체크)이 메인 로직에 직접 포함되어 있습니다. 이는 프로덕션/개발 환경의 분리가 명확하지 않을 수 있습니다.다음과 같은 구조 개선을 제안드립니다:
+import { Environment } from '@extension/shared/types'; + +const initializeDevTools = async () => { + attachShadowTree({ + shadowHostId: OPEN_SIDE_PANEL_ID, + shadowTree: <OpenSidePanelButton />, + }); +}; + +const initialize = async () => { + responsePageContent(); + + if (!isProduction) { + await initializeDevTools(); + } +}; + +initialize();이렇게 변경하면:
- 개발 도구 관련 로직이 명확히 분리됩니다
- 초기화 프로세스가 더 체계적으로 관리됩니다
- 향후 환경별 기능 추가가 용이해집니다
packages/web/src/modules/search-params/useSearchParams.ts (3)
9-9
: URL 생성 로직 개선 제안
getUrl
함수에서 검색 파라미터가 없는 경우에 대한 처리가 필요할 수 있습니다. 또한 URL 인코딩이 올바르게 처리되는지 확인이 필요합니다.다음과 같이 개선을 제안합니다:
- const getUrl = () => `${pathname}${searchParam.getSearchParams()}`; + const getUrl = () => { + const params = searchParam.getSearchParams(); + return params ? `${pathname}${params}` : pathname; + };
11-14
: 객체 스프레드 연산자 사용에 대한 주의사항
searchParam
객체를 스프레드하는 것은 타입 안전성을 저해할 수 있습니다. 필요한 메서드만 명시적으로 노출하는 것이 더 안전할 수 있습니다.필요한 메서드만 명시적으로 반환하는 것을 고려해보세요:
return { get: searchParam.get.bind(searchParam), getAll: searchParam.getAll.bind(searchParam), add: searchParam.add.bind(searchParam), remove: searchParam.remove.bind(searchParam), getUrl, };
4-15
: 커스텀 훅의 메모이제이션 고려
useSearchParams
훅이 리렌더링될 때마다 새로운 객체와 함수를 생성합니다. 성능 최적화를 위해 메모이제이션을 고려해볼 수 있습니다.다음과 같이
useMemo
와useCallback
을 사용하여 최적화할 수 있습니다:export default function useSearchParams() { const searchParams = useSearchParamsNext(); const pathname = usePathname(); const searchParam = useMemo( () => new SearchParams([...searchParams.entries()] as SearchParamType[]), [searchParams] ); const getUrl = useCallback( () => `${pathname}${searchParam.getSearchParams()}`, [pathname, searchParam] ); return useMemo( () => ({ ...searchParam, getUrl, }), [searchParam, getUrl] ); }packages/web/src/hooks/useGetExtensionManifest.ts (1)
5-17
: 로딩 상태 관리 추가 제안사용자 경험 향상을 위해 로딩 상태를 추가하는 것이 좋습니다.
다음과 같이 수정하는 것을 제안합니다:
export default function useGetExtensionManifest() { const [manifest, setManifest] = useState<chrome.runtime.Manifest | undefined | null>(null); + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState<Error | null>(null); useDidMount(() => { let isSubscribed = true; try { + setIsLoading(true); requestGetExtensionManifest(manifest => { - if (isSubscribed) setManifest(manifest); + if (isSubscribed) { + setManifest(manifest); + setIsLoading(false); + } }); } catch (e) { if (isSubscribed) { setManifest(undefined); + setError(e instanceof Error ? e : new Error('알 수 없는 오류가 발생했습니다.')); + setIsLoading(false); } } return () => { isSubscribed = false; }; }); - return manifest; + return { manifest, isLoading, error }; }packages/shared/src/hooks/supabase/useSupabaseUser.ts (1)
16-19
: 반환 구조를 최적화할 수 있습니다.현재 구현에서는 query.data를 user로 다시 할당하고 있는데, 이는 불필요한 중복일 수 있습니다. 다음과 같은 개선을 고려해보세요:
return { ...query, - user: query.data, + user: query.data.user };이렇게 하면 user 객체에 직접 접근할 수 있어 사용성이 개선됩니다. 또한 다음과 같이 타입을 더 명확하게 지정할 수 있습니다:
type UseSupabaseUserReturn = { user: UserResponse['data']['user']; } & Omit<UseSuspenseQueryResult<UserResponse, Error>, 'data'>;packages/web/src/modules/local-storage/constant.ts (2)
1-3
: 정규식 패턴의 가독성 개선이 필요합니다정규식 패턴을 더 명확하고 유지보수하기 쉽게 분리하는 것이 좋을 것 같습니다.
다음과 같이 변경을 제안드립니다:
-const REGEXR_UPDATE_VERSION_VERSION = /^updateVersion\d+\.\d+\.\d+$/; +const VERSION_PATTERN = '\\d+\\.\\d+\\.\\d+'; +const REGEXR_UPDATE_VERSION_VERSION = new RegExp(`^updateVersion(?<version>${VERSION_PATTERN})$`);
8-8
: 각 키의 용도에 대한 문서화가 필요합니다
LOCAL_STORAGE_KEY
배열의 각 키가 어떤 목적으로 사용되는지 명확하지 않습니다. JSDoc 주석을 추가하여 각 키의 용도를 설명해주세요.다음과 같이 문서화를 추가하는 것을 제안드립니다:
+/** + * 로컬 스토리지 키 목록 + * @property guide - 사용자 가이드 표시 여부 + * @property updateVersion - 앱 업데이트 버전 정보 + * @property install - 앱 설치 상태 + */ export const LOCAL_STORAGE_KEY = ['guide', 'updateVersion', 'install'] as const;packages/web/src/app/[lng]/memos/page.tsx (1)
Line range hint
1-19
: 성능 최적화를 위한 제안서버 컴포넌트에서 메모 데이터를 가져오는 현재 구조는 적절하나, 다음과 같은 최적화를 고려해 보시기 바랍니다:
- Next.js의 fetch cache 활용
- 정적 메모 데이터에 대한 ISR(Incremental Static Regeneration) 적용 검토
packages/web/src/app/[lng]/login/page.tsx (1)
Line range hint
9-24
: 에러 처리 개선 제안현재 구현에서
getSupabaseClient()
및checkUserLogin()
호출 시 발생할 수 있는 예외 상황에 대한 처리가 누락되어 있습니다. 사용자 경험 향상을 위해 에러 처리를 추가하는 것이 좋을 것 같습니다.다음과 같은 개선을 제안드립니다:
export default async function page({ params: { lng } }: LanguageParams) { - const supabaseClient = getSupabaseClient(); - const isUserLogin = await checkUserLogin(supabaseClient); + try { + const supabaseClient = getSupabaseClient(); + const isUserLogin = await checkUserLogin(supabaseClient); - if (isUserLogin) redirect(PATHS.memos); - return ( - <main className="relative flex h-full items-center justify-center"> - <LoginSection lng={lng} /> - <PersonalInformationInfo lng={lng} /> - </main> - ); + if (isUserLogin) redirect(PATHS.memos); + return ( + <main className="relative flex h-full items-center justify-center"> + <LoginSection lng={lng} /> + <PersonalInformationInfo lng={lng} /> + </main> + ); + } catch (error) { + console.error('로그인 페이지 로드 중 오류 발생:', error); + return ( + <main className="relative flex h-full items-center justify-center"> + <div>로그인 페이지를 불러오는 중 문제가 발생했습니다. 잠시 후 다시 시도해 주세요.</div> + </main> + ); + } }packages/shared/tsconfig.json (1)
14-15
: 빌드 출력 구성 개선사항선언 파일 생성 및 출력 디렉토리 구성이 개선되었습니다:
- 선언 맵 생성 활성화
- 내부 구현 세부사항 제거
- 일관된 출력 디렉토리 구조
이는 타입 정의 품질과 패키지 배포 구조를 개선합니다.
패키지 배포 시
package.json
의types
필드가dist
디렉토리를 올바르게 참조하는지 확인하세요.Also applies to: 22-24
packages/web/src/modules/i18n/server.js (1)
Line range hint
6-21
: 구현이 깔끔하나 문서화가 필요합니다.전반적인 구현이 잘 되어 있으며, i18next의 모범 사례를 잘 따르고 있습니다. 다만, 다음 사항들에 대한 문서화를 추가하면 좋을 것 같습니다:
- 각 함수의 파라미터 설명
- 반환값 형식
- 사용 예시
다음과 같은 JSDoc 문서화를 추가하는 것을 제안합니다:
+/** + * i18next 인스턴스를 초기화합니다. + * @param {string} lng - 사용할 언어 코드 + * @param {string|string[]} ns - 사용할 네임스페이스 + * @returns {Promise<i18n>} 초기화된 i18next 인스턴스 + */ const initI18next = async (lng, ns) => { +/** + * 번역 유틸리티 함수와 i18next 인스턴스를 반환합니다. + * @param {string} lng - 사용할 언어 코드 + * @param {string|string[]} ns - 사용할 네임스페이스 + * @param {Object} options - 추가 옵션 + * @param {string} [options.keyPrefix] - 키 접두사 + * @returns {Promise<{t: TFunction, i18n: i18n}>} 번역 함수와 i18next 인스턴스 + */ export default async function useTranslation(lng, ns, options = {}) {packages/shared/src/hooks/supabase/useCategoryPostMutation.ts (1)
10-10
: 낙관적 업데이트 구현 제안낙관적 업데이트를 구현하면 사용자 경험을 크게 향상시킬 수 있습니다. React Query의
onMutate
를 활용하여 구현하는 것을 추천드립니다.다음과 같이 구현할 수 있습니다:
export default function useCategoryPostMutation({ supabaseClient }: UseCategoryPostMutationProps) { const queryClient = useQueryClient(); return useMutation<CategorySupabaseResponse, Error, CategoryTable['Insert']>({ mutationFn: postCategoryProps => insertCategory(supabaseClient, postCategoryProps), + onMutate: async (newCategory) => { + await queryClient.cancelQueries({ queryKey: QUERY_KEY.category() }); + const previousCategories = queryClient.getQueryData(QUERY_KEY.category()); + queryClient.setQueryData(QUERY_KEY.category(), (old: CategorySupabaseResponse[] = []) => [ + ...old, + { ...newCategory, id: 'temp-id' }, + ]); + return { previousCategories }; + }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: QUERY_KEY.category() }); }, + onError: (err, newCategory, context) => { + queryClient.setQueryData(QUERY_KEY.category(), context?.previousCategories); + } }); }packages/shared/src/utils/Sentry.ts (1)
Line range hint
25-25
: 릴리즈 버전 관리 개선 제안현재 릴리즈 버전이 하드코딩되어 있습니다. 이를 package.json의 version 필드나 환경 변수를 통해 동적으로 관리하는 것이 좋습니다.
다음과 같은 방식으로 개선할 수 있습니다:
- release: '0.3.1', + release: process.env.NEXT_PUBLIC_APP_VERSION || CONFIG.version,packages/shared/src/hooks/supabase/useMemosQuery.ts (1)
Line range hint
13-23
: 에러 처리에 대한 문서화가 필요합니다.훅의 구현은 잘 되어있지만, 다음 사항들에 대한 문서화를 추가하면 좋을 것 같습니다:
- 발생 가능한 에러 타입들
- 에러 처리 방법
- 재시도 정책
다음과 같은 JSDoc 문서를 추가하는 것을 제안드립니다:
+/** + * Supabase를 사용하여 메모 목록을 조회하는 훅 + * @param supabaseClient - Supabase 클라이언트 인스턴스 + * @param useQueryProps - React Query 옵션 + * @throws {Error} 데이터베이스 연결 실패 시 + * @throws {Error} 인증 오류 발생 시 + * @returns {Object} 쿼리 결과 및 메모 데이터 + */ export default function useMemosQuery({ supabaseClient, ...useQueryProps }: UseMemosQueryProps)packages/web/src/app/[lng]/login/components/LoginSection/ExtensionVersion.tsx (2)
14-14
: 조기 반환문을 더 명시적으로 개선하세요현재 조기 반환문이 너무 간단하여 디버깅이 어려울 수 있습니다.
다음과 같이 개선하는 것을 고려해보세요:
- if (!manifest) return; + if (!manifest) { + console.debug('확장 프로그램 매니페스트를 찾을 수 없습니다.'); + return null; + }
17-19
: 버전 비교 로직을 별도 함수로 분리하세요버전 비교 로직을 컴포넌트에서 직접 처리하는 것보다 별도의 유틸리티 함수로 분리하면 재사용성과 테스트 용이성이 향상됩니다.
다음과 같은 구조를 제안합니다:
const isLatestVersion = (current: string, latest: string) => current === latest; const getVersionMessage = (manifest: Manifest, t: TFunction) => { return isLatestVersion(manifest.version, EXTENSION.lastVersion) ? t('version.itIsLastVersion') : `${t('version.installedVersion')} : ${manifest.version} | ${t('version.lastVersion')} : ${EXTENSION.lastVersion}`; };그리고 컴포넌트에서는 다음과 같이 사용:
- {manifest.version === EXTENSION.lastVersion - ? t('version.itIsLastVersion') - : `${t('version.installedVersion')} : ${manifest.version} | ${t('version.lastVersion')} : ${EXTENSION.lastVersion}`} + {getVersionMessage(manifest, t)}packages/shared/src/constants/Config.ts (1)
6-17
: 구성이 잘 중앙화되었습니다만, 문서화가 필요합니다.환경 설정을 하나의 CONFIG 객체로 통합한 것은 좋은 접근 방식입니다. 하지만 각 설정 값의 용도와 예상되는 값에 대한 JSDoc 문서를 추가하면 좋을 것 같습니다.
다음과 같이 문서화를 추가하는 것을 제안합니다:
+/** + * 애플리케이션 전역 환경 설정 + * @property {string} webUrl - 웹 애플리케이션 URL + * @property {string} supabaseUrl - Supabase 인스턴스 URL + * @property {string} supabaseAnonKey - Supabase 익명 인증 키 + * @property {string} sentryDsn - Sentry 모니터링 DSN + * @property {string} sentryAuthToken - Sentry 인증 토큰 + * @property {'development' | 'production'} nodeEnv - 현재 실행 환경 + * @property {'development' | 'production'} makeWebhookNotionApi - Notion API 웹훅 환경 + * @property {string} openApiKey - OpenAI API 키 + */ export const CONFIG = {packages/shared/src/hooks/supabase/useMemoQuery.ts (1)
26-29
: 타입 안정성을 개선할 수 있습니다.반환 값의 타입을 명시적으로 정의하면 타입 안정성이 향상될 것 같습니다.
다음과 같이 개선해보시는 건 어떨까요?:
+interface MemoQueryResult { + memo: MemoSupabaseResponse['data'][number] | null; + isLoading: boolean; + isError: boolean; + error: Error | null; +} + -return { +return { ...query, memo: query.data, -}; +} as MemoQueryResult;packages/web/src/hooks/useLanguage.ts (2)
Line range hint
6-7
: 몇 가지 개선 사항을 제안드립니다.
REGEXR_PATHNAME_LANGAUGE
상수명에 오타가 있습니다 ('LANGAUGE' → 'LANGUAGE').useEffect
의 의존성 배열에pathname
을 추가하는 것이 좋습니다.- 정규식 매칭 결과에 대한 타입 안전성을 높일 수 있습니다.
다음과 같이 수정하는 것을 제안드립니다:
-const REGEXR_PATHNAME_LANGAUGE = /^\/(\w+)\/.+/; +const REGEXR_PATHNAME_LANGUAGE = /^\/(\w+)\/.+/; useEffect(() => { const pathnameLanguage = pathname.match(REGEXR_PATHNAME_LANGAUGE)?.[1]; if (!pathnameLanguage) return; setLanguage(pathnameLanguage as Language); -}, []); +}, [pathname]);
Line range hint
23-29
: 언어 값 검증 로직 추가를 제안드립니다.
setLanguageRouter
함수에서 언어 값에 대한 유효성 검사가 없습니다. 잘못된 언어 값이 전달될 경우 사용자 경험에 영향을 줄 수 있습니다.다음과 같은 개선을 제안드립니다:
const setLanguageRouter = (value: Language) => { + const validLanguages = Object.values(Language); + if (!validLanguages.includes(value)) { + console.error(`Invalid language value: ${value}`); + return; + } + const pathnameWithoutLanguage = pathname.match(REGEXR_PATHNAME_WITHOUT_LANGUAGE)?.[1]; if (!pathnameWithoutLanguage) return;packages/web/src/app/auth/callback-email/route.ts (1)
Line range hint
23-29
: 심각: 리프레시 토큰이 잘못된 키로 저장되고 있습니다
COOKIE_KEY.sideBarState
를 사용하여 리프레시 토큰을 저장하는 것은 심각한 문제입니다:
- 키 이름이 저장하는 데이터와 일치하지 않아 혼란을 야기할 수 있습니다
- 다른 부분에서 사이드바 상태를 읽으려고 할 때 리프레시 토큰이 노출될 수 있습니다
다음과 같이 수정하는 것을 제안합니다:
- cookieStore.set(COOKIE_KEY.sideBarState, sessionData.session.refresh_token, { + cookieStore.set(COOKIE_KEY.refreshToken, sessionData.session.refresh_token, {packages/web/src/app/[lng]/memos/components/MemoView/index.tsx (1)
Line range hint
22-24
: 메모 필터링 로직을 더 명확하게 개선할 수 있습니다.현재 이중 느낌표(!!)를 사용한 불리언 변환이 다소 암시적입니다. 또한 필터링 로직을 더 명확하게 표현할 수 있습니다.
다음과 같이 개선해보세요:
const filteredMemos = memos - ?.filter(memo => isWish === !!memo.isWish) - .filter(memo => (category ? memo.category?.name === category : true)); + ?.filter(memo => isWish === Boolean(memo.isWish)) + .filter(memo => !category || memo.category?.name === category);packages/web/src/app/[lng]/memos/setting/component/Setting/index.tsx (1)
Line range hint
19-28
: 접근성 개선을 위한 번역 키 추가 제안SelectItem의 언어 텍스트("한글", "English")도 번역 시스템을 통해 관리하면 좋을 것 같습니다.
다음과 같이 수정을 제안드립니다:
<SelectContent> - <SelectItem value="ko">한글</SelectItem> - <SelectItem value="en">English</SelectItem> + <SelectItem value="ko">{t('setting.language.korean')}</SelectItem> + <SelectItem value="en">{t('setting.language.english')}</SelectItem> </SelectContent>packages/web/src/app/[lng]/memos/components/MemoSidebar/SidebarMenuItemAddCategory.tsx (1)
Line range hint
1-42
: 전반적인 컴포넌트 구조에 대한 제안컴포넌트의 기능성은 잘 구현되어 있지만, 다음과 같은 개선사항을 고려해보시기 바랍니다:
- 폼 제출 후 입력 필드 초기화
- 카테고리 생성 실패 시 에러 처리
- 입력 필드에 대한 유효성 검사 추가
다음과 같이 수정하는 것을 제안드립니다:
const { register, handleSubmit } = useForm<CategoryInput>({ defaultValues: { category: '', }, }); - const { mutate: mutateCategoryPost } = useCategoryPostMutation({ supabaseClient }); + const { mutate: mutateCategoryPost, isError } = useCategoryPostMutation({ supabaseClient }); - const onSubmit = handleSubmit(({ category }) => { - mutateCategoryPost({ name: category }); - }); + const onSubmit = handleSubmit(({ category }) => { + mutateCategoryPost( + { name: category }, + { + onSuccess: () => { + setIsEditMode(false); + reset(); + }, + } + ); + }); if (isEditMode) return ( <form onSubmit={onSubmit}> - <Input {...register('category')} /> + <Input + {...register('category', { + required: '카테고리명을 입력해주세요', + minLength: { value: 2, message: '최소 2자 이상 입력해주세요' }, + })} + error={isError ? '카테고리 생성에 실패했습니다' : undefined} + /> </form> );packages/web/src/app/[lng]/memos/utils/guide.ts (2)
Line range hint
19-24
: setInterval 정리가 필요합니다
setInterval
이 생성되지만 정리되지 않고 있습니다. 메모리 누수를 방지하기 위해 cleanup이 필요합니다.다음과 같이 수정을 제안드립니다:
onPopoverRender: () => { - setInterval(() => { + const intervalId = setInterval(() => { requestGetSidePanelOpen(() => { if (driverObj.getActiveIndex() !== 0) return; driverObj.moveNext(); }); }, 500); + return () => clearInterval(intervalId); },
Line range hint
28-33
: 플랫폼별 단축키 안내가 필요합니다현재
Command + S
단축키는 macOS 사용자를 위한 안내입니다. Windows/Linux 사용자를 위해Ctrl + S
도 함께 안내하는 것이 좋겠습니다.다음과 같이 수정을 제안드립니다:
- description: `잘하셨어요 !\n이제 이 사이드 패널에서 메모를 기록하실 수 있답니다.\n메모를 입력하고, Command + S를 눌러 저장해보세요.\n메모 테두리가 파랑색 테두리에서 기본 테두리로 돌아왔다면 저장에 성공한 거에요!\n또한, 3초마다 자동으로 저장되니 안심하세요 ☺️`, + description: `잘하셨어요 !\n이제 이 사이드 패널에서 메모를 기록하실 수 있답니다.\n메모를 입력하고, Command + S (Windows/Linux의 경우 Ctrl + S)를 눌러 저장해보세요.\n메모 테두리가 파랑색 테두리에서 기본 테두리로 돌아왔다면 저장에 성공한 거에요!\n또한, 3초마다 자동으로 저장되니 안심하세요 ☺️`,packages/web/src/app/components/Introduction.tsx (1)
21-23
: URL 참조 방식이 개선되었습니다.
URL.chromeStore
를 사용하는 방식으로 변경된 것이 적절합니다. 다만, 접근성 향상을 위해 버튼에 aria-label을 추가하는 것을 고려해보세요.다음과 같이 aria-label을 추가하는 것을 제안합니다:
-<button className="btn btn-primary text-xl">chrome에 추가하기</button> +<button className="btn btn-primary text-xl" aria-label="크롬 웹스토어에서 확장 프로그램 설치하기">chrome에 추가하기</button>pages/side-panel/src/components/MemoHeader.tsx (1)
17-18
: 메모 URL 처리 로직이 개선되었습니다.
getMemoUrl
함수를 사용하여 URL을 생성하는 방식이 더 모듈화되었습니다. 하지만memoData
가undefined
일 때의 처리가 필요할 수 있습니다.다음과 같이 안전한 처리를 추가하는 것을 고려해보세요:
- const memoUrl = getMemoUrl(memoData?.id); + if (!memoData?.id) return; + const memoUrl = getMemoUrl(memoData.id);packages/web/src/utils/middleware.ts (1)
쿠키 보안 설정이 일관되지 않습니다.
middleware.ts 파일의 쿠키 설정에서 보안 관련 옵션이 누락되어 있습니다. 다른 파일들(callback-email/route.ts)에서는 적절한 보안 설정을 사용하고 있으나, middleware에서는 이러한 보안 설정이 적용되지 않았습니다.
다음 보안 설정을 추가해야 합니다:
httpOnly: true
secure: process.env.NODE_ENV === 'production'
sameSite: 'lax'
특히 서버 쿠키 설정 부분(
request.cookies.set
)에서 options 매개변수가 완전히 누락되어 있습니다.🔗 Analysis chain
Line range hint
12-26
: 쿠키 보안 설정 검증이 필요합니다.Supabase 클라이언트 초기화 부분이 CONFIG 객체를 사용하도록 잘 변경되었습니다. 하지만 쿠키 처리와 관련된 보안 설정을 검증해야 합니다.
다음 스크립트를 실행하여 쿠키 관련 보안 설정을 확인하세요:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: 쿠키 보안 설정 검증 # 쿠키 옵션 설정 확인 rg -A 5 "cookies\.set.*options" # Supabase 설정 관련 파일 검색 fd -e ts -e js -x grep -l "createServerClient.*options"Length of output: 508
Script:
#!/bin/bash # Check cookie handling and security settings in middleware and related files # Search for cookie-related code in middleware rg -A 10 "createServerClient" packages/web/src/utils/middleware.ts # Find Supabase client configuration fd -e ts -e js -x rg -l "supabase.*config" # Search for cookie options or security settings rg -A 5 "cookie.*options|secure.*cookie|httpOnly|sameSite" # Check if there are any other middleware files fd middlewareLength of output: 3619
packages/web/src/middleware.ts (1)
Line range hint
9-42
: 미들웨어 구현에 대한 개선 제안전반적인 구현은 잘 되어있지만, 다음과 같은 개선사항을 고려해보시기 바랍니다:
- URL 조작 로직을 별도의 유틸리티 함수로 분리
- 언어 감지 로직에 대한 에러 처리 강화
- 타입 안전성 개선을 위한 상수 enum화 고려
다음과 같은 리팩토링을 제안드립니다:
+import { LanguageCode } from './types'; -const languages = ['ko', 'en'] as const; +enum LanguageCode { + KO = 'ko', + EN = 'en' +} +function buildLocalizedUrl(url: URL, language: LanguageCode): URL { + return new URL(`/${language}${url.pathname}${url.search}`, url.href); +}또한 다음 사항들을 고려해보시기 바랍니다:
- 언어 설정 변경 시 성능 최적화를 위한 캐싱 전략
- 국제화 관련 설정의 중앙 관리를 위한 설정 파일 도입
packages/web/src/app/components/ExtensionDialog/getExtensionDialogInfo.ts (3)
7-11
: 타입 안전성 개선 제안함수의 반환 타입이 명시적으로 정의되어 있지 않습니다. 타입 안전성을 높이기 위해 반환 타입을 명시적으로 정의하는 것이 좋습니다.
다음과 같이 개선할 수 있습니다:
export const getExtensionDialogInfo = ( lng: Language, manifest: ReturnType<typeof useExtensionDialog>['manifest'], dialogType?: DialogType, - ) => { + ): typeof EXTENSION_DIALOG_INFO_ALL[DialogType] | undefined => {
12-14
: 오류 처리 개선 제안
dialogType
이 없을 때 단순히undefined
를 반환하는 것보다 더 명시적인 처리가 필요할 수 있습니다.다음과 같이 개선할 수 있습니다:
- if (!dialogType) return; + if (!dialogType) { + console.warn('dialogType이 제공되지 않았습니다.'); + return undefined; + }
1-42
: 테스트 및 에러 바운더리 추가 권장이 유틸리티 함수에 대한 단위 테스트와 에러 바운더리가 필요합니다. 특히 다음 사항들을 고려해야 합니다:
- 다양한
dialogType
값에 대한 테스트- 잘못된
manifest
데이터 처리- i18n 관련 에러 처리
테스트 코드 작성을 도와드릴까요?
packages/web/src/app/components/ExtensionDialog/useExtensionDialog.ts (3)
11-11
: 타입 정의에 JSDoc 문서화 추가 제안
DialogType
타입에 대한 설명과 각 유니온 타입 값의 의미를 JSDoc으로 문서화하면 좋을 것 같습니다.+/** + * 확장 프로그램 다이얼로그의 표시 유형을 정의합니다. + * @typedef {('install'|'update')} DialogType + * - 'install': 최초 설치 다이얼로그 + * - 'update': 업데이트 알림 다이얼로그 + */ export type DialogType = 'install' | 'update';
24-33
: 로컬 스토리지 키 상수화 및 에러 처리 개선이 필요합니다로컬 스토리지 키를 문자열 리터럴로 사용하는 것은 오타의 위험이 있습니다. 또한, 로컬 스토리지 접근 시 발생할 수 있는 예외 처리가 필요합니다.
+const STORAGE_KEYS = { + INSTALL: 'install', + UPDATE: 'updateVersion' +} as const; + -if (!isExtensionInstalled && !checkLocalStorageTrue('install')) { +if (!isExtensionInstalled && !checkLocalStorageTrue(STORAGE_KEYS.INSTALL)) { setDialogType('install'); setOpen(true); return; } -if (isExtensionNotLastVersion && !checkLocalStorageTrue('updateVersion')) { +if (isExtensionNotLastVersion && !checkLocalStorageTrue(STORAGE_KEYS.UPDATE)) { setDialogType('update'); setOpen(true); return; }
41-48
: 반환 타입 명시적 정의가 필요합니다훅의 반환 타입을 명시적으로 정의하면 타입 안전성이 향상됩니다.
+interface ExtensionDialogHookReturn { + open: boolean; + setOpen: (open: boolean) => void; + dialogType: DialogType | undefined; + manifest: chrome.runtime.ManifestV3 | undefined | null; + handleClose: (localStorageKey: keyof typeof STORAGE_KEYS) => void; +} + -export default function useExtensionDialog() { +export default function useExtensionDialog(): ExtensionDialogHookReturn {packages/web/src/app/[lng]/memos/layout.tsx (1)
24-24
: 쿠키 키 접근 방식이 개선되었습니다.
COOKIE_KEY.sideBarState
를 사용하는 방식으로 변경되어 타입 안정성이 향상되었습니다. 하지만 쿠키 값의 타입 검증이 필요할 수 있습니다.다음과 같이 타입 안정성을 더욱 강화할 수 있습니다:
- const defaultOpen = cookieStore.get(COOKIE_KEY.sideBarState)?.value === 'true'; + const sideBarState = cookieStore.get(COOKIE_KEY.sideBarState)?.value; + const defaultOpen = sideBarState === 'true' || false;packages/web/src/modules/i18n/locales/ko/translation.json (2)
37-42
: 설치 다이얼로그의 메시지가 친절하고 명확합니다.다만, 설치 취소 시의 제한사항이나 결과에 대한 안내 메시지를 추가하면 좋을 것 같습니다.
다음과 같이 취소 버튼의 텍스트를 수정하는 것을 제안드립니다:
- "cancel": "설치하지 않고 이용하기", + "cancel": "설치하지 않고 이용하기 (일부 기능 제한)",
43-50
: 버전 다이얼로그의 플레이스홀더 사용이 적절합니다.
{{currentVersion}}
과{{lastVersion}}
의 플레이스홀더를 올바르게 사용하고 있습니다. 하지만 버전 비교를 위해 추가적인 메시지가 필요할 수 있습니다.다음과 같은 메시지 추가를 제안드립니다:
"description": "현재 버전 {{currentVersion}}에서 새로운 버전 {{lastVersion}}으로 업데이트할 수 있습니다.", + "versionCompare": "현재 버전보다 {{diffCount}}개의 업데이트가 있습니다.", "itIsLastVersion": "최신 버전입니다.",
packages/shared/src/hooks/supabase/useMemoPostMutation.ts (1)
Line range hint
15-35
: 성공 핸들러의 에러 처리를 개선해주세요.성공 핸들러 내부에서 발생할 수 있는
NoMemosError
에 대한 처리가 누락되어 있습니다. 이는 뮤테이션 플로우를 중단시킬 수 있습니다.다음과 같이 개선하는 것을 제안드립니다:
onSuccess: async (result, variables, context) => { + try { const { data: newData } = result; await queryClient.cancelQueries({ queryKey: QUERY_KEY.memos() }); const previousMemos = queryClient.getQueryData<MemoSupabaseResponse>(QUERY_KEY.memos()); if (!previousMemos || !newData) throw new NoMemosError(); const { data: previousMemosData } = previousMemos; if (!previousMemosData) throw new NoMemosError(); const newMemosData = newData.concat(previousMemosData); await queryClient.setQueryData(QUERY_KEY.memos(), { ...previousMemos, data: newMemosData }); useMutationProps.onSuccess?.(result, variables, context); return { previousMemos }; + } catch (error) { + console.error('메모 업데이트 중 오류 발생:', error); + // 이전 상태로 복원하는 로직 추가 가능 + throw error; + } },packages/shared/src/utils/extension/Supabase.ts (1)
Line range hint
9-24
: 메모리 관리 개선이 필요할 수 있습니다.현재 구현에서는 함수가 호출될 때마다 새로운 Supabase 클라이언트 인스턴스가 생성됩니다. 이는 잠재적인 메모리 누수로 이어질 수 있습니다.
다음과 같은 싱글톤 패턴 구현을 고려해보세요:
+let supabaseClientInstance: Database | null = null; export const getSupabaseClient = async () => { try { + if (supabaseClientInstance) return supabaseClientInstance; const supabaseClientInstance = createClient<Database>...packages/web/package.json (2)
Line range hint
1-57
: 패키지 버전 업데이트 권장일부 패키지들의 버전이 최신 버전과 차이가 있습니다. 보안 및 성능 향상을 위해 업데이트를 고려해보시기 바랍니다.
특히 다음 패키지들의 업데이트를 검토해보시면 좋겠습니다:
- eslint (9.9.1)
- next (14.2.10)
- react (18.3.1)
@supabase/ssr
패키지 제거에 대한 마이그레이션 검토가 완료되었습니다.코드베이스 분석 결과,
@supabase/ssr
패키지가 여전히 사용되고 있으며 제거되지 않았음을 확인했습니다. 다음 파일들에서 해당 패키지를 import하여 사용 중입니다:
packages/web/src/utils/supabase.server.ts
packages/web/src/utils/middleware.ts
packages/web/src/utils/supabase.client.ts
따라서 package.json에서 해당 패키지가 제거된 것은 의도치 않은 실수로 보이며, 의존성을 다시 추가해야 합니다.
🔗 Analysis chain
Line range hint
1-57
: 의존성 패키지들의 호환성 및 보안 검토가 필요합니다.
@supabase/ssr
패키지가 제거되었는데, 이와 관련된 기능들이 정상적으로 마이그레이션 되었는지 확인이 필요합니다.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: 제거된 @supabase/ssr 패키지의 사용처를 검색하고 의존성 충돌을 확인합니다. # @supabase/ssr 임포트 검색 echo "Checking for any remaining @supabase/ssr imports..." rg "from ['\"']@supabase/ssr" # package-lock.json이나 yarn.lock에서 의존성 충돌 확인 echo "Checking for dependency conflicts in lock files..." fd -e json -e lockLength of output: 1716
Script:
#!/bin/bash # Check the implementation of files using @supabase/ssr to understand the migration status echo "Checking supabase.server.ts implementation..." cat packages/web/src/utils/supabase.server.ts echo -e "\nChecking middleware.ts implementation..." cat packages/web/src/utils/middleware.ts echo -e "\nChecking supabase.client.ts implementation..." cat packages/web/src/utils/supabase.client.ts # Search for any new Supabase client implementation that might have replaced @supabase/ssr echo -e "\nChecking for alternative Supabase client implementations..." rg "supabase" --type tsLength of output: 19194
packages/web/src/modules/i18n/client.js (2)
Line range hint
13-23
: 동적 import에 대한 에러 처리 개선이 필요합니다현재 구현에서는 locale 파일의 동적 import 실패에 대한 처리가 없습니다. 사용자 경험 향상을 위해 에러 처리를 추가하는 것이 좋겠습니다.
다음과 같은 개선을 제안드립니다:
.use(resourcesToBackend((language, namespace) => import(`./locales/${language}/${namespace}.json`))) +.use(resourcesToBackend(async (language, namespace) => { + try { + return await import(`./locales/${language}/${namespace}.json`); + } catch (error) { + console.error(`Failed to load locale: ${language}/${namespace}`, error); + return {}; + } +}))
Line range hint
44-51
: 쿠키 설정의 중앙화가 필요합니다쿠키 설정 옵션이 직접 코드에 하드코딩되어 있습니다. 이러한 설정은 별도의 설정 파일로 분리하여 관리하는 것이 좋습니다.
설정을 분리하여 관리하는 방식을 제안드립니다:
+// cookieConfig.js +export const COOKIE_CONFIG = { + path: '/', + maxAge: 365 * 24 * 60 * 60, + secure: process.env.NODE_ENV === 'production', + sameSite: 'strict', +}; - setCookie(cookieName, lng, { - path: '/', - maxAge: 365 * 24 * 60 * 60, - secure: process.env.NODE_ENV === 'production', - sameSite: 'strict', - }); + setCookie(cookieName, lng, COOKIE_CONFIG);packages/shared/src/utils/Supabase.ts (2)
Line range hint
26-31
: 사용자 인증 관련 타입 안정성과 에러 처리를 개선해주세요.
checkUserLogin
함수에서 옵셔널 체이닝을 사용하고 있지만, 더 명확한 타입 가드와 에러 처리가 필요합니다.다음과 같은 개선을 제안드립니다:
export const checkUserLogin = async (supabaseClient: MemoSupabaseClient) => { - const user = await supabaseClient.auth.getUser(); - return !!user?.data?.user; + try { + const { data: { user }, error } = await supabaseClient.auth.getUser(); + if (error) throw error; + return !!user; + } catch (error) { + console.error('사용자 인증 확인 중 오류 발생:', error); + return false; + } };
Line range hint
32-37
: 카테고리 테이블 참조 방식의 일관성이 필요합니다.메모 작업에서는
SUPABASE.schemaMemo
를 사용하는 반면, 카테고리 작업에서는 하드코딩된 문자열을 사용하고 있습니다.다음과 같이 상수를 사용하도록 수정을 제안드립니다:
export const getCategories = async (supabaseClient: MemoSupabaseClient) => - supabaseClient.from('category').select('*').order('created_at', { ascending: false }); + supabaseClient.from(SUPABASE.schemaCategory).select('*').order('created_at', { ascending: false }); export const insertCategory = async (supabaseClient: MemoSupabaseClient, categoryRequest: CategoryTable['Insert']) => - supabaseClient.from('category').insert(categoryRequest).select(); + supabaseClient.from(SUPABASE.schemaCategory).insert(categoryRequest).select();packages/shared/src/hooks/supabase/useMemoPatchMutation.ts (2)
13-15
: 인터페이스에 JSDoc 문서를 추가하면 좋을 것 같습니다.타입 정의는 잘 되어있지만, 인터페이스의 목적과 각 프로퍼티의 역할을 설명하는 문서가 있으면 더 좋을 것 같습니다.
다음과 같이 문서를 추가해보세요:
+/** + * useMemoPatchMutation 훅의 프로퍼티 인터페이스 + * @property supabaseClient - Supabase 클라이언트 인스턴스 + */ interface UseMemoPatchMutationProps extends UseMutationOptions<MutationData, MutationError, MutationVariables> { supabaseClient: MemoSupabaseClient; }
Line range hint
17-39
: 최적화 업데이트 로직을 별도 함수로 분리하면 좋을 것 같습니다.
onMutate
콜백 내부의 로직이 다소 복잡합니다. 이 로직을 별도의 유틸리티 함수로 분리하면 코드의 가독성과 테스트 용이성이 향상될 것 같습니다.다음과 같은 리팩토링을 제안합니다:
+const updateMemoOptimistically = async ( + queryClient: QueryClient, + id: MemoRow['id'], + memoRequest: MemoTable['Update'] +) => { + await queryClient.cancelQueries({ queryKey: QUERY_KEY.memos() }); + const previousMemos = queryClient.getQueryData<MemoSupabaseResponse>(QUERY_KEY.memos()); + + if (!previousMemos) throw new NoMemosError(); + + const { data: previousMemosData } = previousMemos; + + if (!previousMemosData) throw new NoMemosError(); + + const currentMemoIndex = previousMemosData.findIndex(memo => memo.id === id); + const currentMemoBase = previousMemosData.find(memo => memo.id === id); + + if (currentMemoIndex === -1 || !currentMemoBase) throw new NoMemoError(); + + previousMemosData.splice(currentMemoIndex, 1, { ...currentMemoBase, ...memoRequest }); + + await queryClient.setQueryData(QUERY_KEY.memos(), { ...previousMemos, data: previousMemosData }); + + return { previousMemos }; +}; export default function useMemoPatchMutation({ supabaseClient, ...useMutationProps }: UseMemoPatchMutationProps) { const queryClient = useQueryClient(); return useMutation<MutationData, MutationError, MutationVariables>({ ...useMutationProps, mutationFn: async ({ id, memoRequest }) => await updateMemo(supabaseClient, id, memoRequest), - onMutate: async ({ id, memoRequest }) => { - await queryClient.cancelQueries({ queryKey: QUERY_KEY.memos() }); - const previousMemos = queryClient.getQueryData<MemoSupabaseResponse>(QUERY_KEY.memos()); - - if (!previousMemos) throw new NoMemosError(); - - const { data: previousMemosData } = previousMemos; - - if (!previousMemosData) throw new NoMemosError(); - - const currentMemoIndex = previousMemosData.findIndex(memo => memo.id === id); - const currentMemoBase = previousMemosData.find(memo => memo.id === id); - - if (currentMemoIndex === -1 || !currentMemoBase) throw new NoMemoError(); - - previousMemosData.splice(currentMemoIndex, 1, { ...currentMemoBase, ...memoRequest }); - - await queryClient.setQueryData(QUERY_KEY.memos(), { ...previousMemos, data: previousMemosData }); - - return { previousMemos }; - }, + onMutate: async ({ id, memoRequest }) => + await updateMemoOptimistically(queryClient, id, memoRequest), }); }packages/web/src/app/[lng]/memos/components/legacy/MemoTable.tsx (1)
Line range hint
44-46
: 삭제 버튼의 UX 개선이 필요합니다.현재 삭제 버튼이 단순히 'x'로만 표시되어 있어 사용자 경험이 부족합니다. 다음과 같은 개선을 제안드립니다:
- <button type="button" onClick={() => handleDeleteClick(memo.id)} className="w-full text-center"> - x - </button> + <button + type="button" + onClick={() => handleDeleteClick(memo.id)} + className="btn btn-error btn-sm w-full text-center" + > + 삭제 + </button>추가로 고려해볼 사항들:
- 삭제 중 로딩 상태 표시
- 기본 confirm 대신 모달 사용
- 실수로 인한 삭제 방지를 위한 추가 확인 절차
packages/web/src/app/components/ExtensionDialog/index.tsx (1)
34-51
: 접근성 개선이 필요합니다.다이얼로그 컴포넌트의 접근성을 개선할 수 있습니다.
다음과 같은 개선사항을 제안드립니다:
<Dialog open={open} onOpenChange={setOpen}> - <DialogContent> + <DialogContent aria-describedby="dialog-description"> <DialogHeader> <DialogTitle>{extensionDialogInfo.message.title}</DialogTitle> - <DialogDescription>{extensionDialogInfo.message.description}</DialogDescription> + <DialogDescription id="dialog-description">{extensionDialogInfo.message.description}</DialogDescription> </DialogHeader> <DialogFooter> {extensionDialogInfo.message.cancel && ( - <Button onClick={handleCloseClick} variant="secondary"> + <Button onClick={handleCloseClick} variant="secondary" aria-label={extensionDialogInfo.message.cancel}> {extensionDialogInfo.message.cancel} </Button> )} - <Button onClick={handleUpdateClick}>{extensionDialogInfo.message.ok}</Button> + <Button onClick={handleUpdateClick} aria-label={extensionDialogInfo.message.ok}>{extensionDialogInfo.message.ok}</Button> </DialogFooter> </DialogContent> </Dialog>packages/web/src/modules/search-params/SearchParams.ts (3)
6-14
: 생성자의 null 체크 최적화가 필요합니다.12번 라인의 옵셔널 체이닝은 불필요합니다. 10번 라인에서 Set이 생성되었음이 보장되므로, non-null 단언을 사용할 수 있습니다.
다음과 같이 수정하는 것을 제안합니다:
- this.#searchParamsMap.get(key)?.add(value); + this.#searchParamsMap.get(key)!.add(value);
16-23
: get 메서드의 동작을 명확히 문서화해주세요.get 메서드가 첫 번째 값만 반환하는 것은 예상치 못한 동작을 초래할 수 있습니다.
메서드 위에 다음과 같은 JSDoc 주석 추가를 제안합니다:
/** * 주어진 키에 대한 첫 번째 값을 반환합니다. * 여러 값이 있는 경우 첫 번째 값만 반환되며, 값이 없는 경우 빈 문자열을 반환합니다. */
25-45
: add 메서드에도 동일한 null 체크 최적화가 필요합니다.29번 라인의 옵셔널 체이닝도 불필요합니다. 27번 라인에서 Set이 생성되었음이 보장됩니다.
다음과 같이 수정하는 것을 제안합니다:
- this.#searchParamsMap.get(key)?.add(value); + this.#searchParamsMap.get(key)!.add(value);packages/web/src/utils/supabase.server.ts (2)
Line range hint
13-26
: 설정 관리 개선 제안현재 구현은 잘 작동하지만, 더 나은 타입 안전성과 유지보수성을 위해 다음과 같은 개선을 고려해보세요:
CONFIG
객체에 대한 타입 검증 추가- 환경 변수 누락에 대한 명시적인 에러 처리
+const validateConfig = () => { + if (!CONFIG.supabaseUrl || !CONFIG.supabaseAnonKey) { + throw new Error('Missing required Supabase configuration'); + } +}; export const getSupabaseClient = () => { + validateConfig(); if (supabaseClient) return supabaseClient;
Line range hint
29-67
: 인증 구현에 대한 보안 검토인증 구현이 전반적으로 잘 되어 있습니다. 몇 가지 보안 관련 제안사항입니다:
- OAuth 리다이렉트 URL이 올바르게 구성되어 있음
- 에러 처리가 적절히 구현되어 있음
- 로그아웃 시 토큰 정리가 완벽함
추가 보안을 위한 제안:
- CSRF 토큰 구현 고려
- 로그인 시도 횟수 제한 추가
packages/web/src/modules/i18n/locales/en/translation.json (2)
13-20
: 에러 메시지 섹션 추가 필요현재 성공 메시지만 포함되어 있습니다. 사용자 경험 향상을 위해 다음과 같은 에러 상황에 대한 메시지도 추가하는 것이 좋겠습니다:
- 네트워크 오류
- 권한 부족
- 잘못된 입력값
"toastMessage": { "refresh": "Refresh completed.", "memoEdited": "Memo has been edited.", "categoryEdited": "Category has been changed.", "memoDeleted": "Memo has been deleted.", "memoWishListDeleted": "Memo has been removed from the wish list.", - "memoWishListAdded": "Memo has been added to the wish list." + "memoWishListAdded": "Memo has been added to the wish list.", + "error": { + "network": "Network error occurred. Please try again.", + "permission": "You don't have permission for this action.", + "invalidInput": "Please check your input and try again." + } },
45-45
: 버전 설명 메시지 개선 제안현재 버전 설명이 다소 기술적입니다. 일반 사용자를 위해 더 친근한 문구로 수정하는 것이 좋겠습니다.
- "description": "Current Version: {{currentVersion}} | Latest Version: {{lastVersion}}", + "description": "You're using version {{currentVersion}}. Version {{lastVersion}} is now available!",packages/web/src/modules/search-params/SearchParams.test.ts (2)
55-55
: 테스트 설명에 오타가 있습니다"않는다.."에서 마침표가 중복되어 있습니다.
- test('key와 value에 해당하는 값이 없다면 제거하지 않는다..', () => { + test('key와 value에 해당하는 값이 없다면 제거하지 않는다.', () => {
3-75
: 테스트 커버리지 개선을 위한 제안다음과 같은 추가 테스트 케이스들을 고려해보시면 좋을 것 같습니다:
- 특수 문자가 포함된 파라미터 처리
- 빈 문자열 값 처리
- 메서드 호출 시 발생할 수 있는 에러 케이스
- URL 인코딩/디코딩이 필요한 케이스
추가 테스트 케이스 구현을 원하시면 도움을 드릴 수 있습니다.
packages/web/src/app/[lng]/memos/components/Header/index.tsx (2)
Line range hint
39-40
: Supabase 클라이언트 사용 방식 개선이 필요합니다.현재 사용 중인
getSupabaseClient
함수는 더 이상 권장되지 않습니다. 대신useSupabaseClient
훅을 사용하는 것이 좋습니다.다음과 같이 수정하는 것을 제안드립니다:
- const supabaseClient = getSupabaseClient(); + const supabaseClient = useSupabaseClient();관련하여 import 구문도 업데이트가 필요합니다:
- import { getSupabaseClient, signout } from '@src/utils/supabase.server'; + import { useSupabaseClient } from '@supabase/auth-helpers-react'; + import { signout } from '@src/utils/supabase.server';
Line range hint
46-47
: 사용자 아바타 URL의 안전한 처리가 필요합니다.옵셔널 체이닝을 사용한 fallback 처리는 잘 되어있으나, 이미지 URL의 유효성 검사가 추가되면 좋을 것 같습니다.
다음과 같은 유틸리티 함수 사용을 제안드립니다:
const validateImageUrl = (url: string, fallback: string): string => { if (!url || !url.match(/^https?:\/\/.+/)) return fallback; return url; }; // 사용 예시 const userAvatarUrl = validateImageUrl( user?.data?.user?.identities?.[0]?.identity_data?.avatar_url, '/images/pngs/default_image_user.png' );chrome-extension/lib/background/index.ts (2)
Line range hint
71-71
: OpenAI 모델명을 확인해주세요.'gpt-4o-mini'라는 모델명이 올바른지 확인이 필요합니다. 일반적으로 알려진 OpenAI 모델명과 다릅니다.
다음과 같이 수정하는 것을 제안드립니다:
- model: 'gpt-4o-mini', + model: 'gpt-4', // 또는 다른 적절한 OpenAI 모델
Line range hint
64-83
: 스트리밍 응답 처리 로직 검토가 필요합니다.OpenAI API 호출 시 에러 처리가 누락되어 있습니다. 스트리밍 응답 처리 중 발생할 수 있는 예외 상황에 대한 처리가 필요합니다.
다음과 같은 에러 처리 로직 추가를 제안드립니다:
try { const stream = await openai.chat.completions.create({ model: 'gpt-4', messages: [ { role: 'system', content: prompt }, { role: 'user', content: pageContent }, ], stream: true, }); for await (const chunk of stream) { const message = chunk.choices[0]?.delta?.content; port.postMessage(message); } + } catch (error) { + console.error('OpenAI API 호출 중 오류 발생:', error); + port.postMessage({ error: '응답을 처리하는 중 오류가 발생했습니다.' }); + }pages/options/src/components/OptionForm.tsx (1)
Line range hint
23-39
: 다운로드 핸들러의 에러 처리를 개선하면 좋을 것 같습니다.
handleCSVDownloadClick
와handleJSONDownloadClick
함수에서 데이터가 없는 경우 사용자에게 아무런 피드백 없이 함수가 종료됩니다. 사용자 경험 향상을 위해 에러 메시지를 표시하는 것이 좋을 것 같습니다.다음과 같이 개선하는 것을 제안드립니다:
const handleCSVDownloadClick = async () => { const memos = await getMemos(); - if (!memos?.data) return; + if (!memos?.data) { + overlay.open(({ unmount }) => ( + <Toast message={I18n.get('error_no_data')} onClose={unmount} /> + )); + return; + } const csvBlob = convertToCSVBlob(memos.data); downloadBlob(csvBlob, { fileExtension: 'csv' }); };packages/web/src/app/[lng]/memos/components/MemoDialog/index.tsx (1)
35-38
: 폼 유효성 검사 강화 필요MemoInput 타입을 사용하여 타입 안정성이 향상되었지만, 폼 유효성 검사가 부족합니다.
다음과 같은 개선을 제안합니다:
const { register, watch, setValue } = useForm<MemoInput>({ defaultValues: { memo: '', }, + resolver: zodResolver(memoSchema), });
pages/side-panel/src/components/MemoForm.tsx (2)
56-64
: 메모 저장 로직의 에러 처리를 개선하면 좋겠습니다.현재 구현은 기능적으로는 문제가 없으나, 다음과 같은 개선사항을 제안드립니다:
- 네트워크 오류나 저장 실패 시 사용자에게 더 자세한 피드백 제공
- 재시도 메커니즘 추가
const saveMemo = async (data?: MemoInput) => { + try { const memo = data?.memo ?? watch('memo'); const isWish = data?.isWish ?? watch('isWish'); const formattedMemo = await getFormattedMemo({ memo, isWish }); if (memoData) mutateMemoPatch({ id: memoData.id, memoRequest: formattedMemo }); else mutateMemoPost(formattedMemo); + } catch (error) { + setIsSaved(false); + toast({ + title: I18n.get('toast_error_save'), + description: error instanceof Error ? error.message : '알 수 없는 오류가 발생했습니다.', + action: ( + <ToastAction altText="다시 시도" onClick={() => saveMemo(data)}> + 다시 시도 + </ToastAction> + ), + }); + } };
101-104
: 위시리스트 처리 중 로딩 상태 표시가 필요해 보입니다.사용자 경험 향상을 위해 위시리스트 처리 중임을 표시하는 로딩 상태를 추가하면 좋겠습니다.
+ const [isWishProcessing, setIsWishProcessing] = useState(false); const handleWishListClick = () => { + setIsWishProcessing(true); const memoWishListUrl = getMemoWishListUrl(memoData?.id); Tab.create({ url: memoWishListUrl }); + setIsWishProcessing(false); };packages/web/src/app/[lng]/memos/components/MemoView/MemoItem.tsx (1)
34-35
: URL 파라미터 관리 방식이 개선되었습니다.
useSearchParams
를 사용하여 URL 파라미터를 관리하는 방식이 더 체계적으로 변경되었습니다. 특히scroll: false
옵션을 통해 사용자 경험이 개선되었습니다.하지만 URL 파라미터 변경 시 사용자에게 피드백을 제공하는 것이 좋을 것 같습니다.
다음과 같이 토스트 메시지를 추가하는 것을 고려해보세요:
const handleContentClick = (event: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>) => { const id = event.currentTarget.id; if (!id) return; searchParams.set('id', id); router.replace(searchParams.getUrl(), { scroll: false }); + toast({ title: t('toastMessage.memoSelected') }); };
Also applies to: 59-60
packages/web/src/app/[lng]/memos/components/MemoView/MemoOption.tsx (1)
Line range hint
50-65
: 에러 처리를 개선하면 좋을 것 같습니다.삭제 작업 시 에러 처리가 미흡합니다. 다음과 같은 개선을 제안드립니다:
mutateDeleteMemo(memoId, { onSuccess: ({ data }) => { if (!data) return; const saveMemo = () => mutatePostMemo(data[0]); toast({ title: t('toastMessage.memoDeleted'), action: ( <ToastAction altText={t('toastActionMessage.memoDeleteCancel')} onClick={saveMemo}> {t('toastActionMessage.memoDeleteCancel')} </ToastAction> ), }); }, + onError: (error) => { + toast({ + title: t('toastMessage.error'), + description: error.message, + variant: 'destructive', + }); + }, });
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (115)
.coderabbit.yaml
(1 hunks)chrome-extension/lib/background/index.ts
(3 hunks)chrome-extension/utils/openai.ts
(1 hunks)package.json
(4 hunks)packages/shared/package.json
(1 hunks)packages/shared/src/constants/Config.ts
(1 hunks)packages/shared/src/constants/Cookie.ts
(1 hunks)packages/shared/src/constants/Extension.ts
(1 hunks)packages/shared/src/constants/Supabase.ts
(1 hunks)packages/shared/src/constants/Url.ts
(1 hunks)packages/shared/src/hooks/extension/index.ts
(1 hunks)packages/shared/src/hooks/extension/useSupabaseClientQuery.ts
(1 hunks)packages/shared/src/hooks/index.ts
(0 hunks)packages/shared/src/hooks/supabase/index.ts
(0 hunks)packages/shared/src/hooks/supabase/useCategoryPostMutation.ts
(1 hunks)packages/shared/src/hooks/supabase/useCategoryQuery.ts
(2 hunks)packages/shared/src/hooks/supabase/useMemoPatchMutation.ts
(1 hunks)packages/shared/src/hooks/supabase/useMemoPostMutation.ts
(1 hunks)packages/shared/src/hooks/supabase/useMemoQuery.ts
(2 hunks)packages/shared/src/hooks/supabase/useMemosQuery.ts
(1 hunks)packages/shared/src/hooks/supabase/useSupabaseClient.ts
(0 hunks)packages/shared/src/hooks/supabase/useSupabaseUser.ts
(1 hunks)packages/shared/src/hooks/useSearchParamsRouter.ts
(0 hunks)packages/shared/src/utils/Environment.ts
(1 hunks)packages/shared/src/utils/Notion.ts
(2 hunks)packages/shared/src/utils/Sentry.ts
(2 hunks)packages/shared/src/utils/String.ts
(1 hunks)packages/shared/src/utils/Supabase.ts
(2 hunks)packages/shared/src/utils/extension/Storage.ts
(2 hunks)packages/shared/src/utils/extension/Supabase.ts
(2 hunks)packages/shared/src/utils/extension/bridge/getExtensionManifest.ts
(1 hunks)packages/shared/src/utils/extension/bridge/getSidePanelOpen.ts
(1 hunks)packages/shared/src/utils/extension/bridge/refetchTheMemos.ts
(1 hunks)packages/shared/src/utils/index.ts
(1 hunks)packages/shared/tsconfig.json
(1 hunks)packages/web/next-i18next.config.js
(0 hunks)packages/web/package.json
(1 hunks)packages/web/src/app/[lng]/layout.tsx
(2 hunks)packages/web/src/app/[lng]/login/components/LoginSection/ExtensionVersion.tsx
(1 hunks)packages/web/src/app/[lng]/login/components/LoginSection/index.tsx
(2 hunks)packages/web/src/app/[lng]/login/components/PersonalInformationInfo/index.tsx
(1 hunks)packages/web/src/app/[lng]/login/page.tsx
(1 hunks)packages/web/src/app/[lng]/memos/components/Header/RefreshButton.tsx
(1 hunks)packages/web/src/app/[lng]/memos/components/Header/index.tsx
(1 hunks)packages/web/src/app/[lng]/memos/components/MemoDialog/index.tsx
(2 hunks)packages/web/src/app/[lng]/memos/components/MemoSidebar/SidebarGroupCategory.tsx
(2 hunks)packages/web/src/app/[lng]/memos/components/MemoSidebar/SidebarMenuItemAddCategory.tsx
(1 hunks)packages/web/src/app/[lng]/memos/components/MemoSidebar/index.tsx
(1 hunks)packages/web/src/app/[lng]/memos/components/MemoSidebarTrigger/index.tsx
(1 hunks)packages/web/src/app/[lng]/memos/components/MemoView/MemoGrid.tsx
(2 hunks)packages/web/src/app/[lng]/memos/components/MemoView/MemoItem.tsx
(3 hunks)packages/web/src/app/[lng]/memos/components/MemoView/MemoOption.tsx
(4 hunks)packages/web/src/app/[lng]/memos/components/MemoView/index.tsx
(1 hunks)packages/web/src/app/[lng]/memos/components/legacy/MemoTable.tsx
(1 hunks)packages/web/src/app/[lng]/memos/constants/guide.ts
(0 hunks)packages/web/src/app/[lng]/memos/constants/index.ts
(0 hunks)packages/web/src/app/[lng]/memos/hooks/useGuide.ts
(1 hunks)packages/web/src/app/[lng]/memos/layout.tsx
(2 hunks)packages/web/src/app/[lng]/memos/page.tsx
(2 hunks)packages/web/src/app/[lng]/memos/setting/component/Setting/index.tsx
(1 hunks)packages/web/src/app/[lng]/memos/setting/component/SettingHeader/index.tsx
(1 hunks)packages/web/src/app/[lng]/memos/setting/page.tsx
(1 hunks)packages/web/src/app/[lng]/memos/types/Input.ts
(1 hunks)packages/web/src/app/[lng]/memos/types/index.ts
(1 hunks)packages/web/src/app/[lng]/memos/utils/guide.ts
(2 hunks)packages/web/src/app/auth/callback-email/route.ts
(2 hunks)packages/web/src/app/auth/callback/route.ts
(2 hunks)packages/web/src/app/components/ExtensionDialog/getExtensionDialogInfo.ts
(1 hunks)packages/web/src/app/components/ExtensionDialog/index.tsx
(1 hunks)packages/web/src/app/components/ExtensionDialog/useExtensionDialog.ts
(1 hunks)packages/web/src/app/components/Introduction.tsx
(1 hunks)packages/web/src/app/components/index.ts
(1 hunks)packages/web/src/app/i18n/locales/en/translation.json
(0 hunks)packages/web/src/components/Footer.tsx
(2 hunks)packages/web/src/components/ui/sidebar.tsx
(1 hunks)packages/web/src/constants/Config.ts
(1 hunks)packages/web/src/hooks/index.ts
(1 hunks)packages/web/src/hooks/useGetExtensionManifest.ts
(1 hunks)packages/web/src/hooks/useLanguage.ts
(1 hunks)packages/web/src/hooks/useMemoDeleteMutation.ts
(1 hunks)packages/web/src/hooks/useSupabaseClient.ts
(1 hunks)packages/web/src/middleware.ts
(1 hunks)packages/web/src/modules/i18n/client.js
(1 hunks)packages/web/src/modules/i18n/constant.ts
(1 hunks)packages/web/src/modules/i18n/index.ts
(1 hunks)packages/web/src/modules/i18n/locales/en/translation.json
(1 hunks)packages/web/src/modules/i18n/locales/ko/translation.json
(2 hunks)packages/web/src/modules/i18n/server.js
(1 hunks)packages/web/src/modules/i18n/type.ts
(1 hunks)packages/web/src/modules/i18n/util.ts
(1 hunks)packages/web/src/modules/local-storage/LocalStorage.ts
(1 hunks)packages/web/src/modules/local-storage/constant.ts
(1 hunks)packages/web/src/modules/local-storage/index.ts
(1 hunks)packages/web/src/modules/local-storage/type.ts
(1 hunks)packages/web/src/modules/local-storage/util.ts
(1 hunks)packages/web/src/modules/search-params/SearchParams.test.ts
(1 hunks)packages/web/src/modules/search-params/SearchParams.ts
(1 hunks)packages/web/src/modules/search-params/constant.ts
(1 hunks)packages/web/src/modules/search-params/index.ts
(1 hunks)packages/web/src/modules/search-params/type.ts
(1 hunks)packages/web/src/modules/search-params/useSearchParams.ts
(1 hunks)packages/web/src/utils/index.ts
(1 hunks)packages/web/src/utils/middleware.ts
(2 hunks)packages/web/src/utils/supabase.client.ts
(2 hunks)packages/web/src/utils/supabase.server.ts
(5 hunks)packages/web/tsconfig.json
(1 hunks)pages/content-ui/src/index.tsx
(1 hunks)pages/options/src/components/OptionForm.tsx
(2 hunks)pages/side-panel/src/components/LoginSection.tsx
(2 hunks)pages/side-panel/src/components/MemoForm.tsx
(4 hunks)pages/side-panel/src/components/MemoHeader.tsx
(1 hunks)pages/side-panel/src/hoc/withAuthentication.tsx
(1 hunks)pages/side-panel/src/types/Input.ts
(1 hunks)pages/side-panel/src/utils/Url.ts
(1 hunks)vitest.config.ts
(1 hunks)
💤 Files with no reviewable changes (8)
- packages/shared/src/hooks/index.ts
- packages/shared/src/hooks/supabase/index.ts
- packages/shared/src/hooks/supabase/useSupabaseClient.ts
- packages/shared/src/hooks/useSearchParamsRouter.ts
- packages/web/next-i18next.config.js
- packages/web/src/app/[lng]/memos/constants/guide.ts
- packages/web/src/app/[lng]/memos/constants/index.ts
- packages/web/src/app/i18n/locales/en/translation.json
🧰 Additional context used
🪛 Biome (1.9.4)
packages/web/src/modules/local-storage/LocalStorage.ts
[error] 3-11: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
🔇 Additional comments (159)
packages/web/src/app/[lng]/memos/types/index.ts (1)
1-1
: 배럴(barrel) 내보내기 패턴이 올바르게 구현되었습니다.
타입 시스템의 구조화가 잘 되어있습니다. 이는 코드의 가독성과 유지보수성을 향상시킵니다.
Input 모듈의 존재 여부와 내용을 확인하기 위해 다음 스크립트를 실행합니다:
✅ Verification successful
타입 내보내기가 올바르게 구현되었음을 확인했습니다.
Input.ts
파일이 존재하며 CategoryInput
인터페이스와 MemoInput
타입을 올바르게 정의하고 있습니다. 배럴 패턴을 통한 타입 내보내기는 코드의 구조화와 재사용성을 향상시키는 좋은 방법입니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the existence and content of Input module
# Check if Input.ts exists in the same directory
fd -t f "Input.ts" "packages/web/src/app/\[lng\]/memos/types"
# If exists, check its content for the mentioned types
rg -A 5 "interface CategoryInput|type MemoInput" "packages/web/src/app/\[lng\]/memos/types"
Length of output: 364
Script:
#!/bin/bash
# Let's try searching without escaping brackets and with proper path structure
fd -t f "Input.ts" "packages/web/src/app"
# Also search for any files containing Input in their name
fd "Input" "packages/web"
# Search for type definitions related to memos
rg -g "*.ts" "interface|type.*Input"
Length of output: 2391
Script:
#!/bin/bash
# Let's check the content of Input.ts file to verify the types
cat "packages/web/src/app/[lng]/memos/types/Input.ts"
Length of output: 156
packages/web/src/modules/search-params/constant.ts (1)
1-1
: 타입 안전성이 잘 구현되었습니다!
as const
어서션을 사용하여 배열을 읽기 전용으로 만들고 리터럴 타입을 보존한 것이 좋습니다. 이는 타입 안전성을 보장하고 실수로 인한 수정을 방지합니다.
packages/web/src/modules/i18n/index.ts (1)
1-3
: 모듈 구조가 잘 구성되어 있습니다!
배럴(barrel) 파일 패턴을 사용하여 관련 모듈들을 깔끔하게 구성하였습니다. 이는 다른 파일에서 import 할 때 편리성을 높여줄 것입니다.
참조된 모듈들의 존재 여부를 확인하기 위해 다음 스크립트를 실행합니다:
✅ Verification successful
모든 참조 모듈이 정상적으로 존재합니다!
검증 결과, 다음 모듈 파일들이 모두 올바르게 존재함을 확인했습니다:
- packages/web/src/modules/i18n/constant.ts
- packages/web/src/modules/i18n/util.ts
- packages/web/src/modules/i18n/type.ts
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: 참조된 모듈 파일들의 존재 여부 확인
# 현재 디렉토리의 상대 경로 확인
current_dir=$(dirname "packages/web/src/modules/i18n/index.ts")
# 각 모듈 파일 존재 여부 확인
echo "모듈 파일 확인 결과:"
for module in constant util type; do
fd -t f "^${module}\.(ts|js|tsx|jsx)$" "$current_dir"
done
Length of output: 553
packages/web/src/utils/index.ts (1)
3-3
: 모듈 경로 구조 검토 필요
utils 디렉토리 외부의 모듈을 재내보내기하는 것은 아키텍처 관점에서 바람직하지 않을 수 있습니다. search-params 모듈을 utils 디렉토리 내부로 이동하거나, 별도의 독립적인 모듈로 분리하는 것을 고려해보세요.
packages/shared/src/constants/Extension.ts (1)
1-4
: 상수 구조 변경에 따른 사용처 확인이 필요합니다.
EXTENSION_ID에서 EXTENSION.id로의 변경이 다른 파일들에 미치는 영향을 확인해야 합니다.
✅ Verification successful
Let me verify if there are any other potential usages or imports of the extension constant.
구조 변경이 올바르게 적용되어 있습니다
코드베이스 분석 결과, EXTENSION_ID에서 EXTENSION.id로의 변경이 모든 사용처에서 올바르게 반영되어 있습니다. 이전 EXTENSION_ID 상수의 사용이 발견되지 않았으며, 새로운 EXTENSION.id가 필요한 모든 곳에서 정상적으로 임포트되어 사용되고 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify all usages of the extension ID constant
# Check for old usage
echo "Checking for old EXTENSION_ID usage:"
rg "EXTENSION_ID"
# Check for new usage
echo -e "\nChecking for new EXTENSION.id usage:"
rg "EXTENSION\.id"
Length of output: 692
Script:
#!/bin/bash
# Check for imports of EXTENSION constant
echo "Checking for EXTENSION imports:"
rg "import.*EXTENSION.*from"
# Check for any other potential extension ID references
echo -e "\nChecking for direct extension ID references:"
rg "eaiojpmgklfngpjddhoalgcpkepgkclh"
Length of output: 1582
packages/shared/src/utils/Environment.ts (2)
3-3
: 환경 설정 일관성 검증이 필요합니다.
CONFIG.nodeEnv를 사용하는 방식이 다른 파일들과 일관되게 적용되어 있는지 확인이 필요합니다.
다음 스크립트로 nodeEnv 사용 패턴을 검증하겠습니다:
✅ Verification successful
환경 설정 사용 방식이 일관되게 적용되어 있습니다.
코드베이스 분석 결과, 환경 설정 사용이 다음과 같이 일관되게 구현되어 있습니다:
CONFIG.nodeEnv
는shared/src/utils/Environment.ts
에서 중앙 관리되며, 다른 모듈에서 import하여 사용process.env.NODE_ENV
는 주로 쿠키 설정과 빌드 설정에서만 직접 사용Config.ts
에서nodeEnv
설정을 안전하게 추상화하여 제공
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# NODE_ENV와 CONFIG.nodeEnv 사용 패턴 검색
# 기존 NODE_ENV 직접 사용 여부 확인
rg "NODE_ENV.*===.*'production'" -g '!node_modules'
# CONFIG.nodeEnv 사용 패턴 확인
rg "CONFIG\.nodeEnv.*===.*'production'" -g '!node_modules'
Length of output: 523
Script:
#!/bin/bash
# CONFIG 관련 전체 사용 패턴 확인
rg "CONFIG\." -g '!node_modules' -A 2
# process.env.NODE_ENV 전체 사용 패턴 확인
rg "process\.env\.NODE_ENV" -g '!node_modules' -A 2
# Environment.ts 파일이 import되는 위치 확인
rg "from.*Environment" -g '!node_modules'
Length of output: 5690
1-1
: CONFIG 객체의 타입 정의 확인이 필요합니다.
CONFIG 객체가 올바르게 타입 정의되어 있는지 확인하는 것이 중요합니다.
다음 스크립트를 실행하여 CONFIG 객체의 구조와 타입을 확인하겠습니다:
✅ Verification successful
Let me gather more information about the CONFIG usage and type definitions.
CONFIG 객체가 적절하게 구현되어 있으며 타입 안정성이 확보되었습니다.
CONFIG 객체는 다음과 같이 잘 구현되어 있습니다:
getSafeConfig
함수를 통해 환경 변수를 안전하게 관리nodeEnv
는 'development' | 'production' 타입으로 명시적 정의- 전체 코드베이스에서 일관되게 사용됨
따라서 Environment.ts
에서 CONFIG 객체를 사용하는 것은 적절하며 타입 안정성도 보장됩니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# CONFIG 객체의 타입 정의와 구조 확인
# CONFIG 타입 정의 검색
ast-grep --pattern 'type CONFIG = {
$$$
}'
# CONFIG 객체 구현 검색
ast-grep --pattern 'export const CONFIG = {
$$$
}'
Length of output: 1828
Script:
#!/bin/bash
# CONFIG 관련 추가 정보 수집
# getSafeConfig 함수 구현 확인
ast-grep --pattern 'function getSafeConfig($_'
# CONFIG 타입 추론을 위해 타입스크립트 인터페이스나 타입 정의 검색
ast-grep --pattern 'interface $_Config {
$$$
}'
# CONFIG 사용 패턴 확인
rg "CONFIG\." -A 2
Length of output: 4077
packages/web/src/app/components/index.ts (1)
2-2
: 새로운 ExtensionDialog 컴포넌트 내보내기가 추가되었습니다.
컴포넌트 내보내기 패턴이 일관성 있게 적용되어 있습니다.
ExtensionDialog 컴포넌트의 존재 여부를 확인하기 위해 다음 스크립트를 실행하겠습니다:
✅ Verification successful
ExtensionDialog 컴포넌트가 정상적으로 구현되어 있습니다.
ExtensionDialog 컴포넌트가 packages/web/src/app/components/ExtensionDialog/index.tsx
에 존재하며, 필요한 모든 관련 파일들이 함께 구현되어 있습니다:
useExtensionDialog.ts
: 다이얼로그 상태 관리 로직getExtensionDialogInfo.ts
: 다이얼로그 표시 정보 관리
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# ExtensionDialog 컴포넌트 파일의 존재 여부 확인
fd --type f "ExtensionDialog" packages/web/src/app/components
# 컴포넌트의 default export 확인
ast-grep --pattern 'export default function ExtensionDialog'
Length of output: 268
Script:
#!/bin/bash
# ExtensionDialog 컴포넌트 파일 추가 검색
fd --type f "ExtensionDialog.tsx?" packages/web/src/app/components
# ExtensionDialog 디렉토리의 모든 파일 내용 확인
fd --type f . packages/web/src/app/components/ExtensionDialog --exec cat {}
# default export 패턴 추가 검색
ast-grep --pattern 'export default $_'
Length of output: 162406
packages/shared/src/constants/Cookie.ts (1)
1-5
: 구조 변경이 잘 이루어졌습니다만, 주의가 필요합니다.
상수들을 하나의 객체로 통합한 것은 좋은 접근이지만, 이는 breaking change입니다. 다른 파일들에서 이 상수들을 import하는 방식을 업데이트해야 합니다.
다음 스크립트를 실행하여 영향을 받는 파일들을 확인하세요:
✅ Verification successful
상수 구조 변경이 안전하게 적용되어 있습니다
검색 결과를 분석해보니, 모든 파일에서 이미 새로운 COOKIE_KEY
객체 구조를 올바르게 사용하고 있습니다. 이전 상수명(COOKIE_KEY_ACCESS_TOKEN
등)을 사용하는 코드가 없으며, 모든 참조가 COOKIE_KEY.accessToken
과 같은 새로운 형식을 따르고 있습니다.
영향을 받는 파일들:
packages/web/src/utils/supabase.server.ts
packages/web/src/components/ui/sidebar.tsx
packages/web/src/app/auth/callback-email/route.ts
packages/web/src/app/auth/callback/route.ts
packages/web/src/app/[lng]/memos/layout.tsx
packages/shared/src/utils/extension/Supabase.ts
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: 이전 상수 사용 여부 확인
# 이전 상수명으로 사용되는 파일 검색
echo "이전 상수 사용 검색 중..."
rg "COOKIE_KEY_ACCESS_TOKEN|COOKIE_KEY_REFRESH_TOKEN|COOKIE_KEY_SIDEBAR_STATE"
Length of output: 123
Script:
#!/bin/bash
# Search for files importing from Cookie.ts and using COOKIE_KEY
echo "Searching for COOKIE_KEY usage..."
rg -l "COOKIE_KEY" --type ts
# Search for actual usage patterns of COOKIE_KEY
echo -e "\nSearching for COOKIE_KEY usage patterns..."
rg "COOKIE_KEY\." --type ts -A 2
Length of output: 2863
packages/web/src/modules/local-storage/index.ts (2)
1-3
: 모듈 내보내기가 잘 구성되어 있습니다!
모듈의 구조가 barrel 패턴을 따르고 있어 코드의 가독성과 유지보수성이 향상되었습니다.
5-5
: LocalStorage 클래스 구현을 확인해주세요.
LocalStorage 클래스가 올바르게 구현되어 있는지 확인이 필요합니다.
다음 스크립트를 실행하여 LocalStorage 클래스의 구현을 확인하세요:
✅ Verification successful
Let me gather more information about the LocalStorage implementation.
Let me check one more detail about the LocalStorageKeyType.
LocalStorage 클래스가 안전하게 구현되어 있습니다.
LocalStorage 클래스는 다음과 같은 특징을 가지고 있습니다:
- 타입 안전성이 보장된 get/set 메서드 구현
- 올바른 키 타입 제한 (guide, updateVersion, install)
- JSON 직렬화/역직렬화 처리
- 적절한 정적 메서드 사용
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: LocalStorage 클래스의 구현 확인
# LocalStorage 클래스의 구현 확인
ast-grep --pattern $'class LocalStorage {
$$$
static get($_) {
$$$
}
static set($_) {
$$$
}
$$$
}'
# 클래스 사용 패턴 확인
rg -A 3 "LocalStorage\.(get|set)"
Length of output: 633
Script:
#!/bin/bash
# LocalStorage 클래스 파일의 전체 내용 확인
fd "LocalStorage.ts" --exec cat {}
# LOCAL_STORAGE_VALUE_MAP 상수 확인
rg "LOCAL_STORAGE_VALUE_MAP" -A 3
Length of output: 1789
Script:
#!/bin/bash
# LocalStorageKeyType 타입 정의 확인
rg "LocalStorageKeyType" -B 2 -A 2
# 타입 파일 찾기
fd "types?.ts" --exec cat {}
Length of output: 5130
chrome-extension/utils/openai.ts (1)
1-1
: 설정 관리 방식이 개선되었습니다.
중앙 집중식 설정 관리로의 전환은 좋은 접근 방식입니다. 하지만 API 키와 같은 민감한 정보의 보안을 확인해주세요.
보안 설정을 확인하기 위해 다음 스크립트를 실행합니다:
Also applies to: 5-5
✅ Verification successful
API 키 관리가 적절하게 구현되어 있습니다.
환경 변수를 통한 API 키 관리와 .env 파일의 gitignore 설정이 확인되었습니다. 다음과 같은 보안 조치가 적절히 구현되어 있습니다:
- .env 파일이 .gitignore에 포함되어 있어 민감한 정보가 저장소에 노출되지 않습니다
- turbo.json에서 OPENAI_API_KEY가 환경 변수로 적절히 관리되고 있습니다
- getSafeConfig를 통해 환경 변수 값을 안전하게 처리하고 있습니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# CONFIG 객체가 환경 변수나 안전한 방식으로 API 키를 관리하는지 확인
# shared constants 파일에서 API 키 관리 방식 확인
rg -A 5 "openApiKey"
# gitignore 설정 확인
cat .gitignore | grep -i "env\|config"
Length of output: 348
Script:
#!/bin/bash
# getSafeConfig 함수의 구현을 확인
ast-grep --pattern 'function getSafeConfig($_,$_) { $$$ }'
# 환경 변수 관련 설정 파일 검색
rg -l "process\.env"
# Config 파일에서 API 키 관리 방식 전체 확인
rg -A 10 "OPENAI_API_KEY"
Length of output: 1476
packages/web/src/modules/i18n/constant.ts (2)
1-2
: 타입 안정성이 보장된 언어 설정이 잘 구현되었습니다!
as const
타입 어서션을 사용하여 배열의 타입 안정성을 보장한 것이 좋습니다. 또한 fallbackLng
를 languages
배열에서 재사용하여 일관성을 유지한 것도 훌륭합니다.
3-4
: i18next 기본 설정이 적절하게 구성되었습니다.
defaultNS
와 cookieName
의 값이 i18next의 일반적인 컨벤션을 따르고 있어 적절합니다.
다음 스크립트를 실행하여 i18next 설정의 일관성을 확인하겠습니다:
✅ Verification successful
i18next 설정이 일관되게 적용되어 있음을 확인했습니다
constant.ts
에서 정의된 defaultNS
와 cookieName
값이 클라이언트(client.js
)와 서버(server.js
) 양쪽에서 일관되게 사용되고 있으며, 미들웨어에서도 올바르게 참조되고 있습니다. 특히:
util.ts
에서 i18next 초기화 옵션에 정확하게 반영됨middleware.ts
에서 쿠키 처리에 올바르게 활용됨client.js
에서 쿠키 설정에 일관되게 사용됨
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# i18next 관련 설정 파일들을 검색하여 일관성 확인
rg -g '*.{ts,tsx,js,jsx}' -l 'i18next.init|createInstance'
Length of output: 100
Script:
#!/bin/bash
# i18next 서버 설정 파일의 내용을 확인하여 defaultNS와 cookieName 사용을 검증
rg -A 5 -B 5 'i18next.init|createInstance' packages/web/src/modules/i18n/server.js
# i18next 관련 설정이 사용되는 다른 파일들도 확인
rg -g '*.{ts,tsx,js,jsx}' 'defaultNS|cookieName'
Length of output: 1716
packages/web/src/modules/search-params/index.ts (2)
1-2
: 타입과 상수 내보내기가 적절히 구성되어 있습니다.
타입을 먼저 선언하고 상수를 그 다음에 선언하는 구조가 명확하고 일관성 있습니다.
4-5
: 모듈 간 의존성 확인이 필요합니다.
useSearchParams
훅이 SearchParams
클래스에 의존할 것으로 예상됩니다. 순환 참조가 없는지 확인해 주세요.
다음 스크립트로 의존성을 확인할 수 있습니다:
✅ Verification successful
Let me gather more information about the dependencies by checking the full content of both files.
의존성 구조가 올바르게 구현되어 있습니다.
useSearchParams
훅은 SearchParams
클래스를 적절하게 활용하고 있으며, 순환 참조 문제가 없습니다. useSearchParams
는 Next.js의 기본 훅을 확장하여 SearchParams
클래스의 기능을 제공하는 래퍼 역할을 수행합니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: 모듈 간 의존성 확인
# SearchParams.ts와 useSearchParams.ts 파일 내용 확인
echo "=== SearchParams.ts 파일 내용 ==="
rg -A 5 "import.*useSearchParams" "./packages/web/src/modules/search-params/SearchParams.ts" || true
echo -e "\n=== useSearchParams.ts 파일 내용 ==="
rg -A 5 "import.*SearchParams" "./packages/web/src/modules/search-params/useSearchParams.ts" || true
Length of output: 606
Script:
#!/bin/bash
# Description: 전체 파일 내용 확인
echo "=== SearchParams.ts 전체 내용 ==="
cat "./packages/web/src/modules/search-params/SearchParams.ts" || true
echo -e "\n=== useSearchParams.ts 전체 내용 ==="
cat "./packages/web/src/modules/search-params/useSearchParams.ts" || true
Length of output: 2469
packages/web/src/modules/i18n/type.ts (2)
Line range hint 3-11
: 타입 정의가 명확하고 잘 구조화되어 있습니다.
Language, LanguageType, LanguageParams의 타입 정의가 TypeScript의 기능을 잘 활용하여 구현되어 있습니다. 특히 typeof와 array index type을 사용한 방식이 타입 안정성을 잘 보장합니다.
1-1
: import 경로 변경에 대한 검증이 필요합니다.
languages 상수가 index 파일에서 올바르게 내보내지고 있는지 확인이 필요합니다.
다음 스크립트를 실행하여 import 경로 변경이 올바른지 확인하세요:
✅ Verification successful
import 경로 변경이 올바르게 이루어졌습니다.
languages 상수는 constant.ts에서 정의되어 있으며, index.ts에서 re-export되고 있습니다. settings.ts 파일은 더 이상 존재하지 않으며, 모든 import가 올바르게 '.' 경로를 통해 이루어지고 있습니다. 이는 코드베이스 전체에서 일관되게 적용되어 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the languages export in index.ts and its usage
# Check if languages is exported from index.ts
rg -l "export.*languages" "packages/web/src/modules/i18n/"
# Check for any potential broken imports
rg -l "import.*languages.*from.*['\"]\\./settings['\"]" "packages/web/src/"
Length of output: 217
Script:
#!/bin/bash
# Check the content of index.ts and settings.ts to verify the export
echo "=== Content of index.ts ==="
cat packages/web/src/modules/i18n/index.ts || true
echo -e "\n=== Content of settings.ts ==="
cat packages/web/src/modules/i18n/settings.ts || true
# Check if languages is imported from settings in other files
echo -e "\n=== Files importing languages from settings ==="
rg "import.*\{.*languages.*\}.*from.*['\"]./settings['\"]" packages/web/src/modules/i18n/
# Check if languages is imported from index in other files
echo -e "\n=== Files importing languages from index ==="
rg "import.*\{.*languages.*\}.*from.*['\"].['\"]" packages/web/src/modules/i18n/
Length of output: 952
Script:
#!/bin/bash
# Check the content of constant.ts as it might contain the languages export
echo "=== Content of constant.ts ==="
cat packages/web/src/modules/i18n/constant.ts
# Check if there are any other files importing languages
echo -e "\n=== All files importing languages ==="
rg "import.*languages" packages/web/src/
Length of output: 880
packages/shared/src/hooks/extension/index.ts (1)
3-3
: 새로운 useSupabaseClientQuery 훅 내보내기가 추가되었습니다.
기존의 barrel 파일 패턴을 잘 따르고 있습니다. 다만, useSupabaseClientQuery의 구현을 확인해보시기 바랍니다.
다음 스크립트를 실행하여 useSupabaseClientQuery 구현을 확인하겠습니다:
✅ Verification successful
useSupabaseClientQuery 구현이 적절하게 되어 있습니다.
useSupabaseClientQuery는 useSuspenseQuery를 사용하여 Supabase 클라이언트를 관리하고 있으며, 기존의 useSupabaseClient 훅을 대체하는 새로운 구현입니다. 이는 다음과 같은 장점이 있습니다:
- 캐싱과 재시도 로직이 내장되어 있습니다 (retry: 1)
- Suspense를 지원하여 로딩 상태 처리가 더 간단해집니다
- 일관된 queryKey를 사용하여 상태 관리가 용이합니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: useSupabaseClientQuery 구현 확인
# useSupabaseClientQuery 구현 확인
ast-grep --pattern 'export default function useSupabaseClientQuery() {
$$$
}'
# 이전 useSupabaseClient 사용처 확인
rg "useSupabaseClient" -A 3
Length of output: 11189
vitest.config.ts (2)
1-2
: 필요한 의존성이 올바르게 임포트되었습니다.
React 테스팅을 위한 플러그인과 Vitest 설정이 적절하게 임포트되었습니다.
8-8
: 글로벌 설정에 대한 보안 고려사항을 검토하세요.
globals: true
설정은 테스트 환경에서 전역 변수를 사용할 수 있게 하지만, 이는 테스트 격리성에 영향을 줄 수 있습니다.
테스트 파일에서 전역 변수 사용 여부를 확인하기 위해 다음 스크립트를 실행하세요:
✅ Verification successful
Let me analyze the test files to verify the impact of globals: true
setting.
globals: true
설정이 안전하게 사용되고 있습니다
테스트 파일들을 분석한 결과, 모든 테스트 전역 객체들(expect, test 등)이 명시적으로 import되어 사용되고 있으며, 테스트 격리성을 해칠 수 있는 전역 변수의 직접적인 사용은 발견되지 않았습니다. Playwright 테스트 프레임워크의 표준 사용 방식을 따르고 있어 안전합니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# 테스트 파일에서 전역 변수 사용 패턴 검색
rg -t ts -t js "describe|it|test" -A 5
Length of output: 130484
Script:
#!/bin/bash
# Search for global variable usage in test files
rg -t ts -t js "global\." tests/
Length of output: 34
Script:
#!/bin/bash
# Check test files for common test globals like expect, describe, test, etc.
rg -t ts -t js "^(import|const) \{.*?(expect|describe|test|it|jest|beforeEach|afterEach)" tests/
Length of output: 419
packages/web/src/modules/i18n/util.ts (2)
Line range hint 1-11
: 코드가 깔끔하게 정리되었습니다!
상수들을 로컬 모듈에서 가져오도록 변경하여 코드의 구조가 개선되었습니다. getOptions
함수의 구현이 명확하고 잘 구성되어 있습니다.
1-1
: cookieName
상수 제거의 영향을 확인해주세요.
cookieName
상수가 제거되었는데, 이로 인해 쿠키 기반의 언어 설정 지속성에 영향이 없는지 확인이 필요합니다.
다음 스크립트를 실행하여 cookieName
상수의 사용 여부를 확인해보세요:
✅ Verification successful
Let me gather more information about cookie-related functionality in the i18n module.
cookieName
상수 제거는 안전합니다
cookieName
상수가 client.js
에서 직접 사용되고 있었으나, 이는 i18next
라이브러리의 기본 쿠키 이름과 동일한 'i18next'를 사용하고 있었습니다. 상수를 제거하더라도 i18next-browser-languagedetector
가 동일한 쿠키 이름을 기본값으로 사용하므로 기능상의 영향이 없습니다.
packages/web/src/modules/i18n/client.js
에서i18next-browser-languagedetector
를 사용하고 있어 쿠키 기반 언어 설정이 자동으로 처리됩니다.- 현재 코드에서도
cookies.i18next
로 직접 접근하고 있어, 상수 제거가 실제 동작에 영향을 주지 않습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: cookieName 상수의 사용처를 검색합니다.
# 'i18next' 쿠키 관련 코드 검색
echo "Searching for i18next cookie usage:"
rg -i "i18next.*cookie"
# 쿠키 관련 설정 파일 검색
echo -e "\nSearching for cookie configuration files:"
fd -t f -e ts -e js "cookie|config"
Length of output: 827
Script:
#!/bin/bash
# Check i18n module implementation and cookie usage
echo "Checking i18n implementation files:"
rg -l "i18n" packages/web/src/
echo -e "\nChecking cookie usage in i18n related files:"
fd . packages/web/src/modules/i18n/ -t f -x rg -l "cookie"
echo -e "\nChecking content of Cookie.ts:"
cat packages/shared/src/constants/Cookie.ts
echo -e "\nChecking i18next configuration:"
rg "i18next" packages/web/src/ -A 5
Length of output: 5722
packages/web/src/modules/search-params/type.ts (1)
1-5
: 타입 정의가 명확하고 잘 구조화되어 있습니다.
타입스크립트의 typeof와 인덱스 접근을 활용하여 상수로부터 타입을 생성하는 방식이 적절합니다.
packages/web/src/app/[lng]/memos/setting/page.tsx (2)
1-1
: import 경로 변경이 올바르게 적용되었는지 확인이 필요합니다.
import 경로가 @src/app/i18n/type
에서 @src/modules/i18n
으로 변경되었습니다. 이는 코드베이스의 모듈 구조 개선을 위한 변경으로 보입니다.
다른 파일들에서도 동일한 변경이 일관되게 적용되었는지 확인하겠습니다:
✅ Verification successful
import 경로 변경이 성공적으로 완료되었습니다.
검증 결과, 모든 파일에서 @src/app/i18n/type
의 이전 import 경로가 @src/modules/i18n
으로 일관되게 변경되었음을 확인했습니다. 새로운 경로가 전체 코드베이스에서 올바르게 사용되고 있으며, 이전 경로를 사용하는 파일이 없습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: LanguageParams import 경로의 일관성 확인
# 이전 import 경로 사용 확인
echo "기존 import 경로 사용 확인:"
rg "from '@src/app/i18n/type'" -t tsx -t ts
# 새로운 import 경로 사용 확인
echo "\n새로운 import 경로 사용 확인:"
rg "from '@src/modules/i18n'" -t tsx -t ts
Length of output: 262
Script:
#!/bin/bash
# Description: LanguageParams import 경로의 일관성 확인 (수정된 버전)
# 이전 import 경로 사용 확인
echo "기존 import 경로 사용 확인:"
rg "@src/app/i18n/type"
# 새로운 import 경로 사용 확인
echo -e "\n새로운 import 경로 사용 확인:"
rg "@src/modules/i18n"
# i18n 관련 파일 구조 확인
echo -e "\n현재 i18n 관련 파일 구조:"
fd "i18n"
Length of output: 4746
Line range hint 1-11
: 모듈 구조 변경이 적절한지 확인이 필요합니다.
i18n 관련 모듈이 @src/modules
로 이동된 것은 더 나은 모듈화를 위한 것으로 보입니다. 전반적인 컴포넌트 구조는 Next.js의 국제화 라우팅 컨벤션을 잘 따르고 있습니다.
모듈 구조 변경의 영향을 확인하겠습니다:
✅ Verification successful
Let me gather more information about the i18n module structure and its usage.
모듈 구조 변경이 적절하게 이루어졌습니다.
i18n 모듈이 @src/modules/i18n
으로 이동된 것이 확인되었으며, 다음과 같은 이유로 이 변경이 적절합니다:
- 모든 i18n 관련 기능이
modules/i18n
디렉토리에 잘 구조화되어 있습니다 - client와 server 측 번역 로직이 명확하게 분리되어 있습니다
- 타입 정의(
LanguageParams
,LanguageType
)가 일관되게 사용되고 있습니다 - Next.js의 국제화 라우팅 패턴을 준수하며 모든 페이지에서 일관된 방식으로 사용되고 있습니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: i18n 모듈 구조 변경 확인
# modules 디렉토리의 i18n 관련 파일 구조 확인
echo "새로운 i18n 모듈 구조:"
fd . -t f -p "**/modules/i18n/**"
# 다른 i18n 관련 파일들의 위치 확인
echo "\n기타 i18n 관련 파일:"
fd i18n -t f
Length of output: 291
Script:
#!/bin/bash
# Check for i18n related imports and module structure
echo "Checking i18n related imports:"
rg -l "@src/modules/i18n" --type ts --type tsx
echo "\nChecking previous i18n module location:"
rg -l "import.*i18n" --type ts --type tsx
echo "\nChecking i18n type definitions:"
rg "LanguageParams" --type ts --type tsx -A 2
Length of output: 461
Script:
#!/bin/bash
# i18n 모듈 구조와 사용 패턴 분석
echo "i18n 관련 임포트 확인:"
rg "@src/modules/i18n"
echo "\ni18n 모듈 위치 확인:"
rg "import.*i18n"
echo "\nLanguageParams 타입 정의 및 사용 확인:"
rg "LanguageParams"
echo "\n현재 디렉토리 구조 확인:"
fd . --type directory | grep -i "i18n\|modules"
Length of output: 11470
packages/web/src/hooks/index.ts (1)
3-4
: 새로운 훅 내보내기가 일관된 패턴을 따르고 있습니다.
내보내기 패턴이 기존 훅들과 일치하여 코드 일관성이 잘 유지되고 있습니다.
새로운 훅의 구현을 확인하기 위해 다음 스크립트를 실행하겠습니다:
✅ Verification successful
Let me check the implementation of both hooks to ensure they are properly implemented.
새로운 훅들이 적절하게 구현되어 있으며, 일관된 패턴으로 내보내기가 이루어지고 있습니다.
useGetExtensionManifest
: Chrome 확장 프로그램의 매니페스트를 가져오는 훅으로, 적절한 에러 처리와 상태 관리가 구현되어 있습니다.useSupabaseClient
: 메모이제이션된 Supabase 클라이언트를 제공하며, 싱글톤 패턴으로 구현되어 있어 성능 최적화가 잘 되어 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: 새로운 훅 파일들의 존재 여부와 구현을 확인합니다.
echo "useGetExtensionManifest 훅 확인:"
fd "useGetExtensionManifest.ts" --type f
echo "\nuseSupabaseClient 훅 확인:"
fd "useSupabaseClient.ts" --type f
echo "\nuseSupabaseClient 사용 현황 확인:"
rg "useSupabaseClient" -A 3
Length of output: 10851
Script:
#!/bin/bash
# Check implementation of both hooks
echo "useGetExtensionManifest 구현 확인:"
cat packages/web/src/hooks/useGetExtensionManifest.ts
echo "\nuseSupabaseClient 구현 확인:"
cat packages/web/src/hooks/useSupabaseClient.ts
Length of output: 1162
packages/shared/src/utils/index.ts (1)
11-11
: String 모듈 추가가 확인되었습니다.
새로운 String 모듈의 추가는 적절해 보입니다. 이는 문자열 관련 유틸리티 함수들을 더 체계적으로 관리할 수 있게 해줄 것입니다.
String 모듈의 존재와 내용을 확인하기 위해 다음 스크립트를 실행합니다:
✅ Verification successful
String 모듈이 성공적으로 검증되었습니다.
String.ts 파일이 packages/shared/src/utils/ 경로에 존재하며, checkStringArray 함수를 올바르게 내보내고 있음을 확인했습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: String 모듈의 존재와 내용 확인
# String.ts 파일 찾기
fd -t f "String.ts" "packages/shared/src"
# 파일이 존재하면 내용 확인
if [ $? -eq 0 ]; then
echo "String.ts 파일 내용:"
rg -A 10 "export" $(fd -t f "String.ts" "packages/shared/src")
fi
Length of output: 413
packages/web/src/app/[lng]/memos/hooks/useGuide.ts (2)
2-2
: 로컬 스토리지 접근 방식이 개선되었습니다!
중앙 집중화된 로컬 스토리지 접근 방식을 사용함으로써 코드의 일관성과 유지보수성이 향상되었습니다.
7-7
: 가이드 체크 로직이 단순화되었습니다만, 일관성 검증이 필요합니다.
early return 패턴을 사용하여 코드가 더 깔끔해졌습니다. 다만, 'guide' 키가 다른 곳에서도 동일하게 사용되는지 확인이 필요합니다.
로컬 스토리지 키 사용의 일관성을 확인하기 위해 다음 스크립트를 실행하세요:
✅ Verification successful
'guide' 키의 사용이 일관되게 구현되어 있습니다.
코드베이스 검토 결과, 'guide' 키는 다음과 같이 일관되게 사용되고 있습니다:
guide.ts
에서 튜토리얼 완료 시setLocalStorageTrue('guide')
를 호출RefreshButton.tsx
에서도 동일한 키로setLocalStorageTrue('guide')
를 호출useGuide.ts
에서checkLocalStorageTrue('guide')
로 일관되게 확인
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# 로컬 스토리지의 'guide' 키 사용 검증
# 로컬 스토리지 관련 코드에서 'guide' 키워드 검색
echo "로컬 스토리지에서 'guide' 키 사용 확인:"
rg -l "localStorage.*['\"]guide['\"]" || rg -l "setLocalStorageTrue.*['\"]guide['\"]" || rg -l "checkLocalStorageTrue.*['\"]guide['\"]"
Length of output: 280
Script:
#!/bin/bash
# 'guide' 키워드가 사용된 파일들의 내용을 자세히 확인
echo "guide.ts 파일 내용:"
cat packages/web/src/app/[lng]/memos/utils/guide.ts
echo -e "\nRefreshButton.tsx 파일에서 guide 관련 코드:"
rg "guide" -A 3 -B 3 packages/web/src/app/[lng]/memos/components/Header/RefreshButton.tsx
Length of output: 1791
packages/web/tsconfig.json (1)
14-15
: Next.js 구성과의 호환성 확인이 필요합니다
Next.js 프로젝트에서 TypeScript 설정이 올바르게 적용되는지 확인이 필요합니다.
✅ Verification successful
TypeScript 설정이 Next.js와 호환됩니다
현재 설정은 Next.js 14.2.10 버전과 완벽하게 호환됩니다:
next
플러그인이 올바르게 구성되어 있습니다jsx: "preserve"
설정이 Next.js에 적합합니다ES2015
타겟은 Next.js의 지원 범위 내에 있습니다.next/types
가 올바르게 포함되어 있습니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Next.js 설정 파일들을 확인하여 TypeScript 관련 설정 검증
echo "Next.js 설정 파일 확인 중..."
fd -e js -e json -g "next.config.*"
# package.json에서 next 버전 확인
echo "Next.js 버전 확인 중..."
fd -g "package.json" --exec jq -r '.dependencies.next // .devDependencies.next'
Length of output: 326
Script:
#!/bin/bash
# Next.js 설정 파일의 내용 확인
echo "Next.js 설정 파일 내용:"
cat packages/web/next.config.js
# tsconfig.json 전체 내용 확인
echo -e "\nTypeScript 설정 파일 내용:"
cat packages/web/tsconfig.json
# Next.js 관련 의존성 확인
echo -e "\nNext.js 관련 의존성:"
cat packages/web/package.json | jq '.dependencies + .devDependencies'
Length of output: 2164
pages/side-panel/src/utils/Url.ts (1)
1-1
: 설정 상수 가져오기가 적절히 구현되었습니다.
공유 상수를 사용하여 설정을 중앙 집중화한 것은 좋은 접근 방식입니다.
packages/shared/src/hooks/extension/useSupabaseClientQuery.ts (1)
1-3
: 임포트 구성이 깔끔합니다!
모듈 임포트가 잘 구성되어 있으며, 일관된 경로 별칭(@src)을 사용하고 있습니다.
packages/web/src/modules/local-storage/util.ts (1)
1-1
: 깔끔한 import 구문입니다!
필요한 타입과 모듈을 명확하게 가져오고 있습니다.
packages/web/src/modules/local-storage/LocalStorage.ts (1)
1-1
: 타입 정의 확인이 필요합니다.
LOCAL_STORAGE_VALUE_MAP
와 UpdateVersionType
가 임포트되었지만 사용되지 않고 있습니다. 이러한 타입들이 어떻게 사용될 예정인지 확인이 필요합니다.
✅ Verification successful
임포트된 타입들이 모두 사용되고 있습니다.
검색 결과를 통해 확인한 바로는:
LOCAL_STORAGE_VALUE_MAP
은util.ts
에서 로컬 스토리지 값을 설정하고 확인하는데 사용되고 있습니다.UpdateVersionType
은constant.ts
에서 버전 체크 함수의 타입으로 사용되고 있습니다.LocalStorageKeyType
은LocalStorage
클래스의 메서드에서 키 타입으로 사용되고 있습니다.
따라서 해당 임포트들은 모두 필요한 것으로 확인됩니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check how these types are used in other files
rg -t typescript "LOCAL_STORAGE_VALUE_MAP|UpdateVersionType" --no-filename
Length of output: 111
Script:
#!/bin/bash
# Search for type usage with ripgrep, without file type restriction
rg "LOCAL_STORAGE_VALUE_MAP|UpdateVersionType"
# Also check the index file that exports these types
fd "index.ts" --exec cat {} \;
Length of output: 31921
packages/web/src/constants/Config.ts (1)
3-7
: 설정 값들을 하나의 객체로 통합한 것이 좋습니다!
설정 값들을 CONFIG 객체로 통합함으로써 코드의 일관성과 유지보수성이 향상되었습니다.
packages/web/src/components/Footer.tsx (2)
1-1
: URL 상수 관리 방식의 개선이 확인되었습니다.
URL 상수들을 하나의 객체로 통합하여 관리하는 방식으로 변경된 것이 확인되었습니다. 이는 URL 관리의 일관성과 유지보수성을 향상시키는 좋은 변경사항입니다.
10-10
: Chrome 스토어 URL 참조 방식이 개선되었습니다.
기존의 개별 상수 방식에서 구조화된 객체 접근 방식으로 변경되었습니다. 다만, 다른 컴포넌트들에서도 동일한 방식으로 URL을 참조하고 있는지 확인이 필요합니다.
✅ Verification successful
Let me check the actual implementation of these files to ensure consistency.
Let me check the URL constant definition to ensure it's properly structured.
URL 참조 방식이 일관되게 적용되었음을 확인했습니다.
모든 Chrome 스토어 URL 참조가 URL.chromeStore
를 통해 일관되게 이루어지고 있으며, 이는 packages/shared/src/constants/Url.ts
에 중앙 집중화되어 정의되어 있습니다. Footer, Introduction, ExtensionDialog 컴포넌트 모두 동일한 방식으로 URL을 참조하고 있어 일관성이 유지되고 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: URL 상수 사용 방식의 일관성 검증
# 이전 URL_CHROME_STORE 상수 사용 여부 확인
echo "기존 URL_CHROME_STORE 상수 사용 검색:"
rg "URL_CHROME_STORE" -l
# 새로운 URL.chromeStore 사용 패턴 확인
echo "\n새로운 URL.chromeStore 사용 검색:"
rg "URL\.chromeStore" -l
Length of output: 349
Script:
#!/bin/bash
# Check the actual implementation in files using URL.chromeStore
echo "Footer.tsx implementation:"
rg -A 2 "URL\.chromeStore" packages/web/src/components/Footer.tsx
echo "\nIntroduction.tsx implementation:"
rg -A 2 "URL\.chromeStore" packages/web/src/app/components/Introduction.tsx
echo "\ngetExtensionDialogInfo.ts implementation:"
rg -A 2 "URL\.chromeStore" packages/web/src/app/components/ExtensionDialog/getExtensionDialogInfo.ts
# Also check if there are any other URL constant patterns
echo "\nChecking other URL patterns:"
rg "URL\." -l
Length of output: 1160
Script:
#!/bin/bash
# Find and check URL constant definition
echo "Finding URL constant definition:"
rg "const URL" -A 5
# Also check for any potential URL-related type definitions
echo "\nChecking URL-related types:"
rg "type.*URL" -A 3
Length of output: 737
packages/shared/src/utils/Notion.ts (2)
1-1
: 설정 관리 개선이 잘 이루어졌습니다!
설정값을 CONFIG
객체로 중앙 집중화하는 리팩토링이 잘 진행되었습니다.
12-12
: CONFIG 객체의 속성 존재 여부를 확인해주세요.
CONFIG.makeWebhookNotionApi
속성이 올바르게 설정되어 있는지 확인이 필요합니다.
✅ Verification successful
Let me verify the getSafeConfig
function to ensure proper error handling and default values.
Let me check the implementation of getSafeConfig
function one more time with a different pattern.
CONFIG.makeWebhookNotionApi
속성이 안전하게 구현되어 있습니다.
getSafeConfig
함수가 환경 변수가 없을 경우 명시적인 에러를 발생시키며, makeWebhookNotionApi
속성은 'development' 또는 'production' 값만 허용하도록 타입이 정의되어 있습니다. 설정이 올바르게 구현되어 있어 안전하게 사용할 수 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# CONFIG 객체에서 makeWebhookNotionApi 속성의 정의를 확인
# CONFIG 정의 확인
ast-grep --pattern 'export const CONFIG = {
$$$
makeWebhookNotionApi: $_,
$$$
}'
# 다른 파일에서의 사용 패턴 확인
rg "CONFIG.makeWebhookNotionApi"
Length of output: 1437
Script:
#!/bin/bash
# getSafeConfig 함수 구현 확인
ast-grep --pattern 'function getSafeConfig($_,$_) {
$$$
}'
# 관련 타입 정의 확인
rg "type.*Config" -A 3
Length of output: 3609
Script:
#!/bin/bash
# getSafeConfig 함수의 정확한 구현 확인
rg "getSafeConfig" -A 5
# MAKE_WEBHOOK_NOTION_API 환경 변수 관련 타입 정의나 설정 확인
rg "MAKE_WEBHOOK_NOTION_API"
Length of output: 2490
packages/web/src/app/[lng]/memos/setting/component/SettingHeader/index.tsx (2)
Line range hint 1-12
: 구현이 깔끔하고 잘 되어있습니다! 👍
- 서버 사이드 렌더링 적용
- TypeScript를 활용한 타입 정의
- 컴포넌트 구조가 명확함
- UI 컴포넌트와 다국어 처리가 적절히 구현됨
3-4
: 모듈 경로 변경이 일관되게 적용되었는지 확인이 필요합니다.
import 경로가 @src/app/i18n
에서 @src/modules/i18n
으로 변경되었습니다. 이는 모듈 구조 개선을 위한 변경으로 보입니다.
다음 스크립트를 실행하여 프로젝트 전체에서 i18n 관련 import 경로가 일관되게 변경되었는지 확인하겠습니다:
✅ Verification successful
i18n 모듈 경로가 일관되게 적용되어 있습니다.
검색 결과를 분석한 결과, 모든 파일에서 새로운 경로인 @src/modules/i18n
을 사용하고 있으며, 이전 경로인 @src/app/i18n
을 사용하는 파일이 없음을 확인했습니다. 따라서 import 경로 변경이 프로젝트 전체에 걸쳐 일관되게 적용되어 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: i18n 모듈의 import 경로 일관성 검사
echo "기존 경로(@src/app/i18n) 사용 여부 확인:"
rg "@src/app/i18n" -t tsx -t ts
echo "\n새로운 경로(@src/modules/i18n) 사용 확인:"
rg "@src/modules/i18n" -t tsx -t ts
Length of output: 273
Script:
#!/bin/bash
# Description: i18n 모듈의 import 경로 일관성 검사 (수정된 버전)
echo "기존 경로(@src/app/i18n) 사용 여부 확인:"
rg --type-add 'ts:*.{ts,tsx}' --type ts "@src/app/i18n"
echo -e "\n새로운 경로(@src/modules/i18n) 사용 여부 확인:"
rg --type-add 'ts:*.{ts,tsx}' --type ts "@src/modules/i18n"
echo -e "\ni18n 모듈 파일 위치 확인:"
fd -e ts -e tsx "i18n" src/
Length of output: 4895
packages/shared/src/utils/extension/bridge/refetchTheMemos.ts (2)
1-1
: 상수 가져오기 방식의 개선이 확인되었습니다.
상수 관리 구조가 개선되어 더 체계적으로 변경되었습니다. EXTENSION
객체를 통한 통합된 상수 관리는 좋은 접근 방식입니다.
6-6
: 확장 프로그램 ID 참조 방식이 일관되게 수정되었습니다.
EXTENSION.id
를 사용하는 방식으로 변경된 것이 확인되었습니다. 이는 확장 프로그램 관련 상수들의 일관된 관리를 위한 리팩토링과 잘 부합합니다.
다른 파일들에서도 동일한 방식으로 변경되었는지 확인하겠습니다:
✅ Verification successful
Let me generate additional verification scripts to check for any potential inconsistencies:
확장 프로그램 ID 참조가 일관되게 적용되었음을 확인했습니다
코드베이스 전체를 검사한 결과, 모든 chrome.runtime.sendMessage
호출에서 EXTENSION.id
를 일관되게 사용하고 있으며, 이전 방식인 EXTENSION_ID
는 더 이상 사용되지 않음을 확인했습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify consistent usage of EXTENSION.id across the codebase
# Check for any remaining usage of EXTENSION_ID
rg "EXTENSION_ID"
# Check the new pattern usage
rg "EXTENSION\.id"
Length of output: 520
Script:
#!/bin/bash
# Search for any chrome.runtime.sendMessage usage to ensure we haven't missed any cases
rg "chrome\.runtime\.sendMessage" -A 1
# Search for any extension ID related constants or configurations
ast-grep --pattern 'const EXTENSION = { $$$'
Length of output: 1082
packages/web/src/app/[lng]/login/components/PersonalInformationInfo/index.tsx (2)
Line range hint 4-13
: 구현이 깔끔하고 타입 안전성이 잘 보장되어 있습니다.
컴포넌트가 다음과 같은 좋은 패턴을 따르고 있습니다:
- TypeScript를 통한 명확한 타입 정의
- i18n 훅의 올바른 사용
- 단일 책임 원칙을 잘 지킨 간결한 구조
1-2
: 모듈 구조 변경이 올바르게 적용되었는지 확인이 필요합니다.
import 경로가 @src/app/i18n
에서 @src/modules/i18n
으로 변경되었습니다. 이는 i18n 관련 모듈의 구조 개선을 위한 리팩토링의 일부로 보입니다.
다음 스크립트를 실행하여 i18n 모듈의 새로운 구조가 일관되게 적용되었는지 확인하겠습니다:
✅ Verification successful
i18n 모듈 경로 변경이 올바르게 적용되었음을 확인했습니다.
검색 결과를 통해 다음 사항들을 확인했습니다:
- 모든 파일에서
@src/modules/i18n
경로를 일관되게 사용하고 있습니다. - 이전 경로인
@src/app/i18n
을 사용하는 파일이 없습니다. packages/web/src/modules/i18n/
디렉토리가 존재합니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: i18n 모듈의 새 경로가 일관되게 사용되고 있는지 확인
# 이전 경로를 사용하는 파일이 있는지 확인
echo "이전 경로 사용 확인 중..."
rg "@src/app/i18n"
# 새 경로의 실제 존재 여부 확인
echo "새 모듈 구조 확인 중..."
fd -t f . "src/modules/i18n"
Length of output: 235
Script:
#!/bin/bash
# i18n 모듈 구조 확인을 위한 더 자세한 검색
# 1. 전체 저장소에서 i18n 관련 파일 검색
echo "=== i18n 관련 파일 검색 ==="
fd "i18n"
# 2. i18n import 사용 패턴 검색
echo -e "\n=== i18n import 패턴 검색 ==="
rg "from ['\"]@src.*i18n" -A 1
# 3. modules 디렉토리 구조 확인
echo -e "\n=== modules 디렉토리 구조 확인 ==="
fd . "modules" -t d
# 4. 현재 파일의 실제 위치 확인
echo -e "\n=== 대상 파일 위치 확인 ==="
fd "PersonalInformationInfo"
Length of output: 7650
packages/web/src/hooks/useSupabaseClient.ts (1)
1-5
: 전역 변수 사용에 대한 주의 필요
전역 변수 client
를 사용하는 것은 다음과 같은 잠재적인 문제를 일으킬 수 있습니다:
- 테스트 환경에서 격리가 어려움
- 여러 Supabase 프로젝트를 동시에 사용해야 하는 경우 문제 발생 가능
다음 스크립트를 실행하여 다중 Supabase 프로젝트 사용 여부를 확인하세요:
✅ Verification successful
전역 변수 client
사용은 안전합니다
코드베이스 분석 결과, 현재 구현은 다음과 같은 이유로 안전합니다:
- 단일 Supabase 프로젝트만 사용 중이며,
CONFIG.supabaseUrl
로 중앙 관리됨 getSupabaseClient()
는 브라우저 환경에 최적화된 클라이언트를 생성- 전역 변수는 클라이언트 인스턴스를 메모이제이션하는 용도로만 사용되어 적절함
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: 여러 Supabase 프로젝트 설정이 있는지 확인
# env 파일에서 여러 Supabase URL 검색
rg "SUPABASE.*URL" -g "*.env*"
Length of output: 181
Script:
#!/bin/bash
# Check for Supabase configuration and usage patterns
# Search for Supabase URL configuration in any file
rg "SUPABASE.*URL"
# Search for Supabase client initialization patterns
ast-grep --pattern 'createClient($$$)'
# Search for multiple Supabase project usage
rg "supabase" -l
Length of output: 2412
Script:
#!/bin/bash
# Check Supabase client implementation details
# Check the client implementation in supabase.client.ts
cat packages/web/src/utils/supabase.client.ts
# Check if there are multiple client instances
rg "createClient\(" -A 5
# Check for any conditional client creation
rg "new.*Supabase" -A 5
Length of output: 905
packages/shared/src/utils/extension/Storage.ts (2)
1-1
: 설정 관리 개선이 잘 이루어졌습니다!
상수들을 중앙 집중화된 객체로 관리하도록 변경한 것이 좋은 개선사항입니다. 이는 설정 값의 유지보수성과 일관성을 향상시킵니다.
6-7
: 상수 정의 확인이 필요합니다.
SUPABASE.authToken
과 CONFIG.webUrl
상수가 올바르게 정의되어 있는지 확인이 필요합니다.
✅ Verification successful
상수가 올바르게 정의되어 있음을 확인했습니다
SUPABASE.authToken
과 CONFIG.webUrl
상수가 각각 다음 위치에서 적절하게 정의되어 있습니다:
packages/shared/src/constants/Supabase.ts
에서authToken: 'sb-czwtqukymcqoberdoltq-auth-token'
packages/shared/src/constants/Config.ts
에서webUrl: getSafeConfig('WEB_URL', process.env.WEB_URL)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the constant definitions
# Check for SUPABASE.authToken definition
rg -A 2 "SUPABASE\s*=\s*{[^}]*authToken"
# Check for CONFIG.webUrl definition
rg -A 2 "CONFIG\s*=\s*{[^}]*webUrl"
Length of output: 331
Script:
#!/bin/bash
# Search for SUPABASE constant definition
rg "export const SUPABASE" -A 5
# Search for CONFIG constant definition
rg "export const CONFIG" -A 5
# Alternative search for these constants
rg "SUPABASE.*=.*{" -A 5
rg "CONFIG.*=.*{" -A 5
# Search for files that might contain these constants
fd -e ts -e js -x grep -l "SUPABASE\|CONFIG"
Length of output: 2522
pages/content-ui/src/index.tsx (1)
1-2
: 임포트 간소화 검증 필요
여러 유틸리티 함수들의 임포트가 제거되었습니다. 특히 getMemo
, insertMemo
, getSupabaseClient
등의 제거는 기존 기능에 영향을 줄 수 있습니다.
다음 스크립트를 실행하여 제거된 기능들이 다른 곳으로 적절히 이전되었는지 확인하겠습니다:
✅ Verification successful
임포트 변경이 적절히 처리됨
코드베이스 분석 결과, 제거된 기능들이 다른 컴포넌트로 적절히 이전되었음을 확인했습니다:
getMemo
,insertMemo
함수들은packages/shared/src/utils/Supabase.ts
에서 중앙 관리되고 있습니다.- Supabase 클라이언트 관련 기능은
packages/shared/src/hooks/supabase/
디렉토리에서 체계적으로 관리되고 있습니다. OPEN_SIDE_PANEL_ID
와responsePageContent
는 extension 관련 유틸리티로 적절히 유지되고 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: 제거된 기능들이 다른 파일로 이전되었는지 확인
# getMemo, insertMemo 함수 사용처 확인
rg "getMemo|insertMemo" -t typescript -t javascript
# Supabase 클라이언트 관련 새로운 구현 확인
rg "useSupabaseClient" -t typescript -t javascript
Length of output: 174
Script:
#!/bin/bash
# Description: 제거된 기능들이 다른 파일로 이전되었는지 확인
# getMemo, insertMemo 함수 사용처 확인
rg "getMemo|insertMemo"
# Supabase 클라이언트 관련 새로운 구현 확인
rg "useSupabaseClient"
# 전체 코드베이스에서 메모 관련 기능 검색
rg "memo" -i
# extension 관련 기능 검색
rg "OPEN_SIDE_PANEL_ID|responsePageContent"
Length of output: 54245
packages/shared/src/utils/extension/bridge/getSidePanelOpen.ts (2)
1-1
: 구조화된 상수 객체 사용으로의 개선을 승인합니다.
단일 상수 대신 구조화된 EXTENSION
객체를 사용하는 것은 확장 프로그램 관련 상수들을 더 체계적으로 관리할 수 있게 해주는 좋은 변경사항입니다.
6-6
: 전체 코드베이스에서 EXTENSION 객체 사용 확인이 필요합니다.
EXTENSION.id
를 사용하도록 변경된 부분이 정확합니다. 다만, 다른 파일들에서도 이러한 변경이 일관되게 적용되었는지 확인이 필요합니다.
다음 스크립트를 실행하여 검증하세요:
✅ Verification successful
Let me verify the usage of EXTENSION
object in the codebase to ensure we have a complete understanding.
EXTENSION
객체의 사용이 일관되게 적용되었음을 확인했습니다
코드베이스 검사 결과, EXTENSION.id
가 올바르게 사용되고 있으며 이전 EXTENSION_ID
상수의 사용이 완전히 제거되었음을 확인했습니다. EXTENSION
객체는 constants/Extension.ts
에서 정의되어 있고, 필요한 모든 파일에서 적절하게 임포트되어 사용되고 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# EXTENSION_ID에서 EXTENSION.id로의 마이그레이션이 완전히 이루어졌는지 확인
# EXTENSION_ID 사용 여부 확인
echo "Checking for any remaining EXTENSION_ID usage:"
rg "EXTENSION_ID"
# EXTENSION.id 사용 확인
echo -e "\nVerifying EXTENSION.id usage:"
rg "EXTENSION\.id"
Length of output: 698
Script:
#!/bin/bash
# Check EXTENSION object definition and imports
echo "Checking EXTENSION object definition:"
rg "export const EXTENSION" -A 3
echo -e "\nChecking EXTENSION imports:"
rg "import.*EXTENSION.*from"
Length of output: 1339
packages/web/src/modules/search-params/useSearchParams.ts (1)
8-8
: 타입 캐스팅 검증이 필요합니다
searchParams.entries()
의 결과를 SearchParamType[]
으로 타입 캐스팅하는 것이 안전한지 확인이 필요합니다. 런타임에서 예기치 않은 타입으로 인한 오류가 발생할 수 있습니다.
✅ Verification successful
타입 캐스팅이 안전합니다
searchParams.entries()
의 결과를 SearchParamType[]
으로 타입 캐스팅하는 것이 안전합니다. 그 이유는:
SearchParamKeyType
이 'id', 'isWish', 'category'로 명확하게 제한되어 있습니다SearchParamValueType
이 string 타입으로 정의되어 있어 URLSearchParams의 값과 일치합니다SearchParams
클래스가 내부적으로 Map과 Set을 사용하여 데이터를 안전하게 관리합니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# SearchParamType 정의를 확인
ast-grep --pattern 'type SearchParamType = $_'
# SearchParams 클래스에서 타입 검증 로직 확인
ast-grep --pattern 'class SearchParams {
constructor($_) {
$$$
}
}'
Length of output: 249
Script:
#!/bin/bash
# SearchParamKeyType과 SearchParamValueType 정의 확인
ast-grep --pattern 'type SearchParamKeyType = $_'
ast-grep --pattern 'type SearchParamValueType = $_'
# SearchParams 클래스의 전체 구현 확인
rg -A 10 "class SearchParams"
# 실제 사용 예시 확인
rg "new SearchParams" -A 2
Length of output: 1981
Script:
#!/bin/bash
# SEARCH_PARAMS_KEYS 상수 정의 확인
rg "SEARCH_PARAMS_KEYS.*=" -A 5
# searchParams.entries()의 실제 사용 확인
rg "searchParams\.entries\(\)" -A 2 -B 2
Length of output: 686
pages/side-panel/src/hoc/withAuthentication.tsx (2)
1-2
: 훅 임포트 구조가 개선되었습니다.
공유 훅을 사용하는 방식이 더 명확하고 구조화되었습니다. useSupabaseClientQuery
를 사용함으로써 React Query의 장점을 활용할 수 있게 되었습니다.
7-8
: 데이터 추출 방식 검증이 필요합니다.
useSupabaseClientQuery
와 useSupabaseUser
훅의 반환 타입이 변경되었습니다. 이러한 변경이 다른 컴포넌트에 영향을 미치지 않는지 확인이 필요합니다.
다음 스크립트를 실행하여 영향을 받는 컴포넌트를 확인하세요:
React Query를 사용하는 것은 좋은 선택입니다. 다만, 에러 처리와 로딩 상태 처리를 추가하는 것을 고려해보세요:
- const { data: supabaseClient } = useSupabaseClientQuery();
- const { user } = useSupabaseUser({ supabaseClient });
+ const { data: supabaseClient, isLoading: isClientLoading } = useSupabaseClientQuery();
+ const { user, isLoading: isUserLoading } = useSupabaseUser({ supabaseClient });
+
+ if (isClientLoading || isUserLoading) return <LoadingSpinner />;
✅ Verification successful
데이터 추출 방식이 일관되게 적용되어 있습니다.
검토 결과, useSupabaseUser
와 useSupabaseClientQuery
훅의 반환 타입이 일관성 있게 구현되어 있습니다. 두 훅 모두 useSuspenseQuery
를 사용하며, 반환되는 데이터 구조가 명확하게 정의되어 있습니다. 현재 구현된 데이터 추출 방식은 다음과 같이 안전합니다:
useSupabaseClientQuery
:data
속성을 통해 클라이언트 인스턴스 반환useSupabaseUser
:user
속성을 통해 사용자 정보 반환
다른 컴포넌트들도 동일한 패턴으로 데이터를 추출하고 있어 호환성 문제가 없습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: useSupabaseUser 훅의 사용 패턴을 검색합니다.
echo "useSupabaseUser 훅 사용 검색:"
rg "useSupabaseUser.*data:\s*user" -t tsx -t ts
echo "\nuseSupabaseClientQuery 사용 검색:"
rg "useSupabaseClient(Query)?\s*\(\)" -t tsx -t ts
Length of output: 290
Script:
#!/bin/bash
# Let's try searching without file type restrictions
echo "useSupabaseUser 훅 사용 검색:"
rg "useSupabaseUser"
echo "\nuseSupabaseClientQuery 사용 검색:"
rg "useSupabaseClientQuery"
# Let's also check the file structure to understand the file extensions
echo "\n파일 구조 확인:"
fd . --extension tsx --extension ts
Length of output: 14534
Script:
#!/bin/bash
# useSupabaseUser 훅의 구현 확인
echo "useSupabaseUser 훅 구현 확인:"
cat packages/shared/src/hooks/supabase/useSupabaseUser.ts
echo "\nuseSupabaseClientQuery 훅 구현 확인:"
cat packages/shared/src/hooks/extension/useSupabaseClientQuery.ts
Length of output: 1167
packages/shared/src/hooks/supabase/useCategoryQuery.ts (2)
3-3
: 임포트 변경이 적절히 이루어졌습니다.
getCategory
에서 getCategories
로의 함수명 변경이 일관성 있게 반영되었습니다.
12-12
: 쿼리 함수 구현이 개선되었습니다.
화살표 함수를 사용한 더 간단한 구현으로 변경되었습니다. 다만, 이 변경이 다른 파일들에도 영향을 미칠 수 있으므로 전체적인 리팩토링이 제대로 이루어졌는지 확인이 필요합니다.
다음 스크립트를 실행하여 getCategory
함수의 사용처가 모두 업데이트되었는지 확인하세요:
✅ Verification successful
Let me analyze the results from the shell scripts. I can see that there are no remaining references to getCategory
(singular), and all usages are consistently using getCategories
(plural). The function is used in three files:
- Defined in
packages/shared/src/utils/Supabase.ts
- Used in
packages/shared/src/hooks/supabase/useCategoryQuery.ts
- Used in
packages/web/src/app/[lng]/memos/layout.tsx
I can now generate the final response:
리팩토링이 일관되게 적용되었습니다
모든 코드베이스에서 getCategories
함수가 일관되게 사용되고 있으며, 이전 getCategory
함수에 대한 참조가 남아있지 않습니다. 리팩토링이 성공적으로 완료되었습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that all usages of getCategory have been updated to getCategories
# Check for any remaining references to getCategory
echo "Checking for remaining 'getCategory' references:"
rg "getCategory" --type ts
# Check for new getCategories usage
echo -e "\nVerifying 'getCategories' implementation:"
rg "getCategories" --type ts
Length of output: 866
packages/shared/src/hooks/supabase/useSupabaseUser.ts (1)
11-14
: 쿼리 구현이 깔끔하고 타입 안전성이 잘 보장되어 있습니다.
useSuspenseQuery의 구현이 간결하면서도 타입 안전성이 잘 보장되어 있습니다. Error 타입을 명시적으로 지정한 것이 좋은 실천 사례입니다.
packages/shared/src/utils/extension/bridge/getExtensionManifest.ts (2)
1-1
: 상수 구조 개선이 잘 이루어졌습니다.
상수 관리 방식이 개선되어 더 체계적인 구조로 변경되었습니다.
6-6
: EXTENSION 상수 변경에 따른 영향도 확인이 필요합니다.
EXTENSION_ID에서 EXTENSION.id로의 변경이 다른 파일들에도 일관되게 적용되었는지 확인이 필요합니다.
다음 스크립트를 실행하여 변경사항의 일관성을 검증하세요:
✅ Verification successful
Let me verify the usage of EXTENSION
constant to ensure we have a complete picture.
EXTENSION 상수 변경이 일관되게 적용되었음을 확인했습니다.
코드베이스 검사 결과, 이전 EXTENSION_ID
사용이 완전히 제거되었으며, 모든 관련 파일에서 EXTENSION.id
를 일관되게 사용하고 있습니다. EXTENSION
상수는 packages/shared/src/constants/Extension.ts
에 올바르게 정의되어 있으며, 모든 참조가 이 새로운 형식을 따르고 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# EXTENSION_ID 사용 여부 확인
echo "Checking for any remaining EXTENSION_ID usage:"
rg "EXTENSION_ID"
# EXTENSION.id 사용 패턴 확인
echo -e "\nChecking current EXTENSION.id usage:"
rg "EXTENSION\.id"
Length of output: 712
Script:
#!/bin/bash
# Check for EXTENSION constant definition and its usage
echo "Checking EXTENSION constant definition:"
rg "const EXTENSION" -A 3
# Check for any other potential EXTENSION usages
echo -e "\nChecking other EXTENSION usages:"
rg "EXTENSION\." --type ts
Length of output: 2013
packages/web/src/modules/local-storage/constant.ts (2)
5-6
: 타입 가드 구현이 잘 되어있습니다
타입 안전성을 보장하는 타입 가드 패턴이 적절하게 구현되어 있습니다.
13-15
: 값 매핑의 목적과 확장성 검토가 필요합니다
LOCAL_STORAGE_VALUE_MAP
이 현재 단일 값만 매핑하고 있습니다. 이 상수의 목적과 향후 확장 계획을 명확히 하면 좋을 것 같습니다.
다음 스크립트로 이 매핑이 다른 곳에서 어떻게 사용되는지 확인해보겠습니다:
pages/side-panel/src/components/LoginSection.tsx (2)
1-1
: 설정 관리 개선을 위한 좋은 변경사항입니다.
중앙 집중식 설정 관리를 위해 CONFIG
객체를 사용하는 것은 좋은 접근 방식입니다.
13-13
: CONFIG 객체의 구조 확인이 필요합니다.
CONFIG.webUrl
이 올바르게 설정되어 있는지 확인하겠습니다.
✅ Verification successful
Let me verify the getSafeConfig
function implementation to ensure proper configuration handling.
CONFIG 객체가 올바르게 구성되어 있음을 확인했습니다.
검증 결과:
CONFIG.webUrl
은 환경 변수에서 적절히 설정되고 있습니다- 여러 컴포넌트에서 일관되게 사용되고 있습니다
- 로그인 페이지 URL 구성에 문제가 없습니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# CONFIG 객체의 구조와 webUrl 속성 확인
# constants 파일에서 CONFIG 정의 확인
rg -A 5 "export const CONFIG"
# webUrl 사용 패턴 확인
rg "CONFIG\.webUrl"
Length of output: 2308
Script:
#!/bin/bash
# getSafeConfig 함수 구현 확인
ast-grep --pattern 'function getSafeConfig($_) {
$$$
}'
# CONFIG import 확인
rg "import.*CONFIG" pages/side-panel/src/
Length of output: 294
packages/web/src/app/[lng]/memos/page.tsx (2)
4-5
: getMemos 함수의 구현 확인이 필요합니다.
getMemo에서 getMemos로의 변경이 감지되었습니다. 이 변경이 올바르게 구현되었는지 확인이 필요합니다.
✅ Verification successful
getMemos 함수가 정상적으로 구현되어 있음을 확인했습니다.
getMemos 함수는 Supabase 클라이언트를 사용하여 메모 데이터를 조회하는 기능을 올바르게 구현하고 있습니다. 이전 getMemo 함수는 더 이상 존재하지 않으며, getMemos로의 변경이 적절하게 이루어졌습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# getMemos 함수의 구현을 확인합니다
ast-grep --pattern 'export const getMemos = $_'
Length of output: 312
Script:
#!/bin/bash
# Check if getMemo (singular) exists in the codebase
ast-grep --pattern 'export const getMemo = $_'
# Check the implementation details of getMemos
rg -A 5 "export const getMemos" packages/shared/src/utils/Supabase.ts
Length of output: 489
14-14
: 데이터 페칭 로직 검토가 필요합니다.
HydrationBoundaryWrapper의 queryFn이 getMemos로 변경되었습니다. 다음 사항들을 확인해 주세요:
- QUERY_KEY.memos()가 새로운 getMemos 함수와 일관성이 있는지
- 에러 처리가 적절히 구현되어 있는지
✅ Verification successful
Let me gather more information about the QUERY_KEY definition and getMemos implementation.
Let me check the getMemos implementation with a different pattern and look for error handling.
데이터 페칭 로직이 일관성 있게 구현되어 있습니다.
검증 결과:
- QUERY_KEY.memos()는 ['memos']를 반환하며, 이는 getMemos 함수와 함께 일관되게 사용되고 있습니다.
- getMemos 함수는 Supabase 클라이언트를 통해 데이터를 조회하며, 쿼리 키와 함께 적절히 캐시 관리가 이루어지고 있습니다.
- 에러 처리는 React Query의 기본 에러 처리 메커니즘을 통해 자동으로 처리됩니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# QUERY_KEY 정의와 에러 처리 구현을 확인
rg -A 5 "QUERY_KEY.memos"
ast-grep --pattern 'try { $$ } catch (error) { $$ }'
Length of output: 5521
Script:
#!/bin/bash
# Check QUERY_KEY definition and getMemos implementation
rg -A 3 "export const QUERY_KEY"
ast-grep --pattern 'const getMemos = async ($_) => { $$ }'
Length of output: 366
Script:
#!/bin/bash
# Check getMemos implementation and error handling
rg -A 10 "getMemos.*=.*async"
ast-grep --pattern 'export async function getMemos($_) { $$ }'
Length of output: 1902
packages/web/src/app/[lng]/login/page.tsx (1)
5-5
: i18n 모듈 경로 변경 검증 필요
모듈 구조 개선을 위한 import 경로 변경이 확인되었습니다. 다른 컴포넌트들에서도 동일한 방식으로 import가 이루어지고 있는지 확인이 필요합니다.
다음 스크립트를 실행하여 일관성을 검증하겠습니다:
✅ Verification successful
i18n 모듈 경로가 일관되게 적용되었음을 확인했습니다
모든 파일에서 새로운 import 경로 @src/modules/i18n
를 사용하고 있으며, 이전 경로 @src/app/i18n/type
를 사용하는 파일이 없음을 확인했습니다. 코드베이스 전반에 걸쳐 일관성이 유지되고 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify consistency of LanguageParams imports across the codebase
# Check for any remaining old imports
echo "Checking for old import path usage..."
rg "from '@src/app/i18n/type'" -l
# Check new import usage
echo "Checking new import path usage..."
rg "from '@src/modules/i18n'" -l
Length of output: 1675
packages/shared/tsconfig.json (3)
26-26
: 프로젝트 구조 단순화
include
패턴을 "src"
로 단순화한 것은 좋은 변경사항입니다. 하지만 모든 소스 파일이 src
디렉토리 내에 있는지 확인이 필요합니다.
✅ Verification successful
packages/shared
패키지의 TypeScript 파일이 모두 src
디렉토리 내에 있음을 확인했습니다
packages/shared
패키지의 모든 TypeScript 소스 파일이 src
디렉토리와 그 하위 디렉토리에 올바르게 위치해 있습니다. 따라서 tsconfig.json
의 "include": ["src"]
설정이 적절합니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# src 디렉토리 외부의 TypeScript 파일 검사
fd -e ts -e tsx -E src -E node_modules -E dist
Length of output: 1355
Script:
#!/bin/bash
# packages/shared/src 디렉토리의 TypeScript 파일 확인
fd -e ts -e tsx . packages/shared/src
# packages/shared 디렉토리의 전체 구조 확인
tree packages/shared
Length of output: 5455
5-5
: Jest 타입 정의 추가에 대한 검토
Jest 타입을 추가한 것은 테스트 인프라 통합을 위한 좋은 변경사항입니다. 단, 테스트 파일이 올바르게 구성되어 있는지 확인이 필요합니다.
✅ Verification successful
Jest 타입 정의 추가가 적절히 구성되었음을 확인했습니다
테스트 파일들이 packages/web/src/modules/
및 tests/e2e/
디렉토리에 적절히 존재하는 것을 확인했습니다. Jest 타입 정의를 shared 패키지의 tsconfig.json에 추가한 것은 타당한 변경사항입니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Jest 설정 및 테스트 파일 존재 여부 확인
fd -e test.ts -e test.tsx -e spec.ts -e spec.tsx
Length of output: 194
Script:
#!/bin/bash
# Jest 설정 파일 확인
fd jest.config
Length of output: 16
Script:
#!/bin/bash
# package.json에서 Jest 관련 설정 및 의존성 확인
fd package.json --exec cat {} | jq 'select(.jest != null or .dependencies.jest != null or .devDependencies.jest != null)'
Length of output: 125
Script:
#!/bin/bash
# shared 패키지의 테스트 관련 import 확인
rg "import.*jest" packages/shared/
Length of output: 36
9-9
:
모듈 해결 전략 변경에 대한 중요 검토
모듈 해결 방식의 주요 변경사항이 있습니다:
- 경로 매핑이 더 일반적인
@*
로 변경됨 - 모듈 시스템이 "es2015"로 변경됨
- moduleResolution이 "bundler"로 변경됨
이러한 변경은 번들러 호환성을 개선하지만, 기존 임포트 구문의 호환성을 확인해야 합니다.
Also applies to: 16-16, 20-20
✅ Verification successful
모듈 해결 전략 변경이 안전함을 확인했습니다
코드베이스 분석 결과, 다음과 같은 이유로 변경이 안전합니다:
- 대부분의 임포트가
@extension
,@src
,@root
등 명확한 접두사를 사용하고 있어 와일드카드 패턴@*
이 기존 임포트를 모두 포함합니다. - 모듈 시스템이 "es2015"로 변경되었지만, 대부분의 코드가 이미 ES 모듈 구문을 사용하고 있습니다.
- "bundler" moduleResolution은 Vite, Webpack과 같은 현대 번들러와의 호환성을 개선합니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# 기존 임포트 패턴 검사
rg -t typescript -t javascript "from ['\"]@src/"
Length of output: 87
Script:
#!/bin/bash
# TypeScript 파일에서 @ 접두사로 시작하는 모든 임포트 검색
rg "from ['\"]@" --type=ts --type=tsx
# 현재 tsconfig 파일들의 paths 설정 확인
fd tsconfig.json --exec cat {}
Length of output: 3291
Script:
#!/bin/bash
# 모든 소스 파일에서 @ 접두사로 시작하는 임포트 패턴 검색
rg "from ['\"]@"
# 파일 확장자 패턴 확인
fd -e ts -e tsx -e js -e jsx --exec echo {}
Length of output: 57228
packages/web/src/modules/i18n/server.js (1)
4-4
: import 경로 변경에 대한 검증이 필요합니다.
getOptions 함수의 import 경로가 './settings'에서 './util'로 변경되었습니다. 이 변경이 올바르게 적용되었는지 확인이 필요합니다.
✅ Verification successful
import 경로 변경이 정상적으로 확인되었습니다.
getOptions
함수가 util.ts
에 올바르게 구현되어 있으며, 다음과 같이 검증되었습니다:
util.ts
에서getOptions
함수가 정상적으로 export 되어 있음client.js
와server.js
모두 새로운 경로인 './util'에서 import하여 사용 중- 함수의 사용 방식이 동일하게 유지됨 (
getOptions(lng, ns)
형태로 호출)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify getOptions function exists in new location and check for any references to old location
# Check if getOptions exists in new location
echo "Checking for getOptions in util file..."
rg -l "export.*getOptions" "packages/web/src/modules/i18n"
# Check for any remaining references to old path
echo "Checking for remaining references to old path..."
rg -l "from.*['\"]./settings['\"]" "packages/web/src/modules/i18n"
Length of output: 363
Script:
#!/bin/bash
# Let's verify the actual implementation of getOptions in both files
# Check the implementation in util.ts
echo "=== Content of getOptions in util.ts ==="
ast-grep --pattern 'export $_ getOptions$_' -f packages/web/src/modules/i18n/util.ts -A 10
# Check if there are any remaining files that might contain the old implementation
echo -e "\n=== Files containing 'getOptions' ==="
rg "getOptions" packages/web/src/modules/i18n --type ts --type js -C 2
# Check for any potential usage differences
echo -e "\n=== Usage of getOptions in server.js ==="
rg "getOptions" packages/web/src/modules/i18n/server.js -C 2
Length of output: 3067
packages/shared/src/utils/Sentry.ts (2)
16-16
: DSN 설정 변경이 적절합니다
중앙 집중식 설정 관리로의 전환이 잘 이루어졌습니다.
4-4
: CONFIG 상수의 구조 확인이 필요합니다
CONFIG 객체에서 sentryDsn이 올바르게 정의되어 있는지 확인이 필요합니다.
✅ Verification successful
CONFIG 상수가 올바르게 구현되어 있습니다
CONFIG 객체에 sentryDsn이 적절하게 정의되어 있으며, getSafeConfig 함수를 통해 환경 변수가 없을 경우의 에러 처리도 잘 구현되어 있습니다. Sentry.ts 파일에서의 사용도 정확합니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# CONFIG 객체의 구조와 sentryDsn 속성 확인
# CONFIG 타입 정의 확인
ast-grep --pattern 'interface CONFIG {
$$$
sentryDsn: $_
$$$
}'
# CONFIG 객체 정의 확인
ast-grep --pattern 'export const CONFIG = {
$$$
sentryDsn: $_
$$$
}'
Length of output: 148
Script:
#!/bin/bash
# CONFIG 관련 파일 찾기
fd "config|constants" --type f
# CONFIG 정의 검색 (다른 패턴 시도)
rg -l "CONFIG.*=.*{" --type ts
# sentryDsn 문자열 검색
rg "sentryDsn" --type ts -A 2
Length of output: 1742
Script:
#!/bin/bash
# Config.ts 파일의 전체 내용 확인
cat packages/shared/src/constants/Config.ts
# Sentry.ts 파일의 전체 내용 확인
cat packages/shared/src/utils/Sentry.ts
Length of output: 1758
packages/web/src/utils/supabase.client.ts (3)
1-1
: 설정 관리 개선을 위한 import 구조 변경이 확인되었습니다.
개별 상수들을 중앙 집중식 설정 객체로 통합한 것은 좋은 접근 방식입니다. 이는 설정 관리를 더욱 용이하게 만들어줍니다.
Also applies to: 3-3
21-21
: 스키마 참조 방식이 개선되었습니다.
SUPABASE.schemaMemo
를 통한 스키마 참조는 타입 안정성을 높여주는 좋은 접근입니다.
스키마 상수가 올바르게 정의되어 있는지 확인하겠습니다:
✅ Verification successful
SUPABASE.schemaMemo
사용이 일관되게 구현되어 있습니다
packages/shared/src/constants/Supabase.ts
에서 schemaMemo
가 'memo'로 올바르게 정의되어 있으며, 이 상수가 클라이언트, 서버 및 공유 유틸리티 전반에 걸쳐 일관되게 사용되고 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify schema constant definition
# Check SUPABASE schema definition
ast-grep --pattern 'export const SUPABASE = {
$$$
schemaMemo: $_
$$$
}'
Length of output: 79
Script:
#!/bin/bash
# Let's try to find SUPABASE constant definition with ripgrep
rg "SUPABASE.*=.*{" -A 10
# Also search for schemaMemo usage
rg "schemaMemo" -A 2
Length of output: 2209
Line range hint 7-21
: 인증 관련 설정의 보안성 검증이 필요합니다.
쿠키 기반의 인증 저장소 구현이 적절해 보이나, 보안 설정을 확인해야 합니다.
다음 스크립트를 실행하여 환경 설정 값들이 올바르게 참조되는지 확인하세요:
✅ Verification successful
Let me gather more information about the configuration values.
Let me check one more thing about the configuration and environment variables.
인증 관련 쿠키 설정이 적절하게 구현되어 있습니다.
현재 구현된 인증 저장소의 쿠키 설정이 다음과 같이 적절한 보안 설정을 포함하고 있습니다:
SameSite=Strict
: CSRF 공격 방지Secure
: HTTPS 통신 강제max-age=31536000
: 1년의 적절한 만료 기간 설정path=/
: 올바른 경로 설정
또한 Supabase 클라이언트 구성이 환경 변수를 통해 안전하게 관리되고 있음을 확인했습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the configuration values and their usage
# Check if CONFIG values are properly defined
rg -A 2 "CONFIG\." "packages/shared/src/constants/"
# Verify cookie security settings across the codebase
rg "SameSite|Secure|max-age" --type ts
Length of output: 527
Script:
#!/bin/bash
# Check for CONFIG definition and usage
rg -p "CONFIG\s*=\s*{" --type ts -A 10
# Check for any other cookie-related security configurations
rg -p "cookie.*=.*" --type ts
# Look for any environment variable definitions that might contain Supabase configuration
fd .env --exec cat {} \; || true
Length of output: 2338
Script:
#!/bin/bash
# Check for Supabase configuration and environment variables
rg -p "supabase.*Key|SUPABASE_" --type ts -A 2
# Check for any environment variable files
fd -e env -e env.example -e env.local --exec cat {} \; || true
# Look for schema definitions
rg "schemaMemo" --type ts -A 5
Length of output: 4631
packages/shared/src/hooks/supabase/useMemosQuery.ts (2)
2-7
: 타입 정의가 잘 구현되었습니다!
타입 안전성을 높이기 위한 다음 변경사항들이 잘 구현되었습니다:
MemoSupabaseClient
를 타입으로 임포트QueryData
타입을getMemos
함수의 반환 타입으로부터 자동 유추QueryError
를Error
타입으로 명시적 정의
9-11
: 인터페이스 설계가 견고합니다!
UseMemosQueryProps
인터페이스가 다음과 같이 잘 설계되었습니다:
UseQueryOptions
를 확장하여 React Query의 모든 옵션을 지원queryKey
와queryFn
을 올바르게 제외하여 내부 구현과의 충돌 방지
packages/web/src/app/[lng]/login/components/LoginSection/ExtensionVersion.tsx (1)
3-6
: 깔끔한 의존성 관리와 타입 정의
모듈 임포트가 잘 구성되어 있으며, 공유 상수와 국제화 모듈을 적절히 활용하고 있습니다.
packages/web/src/app/[lng]/memos/components/MemoSidebarTrigger/index.tsx (2)
Line range hint 1-24
: 컴포넌트 구조 검토 완료
서버 컴포넌트로 적절히 구현되어 있으며, 사이드바 트리거와 툴팁 기능이 잘 통합되어 있습니다. 타입 정의와 번역 처리도 올바르게 구현되어 있습니다.
6-7
: i18n 모듈 경로 변경 검증 필요
i18n 관련 모듈의 import 경로가 변경되었습니다. 이는 전반적인 i18n 기능의 모듈화 작업의 일환으로 보입니다.
다음 스크립트를 실행하여 i18n 모듈의 일관된 사용을 확인하겠습니다:
✅ Verification successful
i18n 모듈 경로 변경이 일관되게 적용되었습니다
검증 결과, 모든 i18n 관련 import가 새로운 경로인 @src/modules/i18n
을 사용하고 있으며, 이전 경로인 @src/app/i18n
을 사용하는 파일이 없음을 확인했습니다. 경로 변경이 프로젝트 전반에 걸쳐 일관되게 적용되었습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# i18n 모듈 사용 패턴 검증
# 이전 경로 사용 여부 확인
echo "이전 경로 사용 검사 중..."
rg "@src/app/i18n/(type|server)"
# 새로운 경로 사용 패턴 확인
echo "새로운 경로 사용 패턴 검사 중..."
rg "@src/modules/i18n(/server)?"
Length of output: 4614
packages/web/src/hooks/useMemoDeleteMutation.ts (2)
2-2
: 불필요한 import 제거 및 필요한 import 추가 완료
사용하지 않는 MemoTable
타입을 제거하고 useSupabaseClient
훅을 추가한 변경이 적절합니다.
Also applies to: 5-5
13-13
: Supabase 클라이언트 관리 방식 개선
getSupabaseClient()
에서 useSupabaseClient
훅으로 변경한 것은 다음과 같은 이점이 있습니다:
- React 훅 패턴을 따르는 일관된 구현
- 컴포넌트 수준에서 클라이언트 인스턴스 관리
- 불필요한 클라이언트 재생성 방지
packages/shared/src/constants/Config.ts (1)
12-15
: 타입 어서션 사용이 올바른지 확인이 필요합니다.
nodeEnv
와 makeWebhookNotionApi
에 대한 타입 어서션이 적절히 구현되어 있습니다. 하지만 이러한 타입 제한이 애플리케이션의 다른 부분에서도 일관되게 적용되는지 확인이 필요합니다.
다음 스크립트로 타입 사용을 확인해보세요:
✅ Verification successful
Let me gather more information about the type usage and validation.
타입 어서션이 적절하게 사용되고 있음을 확인했습니다.
코드베이스 분석 결과:
nodeEnv
는isProduction
체크에서 올바르게 사용되고 있으며, 빌드 설정과 쿠키 보안 설정에서도 일관되게 'production'/'development' 값이 활용됩니다.makeWebhookNotionApi
는 Notion API 호출 시에만 사용되며, 타입 제한된 값이 적절히 전달됩니다.getSafeConfig
함수가 환경 변수의 존재 여부를 확실히 검증하므로, 타입 어서션의 안전성이 보장됩니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: CONFIG 객체의 타입 어서션 사용 확인
# nodeEnv와 makeWebhookNotionApi 타입 사용 검색
echo "Checking nodeEnv usage:"
rg "CONFIG\.nodeEnv" -A 2
echo "Checking makeWebhookNotionApi usage:"
rg "CONFIG\.makeWebhookNotionApi" -A 2
Length of output: 536
Script:
#!/bin/bash
# Check type definitions and validations for these environment variables
echo "Checking getSafeConfig implementation:"
rg "getSafeConfig" -A 5
echo "Checking environment type definitions:"
ast-grep --pattern 'type $_ = $$$| "development" |$$$| "production" |$$$'
echo "Checking environment validation:"
rg "process\.env\.(NODE_ENV|MAKE_WEBHOOK_NOTION_API)" -A 2
Length of output: 4049
packages/shared/src/hooks/supabase/useMemoQuery.ts (1)
3-3
: 함수 이름 변경이 일관성 있게 적용되었습니다!
getMemo
에서 getMemos
로의 변경이 다른 파일들의 변경사항과 잘 맞춰져 있습니다.
packages/web/src/app/auth/callback/route.ts (1)
4-4
: 쿠키 키 상수 통합 변경 승인
쿠키 키 상수들을 하나의 객체로 통합한 변경이 전반적인 코드 구조를 개선했습니다.
packages/web/src/hooks/useLanguage.ts (1)
1-2
: 모듈 구조 개선이 잘 이루어졌습니다.
i18n 관련 import를 @src/modules/i18n
으로 중앙화하여 모듈 구조가 개선되었습니다. 이는 코드의 유지보수성과 가독성을 향상시킵니다.
새로운 import 경로가 올바르게 설정되어 있는지 확인하겠습니다:
✅ Verification successful
모듈 구조 변경이 정상적으로 구현되었습니다.
@src/modules/i18n
경로의 모듈이 올바르게 구성되어 있으며, fallbackLng
와 Language
타입이 정확하게 export되어 있는 것을 확인했습니다. 모듈화가 잘 되어있어 코드의 구조와 유지보수성이 향상되었습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the existence of the new i18n module structure
# Check if the new i18n module exists and contains the required exports
fd -e ts -e tsx "i18n.(ts|tsx)$" src/modules/ --exec grep -l "export.*{.*fallbackLng.*}"
fd -e ts -e tsx "i18n.(ts|tsx)$" src/modules/ --exec grep -l "export.*{.*Language.*}"
Length of output: 378
Script:
#!/bin/bash
# Let's try searching in the packages directory structure
fd -e ts -e tsx "i18n.(ts|tsx)$" packages/ --exec grep -l "export.*{.*fallbackLng.*}"
fd -e ts -e tsx "i18n.(ts|tsx)$" packages/ --exec grep -l "export.*{.*Language.*}"
# Also search for the actual module path
fd -e ts -e tsx "i18n.(ts|tsx)$" packages/web/src/modules/ --exec grep -l "export.*{.*fallbackLng.*}"
fd -e ts -e tsx "i18n.(ts|tsx)$" packages/web/src/modules/ --exec grep -l "export.*{.*Language.*}"
# Let's check if the file exists first
fd -e ts -e tsx "i18n.(ts|tsx)$" packages/
Length of output: 473
Script:
#!/bin/bash
# Let's check the content of the found i18n file and the import path structure
cat packages/shared/src/utils/extension/module/I18n.ts
# Let's also check if there are any other i18n-related files in the project
rg -l "fallbackLng|Language.*export" packages/
Length of output: 419
Script:
#!/bin/bash
# Let's check the content of the found i18n-related files in web package
cat packages/web/src/modules/i18n/util.ts
cat packages/web/src/modules/i18n/constant.ts
# Also check the actual import path mentioned in the review
ls -la packages/web/src/modules/i18n/
Length of output: 1059
Script:
#!/bin/bash
# Let's check the content of type.ts and index.ts to verify the Language export
cat packages/web/src/modules/i18n/type.ts
cat packages/web/src/modules/i18n/index.ts
Length of output: 358
packages/web/src/app/auth/callback-email/route.ts (2)
4-4
: LGTM! 쿠키 상수 가져오기 개선
쿠키 키 상수들을 단일 객체로 통합한 것은 유지보수성 향상에 도움이 됩니다.
16-22
: LGTM! 접근 토큰 쿠키 설정
접근 토큰에 대한 쿠키 설정이 적절하게 구현되었습니다. 보안 관련 설정(httpOnly, secure, sameSite)이 올바르게 유지되었습니다.
packages/web/src/app/[lng]/memos/components/MemoView/index.tsx (2)
3-3
: 임포트 구조가 개선되었습니다!
Next.js의 기본 기능을 활용하는 방향으로 리팩토링이 잘 이루어졌습니다. 커스텀 라우터 대신 내장 기능을 사용함으로써 코드의 복잡성이 줄어들었습니다.
Also applies to: 5-5, 6-6, 9-9
14-17
: 🛠️ Refactor suggestion
검색 파라미터 처리 시 null 안전성 개선이 필요합니다.
searchParams.get()이 null을 반환할 수 있으므로, 기본값 처리를 추가하는 것이 좋습니다.
다음과 같이 개선해보세요:
- const isWish = searchParams.get('isWish') === 'true';
- const category = searchParams.get('category');
+ const isWish = searchParams.get('isWish') === 'true' ?? false;
+ const category = searchParams.get('category') ?? undefined;
Likely invalid or redundant comment.
packages/web/src/app/[lng]/memos/components/Header/RefreshButton.tsx (2)
5-6
: 모듈 구조 개선이 잘 이루어졌습니다!
i18n 관련 모듈들이 더 명확한 위치로 이동되었고, local storage 관련 기능이 모듈화되어 재사용성이 향상되었습니다.
Also applies to: 11-11
18-18
: 성능 최적화가 잘 이루어졌습니다!
queryClient를 핸들러 함수 외부에서 초기화하여 불필요한 재생성을 방지했습니다.
packages/web/src/app/[lng]/memos/setting/component/Setting/index.tsx (1)
3-4
: 모듈 경로 변경이 일관되게 적용되었는지 확인이 필요합니다.
import 경로가 @src/app/i18n
에서 @src/modules/i18n
으로 변경되었습니다. 변경 자체는 적절해 보이나, 다른 컴포넌트들에서도 동일한 방식으로 적용되었는지 확인이 필요합니다.
다음 스크립트를 실행하여 일관성을 확인하세요:
✅ Verification successful
모듈 경로 변경이 성공적으로 완료되었습니다.
검색 결과에 따르면 @src/app/i18n
의 이전 경로를 사용하는 파일이 없으며, 모든 관련 파일들이 새로운 @src/modules/i18n
경로를 일관되게 사용하고 있습니다. 이는 리팩토링이 프로젝트 전체에 걸쳐 완전히 적용되었음을 보여줍니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: i18n 모듈의 import 경로 일관성 검사
# 이전 경로를 사용하는 파일 검색
echo "이전 경로(@src/app/i18n)를 사용 중인 파일 확인:"
rg "@src/app/i18n" --type ts --type tsx
# 새로운 경로를 사용하는 파일 검색
echo -e "\n새로운 경로(@src/modules/i18n)를 사용 중인 파일 확인:"
rg "@src/modules/i18n" --type ts --type tsx
Length of output: 313
Script:
#!/bin/bash
# Let's try a different approach using ripgrep without file type filters
echo "이전 경로(@src/app/i18n)를 사용 중인 파일 검색:"
rg -l "@src/app/i18n"
echo -e "\n새로운 경로(@src/modules/i18n)를 사용 중인 파일 검색:"
rg -l "@src/modules/i18n"
Length of output: 1652
packages/web/src/app/[lng]/memos/components/MemoSidebar/SidebarMenuItemAddCategory.tsx (3)
5-5
: 임포트 구조가 개선되었습니다.
클라이언트 관리 방식이 유틸리티 함수에서 훅 기반으로 변경되었고, 타입 정의가 별도 파일로 분리되어 재사용성이 향상되었습니다.
Also applies to: 9-9
12-12
: Supabase 클라이언트 초기화 방식이 개선되었습니다.
훅 기반 접근 방식으로 변경되어 컴포넌트의 생명주기와 더 잘 통합되었습니다. 또한 타입 안정성이 향상되었습니다.
다른 컴포넌트들도 동일한 패턴을 따르는지 확인이 필요합니다:
Also applies to: 14-14
✅ Verification successful
Supabase 클라이언트 초기화 패턴이 일관되게 적용되어 있습니다.
검증 결과, 웹 애플리케이션의 클라이언트 사이드 컴포넌트들은 모두 useSupabaseClient
훅을 사용하고 있으며, 서버 사이드 컴포넌트들은 getSupabaseClient
를 사용하는 일관된 패턴을 보여주고 있습니다. 이는 의도된 설계대로 올바르게 구현되어 있습니다.
- 클라이언트 컴포넌트들:
MemoSidebar
,MemoDialog
,MemoView
등에서useSupabaseClient
사용 - 서버 컴포넌트들:
layout.tsx
,page.tsx
,route.ts
등에서getSupabaseClient
사용
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: 기존 getSupabaseClient 사용 여부 확인
rg "getSupabaseClient" --type typescript
Length of output: 75
Script:
#!/bin/bash
# Search for getSupabaseClient usage with ripgrep
rg "getSupabaseClient"
# Search for useSupabaseClient usage to verify the new pattern
rg "useSupabaseClient"
# Search for supabase client initialization patterns in typescript files
fd -e ts -e tsx --exec rg -l "supabase.*client"
Length of output: 5784
20-20
: 뮤테이션 훅 사용이 일관성 있게 수정되었습니다.
Supabase 클라이언트가 적절하게 뮤테이션 훅에 전달되도록 변경되었습니다.
다른 뮤테이션 훅들도 동일한 패턴을 따르는지 확인이 필요합니다:
✅ Verification successful
뮤테이션 훅의 일관성이 확인되었습니다.
검색 결과를 통해 다음과 같은 사항들이 확인되었습니다:
useMemoPostMutation
,useMemoPatchMutation
,useCategoryPostMutation
등 모든 Supabase 관련 뮤테이션 훅들이supabaseClient
를 일관되게 전달받고 있습니다.- 각 컴포넌트에서 이러한 뮤테이션 훅들을 사용할 때도 동일한 패턴으로
supabaseClient
를 전달하고 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: 뮤테이션 훅 패턴 확인
ast-grep --pattern 'use$_Mutation({ supabaseClient })'
Length of output: 56
Script:
#!/bin/bash
# Search for mutation hook usage patterns
rg "use.*Mutation.*supabaseClient" -A 2
Length of output: 1588
Script:
#!/bin/bash
# Search for mutation hook declarations
ast-grep --pattern 'export const use$_Mutation = ({ supabaseClient }: { supabaseClient: SupabaseClient }) => {'
Length of output: 113
Script:
#!/bin/bash
# Search for any mutation hook usage
rg "use.*Mutation" -A 2
Length of output: 10508
packages/web/src/app/[lng]/memos/utils/guide.ts (2)
2-5
: 가져오기 구문이 잘 정리되었습니다! ✨
CSS, 내부 모듈, 외부 모듈 순서로 잘 정리되어 있으며, 로컬 스토리지 관리를 중앙화하는 방식으로 개선되었습니다.
40-43
: 가이드 완료 처리가 개선되었습니다! 👍
로컬 스토리지 관리를 중앙화된 유틸리티 함수를 통해 처리하도록 개선된 점이 좋습니다.
가이드 완료 상태가 다른 컴포넌트에서도 올바르게 사용되는지 확인이 필요합니다:
✅ Verification successful
Let me analyze the usage of guide-related localStorage operations more broadly to verify the implementation.
가이드 상태 관리가 일관되게 구현되어 있습니다 ✅
가이드 완료 상태가 다음과 같이 일관된 방식으로 관리되고 있음을 확인했습니다:
LOCAL_STORAGE_KEY
에 'guide' 키가 상수로 정의되어 있습니다useGuide
훅에서checkLocalStorageTrue('guide')
를 통해 가이드 상태를 확인합니다RefreshButton
컴포넌트와 가이드 유틸리티에서setLocalStorageTrue('guide')
를 사용하여 가이드 완료를 처리합니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# 가이드 완료 상태 사용 확인
rg "getLocalStorage.*('guide')" --type ts
Length of output: 49
Script:
#!/bin/bash
# Search for any usage of 'guide' in localStorage related operations
rg "localStorage.*guide" --type ts -A 2
# Also search for guide-related state management
rg "('|\")guide('|\")" --type ts -A 2
Length of output: 1181
packages/web/src/app/components/Introduction.tsx (2)
1-1
: URL 상수 관리 개선이 잘 이루어졌습니다.
개별 URL 상수를 하나의 객체로 통합하여 관리하는 방식으로 변경된 것이 좋습니다. 이는 URL 관리의 일관성과 유지보수성을 향상시킵니다.
7-8
: 클래스명 구조가 개선되었습니다.
Tailwind 클래스명의 순서가 더 일관성 있게 정리되었습니다. 이는 코드의 가독성을 향상시킵니다.
Also applies to: 15-15
pages/side-panel/src/components/MemoHeader.tsx (3)
1-2
: 훅 임포트 구조가 개선되었습니다.
공통 훅과 확장 프로그램 전용 훅이 명확하게 구분되어 있어 코드의 구조가 더 명확해졌습니다.
9-9
: Supabase 클라이언트 사용 방식이 개선되었습니다.
useSupabaseClientQuery
를 사용하여 클라이언트를 가져오는 방식이 더 일관성 있고 타입 안정성이 향상되었습니다.
11-14
: 메모 데이터 구조 변경을 확인해주세요.
useMemoQuery
훅의 반환값 구조가 변경되었습니다 (data: currentMemo
→ memo: memoData
). 이 변경이 다른 컴포넌트에도 영향을 미칠 수 있습니다.
다른 컴포넌트에서의 사용을 확인하기 위해 다음 스크립트를 실행하세요:
✅ Verification successful
Let me analyze the usage of useMemoQuery
across the codebase. I can see that all instances are using the new structure with memo: memoData
. Let me verify the implementation of the hook itself to ensure completeness.
useMemoQuery
훅의 변경이 일관되게 적용되어 있습니다.
코드베이스 전체를 검토한 결과, useMemoQuery
훅의 반환값 구조 변경(data: currentMemo
→ memo: memoData
)이 모든 사용처에서 일관되게 적용되어 있음을 확인했습니다. 다음 파일들에서 모두 새로운 구조를 사용하고 있습니다:
pages/side-panel/src/components/MemoForm.tsx
pages/side-panel/src/components/MemoHeader.tsx
packages/web/src/app/[lng]/memos/components/MemoDialog/index.tsx
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# useMemoQuery 훅의 사용 패턴을 검색
rg "useMemoQuery" -A 3
Length of output: 3103
Script:
#!/bin/bash
# Check the implementation of useMemoQuery hook
ast-grep --pattern 'export default function useMemoQuery($_) {
$$$
}'
Length of output: 1657
packages/web/src/utils/middleware.ts (1)
2-2
: 설정 관리 개선이 잘 이루어졌습니다!
개별 상수 import에서 통합된 CONFIG 객체를 사용하도록 변경한 것이 좋은 개선사항입니다. 이는 설정 관리를 중앙화하고 유지보수성을 향상시킵니다.
packages/web/src/middleware.ts (2)
2-5
: 모듈 구조 변경 검증 필요
i18n 관련 상수들의 import 경로가 변경되었습니다. 이러한 구조 변경이 전체 코드베이스에서 일관되게 적용되었는지 확인이 필요합니다.
✅ Verification successful
Let me gather more information about the i18n related imports to verify the module structure changes.
모듈 구조 변경이 일관되게 적용되었음을 확인했습니다
i18n 관련 상수들과 타입들이 modules/i18n
디렉토리로 올바르게 이전되었으며, 모든 참조 파일들(middleware.ts
, hooks/useLanguage.ts
, app/[lng]/layout.tsx
등)에서 새로운 경로를 사용하고 있습니다. 이전 경로인 ./app/i18n/settings
를 사용하는 파일이 없어 구조 변경이 완전히 이루어졌음을 확인했습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify consistent usage of new import paths
# Check for any remaining old import paths
rg -l "from './app/i18n/settings'"
# Check adoption of new import path
rg -l "from './modules/i18n'"
Length of output: 111
Script:
#!/bin/bash
# Search for any i18n related imports and constants
rg -l "fallbackLng|languages|cookieName" --type ts
# Check content of files that might be using i18n constants
rg "fallbackLng|languages|cookieName" --type ts -C 2
Length of output: 4563
7-7
: 새로운 유효성 검사 메서드의 동작 확인 필요
isStringArray
에서 checkStringArray
로의 변경이 있었습니다. 두 함수의 동작이 완전히 동일한지 확인이 필요합니다.
✅ Verification successful
유효성 검사 메서드 변경이 적절하게 이루어졌습니다
checkStringArray
함수의 구현을 확인한 결과, 이전 isStringArray
함수와 동일한 검증 로직을 수행합니다:
- 입력값이 배열인지 확인
- 배열의 모든 요소가 문자열인지 검증
- 타입 가드로서
value is string[]
타입 보장
이는 안전한 변경이며 기존 기능이 그대로 유지됩니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Compare the implementation of both validation methods
# Search for the new validation method implementation
ast-grep --pattern 'export function checkStringArray($_) {
$$$
}'
# Search for any remaining usage of old validation method
rg 'isStringArray'
Length of output: 88
Script:
#!/bin/bash
# Let's try a broader search for both functions and their usages
# Search for checkStringArray function or type definition
rg -A 5 "checkStringArray"
# Search for isStringArray function or type definition
rg -A 5 "isStringArray"
# Search for files containing either of these functions
fd -t f -e ts -e tsx -x grep -l "checkStringArray\|isStringArray" {}
Length of output: 1154
packages/web/src/app/components/ExtensionDialog/getExtensionDialogInfo.ts (1)
30-33
: 버전 비교 로직 검증 필요
manifest?.version
이 없는 경우나 버전 형식이 일치하지 않는 경우에 대한 처리가 필요합니다.
버전 비교 로직을 검증하기 위해 다음 스크립트를 실행하세요:
✅ Verification successful
Let me gather more information about the version handling logic.
Let me try one more search to find the EXTENSION constant definition with a corrected regex:
버전 처리가 적절히 구현되어 있습니다
버전 비교 로직이 다음과 같이 안전하게 구현되어 있습니다:
manifest?.version
으로 옵셔널 체이닝을 사용하여 manifest가 없는 경우를 처리EXTENSION.lastVersion
이 상수로 명확하게 정의되어 있음 ('1.6.4')- 버전 비교가 엄격한 동등 비교 연산자(
!==
)를 사용하여 정확하게 수행됨
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# manifest와 EXTENSION.lastVersion의 사용을 확인
rg -A 2 "manifest.*version|EXTENSION\.lastVersion"
Length of output: 1681
Script:
#!/bin/bash
# Check how manifest and version are handled
ast-grep --pattern 'const manifest = $_'
# Check EXTENSION constant definition
rg "EXTENSION.*=.*{" -A 5
# Check version comparison implementation
ast-grep --pattern 'if ($_ !== EXTENSION.lastVersion) {
$$$
}'
Length of output: 4389
Script:
#!/bin/bash
# Check EXTENSION constant definition with fixed regex
rg "EXTENSION\s*=\s*" -A 5
# Check how version is used in the extension dialog
ast-grep --pattern 'useExtensionDialog($$$)'
Length of output: 489
packages/web/src/app/[lng]/layout.tsx (2)
11-12
: 모듈 임포트 구조가 개선되었습니다.
상대 경로에서 절대 경로로의 변경은 코드의 가독성과 유지보수성을 향상시킵니다. @src/modules/i18n
에서 타입과 상수를 가져오는 방식이 더 명확합니다.
46-46
: ExtensionDialog 배치 위치를 검토해주세요.
ExtensionDialog
가 전역 레이아웃에 추가된 것은 적절해 보이나, 다음 사항들을 확인해주시기 바랍니다:
- 다이얼로그가 다른 UI 요소들(예: Toaster)과 겹치지 않는지
- z-index 관리가 적절한지
- 페이지 전환 시 다이얼로그 상태가 올바르게 유지되는지
다음 스크립트로 z-index 충돌 여부를 확인할 수 있습니다:
✅ Verification successful
ExtensionDialog의 배치가 적절합니다
레이아웃 파일을 검토한 결과, ExtensionDialog와 Toaster의 배치가 적절하게 되어 있습니다:
- ExtensionDialog와 Toaster가 모두 body 태그의 마지막에 위치하여 다른 UI 요소들과의 겹침 문제를 방지합니다.
- 두 컴포넌트가 ThemeProvider와 QueryProvider의 context 내부에 있어 전역 상태 관리가 가능합니다.
- 페이지 전환과 무관하게 body 레벨에서 렌더링되어 상태가 안정적으로 유지됩니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for potential z-index conflicts in styles
rg -g '*.{css,scss,tsx}' 'z-index'
Length of output: 34
Script:
#!/bin/bash
# Check for dialog-related styles and z-index
rg -g '*.{css,scss,tsx}' -i '(dialog|modal|toast|notification).*style|style.*?(dialog|modal|toast|notification)|z-index'
# Find ExtensionDialog component definition
ast-grep --pattern 'const ExtensionDialog = $$$'
# Find other dialog/modal components in layout
ast-grep --pattern 'import.*Dialog' packages/web/src/app/[lng]/layout.tsx
Length of output: 251
Script:
#!/bin/bash
# Find ExtensionDialog component file
fd ExtensionDialog
# Find dialog/modal related components in the codebase
rg -l -g '*.tsx' '<dialog|<Modal|<Toaster'
# Check imports in layout file
cat packages/web/src/app/[lng]/layout.tsx
Length of output: 1901
packages/web/src/app/[lng]/memos/layout.tsx (2)
3-5
: 상수 및 유틸리티 임포트 구조가 개선되었습니다.
상수와 유틸리티 함수의 임포트 구조가 더 명확하고 일관성 있게 변경되었습니다. COOKIE_KEY
를 객체로 사용하는 방식은 키 관리 측면에서 더 안전하고 체계적입니다.
31-34
: HydrationBoundary 컴포넌트의 데이터 흐름이 개선되었습니다.
getCategories
함수로의 변경은 적절해 보이나, 데이터 페칭 실패 시의 처리가 누락되어 있습니다.
카테고리 데이터 처리 방식을 확인하기 위해 다음 스크립트를 실행합니다:
✅ Verification successful
카테고리 데이터 처리가 적절히 구현되어 있습니다.
코드베이스 분석 결과, 카테고리 데이터 처리가 다음과 같이 안전하게 구현되어 있음을 확인했습니다:
useCategoryQuery
훅에서enabled
옵션을 통해supabaseClient
존재 여부를 확인useCategoryPostMutation
에서 에러 타입이 명시적으로 정의되어 있음- React Query의
HydrationBoundary
를 통해 서버-클라이언트 간 데이터 동기화가 적절히 처리됨
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: 카테고리 관련 에러 처리 로직 확인
# getCategories 함수의 구현 확인
ast-grep --pattern 'export const getCategories = async ($_) => { $$$ }'
# 에러 처리 패턴 검색
rg -A 5 "catch.*getCategories"
Length of output: 106
Script:
#!/bin/bash
# 카테고리 관련 함수 및 에러 처리 검색
# getCategories 함수 검색 (다른 패턴으로 시도)
ast-grep --pattern 'const getCategories = async'
# 카테고리 관련 파일 내용 확인
fd "categories?" -t f | xargs cat
# HydrationBoundaryWrapper 컴포넌트 구현 확인
ast-grep --pattern 'const HydrationBoundaryWrapper = ({ $_' -l
# 에러 처리 관련 코드 검색 (더 넓은 범위)
rg "error.*categor" -i
Length of output: 425
Script:
#!/bin/bash
# 카테고리 관련 코드 분석
# HydrationBoundaryWrapper 컴포넌트 검색 (언어 지정)
ast-grep --pattern 'const HydrationBoundaryWrapper = ({ $$ }) => { $$ }' --lang typescript
# getCategories 함수 검색 (수정된 패턴)
ast-grep --pattern 'export async function getCategories' --lang typescript
# 카테고리 관련 파일 찾기
fd -e ts -e tsx | grep -i "categor" | xargs cat
# HydrationBoundary 관련 에러 처리 검색
rg -A 5 "HydrationBoundary.*error"
Length of output: 4793
packages/web/src/modules/i18n/locales/ko/translation.json (2)
16-16
: 카테고리 변경 메시지가 기존 토스트 메시지와 일관성이 있습니다.
기존의 다른 토스트 메시지들과 동일한 문체와 종결어미를 사용하여 일관성을 유지하고 있습니다.
21-24
: 새로운 토스트 액션 메시지의 용어 선택이 적절합니다.
"바로가기"와 "제거 취소"는 사용자가 직관적으로 이해할 수 있는 간단명료한 용어를 사용했습니다.
packages/web/src/app/[lng]/login/components/LoginSection/index.tsx (2)
19-27
: OAuth 버튼 핸들러 개선 👍
bind()
메서드 대신 화살표 함수를 사용하여 코드가 더 명확하고 이해하기 쉽게 개선되었습니다.
2-3
: i18n 모듈 경로 변경 확인 필요
모듈 구조 개선을 위해 i18n 관련 import 경로가 변경되었습니다. 새로운 경로가 올바르게 설정되어 있는지 확인이 필요합니다.
✅ Verification successful
Let me analyze the repository structure first to locate the i18n module files correctly. The previous command assumed a specific directory structure that might not be accurate. This new command will help us find the correct location of the modules directory and i18n related files.
i18n 모듈 import 경로가 정상적으로 설정되었습니다
packages/web/src/modules/i18n
경로에서 필요한 모든 모듈이 확인되었습니다:
LanguageType
은type.ts
에 정의되어 있습니다useTranslation
은server.js
와client.js
에 모두 구현되어 있습니다
import 구문의 경로 변경이 올바르게 이루어졌습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# i18n 모듈의 새로운 경로 확인
fd -e ts -e tsx "i18n" src/modules
Length of output: 133
Script:
#!/bin/bash
# Check repository structure first
fd -t d "modules"
# Then search for i18n related files
fd -e ts -e tsx "i18n"
Length of output: 117
Script:
#!/bin/bash
# Check i18n module contents in packages/web/src/modules
fd -e ts -e tsx . packages/web/src/modules/i18n
# Check if LanguageType and useTranslation exist
rg "export.*LanguageType" -A 2 packages/web/src/modules/i18n
rg "export.*useTranslation" -A 2 packages/web/src/modules/i18n
Length of output: 1037
packages/shared/src/hooks/supabase/useMemoPostMutation.ts (1)
6-11
: 타입 정의가 개선되었습니다!
MutationData
와 MutationError
타입 별칭을 도입하여 코드의 타입 안전성과 가독성이 향상되었습니다. ReturnType
과 Awaited
를 활용한 타입 추론도 잘 구현되었습니다.
packages/shared/src/utils/extension/Supabase.ts (1)
1-5
: 깔끔한 import 구조입니다!
상수들을 CONFIG 객체로 통합한 것이 좋은 접근 방식입니다.
packages/web/package.json (1)
8-9
: TypeScript 타입 체크 스크립트 추가에 대해 긍정적입니다.
타입 체크 스크립트를 추가한 것은 개발 프로세스 향상에 도움이 될 것 같습니다. 이는 빌드 전에 타입 오류를 미리 발견할 수 있게 해줍니다.
packages/web/src/modules/i18n/client.js (1)
9-9
: import 경로 변경에 대한 검증이 필요합니다
import 경로가 './settings'에서 './util'로 변경되었습니다. 필요한 모든 엔티티들이 새로운 위치에서 올바르게 export되고 있는지 확인이 필요합니다.
✅ Verification successful
import 경로 변경이 올바르게 이루어졌습니다
필요한 모든 엔티티들이 새로운 구조에서 정상적으로 export되고 있음을 확인했습니다:
getOptions
는util.ts
에서 직접 export됨languages
와cookieName
은constant.ts
에서 export되고 index.ts를 통해 재export됨- 모든 import가 정상적으로 작동할 것으로 예상됨
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the existence of required exports in the new util file
# Check if util file exists and contains the required exports
rg -U "export.*(?:getOptions|languages|cookieName)" "$(fd -t f util.ts util.js -d 1 packages/web/src/modules/i18n)"
Length of output: 271
Script:
#!/bin/bash
# Let's check the content of util.ts to verify all exports
cat "$(fd -t f util.ts -d 1 packages/web/src/modules/i18n)"
Length of output: 341
Script:
#!/bin/bash
# Let's check the index file for languages and cookieName exports
cat "$(fd -t f "index.ts|index.js" -d 1 packages/web/src/modules/i18n)"
Length of output: 186
Script:
#!/bin/bash
# Let's check the constant file for languages and cookieName exports
cat "$(fd -t f "constant.ts|constant.js" -d 1 packages/web/src/modules/i18n)"
Length of output: 284
packages/web/src/app/[lng]/memos/components/MemoSidebar/SidebarGroupCategory.tsx (2)
Line range hint 3-18
: 임포트 구문이 잘 정리되었습니다!
훅과 타입 임포트가 논리적으로 잘 구성되어 있으며, 컴포넌트에서 모두 적절히 사용되고 있습니다.
22-24
: Supabase 클라이언트 사용이 개선되었습니다.
useSupabaseClient
훅을 사용하는 방식으로 변경된 것이 React의 관례에 더 부합하며, 코드베이스 전반의 일관성을 향상시켰습니다.
다른 컴포넌트들에서도 동일한 패턴으로 마이그레이션이 이루어졌는지 확인이 필요합니다:
✅ Verification successful
Let me analyze the results and provide a final response in Korean.
Supabase 클라이언트 사용 패턴이 일관되게 적용되어 있습니다.
코드베이스 분석 결과:
- 웹 애플리케이션의 클라이언트 컴포넌트들은
useSupabaseClient
훅을 일관되게 사용하고 있습니다. getSupabaseClient
는 서버 컴포넌트(*.server.ts
)와 확장 프로그램에서만 사용되고 있어 적절한 구분이 이루어져 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify consistent usage of useSupabaseClient across components
# Check for any remaining instances of getSupabaseClient
rg "getSupabaseClient"
# Check for adoption of useSupabaseClient
rg "useSupabaseClient"
Length of output: 5688
packages/web/src/app/[lng]/memos/components/MemoView/MemoGrid.tsx (2)
Line range hint 27-56
: 구현이 잘 되어있습니다! 👍
컴포넌트가 다음과 같은 우수한 구현 사항을 포함하고 있습니다:
- 효율적인 페이지네이션 로직
- 적절한 상태 관리
- 부드러운 애니메이션 처리
- 타입 안정성 확보
4-4
: 타입 변경 사항 검증이 필요합니다.
타입 변경이 올바르게 이루어졌는지 확인이 필요합니다:
GetMemoType
에서GetMemoResponse
로의 변경LanguageType
임포트 경로 변경
Also applies to: 8-8, 23-23
✅ Verification successful
Based on the results, I can now generate the final response since we have clear evidence that:
- No references to
GetMemoType
exist in the codebase GetMemoResponse
is consistently used in related files and properly defined inshared/src/utils/Supabase.ts
- All
LanguageType
imports consistently use the path@src/modules/i18n
타입 변경이 올바르게 적용되었습니다.
타입 변경이 전체 코드베이스에서 일관되게 이루어졌음을 확인했습니다:
GetMemoType
은 완전히 제거되었으며GetMemoResponse
로 올바르게 대체되었습니다GetMemoResponse
는shared/src/utils/Supabase.ts
에서 정의되어 있으며 관련 컴포넌트에서 일관되게 사용됩니다LanguageType
임포트 경로가 모든 파일에서@src/modules/i18n
으로 통일되어 있습니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify type changes across the codebase
# Check for any remaining references to GetMemoType
echo "Checking for remaining GetMemoType references..."
rg "GetMemoType"
# Check for consistent usage of GetMemoResponse
echo "Checking GetMemoResponse usage..."
rg "GetMemoResponse"
# Verify LanguageType import path consistency
echo "Checking LanguageType import paths..."
rg "import.*LanguageType.*from"
Length of output: 2805
packages/shared/package.json (1)
38-41
: 웹 훅을 위한 새로운 내보내기 경로가 올바르게 추가되었습니다.
내보내기 구조가 기존 패턴을 잘 따르고 있으며, 웹과 확장 프로그램 코드의 분리를 적절히 지원합니다.
packages/shared/src/utils/Supabase.ts (1)
1-3
: 타입 정의와 임포트가 깔끔하게 구성되어 있습니다.
상수와 타입 정의가 잘 분리되어 있으며, 필요한 타입들이 명확하게 임포트되어 있습니다.
packages/shared/src/hooks/supabase/useMemoPatchMutation.ts (1)
6-11
: 타입 정의가 명확하고 잘 구조화되어 있습니다! 👍
MutationVariables
, MutationData
, MutationError
와 같은 타입 별칭을 사용하여 코드의 가독성과 유지보수성이 향상되었습니다. 특히 Awaited
타입을 사용하여 비동기 응답 타입을 정의한 것이 인상적입니다.
packages/web/src/app/[lng]/memos/components/legacy/MemoTable.tsx (1)
4-4
: Supabase 클라이언트 관리 방식이 개선되었습니다!
함수형 컴포넌트에서 훅을 사용하는 방식으로 변경한 것이 React의 패턴에 더 적합합니다.
Also applies to: 8-8
packages/web/src/app/components/ExtensionDialog/index.tsx (1)
1-16
: 타입 정의와 임포트 구조가 깔끔합니다!
컴포넌트의 타입 정의가 간단하면서도 명확하며, 필요한 의존성들이 잘 구성되어 있습니다.
packages/web/src/modules/search-params/SearchParams.ts (1)
1-5
: 타입 안정성과 캡슐화가 잘 구현되었습니다!
private 필드를 사용한 캡슐화와 타입 정의가 잘 되어있습니다.
packages/web/src/utils/supabase.server.ts (1)
1-10
: 서버 사이드 상태 관리에 대한 고려사항
supabaseClient
를 전역 변수로 관리하는 것은 서버 사이드 렌더링 환경에서 잠재적인 문제를 일으킬 수 있습니다. Next.js의 서버 컴포넌트는 여러 요청에서 공유될 수 있으므로, 전역 상태를 신중하게 관리해야 합니다.
다음 스크립트를 실행하여 다른 서버 컴포넌트에서 이 클라이언트를 어떻게 사용하는지 확인하겠습니다:
✅ Verification successful
서버 사이드 상태 관리는 안전하게 구현되어 있습니다
코드베이스 분석 결과, supabaseClient
싱글톤 패턴의 구현이 Next.js 서버 컴포넌트 환경에서 안전하게 사용되고 있음을 확인했습니다:
getSupabaseClient()
는 각 요청마다 새로운 쿠키 컨텍스트를 사용하여 클라이언트를 초기화합니다- 서버 컴포넌트들(
app/[lng]
경로)은 독립적으로getSupabaseClient()
를 호출하여 요청별 컨텍스트를 유지합니다 - 클라이언트 사이드 컴포넌트들은
useSupabaseClient
훅을 통해 별도의 브라우저 클라이언트를 사용합니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check usage of supabase client in server components
rg -t typescript "getSupabaseClient" --glob "**/*.server.ts*"
Length of output: 96
Script:
#!/bin/bash
# Search for getSupabaseClient usage in all TypeScript files
rg "getSupabaseClient" --type-add 'ts:*.{ts,tsx}' -t ts
# Check how supabaseClient is used across the codebase
rg "supabaseClient" --type-add 'ts:*.{ts,tsx}' -t ts
# Look for server component files that might use Supabase
fd -e ts -e tsx "server" --full-path
Length of output: 13434
packages/web/src/modules/i18n/locales/en/translation.json (2)
1-59
: JSON 구조가 잘 구성되어 있습니다.
전반적으로 구조가 깔끔하고 논리적으로 잘 구성되어 있습니다.
1-59
: 번역키 사용 현황 확인 필요
정의된 번역키들이 실제 컴포넌트에서 올바르게 사용되고 있는지 확인이 필요합니다.
✅ Verification successful
번역키가 적절하게 사용되고 있음을 확인했습니다
코드베이스 분석 결과, translation.json에 정의된 모든 번역키들이 컴포넌트에서 올바르게 사용되고 있습니다:
common.*
: Header 컴포넌트에서 사용sideBar.*
: MemoSidebar 컴포넌트에서 사용header.*
: Header 컴포넌트에서 사용toastMessage.*
: MemoItem, MemoOption, RefreshButton 등에서 사용toastActionMessage.*
: MemoOption에서 사용option.*
: MemoOption에서 사용login.*
: LoginSection에서 사용dialogInstall.*
,dialogVersion.*
: ExtensionDialog에서 사용tooltip.*
: MemoSidebarTrigger에서 사용setting.*
: Setting 컴포넌트에서 사용
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify translation key usage in the codebase
# Search for translation key usage
rg -t tsx -t ts "useTranslation|t\(['\"]" ./packages/web/src/
Length of output: 93
Script:
#!/bin/bash
# Search for translation key usage without file type restrictions
rg "useTranslation|[\"']common\.|[\"']sideBar\.|[\"']header\.|[\"']toastMessage\.|[\"']toastActionMessage\.|[\"']option\.|[\"']login\.|[\"']dialogInstall\.|[\"']dialogVersion\.|[\"']tooltip\.|[\"']setting\." ./packages/web/src/
Length of output: 8648
packages/web/src/app/[lng]/memos/components/MemoSidebar/index.tsx (1)
21-22
: i18n 모듈 경로 변경이 적절히 이루어졌습니다.
모듈 구조 개선을 위한 import 경로 변경이 잘 이루어졌습니다. 다만, 다른 컴포넌트들에서도 동일한 변경이 일관되게 적용되었는지 확인이 필요합니다.
다른 컴포넌트들의 import 경로 변경 여부를 확인하기 위해 다음 스크립트를 실행합니다:
✅ Verification successful
i18n 모듈 경로가 전체 코드베이스에서 일관되게 변경되었습니다.
검증 결과, 이전 경로(@src/app/i18n
)를 사용하는 파일이 없으며, 새로운 경로(@src/modules/i18n
)가 모든 관련 컴포넌트에서 일관되게 사용되고 있음을 확인했습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: i18n 관련 모듈의 import 경로 일관성 검사
# 이전 경로를 사용하는 파일 검색
echo "이전 경로(@src/app/i18n)를 사용하는 파일 검색:"
rg -l "@src/app/i18n"
# 새로운 경로를 사용하는 파일 검색
echo -e "\n새로운 경로(@src/modules/i18n)를 사용하는 파일 검색:"
rg -l "@src/modules/i18n"
Length of output: 1648
.coderabbit.yaml (1)
35-35
: base_branches 설정이 적절히 추가되었습니다.
'master'와 'develop' 브랜치를 base_branches로 설정한 것은 GitFlow 브랜칭 전략과 잘 부합합니다. 이는 주요 브랜치에 대한 코드 품질을 유지하는데 도움이 될 것입니다.
현재 저장소의 브랜치 전략을 확인하기 위해 다음 스크립트를 실행하세요:
packages/web/src/modules/search-params/SearchParams.test.ts (3)
1-12
: 테스트 설정이 잘 구성되어 있습니다!
테스트 데이터가 다양한 시나리오를 커버할 수 있도록 적절히 구성되어 있습니다.
26-31
: getAll 메서드 테스트가 잘 작성되었습니다!
단일 값과 다중 값 케이스를 모두 적절히 검증하고 있습니다.
62-74
: removeAll과 getSearchParams 테스트가 잘 구현되었습니다!
각 메서드의 핵심 기능을 정확하게 검증하고 있습니다.
packages/web/src/app/[lng]/memos/components/Header/index.tsx (1)
15-16
: i18n 모듈 경로 변경이 올바르게 적용되었습니다.
모듈 구조 개선을 위한 import 경로 변경이 일관성 있게 이루어졌습니다.
chrome-extension/lib/background/index.ts (4)
1-1
: 상수 관리 방식이 개선되었습니다.
URL과 설정 관련 상수들이 CONFIG와 URL 객체로 통합되어 관리되는 것은 좋은 변경사항입니다.
27-27
: 웹 URL 참조 방식이 개선되었습니다.
하드코딩된 URL 대신 CONFIG.webUrl을 사용하여 URL을 관리하는 것은 좋은 접근 방식입니다.
51-51
: URL 참조의 일관성이 향상되었습니다.
메모 페이지와 가이드 페이지의 URL 참조가 CONFIG.webUrl과 URL 객체를 통해 일관되게 관리되고 있습니다.
Also applies to: 54-55
60-60
: 제거 설문 URL 관리가 개선되었습니다.
확장 프로그램 제거 시 표시되는 설문 URL이 URL 객체를 통해 관리되도록 변경된 것은 좋은 개선사항입니다.
pages/options/src/components/OptionForm.tsx (2)
3-8
: 가져오기 구문이 더 명확하게 정리되었습니다.
유틸리티 함수들의 이름이 더 명시적으로 변경되어 코드의 가독성이 향상되었습니다. 특히 getMemos as getMemosSupabase
로의 변경은 함수의 출처와 목적을 더 잘 나타냅니다.
20-20
: 함수 호출이 일관되게 업데이트되었습니다.
getMemo
에서 getMemosSupabase
로의 변경이 올바르게 적용되었습니다. 다만, 이 변경으로 인한 영향을 확인할 필요가 있습니다.
✅ Verification successful
getMemo
관련 함수들이 정상적으로 사용되고 있습니다.
검색 결과를 분석해보면, getMemo
에서 getMemosSupabase
로의 변경은 pages/options/src/components/OptionForm.tsx
파일에서만 필요했던 것으로 확인됩니다. 다른 파일들에서 발견된 getMemo
관련 함수들(getMemoUrl
, getMemoWishListUrl
, getMemoItems
)은 완전히 다른 용도의 함수들이므로 변경이 필요하지 않습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the consistent usage of getMemosSupabase across the codebase
# Search for any remaining instances of getMemo
rg "getMemo[^s]" --type ts --type tsx
# Search for current usage of getMemosSupabase
rg "getMemosSupabase" --type ts --type tsx
Length of output: 138
Script:
#!/bin/bash
# Search for any remaining instances of getMemo
rg "getMemo[^s]"
# Search for current usage of getMemosSupabase
rg "getMemosSupabase"
Length of output: 1166
packages/web/src/app/[lng]/memos/components/MemoDialog/index.tsx (1)
4-5
: 모듈 구조 개선 확인 필요
i18n과 타입 관련 임포트 경로가 변경되었습니다. 새로운 모듈 구조가 프로젝트 전반에 걸쳐 일관되게 적용되었는지 확인이 필요합니다.
Also applies to: 14-16
✅ Verification successful
i18n 모듈 경로 변경이 일관되게 적용되었습니다
코드베이스 전반에 걸쳐 @src/modules/i18n
경로가 일관되게 사용되고 있으며, 이전 경로인 @src/app/i18n
은 더 이상 사용되지 않음을 확인했습니다. 모든 컴포넌트가 새로운 모듈 구조를 따르고 있어 문제가 없습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify consistent usage of new module paths across the codebase
# Check for any remaining old import paths
rg -l "@src/app/i18n"
# Verify new module structure adoption
rg -l "@src/modules/i18n"
rg -l "@src/modules/search-params"
Length of output: 1707
Script:
#!/bin/bash
# Let's check the actual import statements to understand the pattern
rg "@src/(app|modules)/i18n" -A 2
# Also check if there are any imports from the old path that need updating
rg "from ['\"]\@src/app/i18n" --type typescript
Length of output: 9583
package.json (3)
28-28
: 테스트 스크립트 추가 검토
Vitest를 사용하여 Jest 테스트를 실행하는 새로운 스크립트가 추가되었습니다. 하지만 기존의 Playwright 테스트 스크립트와 함께 사용될 때 혼란을 줄 수 있습니다.
다음 스크립트를 실행하여 테스트 설정을 확인하겠습니다:
스크립트 이름을 더 명확하게 변경하는 것을 고려해보세요:
- "test:jest": "vitest",
+ "test:unit": "vitest",
✅ Verification successful
테스트 스크립트 구성이 적절합니다
현재 테스트 환경이 명확하게 구분되어 있습니다:
- Vitest로 단위 테스트 실행 (
test:jest
) - Playwright로 E2E 테스트 실행 (
test
)
각 테스트 유형이 다른 목적으로 사용되고 있어 스크립트 이름 변경이 불필요합니다:
- 단위 테스트:
SearchParams.test.ts
와 같은 비즈니스 로직 테스트 - E2E 테스트:
LoginPage.spec.ts
와 같은 통합 테스트
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# vitest.config.ts 파일의 존재 여부 확인
fd -t f "vitest.config.ts"
# Jest 테스트 파일 검색
rg -t ts -t tsx "describe|test|it\("
Length of output: 110
Script:
#!/bin/bash
# Check vitest.config.ts content
cat vitest.config.ts
# Search for test files with proper extension patterns
rg -t typescript -t js "describe|test|it\("
# Check if there are any existing test files
fd -e test.ts -e test.js -e spec.ts -e spec.js
Length of output: 506
Script:
#!/bin/bash
# Check package.json for all test-related scripts
cat package.json | grep -A 5 -B 5 "\"test"
# Check content of a unit test file
cat "packages/web/src/modules/search-params/SearchParams.test.ts"
# Check content of an e2e test file
cat "tests/e2e/LoginPage.spec.ts"
Length of output: 4176
43-43
: 프로덕션 의존성 업데이트 검토
새로운 의존성들이 추가되었습니다:
@supabase/ssr
: Supabase SSR 지원lucide-react
: 아이콘 라이브러리vite-plugin-svgr
: SVG 지원
의존성 버전의 호환성을 확인하겠습니다:
Supabase SSR 구현 시 다음 사항들을 고려해주세요:
- 서버 사이드 환경에서의 인증 처리
- 클라이언트/서버 상태 동기화
- 캐싱 전략
Also applies to: 50-50, 59-59
✅ Verification successful
의존성 호환성 검증 완료
의존성 분석 결과 모든 패키지가 호환되며 안전하게 사용할 수 있습니다:
@supabase/[email protected]
은 peer dependency로@supabase/supabase-js@^2.43.4
를 요구하며, 현재 프로젝트는2.45.4
버전을 사용하고 있어 호환됩니다.[email protected]
은 React 16.5.1 이상을 요구하며, 프로젝트의 React 18.3.1 버전과 호환됩니다.[email protected]
은 별도의 peer dependency 요구사항이 없습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# package-lock.json 또는 pnpm-lock.yaml 파일 검색
fd -t f "package-lock.json|pnpm-lock.yaml"
# peer dependencies 충돌 확인
npm ls @supabase/ssr lucide-react vite-plugin-svgr
Length of output: 293
Script:
#!/bin/bash
# pnpm-lock.yaml에서 의존성 정보 확인
cat pnpm-lock.yaml | grep -A 10 "@supabase/ssr"
cat pnpm-lock.yaml | grep -A 10 "lucide-react"
# package.json에서 관련 의존성들의 버전 범위 확인
cat package.json | grep -A 20 '"dependencies":'
Length of output: 2418
66-66
: 🛠️ Refactor suggestion
개발 의존성 업데이트 검토
테스트 및 빌드 도구 관련 의존성이 추가되었습니다:
- Jest 타입스크립트 지원
- Vite React 플러그인
- Vitest 테스트 프레임워크
Vite 버전 고정에 대한 이유를 확인하겠습니다:
Vite 버전을 고정하는 대신 유연한 버전 관리를 권장드립니다:
- "vite": "5.3.3",
+ "vite": "^5.3.3",
Also applies to: 72-72, 96-97
✅ Verification successful
Let me gather more information about the Vite configuration and dependencies to understand if there's any specific reason for version pinning.
Let me check the dependencies and plugins that might require a specific Vite version.
Vite 버전 고정에 대한 검토 완료
현재 프로젝트에서는 Vite 관련 플러그인들(@vitejs/plugin-react
, vite-plugin-svgr
, @sentry/vite-plugin
)이 모두 유연한 버전 관리(^)를 사용하고 있는 반면, Vite 자체는 5.3.3으로 고정되어 있습니다. 특별한 호환성 이슈나 마이그레이션 가이드가 발견되지 않았고, 다른 의존성들과의 충돌 문제도 확인되지 않았습니다. 따라서 Vite도 다른 패키지들과 동일하게 유연한 버전 관리를 사용하는 것이 좋겠습니다.
package.json
에서 Vite 버전을"^5.3.3"
으로 변경하는 것을 권장합니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# 프로젝트의 변경 이력에서 Vite 관련 이슈 검색
rg -g "!{node_modules,dist}/*" "vite.*5\.3\.3"
Length of output: 1109
Script:
#!/bin/bash
# Check for Vite configuration files and any comments about version requirements
fd -e js -e ts -e mjs "vite.config" --exec cat {}
# Check package.json for peer dependencies that might require specific Vite version
cat package.json | jq '.peerDependencies'
# Look for any documentation about Vite version requirements
fd "README" --exec cat {}
Length of output: 4101
Script:
#!/bin/bash
# Check all Vite-related dependencies and their versions
cat package.json | jq '.dependencies, .devDependencies' | grep -i "vite"
# Look for any migration guides or breaking changes in the repository
rg -g "!{node_modules,dist}/*" "migration|breaking.?changes|upgrade" -i
Length of output: 289
pages/side-panel/src/components/MemoForm.tsx (2)
10-14
: 타입 시스템 개선 및 Supabase 클라이언트 관리 방식 변경이 적절해 보입니다.
useSupabaseClientQuery
로의 전환과 MemoInput
타입의 도입으로 코드의 타입 안정성이 향상되었습니다.
24-28
: Supabase 클라이언트 사용 방식 변경에 대한 검증이 필요합니다.
useSupabaseClientQuery
로의 전환이 적절해 보이나, 다른 컴포넌트들과의 일관성 확인이 필요합니다.
✅ Verification successful
Supabase 클라이언트 사용이 일관되게 적용되어 있습니다.
검증 결과, 웹 확장 프로그램의 사이드 패널 컴포넌트들(pages/side-panel/
)에서는 모두 useSupabaseClientQuery
를 일관되게 사용하고 있으며, 웹 애플리케이션(packages/web/
)에서는 useSupabaseClient
를 사용하고 있습니다. 이는 각 환경에 맞는 적절한 구현 방식을 따르고 있는 것으로 확인됩니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify consistent usage of useSupabaseClientQuery across components
# Search for any remaining useSupabaseClient usage
rg "useSupabaseClient[^Q]" --type tsx
Length of output: 67
Script:
#!/bin/bash
# Search for any remaining useSupabaseClient usage (without extension filter)
rg "useSupabaseClient[^Q]"
# Search for useSupabaseClientQuery usage to verify consistency
rg "useSupabaseClientQuery"
# Find all TypeScript/React files that might use Supabase
fd "\.(tsx?|jsx?)$" | grep -i "supabase"
Length of output: 4029
packages/web/src/app/[lng]/memos/components/MemoView/MemoItem.tsx (4)
3-18
: 임포트 구조가 개선되었습니다.
공유 훅과 타입을 사용하도록 변경되어 코드의 재사용성이 향상되었습니다. 특히 useSearchParams
를 사용하여 URL 파라미터 관리가 체계화되었습니다.
21-21
: 타입 정의가 더 명확해졌습니다.
GetMemoResponse
타입으로 변경되어 메모 데이터의 구조가 더 명확하게 정의되었습니다.
28-28
: Supabase 클라이언트 사용이 개선되었습니다.
useSupabaseClient
훅을 직접 사용하도록 변경되어 클라이언트 관리가 더 모듈화되었습니다.
Also applies to: 32-32
126-126
: prop 이름이 더 명확해졌습니다.
id
대신 memoId
를 사용하여 prop의 목적이 더 명확해졌습니다.
packages/web/src/app/[lng]/memos/components/MemoView/MemoOption.tsx (3)
25-27
: Props 인터페이스의 명확성이 개선되었습니다.
id
에서 memoId
로의 이름 변경은 props의 목적을 더 명확하게 표현합니다. 이는 코드의 가독성과 유지보수성을 향상시킵니다.
Line range hint 32-38
: Supabase 클라이언트 관리가 개선되었습니다.
useSupabaseClient
훅을 사용하여 클라이언트를 관리하는 방식은 React의 훅 패턴을 잘 따르고 있습니다. 쿼리 캐시 무효화도 적절히 구현되어 있습니다.
60-61
: 번역 키가 올바르게 정의되어 있는지 확인이 필요합니다.
사용된 번역 키들이 실제로 번역 파일에 정의되어 있는지 확인이 필요합니다.
Also applies to: 81-85
✅ Verification successful
번역 키가 모두 올바르게 정의되어 있습니다.
toastActionMessage.memoDeleteCancel
와 toastActionMessage.goTo
키가 영어와 한국어 번역 파일 모두에서 적절하게 정의되어 있는 것을 확인했습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# 번역 키 존재 여부 확인
rg -l "toastActionMessage\.(memoDeleteCancel|goTo)" public/locales/
Length of output: 125
Script:
#!/bin/bash
# Find translation files in the repository
fd -t f "translation|locale|i18n|lang" -e json -e yaml -e yml
# After finding translation files, let's check their content
Length of output: 179
Script:
#!/bin/bash
# Check translation keys in both files
echo "=== English translations ==="
cat packages/web/src/modules/i18n/locales/en/translation.json | jq '.toastActionMessage'
echo -e "\n=== Korean translations ==="
cat packages/web/src/modules/i18n/locales/ko/translation.json | jq '.toastActionMessage'
Length of output: 430
packages/web/src/components/ui/sidebar.tsx (1)
16-16
: 쿠키 키 관리 방식이 개선되었습니다.
쿠키 키를 중앙 집중식으로 관리하도록 변경한 것은 좋은 개선입니다. 이는 유지보수성을 향상시키고 일관성을 보장합니다.
다른 파일에서도 동일한 방식으로 쿠키 키를 사용하는지 확인하겠습니다:
Also applies to: 18-18
✅ Verification successful
Let me verify the cookie key usage by checking the shared constants file to ensure the structure is properly defined.
쿠키 키 관리가 일관되게 적용되어 있습니다.
@extension/shared/constants
의 COOKIE_KEY
객체를 통해 모든 쿠키 키가 중앙 집중식으로 관리되고 있으며, 코드베이스 전반에 걸쳐 일관되게 사용되고 있습니다. 특히:
- 인증 관련 쿠키 (
accessToken
,refreshToken
) - 사이드바 상태 관리 쿠키 (
sideBarState
)
모두 동일한 패턴으로 구현되어 있어 유지보수성이 향상되었습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: 쿠키 키 사용 방식의 일관성 확인
# COOKIE_KEY 상수 사용 패턴 검색
rg "COOKIE_KEY\." -A 2
# 이전 쿠키 키 상수 사용 여부 확인
rg "COOKIE_KEY_SIDE_BAR_STATE"
Length of output: 2366
Script:
#!/bin/bash
# Check the shared constants file for COOKIE_KEY definition
fd "constants.ts" --exec cat {}
Length of output: 231
Script:
#!/bin/bash
# Let's search for COOKIE_KEY definition in the entire codebase
rg "export const COOKIE_KEY" -A 5
Length of output: 363
pages/side-panel/src/types/Input.ts
Outdated
export interface MemoInput { | ||
memo: string; | ||
isWish: boolean; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
인터페이스 불일치 문제 발견
MemoInput
인터페이스가 두 위치에서 서로 다르게 정의되어 있습니다:
pages/side-panel/src/types/Input.ts
에서는memo: string
과isWish: boolean
을 포함packages/web/src/app/[lng]/memos/types/Input.ts
에서는memo: string
만 포함
이는 다음과 같은 문제를 야기할 수 있습니다:
MemoDialog
컴포넌트에서는isWish
속성을 사용하지 않지만,MemoForm
컴포넌트에서는 해당 속성을 필요로 함- 두 컴포넌트가 동일한 데이터를 다루고 있음에도 타입 정의가 불일치
🔗 Analysis chain
인터페이스 사용 현황 확인 필요
새로 추가된 MemoInput
인터페이스가 애플리케이션 전반에 걸쳐 일관되게 사용되고 있는지 확인이 필요합니다.
다음 스크립트를 실행하여 인터페이스 사용 현황을 확인하세요:
Let me verify the implementation details of MemoInput in both locations to ensure consistency.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: MemoInput 인터페이스의 사용 현황 확인
# MemoInput 타입이 사용된 모든 파일 검색
echo "MemoInput 타입 사용 현황:"
rg -l "MemoInput"
# useForm 훅에서 MemoInput 사용 확인
echo -e "\nuseForm 훅에서 MemoInput 사용 현황:"
rg "useForm.*MemoInput"
Length of output: 591
Script:
#!/bin/bash
# Check the implementation of MemoInput interface in both locations
echo "=== MemoInput in pages/side-panel/src/types/Input.ts ==="
cat pages/side-panel/src/types/Input.ts
echo -e "\n=== MemoInput in packages/web/src/app/[lng]/memos/types/Input.ts ==="
cat packages/web/src/app/[lng]/memos/types/Input.ts
# Check how MemoInput is used in the components
echo -e "\n=== Usage in MemoForm.tsx ==="
cat pages/side-panel/src/components/MemoForm.tsx
echo -e "\n=== Usage in MemoDialog/index.tsx ==="
cat packages/web/src/app/[lng]/memos/components/MemoDialog/index.tsx
Length of output: 8464
pages/side-panel/src/utils/Url.ts
Outdated
if (id) return `${CONFIG.webUrl}/memos?id=${id}`; | ||
return `${CONFIG.webUrl}/memos`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
URL 생성 시 XSS 취약점 방지가 필요합니다.
id 파라미터가 직접 URL에 삽입되고 있습니다. 보안을 강화하기 위해 URL 인코딩을 추가하는 것이 좋겠습니다.
다음과 같이 수정을 제안드립니다:
- if (id) return `${CONFIG.webUrl}/memos?id=${id}`;
+ if (id) return `${CONFIG.webUrl}/memos?id=${encodeURIComponent(id)}`;
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (id) return `${CONFIG.webUrl}/memos?id=${id}`; | |
return `${CONFIG.webUrl}/memos`; | |
if (id) return `${CONFIG.webUrl}/memos?id=${encodeURIComponent(id)}`; | |
return `${CONFIG.webUrl}/memos`; |
packages/web/src/app/[lng]/memos/components/MemoDialog/index.tsx
Outdated
Show resolved
Hide resolved
packages/web/src/app/[lng]/memos/components/MemoView/MemoOption.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 14
🧹 Outside diff range and nitpick comments (15)
packages/shared/src/modules/local-storage/type.ts (2)
1-1
: 명시적인 import 경로 사용 권장현재 index 파일에서 간접적으로
LOCAL_STORAGE_KEY
를 가져오고 있습니다. 유지보수성과 가독성을 위해 직접적인 파일 경로를 사용하는 것이 좋습니다.-import { LOCAL_STORAGE_KEY } from '.'; +import { LOCAL_STORAGE_KEY } from './constant';
3-3
: 버전 번호에 대한 제약 조건 추가 고려현재 버전 번호에 대한 제약이 없어 음수나 매우 큰 숫자도 허용됩니다. 유효한 버전 범위를 제한하는 것이 좋을 것 같습니다.
type VersionNumber = `${0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}${number}` | number; export type UpdateVersionType = `updateVersion${VersionNumber}.${VersionNumber}.${VersionNumber}`;packages/shared/src/modules/search-params/type.ts (1)
3-5
: 타입 정의가 잘 구성되어 있습니다만, 문서화를 추가하면 좋겠습니다타입 정의가 명확하고 타입 안전성이 잘 보장되어 있습니다. 다만, 각 타입의 용도와 제약사항을 설명하는 JSDoc 문서를 추가하면 더 좋을 것 같습니다.
다음과 같이 문서화를 추가해보세요:
+/** 검색 파라미터의 키 타입. SEARCH_PARAMS_KEYS에 정의된 값들만 허용됩니다. */ export type SearchParamKeyType = (typeof SEARCH_PARAMS_KEYS)[number]; +/** 검색 파라미터의 값 타입 */ export type SearchParamValueType = string; +/** 검색 파라미터의 키-값 쌍을 나타내는 튜플 타입 */ export type SearchParamType = [SearchParamKeyType, SearchParamValueType];packages/shared/src/modules/local-storage/LocalStorage.ts (1)
8-10
: 타입 안전성과 오류 처리를 강화하세요.값을 저장할 때 타입 검증과 오류 처리가 필요합니다.
다음과 같이 개선하는 것을 제안합니다:
- static set(key: LocalStorageKeyType, value: unknown) { - localStorage.setItem(key, JSON.stringify(value)); + static set(key: LocalStorageKeyType, value: unknown): boolean { + try { + localStorage.setItem(key, JSON.stringify(value)); + return true; + } catch (error) { + console.error(`LocalStorage save error for key ${key}:`, error); + return false; + } }packages/shared/src/modules/local-storage/util.ts (1)
1-9
: localStorage 추상화 계층 개선을 제안드립니다.현재 구현은 기본적인 기능만을 제공하고 있습니다. 다음과 같은 개선사항을 고려해보시면 좋을 것 같습니다:
- localStorage 사용 가능 여부를 확인하는 초기화 로직
- 메모리 캐싱을 통한 성능 최적화
- 저장된 값의 유효성 검사
- 만료 시간 설정 기능
이러한 기능들을 추가하면 더욱 안정적이고 확장 가능한 모듈이 될 것 같습니다.
packages/shared/src/modules/search-params/useSearchParams.ts (1)
1-5
: 클라이언트 컴포넌트 지시자와 임포트 구성이 적절합니다.'use client' 지시자와 Next.js navigation 기능의 임포트가 올바르게 구성되어 있습니다. useSearchParams를 useSearchParamsNext로 별칭을 지정한 것은 이름 충돌을 방지하는 좋은 방법입니다.
상대 경로 대신 절대 경로를 사용하는 것을 고려해보세요:
-import { SearchParams, SearchParamType } from '.'; +import { SearchParams, SearchParamType } from '@shared/modules/search-params';packages/shared/src/modules/local-storage/constant.ts (2)
5-6
: 함수 문서화가 필요합니다.타입 가드 함수의 목적과 사용법을 설명하는 JSDoc 문서를 추가하면 좋을 것 같습니다.
다음과 같이 문서를 추가해보세요:
+/** + * 주어진 문자열이 유효한 업데이트 버전 키인지 확인합니다. + * @param value - 검사할 문자열 + * @returns 문자열이 'updateVersionX.Y.Z' 형식을 따르는지 여부 + */ export const checkUpdateVersionKey = (value: string): value is UpdateVersionType => REGEXR_UPDATE_VERSION_VERSION.test(value);
10-11
: 타입 체크 로직 최적화를 제안합니다.현재 구현은 올바르지만, 배열 검색을 최적화할 수 있습니다.
Set
을 사용하여 검색 성능을 개선해보세요:+const LOCAL_STORAGE_KEY_SET = new Set(LOCAL_STORAGE_KEY); export const checkLocalStorageKey = (value: string): value is LocalStorageKeyType => - checkUpdateVersionKey(value) || (LOCAL_STORAGE_KEY as readonly string[]).includes(value); + checkUpdateVersionKey(value) || LOCAL_STORAGE_KEY_SET.has(value);packages/shared/src/modules/search-params/SearchParams.ts (1)
16-23
: get 메서드의 반환 값 처리를 개선할 수 있습니다.get 메서드에서 빈 값 처리를 더 명시적으로 할 수 있습니다.
다음과 같이 개선해보세요:
get = (key: SearchParamKeyType) => { const values = this.#searchParamsMap.get(key); - return values ? Array.from(values)[0] || '' : ''; + if (!values || values.size === 0) return ''; + return Array.from(values)[0]; };packages/shared/src/modules/search-params/SearchParams.test.ts (4)
1-12
: 타입 안전성 및 테스트 데이터 구성 개선 제안테스트 데이터 설정이 잘 되어 있지만, 다음과 같은 개선사항을 제안드립니다:
- 테스트 데이터를 상수로 분리하여 재사용성을 높이고 유지보수를 용이하게 할 수 있습니다.
- 테스트 데이터의 타입을 명시적으로 정의하면 타입 안전성을 향상시킬 수 있습니다.
const TEST_SEARCH_PARAMS: [string, string][] = [ ['id', '5'], ['id', '10'], ['category', 'book'], ] as const;
26-31
: 테스트 케이스 보완 제안현재 테스트가 잘 작성되어 있지만, 다음과 같은 엣지 케이스 테스트를 추가하면 좋을 것 같습니다:
- 존재하지 않는 키에 대한 테스트
- 빈 값이 포함된 경우의 테스트
test('존재하지 않는 key값의 경우 빈 배열을 반환한다.', () => { expect(searchParams.getAll('nonexistent')).toStrictEqual([]); }); test('빈 값이 포함된 경우를 처리한다.', () => { searchParams.add('empty', ''); expect(searchParams.getAll('empty')).toStrictEqual(['']); });
55-55
: 테스트 설명 오타 수정 필요테스트 설명에 마침표가 두 번 들어간 오타가 있습니다: "제거하지 않는다.."
- test('key와 value에 해당하는 값이 없다면 제거하지 않는다..', () => { + test('key와 value에 해당하는 값이 없다면 제거하지 않는다.', () => {
62-68
: removeAll 메서드 테스트 케이스 보완 필요현재 기본적인 케이스만 테스트하고 있습니다. 다음과 같은 추가 테스트 케이스를 고려해보세요:
- 존재하지 않는 키에 대한 removeAll 호출
- 여러 키를 연속적으로 제거하는 경우
test('존재하지 않는 key에 대해 removeAll을 호출해도 에러가 발생하지 않는다.', () => { expect(() => searchParams.removeAll('nonexistent')).not.toThrow(); }); test('여러 key를 연속적으로 제거할 수 있다.', () => { searchParams.removeAll('id'); searchParams.removeAll('category'); expect(searchParams.getSearchParams()).toBe(''); });packages/web/src/app/[lng]/memos/components/MemoDialog/index.tsx (1)
4-5
: 모듈 구조 개선을 위한 제안imports를 다음과 같이 그룹화하여 정리하면 코드 가독성이 향상될 것 같습니다:
- 외부 라이브러리
- 내부 모듈
- 컴포넌트
- 타입
'use client'; import { useCloseOnEscape, useMemoPatchMutation, useMemoQuery } from '@extension/shared/hooks'; + import { useSearchParams } from '@extension/shared/modules/search-params'; import { Button } from '@extension/ui'; + import { useRouter } from 'next/navigation'; + import Image from 'next/image'; + import Link from 'next/link'; + import { useEffect, useState } from 'react'; + import { useForm } from 'react-hook-form'; import useTranslation from '@src/modules/i18n/client'; import { LanguageType } from '@src/modules/i18n'; import { useSupabaseClient } from '@src/hooks'; import { useToast } from '@src/hooks/use-toast'; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@src/components/ui/dialog'; import { Textarea } from '@src/components/ui/textarea'; - import Image from 'next/image'; - import Link from 'next/link'; - import { useEffect, useState } from 'react'; - import { useForm } from 'react-hook-form'; import { MemoInput } from '../../types'; - import { useRouter } from 'next/navigation'; - import { useSearchParams } from '@extension/shared/modules/search-params';Also applies to: 14-16
packages/web/src/app/[lng]/memos/components/MemoView/MemoItem.tsx (1)
3-18
: 의존성 관리 개선이 필요합니다.불필요한 import를 제거하고 필요한 의존성을 추가한 것은 좋은 변경사항입니다. 하지만 몇 가지 개선할 점이 있습니다:
- 관련된 import들을 그룹화하여 정리하면 가독성이 향상될 것 같습니다.
- 외부/내부 의존성을 명확하게 구분하면 좋겠습니다.
다음과 같이 import문을 정리하는 것을 제안합니다:
// React & Next.js import { HTMLAttributes, KeyboardEvent, memo, MouseEvent, MouseEventHandler, useState } from 'react'; import Image from 'next/image'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; // External dependencies import { HeartIcon } from 'lucide-react'; // Internal shared modules import { useMemoPatchMutation } from '@extension/shared/hooks'; import { GetMemoResponse } from '@extension/shared/utils'; import { useSearchParams } from '@extension/shared/modules/search-params'; // Internal UI components import { Badge } from '@src/components/ui/badge'; import { Card, CardContent, CardFooter, CardHeader } from '@src/components/ui/card'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@src/components/ui/tooltip'; // Internal hooks & utils import useTranslation from '@src/modules/i18n/client'; import { LanguageType } from '@src/modules/i18n'; import { useSupabaseClient } from '@src/hooks'; import { useToast } from '@src/hooks/use-toast'; import { cn } from '@src/utils';
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (28)
packages/shared/package.json
(1 hunks)packages/shared/src/constants/Extension.ts
(1 hunks)packages/shared/src/constants/Supabase.ts
(1 hunks)packages/shared/src/modules/local-storage/LocalStorage.ts
(1 hunks)packages/shared/src/modules/local-storage/constant.ts
(1 hunks)packages/shared/src/modules/local-storage/index.ts
(1 hunks)packages/shared/src/modules/local-storage/type.ts
(1 hunks)packages/shared/src/modules/local-storage/util.ts
(1 hunks)packages/shared/src/modules/search-params/SearchParams.test.ts
(1 hunks)packages/shared/src/modules/search-params/SearchParams.ts
(1 hunks)packages/shared/src/modules/search-params/constant.ts
(1 hunks)packages/shared/src/modules/search-params/index.ts
(1 hunks)packages/shared/src/modules/search-params/type.ts
(1 hunks)packages/shared/src/modules/search-params/useSearchParams.ts
(1 hunks)packages/shared/src/utils/web/Environment.ts
(0 hunks)packages/shared/src/utils/web/index.ts
(0 hunks)packages/web/src/app/[lng]/layout.tsx
(3 hunks)packages/web/src/app/[lng]/memos/components/Header/RefreshButton.tsx
(1 hunks)packages/web/src/app/[lng]/memos/components/MemoDialog/index.tsx
(2 hunks)packages/web/src/app/[lng]/memos/components/MemoView/MemoItem.tsx
(4 hunks)packages/web/src/app/[lng]/memos/components/MemoView/index.tsx
(1 hunks)packages/web/src/app/[lng]/memos/hooks/useGuide.ts
(1 hunks)packages/web/src/app/[lng]/memos/utils/guide.ts
(2 hunks)packages/web/src/app/components/ExtensionDialog/getExtensionDialogInfo.ts
(1 hunks)packages/web/src/app/components/ExtensionDialog/useExtensionDialog.ts
(1 hunks)packages/web/src/modules/i18n/client.js
(1 hunks)packages/web/src/utils/index.ts
(1 hunks)pages/side-panel/src/utils/Url.ts
(1 hunks)
💤 Files with no reviewable changes (2)
- packages/shared/src/utils/web/Environment.ts
- packages/shared/src/utils/web/index.ts
✅ Files skipped from review due to trivial changes (3)
- packages/shared/src/modules/local-storage/index.ts
- packages/shared/src/modules/search-params/constant.ts
- packages/shared/src/modules/search-params/index.ts
🚧 Files skipped from review as they are similar to previous changes (13)
- packages/shared/package.json
- packages/shared/src/constants/Extension.ts
- packages/shared/src/constants/Supabase.ts
- packages/web/src/app/[lng]/layout.tsx
- packages/web/src/app/[lng]/memos/components/Header/RefreshButton.tsx
- packages/web/src/app/[lng]/memos/components/MemoView/index.tsx
- packages/web/src/app/[lng]/memos/hooks/useGuide.ts
- packages/web/src/app/[lng]/memos/utils/guide.ts
- packages/web/src/app/components/ExtensionDialog/getExtensionDialogInfo.ts
- packages/web/src/app/components/ExtensionDialog/useExtensionDialog.ts
- packages/web/src/modules/i18n/client.js
- packages/web/src/utils/index.ts
- pages/side-panel/src/utils/Url.ts
🧰 Additional context used
🪛 Biome (1.9.4)
packages/shared/src/modules/local-storage/LocalStorage.ts
[error] 3-11: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
🔇 Additional comments (14)
packages/shared/src/modules/local-storage/type.ts (1)
5-5
: 타입 정의가 잘 되어있습니다!
typeof
를 사용한 타입 추론과 유니온 타입의 조합이 잘 구현되어 있습니다. 타입 안전성을 보장하면서도 확장 가능한 구조입니다.
packages/shared/src/modules/search-params/type.ts (1)
1-1
: 상수 파일의 존재 여부와 내용을 확인하세요
SEARCH_PARAMS_KEYS
상수가 올바르게 정의되어 있는지 확인이 필요합니다.
✅ Verification successful
SEARCH_PARAMS_KEYS
상수가 올바르게 정의되어 있음을 확인했습니다
constant.ts
파일에서 SEARCH_PARAMS_KEYS
가 ['id', 'isWish', 'category']
로 정확하게 정의되어 있으며, 타입 정의에서도 적절하게 사용되고 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the existence and content of SEARCH_PARAMS_KEYS constant
# Check if the constant file exists and show its content
fd -e ts -e tsx constant.ts --exec cat {}
# Find usages of SEARCH_PARAMS_KEYS
rg "SEARCH_PARAMS_KEYS"
Length of output: 1375
packages/shared/src/modules/local-storage/LocalStorage.ts (1)
1-1
: 타입 정의를 검토하세요.
LocalStorageKeyType
의 정의를 확인하고 필요한 모든 키가 포함되어 있는지 검증해야 합니다.
✅ Verification successful
LocalStorageKeyType 정의가 명확하게 확인되었습니다.
LocalStorageKeyType
은 다음 키들을 포함하고 있습니다:
- 'guide': 가이드 관련 상태
- 'updateVersion': 업데이트 버전 관련 상태
- 'install': 설치 관련 상태
updateVersion${number}.${number}.${number}
형식의 버전 문자열
모든 필수 키가 포함되어 있으며, 타입 정의가 적절하게 되어 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# LocalStorageKeyType 정의를 확인
rg -t typescript "type LocalStorageKeyType" -A 5
Length of output: 85
Script:
#!/bin/bash
# LocalStorageKeyType 정의를 찾기 위한 다양한 검색 시도
rg "LocalStorageKeyType" -A 5
# index.ts 파일에서 타입 정의 찾기
fd "index.ts" --exec cat {} \; --exec echo "---" \;
# 타입 정의가 있을 수 있는 모든 타입스크립트 파일 검색
fd -e ts --exec cat {} \; --exec echo "---" \;
Length of output: 100294
Script:
#!/bin/bash
# LOCAL_STORAGE_KEY 상수 정의 찾기
rg "LOCAL_STORAGE_KEY" -A 5
# constant.ts 파일에서 LocalStorageKeyType 관련 정의 찾기
fd "constant.ts" --exec cat {} \; --exec echo "---" \;
Length of output: 2470
packages/shared/src/modules/local-storage/util.ts (1)
1-1
: 깔끔한 import 구문입니다!
필요한 타입과 상수들을 명확하게 import하고 있습니다.
packages/shared/src/modules/local-storage/constant.ts (2)
3-3
: 정규식 패턴이 적절해 보입니다.
시맨틱 버저닝 형식을 정확하게 검증할 수 있는 패턴입니다.
1-1
: 타입 임포트 검증이 필요합니다.
임포트된 타입들이 올바르게 정의되어 있는지 확인이 필요합니다.
✅ Verification successful
타입 임포트가 올바르게 정의되어 있음을 확인했습니다.
UpdateVersionType
과 LocalStorageKeyType
타입이 packages/shared/src/modules/local-storage/type.ts
파일에서 적절하게 정의되어 있고, 올바르게 내보내기(export)되어 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if the imported types are properly defined
ast-grep --pattern 'type UpdateVersionType = $_'
ast-grep --pattern 'type LocalStorageKeyType = $_'
Length of output: 375
packages/shared/src/modules/search-params/SearchParams.ts (1)
1-5
: 코드가 깔끔하고 타입이 잘 정의되어 있습니다!
타입스크립트의 타입 시스템을 잘 활용하고 있으며, private 필드를 사용하여 캡슐화가 잘 되어있습니다.
packages/web/src/app/[lng]/memos/components/MemoDialog/index.tsx (2)
28-29
: 이전 리뷰 코멘트가 여전히 유효함
데이터 페칭 에러 처리와 로딩 상태 처리가 아직 구현되지 않았습니다.
60-64
: 이전 리뷰 코멘트가 여전히 유효함
저장되지 않은 변경사항이 있을 때의 사용자 경험 처리가 아직 구현되지 않았습니다.
packages/web/src/app/[lng]/memos/components/MemoView/MemoItem.tsx (5)
21-21
: 타입 정의가 개선되었습니다.
GetMemoResponse
타입으로 변경한 것은 좋은 선택입니다. API 응답 타입과 일치하도록 개선되었습니다.
28-28
: Supabase 클라이언트 사용 방식이 개선되었습니다.
useSupabaseClient
훅을 사용하는 방식으로 변경한 것은 다음과 같은 장점이 있습니다:
- 컴포넌트 생명주기와 잘 통합됩니다
- 다른 컴포넌트들과 일관된 방식을 유지합니다
Also applies to: 32-32
86-86
: 이미지 스타일링이 개선되었습니다.
object-fit: 'contain'
과 height: 'auto'
설정으로 이미지 비율이 깨지지 않도록 수정된 점이 좋습니다.
126-126
: prop 이름이 더 명확해졌습니다.
id
에서 memoId
로 prop 이름을 변경한 것은 좋은 개선입니다. 이는 prop의 목적을 더 명확하게 전달합니다.
34-35
: 검색 파라미터 처리 방식 검증이 필요합니다.
새로운 검색 파라미터 처리 방식이 도입되었습니다. 다음 사항들을 확인해주세요:
- URL 업데이트 시 스크롤 동작이 의도한대로 작동하는지
- 브라우저 뒤로가기 동작이 올바르게 처리되는지
Also applies to: 59-60
✅ Verification successful
Let me gather more information about the scroll behavior implementation.
Let me check the implementation of browser history handling.
URL 파라미터 처리가 적절하게 구현되어 있습니다.
코드 분석 결과, 다음과 같은 사항들이 확인되었습니다:
-
스크롤 동작:
- MemoItem과 MemoDialog에서 URL 업데이트 시
{ scroll: false }
옵션을 사용하여 불필요한 스크롤을 방지 - 카테고리 이동 시에만
{ scroll: true }
를 사용하여 의도적인 스크롤 동작 구현
- MemoItem과 MemoDialog에서 URL 업데이트 시
-
브라우저 히스토리:
router.replace()
를 사용하여 불필요한 히스토리 스택 쌓임을 방지- 공통
useSearchParams
훅을 통해 일관된 URL 파라미터 처리
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# URL 파라미터 처리 관련 코드 검색
rg "useSearchParams|router\.replace" -A 3
Length of output: 4159
Script:
#!/bin/bash
# Search for scroll-related configurations and implementations
rg "scroll:|scrollTo|scrollIntoView" -A 3
Length of output: 2446
Script:
#!/bin/bash
# Search for router and navigation related implementations
rg "useRouter|router\.(back|forward|push|replace)" -A 3
Length of output: 5903
packages/web/src/app/[lng]/memos/components/MemoDialog/index.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Outside diff range and nitpick comments (7)
packages/shared/src/modules/local-storage/type.ts (2)
3-3
: 버전 형식에 대한 문서화가 필요합니다.템플릿 리터럴 타입을 사용하여 버전 문자열 형식을 잘 정의했습니다. 하지만 이 형식이 어떤 상황에서 사용되는지 설명하는 JSDoc 주석을 추가하면 좋을 것 같습니다.
다음과 같이 문서화를 추가해보세요:
+/** + * 업데이트 버전을 나타내는 문자열 타입 + * @example 'updateVersion1.0.0' + */ export type UpdateVersionType = `updateVersion${number}.${number}.${number}`;
6-6
: 타입 설계가 잘 되었습니다!
BasicStorageKeyType
과UpdateVersionType
을 유니온 타입으로 결합한 것은 좋은 설계입니다. 이는 기본 스토리지 키와 버전 관련 키를 명확하게 구분하면서도 함께 사용할 수 있게 해줍니다.향후 새로운 종류의 키가 필요할 경우, 이 유니온 타입에 추가하면 됩니다. 단, 키의 종류가 많아진다면 카테고리별로 분리하는 것을 고려해보세요.
packages/shared/src/modules/local-storage/util.ts (1)
1-10
: 단위 테스트 추가를 고려해주세요.localStorage 관련 기능은 중요한 부분이므로, 다음과 같은 테스트 케이스 추가를 권장드립니다:
- 정상적인 값 설정/조회
- localStorage 접근 불가 상황
- 잘못된 키 사용
단위 테스트 코드 작성을 도와드릴까요?
packages/shared/src/modules/local-storage/constant.ts (3)
3-3
: 정규식 패턴을 더 엄격하게 개선해 보세요.현재 정규식은 부분 일치를 허용할 수 있으며, 버전 번호의 범위가 제한되어 있지 않습니다.
다음과 같이 개선하는 것을 제안드립니다:
-const REGEXR_UPDATE_VERSION_VERSION = /^updateVersion\d+\.\d+\.\d+$/; +const REGEXR_UPDATE_VERSION_VERSION = /^updateVersion(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;이렇게 수정하면:
- 각 버전 번호가 0이거나 1-9로 시작하는 숫자만 허용
- 불필요한 선행 0을 방지
5-6
: 입력값 검증을 추가하면 좋을 것 같습니다.현재 구현은
undefined
또는null
입력에 대한 처리가 없습니다.다음과 같이 개선하는 것을 제안드립니다:
-export const checkUpdateVersionKey = (value: string): value is UpdateVersionType => - REGEXR_UPDATE_VERSION_VERSION.test(value); +export const checkUpdateVersionKey = (value: string): value is UpdateVersionType => + typeof value === 'string' && REGEXR_UPDATE_VERSION_VERSION.test(value);
8-8
: 각 스토리지 키의 용도를 문서화하면 좋을 것 같습니다.현재 코드만으로는 각 키의 구체적인 용도를 파악하기 어렵습니다.
다음과 같이 JSDoc을 추가하는 것을 제안드립니다:
+/** + * 로컬 스토리지 키 목록 + * - guide: 사용자 가이드 표시 여부 + * - updateVersion: 앱 업데이트 버전 정보 + * - install: 앱 설치 상태 + */ export const LOCAL_STORAGE_KEYS = ['guide', 'updateVersion', 'install'] as const;packages/web/src/app/components/ExtensionDialog/useExtensionDialog.ts (1)
18-34
: useEffect 로직 개선이 필요합니다현재 구현은 다음과 같은 개선이 필요합니다:
- 조건문이 중첩되어 있어 가독성이 떨어집니다
- 상태 업데이트 로직이 반복됩니다
다음과 같이 리팩토링하는 것을 제안드립니다:
useEffect(() => { if (manifest === null) return; const isExtensionInstalled = manifest !== undefined; const isExtensionNotLastVersion = isExtensionInstalled && manifest.version !== EXTENSION.lastVersion; - if (!isExtensionInstalled && !checkLocalStorageTrue('install')) { - setDialogType('install'); - setOpen(true); - return; - } - if (isExtensionNotLastVersion && !checkLocalStorageTrue('updateVersion')) { - setDialogType('update'); - setOpen(true); - return; - } + const shouldShowInstall = !isExtensionInstalled && !checkLocalStorageTrue('install'); + const shouldShowUpdate = isExtensionNotLastVersion && !checkLocalStorageTrue('updateVersion'); + + if (shouldShowInstall || shouldShowUpdate) { + setDialogType(shouldShowInstall ? 'install' : 'update'); + setOpen(true); + } }, [manifest]);
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (11)
packages/shared/src/modules/local-storage/LocalStorage.ts
(1 hunks)packages/shared/src/modules/local-storage/constant.ts
(1 hunks)packages/shared/src/modules/local-storage/type.ts
(1 hunks)packages/shared/src/modules/local-storage/util.ts
(1 hunks)packages/shared/src/modules/search-params/SearchParams.test.ts
(1 hunks)packages/shared/src/modules/search-params/SearchParams.ts
(1 hunks)packages/web/src/app/auth/callback/route.ts
(2 hunks)packages/web/src/app/components/ExtensionDialog/getExtensionDialogInfo.ts
(1 hunks)packages/web/src/app/components/ExtensionDialog/index.tsx
(1 hunks)packages/web/src/app/components/ExtensionDialog/useExtensionDialog.ts
(1 hunks)packages/web/tsconfig.json
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- packages/shared/src/modules/search-params/SearchParams.test.ts
- packages/shared/src/modules/search-params/SearchParams.ts
- packages/web/src/app/components/ExtensionDialog/getExtensionDialogInfo.ts
- packages/web/src/app/components/ExtensionDialog/index.tsx
- packages/web/tsconfig.json
🧰 Additional context used
🪛 Biome (1.9.4)
packages/shared/src/modules/local-storage/LocalStorage.ts
[error] 3-11: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
🔇 Additional comments (12)
packages/shared/src/modules/local-storage/type.ts (2)
1-1
: 상수 가져오기가 올바르게 구현되었습니다!
로컬 스토리지 키 상수를 상대 경로로 올바르게 가져오고 있습니다.
4-4
: LOCAL_STORAGE_KEYS 상수의 정의를 확인해주세요.
LOCAL_STORAGE_KEYS
상수로부터 타입을 추출하는 방식이 적절합니다. 하지만 상수의 정의가 올바른지 확인이 필요합니다.
다음 스크립트로 상수 정의를 확인할 수 있습니다:
✅ Verification successful
LOCAL_STORAGE_KEYS 상수가 올바르게 정의되어 있습니다.
LOCAL_STORAGE_KEYS
상수가 guide
, updateVersion
, install
세 가지 키를 포함하는 문자열 배열로 적절하게 정의되어 있으며, as const
단언을 통해 타입 안전성이 보장되어 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# LOCAL_STORAGE_KEYS 상수의 정의 확인
ast-grep --pattern 'const LOCAL_STORAGE_KEYS = [$$$] as const'
Length of output: 202
packages/shared/src/modules/local-storage/util.ts (1)
1-2
: LGTM!
타입과 의존성이 명확하게 정의되어 있습니다.
packages/shared/src/modules/local-storage/LocalStorage.ts (2)
4-6
: JSON 파싱 및 오류 처리가 필요합니다
이전 리뷰에서 지적된 JSON 파싱 관련 문제가 아직 해결되지 않았습니다.
3-11
: 정적 메서드만 포함된 클래스를 함수로 변경하세요
이전 리뷰에서 제안된 클래스 구조 개선이 아직 반영되지 않았습니다.
🧰 Tools
🪛 Biome (1.9.4)
[error] 3-11: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
packages/shared/src/modules/local-storage/constant.ts (2)
1-1
: 타입 임포트가 깔끔하게 구성되어 있습니다!
타입 정의를 별도 파일로 분리하고, 명확한 네이밍을 사용한 점이 좋습니다.
10-14
: 타입 안전성이 잘 구현되어 있습니다!
isBasicStorageKey
와 checkLocalStorageKey
함수가 타입 가드를 효과적으로 활용하고 있어 타입 안전성을 보장합니다.
packages/web/src/app/auth/callback/route.ts (1)
4-4
: 상수 관리 개선이 잘 되었습니다!
개별 상수들을 COOKIE_KEY
객체로 통합하여 관리하는 방식으로 개선된 것이 좋습니다.
packages/web/src/app/components/ExtensionDialog/useExtensionDialog.ts (4)
1-11
: 경로 별칭 설정 확인이 필요합니다
이전 리뷰에서 지적된 @extension
경로 별칭 문제가 여전히 존재합니다.
13-17
: 상태 관리가 잘 구현되어 있습니다
open
과 dialogType
상태가 명확하게 분리되어 있고, 타입 정의도 적절합니다.
21-23
: 버전 비교 로직 개선이 필요합니다
이전 리뷰에서 지적된 버전 비교 문제가 해결되지 않았습니다. 시맨틱 버저닝을 올바르게 처리하기 위해 semver
라이브러리 사용을 권장드립니다.
36-39
: handleClose 함수가 적절하게 구현되어 있습니다
로컬 스토리지 키 검증 후 상태를 업데이트하는 로직이 안전하게 구현되어 있습니다.
export const setLocalStorageTrue = (key: LocalStorageKeyType) => { | ||
LocalStorage.set(key, true); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
localStorage 사용 시 안전성 개선이 필요합니다.
다음과 같은 개선사항을 제안드립니다:
- localStorage 접근 실패에 대한 예외 처리
- 반환 타입 명시
- 값 매핑 상수 사용
-export const setLocalStorageTrue = (key: LocalStorageKeyType) => {
+export const setLocalStorageTrue = (key: LocalStorageKeyType): void => {
+ try {
- LocalStorage.set(key, true);
+ LocalStorage.set(key, LOCAL_STORAGE_VALUE_MAP.true);
+ } catch (error) {
+ console.error(`localStorage 설정 중 오류 발생: ${error}`);
+ }
};
Committable suggestion skipped: line range outside the PR's diff.
export const checkLocalStorageTrue = (key: LocalStorageKeyType) => { | ||
return LocalStorage.get(key) === true; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
타입 안전성과 예외 처리가 필요합니다.
boolean 값 비교 시 LOCAL_STORAGE_VALUE_MAP.true를 사용하고, localStorage 접근 실패에 대한 처리가 필요합니다.
-export const checkLocalStorageTrue = (key: LocalStorageKeyType) => {
+export const checkLocalStorageTrue = (key: LocalStorageKeyType): boolean => {
+ try {
- return LocalStorage.get(key) === true;
+ return LocalStorage.get(key) === LOCAL_STORAGE_VALUE_MAP.true;
+ } catch (error) {
+ console.error(`localStorage 확인 중 오류 발생: ${error}`);
+ return false;
+ }
};
Committable suggestion skipped: line range outside the PR's diff.
static get<T>(key: LocalStorageKeyType): T | null { | ||
return JSON.parse(localStorage.getItem(key) ?? ''); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제네릭 타입 안전성을 개선하세요
현재 구현은 타입 안전성이 보장되지 않습니다. 저장된 데이터의 타입과 반환 타입이 일치하지 않을 수 있습니다.
다음과 같이 개선하는 것을 제안합니다:
- static get<T>(key: LocalStorageKeyType): T | null {
- return JSON.parse(localStorage.getItem(key) ?? '');
+ static get<T>(key: LocalStorageKeyType): T | null {
+ try {
+ const item = localStorage.getItem(key);
+ if (!item) return null;
+
+ const parsed = JSON.parse(item);
+ // 런타임 타입 검사 추가
+ if (typeof parsed !== typeof {} as T) {
+ console.warn(`Type mismatch for key ${key}`);
+ return null;
+ }
+ return parsed as T;
+ } catch (error) {
+ console.error(`Failed to parse localStorage key ${key}:`, error);
+ return null;
+ }
}
Committable suggestion skipped: line range outside the PR's diff.
cookieStore.set(COOKIE_KEY.accessToken, sessionData.session.access_token, { | ||
maxAge: 3600 * 24 * 365, // 1년 | ||
secure: true, | ||
httpOnly: true, | ||
sameSite: 'strict', | ||
}); | ||
cookieStore.set(COOKIE_KEY.refreshToken, sessionData.session.refresh_token, { | ||
maxAge: 3600 * 24 * 365, // 1년 | ||
secure: true, | ||
httpOnly: true, | ||
sameSite: 'strict', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
보안 설정은 개선되었으나, 만료 기간 검토가 필요합니다.
쿠키 보안 설정(secure
, httpOnly
, sameSite
)이 추가된 것은 매우 긍정적인 변화입니다. 하지만 여전히 다음 사항에 대한 검토가 필요합니다:
토큰의 만료 기간이 1년으로 설정되어 있는데, 이는 보안상 너무 긴 기간입니다. 다음과 같이 수정하는 것을 권장드립니다:
cookieStore.set(COOKIE_KEY.accessToken, sessionData.session.access_token, {
- maxAge: 3600 * 24 * 365, // 1년
+ maxAge: 3600 * 24 * 30, // 30일
secure: true,
httpOnly: true,
sameSite: 'strict',
});
cookieStore.set(COOKIE_KEY.refreshToken, sessionData.session.refresh_token, {
- maxAge: 3600 * 24 * 365, // 1년
+ maxAge: 3600 * 24 * 30, // 30일
secure: true,
httpOnly: true,
sameSite: 'strict',
});
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
cookieStore.set(COOKIE_KEY.accessToken, sessionData.session.access_token, { | |
maxAge: 3600 * 24 * 365, // 1년 | |
secure: true, | |
httpOnly: true, | |
sameSite: 'strict', | |
}); | |
cookieStore.set(COOKIE_KEY.refreshToken, sessionData.session.refresh_token, { | |
maxAge: 3600 * 24 * 365, // 1년 | |
secure: true, | |
httpOnly: true, | |
sameSite: 'strict', | |
cookieStore.set(COOKIE_KEY.accessToken, sessionData.session.access_token, { | |
maxAge: 3600 * 24 * 30, // 30일 | |
secure: true, | |
httpOnly: true, | |
sameSite: 'strict', | |
}); | |
cookieStore.set(COOKIE_KEY.refreshToken, sessionData.session.refresh_token, { | |
maxAge: 3600 * 24 * 30, // 30일 | |
secure: true, | |
httpOnly: true, | |
sameSite: 'strict', |
Summary by CodeRabbit
릴리스 노트
신규 기능
useSupabaseClientQuery
후크 추가: Supabase 클라이언트를 더 효율적으로 관리합니다.ExtensionDialog
컴포넌트 추가: 확장 프로그램 설치 및 업데이트 알림을 사용자에게 제공합니다.SearchParams
클래스 추가: 검색 매개변수를 쉽게 관리할 수 있도록 합니다.LocalStorage
클래스 추가: 로컬 스토리지와의 상호작용을 단순화합니다.버그 수정
문서화
리팩토링