From 439653fa2f30feb38a5940c7f405576f4d0f10df Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 22:35:44 +0000 Subject: [PATCH] Remove on-premise Supabase test code Remove code related to on-premise Supabase testing. --- src/components/SyncSettings.tsx | 14 +- src/components/auth/ServerStatusAlert.tsx | 45 ------ .../auth/SupabaseConnectionStatus.tsx | 66 --------- src/components/auth/TestConnectionSection.tsx | 79 ---------- src/components/auth/types.ts | 21 --- .../supabase/ConnectionTestButton.tsx | 34 ----- src/components/supabase/CorsProxyToggle.tsx | 39 ----- src/components/supabase/ProxyInfoCard.tsx | 20 --- src/components/supabase/ProxyTypeSelector.tsx | 37 ----- .../supabase/SaveSettingsButton.tsx | 36 ----- .../supabase/SupabaseConnectionTest.tsx | 85 ----------- .../supabase/SupabaseHelpSection.tsx | 54 ------- src/components/supabase/SupabaseKeyInput.tsx | 40 ----- .../supabase/SupabaseSettingsForm.tsx | 137 ------------------ src/components/supabase/SupabaseUrlInput.tsx | 53 ------- src/components/supabase/TestResultItem.tsx | 20 --- src/lib/supabase/client.ts | 9 +- src/lib/supabase/config.ts | 35 +---- src/lib/supabase/connectionTest.ts | 69 --------- src/lib/supabase/index.ts | 6 +- src/lib/supabase/setup/index.ts | 6 +- src/lib/supabase/setup/status.ts | 43 ------ src/lib/supabase/tests/index.ts | 93 ------------ src/pages/SupabaseSettings.tsx | 45 ------ src/utils/sync/syncSettings.ts | 2 +- 25 files changed, 8 insertions(+), 1080 deletions(-) delete mode 100644 src/components/auth/ServerStatusAlert.tsx delete mode 100644 src/components/auth/SupabaseConnectionStatus.tsx delete mode 100644 src/components/auth/TestConnectionSection.tsx delete mode 100644 src/components/auth/types.ts delete mode 100644 src/components/supabase/ConnectionTestButton.tsx delete mode 100644 src/components/supabase/CorsProxyToggle.tsx delete mode 100644 src/components/supabase/ProxyInfoCard.tsx delete mode 100644 src/components/supabase/ProxyTypeSelector.tsx delete mode 100644 src/components/supabase/SaveSettingsButton.tsx delete mode 100644 src/components/supabase/SupabaseConnectionTest.tsx delete mode 100644 src/components/supabase/SupabaseHelpSection.tsx delete mode 100644 src/components/supabase/SupabaseKeyInput.tsx delete mode 100644 src/components/supabase/SupabaseSettingsForm.tsx delete mode 100644 src/components/supabase/SupabaseUrlInput.tsx delete mode 100644 src/components/supabase/TestResultItem.tsx delete mode 100644 src/lib/supabase/connectionTest.ts delete mode 100644 src/lib/supabase/tests/index.ts delete mode 100644 src/pages/SupabaseSettings.tsx diff --git a/src/components/SyncSettings.tsx b/src/components/SyncSettings.tsx index 6d1fff7..d662a8e 100644 --- a/src/components/SyncSettings.tsx +++ b/src/components/SyncSettings.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'; import { Switch } from "@/components/ui/switch"; import { Label } from "@/components/ui/label"; -import { CloudUpload, RefreshCw, Database } from "lucide-react"; +import { CloudUpload, RefreshCw } from "lucide-react"; import { isSyncEnabled, setSyncEnabled, syncAllData, getLastSyncTime } from "@/utils/syncUtils"; import { toast } from "@/hooks/useToast.wrapper"; import { useAuth } from "@/contexts/auth"; @@ -139,18 +139,6 @@ const SyncSettings = () => { )} - - {/* 온프레미스 Supabase 설정 버튼 추가 */} -
- -
); }; diff --git a/src/components/auth/ServerStatusAlert.tsx b/src/components/auth/ServerStatusAlert.tsx deleted file mode 100644 index c8456ef..0000000 --- a/src/components/auth/ServerStatusAlert.tsx +++ /dev/null @@ -1,45 +0,0 @@ - -import React from "react"; -import { RefreshCcw } from "lucide-react"; -import { Button } from "@/components/ui/button"; -import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert"; - -interface ServerStatusAlertProps { - serverStatus: { - checked: boolean; - connected: boolean; - message: string; - }; - checkServerConnection: () => Promise; -} - -const ServerStatusAlert: React.FC = ({ - serverStatus, - checkServerConnection, -}) => { - if (!serverStatus.checked || serverStatus.connected) { - return null; - } - - return ( - - - 서버 연결 문제 - - - - {serverStatus.message} -

회원가입을 시도하기 전에 서버 연결 문제를 해결해주세요.

-
-
- ); -}; - -export default ServerStatusAlert; diff --git a/src/components/auth/SupabaseConnectionStatus.tsx b/src/components/auth/SupabaseConnectionStatus.tsx deleted file mode 100644 index 0b4942e..0000000 --- a/src/components/auth/SupabaseConnectionStatus.tsx +++ /dev/null @@ -1,66 +0,0 @@ - -import React from "react"; -import { Link } from "react-router-dom"; -import { ArrowRight, Shield } from "lucide-react"; -import { TestResults } from "@/lib/supabase/tests/types"; - -interface TestResultProps { - testResults: TestResults | null; -} - -const SupabaseConnectionStatus: React.FC = ({ testResults }) => { - if (!testResults) { - return null; - } - - return ( -
- 고급 진단 정보 -
-
-

Supabase URL:

-

{testResults?.url || '알 수 없음'}

-
- {testResults?.usingProxy && ( -
-

CORS 프록시:

-
- -

활성화됨 - {testResults.proxyUrl}

-
-
- )} -
-

클라이언트 초기화:

-

{testResults?.client ? '성공' : '실패'}

-
-
-

브라우저 정보:

-

{navigator.userAgent}

-
-
-

앱 버전:

-

1.0.0

-
- {testResults && ( -
-

REST API: {testResults.restApi ? '✅' : '❌'}

-

인증: {testResults.auth ? '✅' : '❌'}

-

데이터베이스: {testResults.database ? '✅' : '❌'}

-
- )} -
- - Supabase 설정 변경 - - -
-
-
- ); -}; - -export default SupabaseConnectionStatus; diff --git a/src/components/auth/TestConnectionSection.tsx b/src/components/auth/TestConnectionSection.tsx deleted file mode 100644 index 01e33a7..0000000 --- a/src/components/auth/TestConnectionSection.tsx +++ /dev/null @@ -1,79 +0,0 @@ - -import React, { useState } from "react"; -import { RefreshCw } from "lucide-react"; -import { testSupabaseConnection } from "@/lib/supabase"; -import { useToast } from "@/hooks/useToast.wrapper"; -import { TestResults } from "@/lib/supabase/tests/types"; - -interface TestConnectionSectionProps { - setLoginError: (error: string | null) => void; - setTestResults: (results: TestResults) => void; -} - -const TestConnectionSection: React.FC = ({ - setLoginError, - setTestResults -}) => { - const [testLoading, setTestLoading] = useState(false); - const { toast } = useToast(); - - const runConnectionTest = async () => { - setTestLoading(true); - setLoginError(null); - try { - const results = await testSupabaseConnection(); - setTestResults(results); - - if (results.errors.length === 0) { - toast({ - title: "연결 테스트 성공", - description: "Supabase 서버 연결이 정상입니다.", - }); - } else { - toast({ - title: "연결 테스트 실패", - description: `오류 발생: ${results.errors[0]}`, - variant: "destructive" - }); - } - } catch (error: any) { - console.error("연결 테스트 중 오류:", error); - setLoginError(error.message || "테스트 실행 중 예상치 못한 오류가 발생했습니다."); - - toast({ - title: "연결 테스트 오류", - description: "테스트 실행 중 예상치 못한 오류가 발생했습니다.", - variant: "destructive" - }); - } finally { - setTestLoading(false); - } - }; - - return ( -
-

Supabase 연결 진단

-
- -
-
- ); -}; - -export default TestConnectionSection; diff --git a/src/components/auth/types.ts b/src/components/auth/types.ts deleted file mode 100644 index fc92dd6..0000000 --- a/src/components/auth/types.ts +++ /dev/null @@ -1,21 +0,0 @@ - -// 서버 연결 상태 타입 -export interface ServerStatus { - checked: boolean; - connected: boolean; - message: string; -} - -// 회원가입 응답 타입 -export interface SignUpResponse { - error: any; - user: any; - redirectToSettings?: boolean; - emailConfirmationRequired?: boolean; -} - -// 회원가입 폼 공통 props -export interface RegisterFormCommonProps { - serverStatus: ServerStatus; - setRegisterError: React.Dispatch>; -} diff --git a/src/components/supabase/ConnectionTestButton.tsx b/src/components/supabase/ConnectionTestButton.tsx deleted file mode 100644 index 41564cf..0000000 --- a/src/components/supabase/ConnectionTestButton.tsx +++ /dev/null @@ -1,34 +0,0 @@ - -import React from 'react'; -import { Button } from "@/components/ui/button"; -import { RefreshCw } from "lucide-react"; - -interface ConnectionTestButtonProps { - onClick: () => void; - isTesting: boolean; -} - -const ConnectionTestButton: React.FC = ({ onClick, isTesting }) => { - return ( - - ); -}; - -export default ConnectionTestButton; diff --git a/src/components/supabase/CorsProxyToggle.tsx b/src/components/supabase/CorsProxyToggle.tsx deleted file mode 100644 index 0f00769..0000000 --- a/src/components/supabase/CorsProxyToggle.tsx +++ /dev/null @@ -1,39 +0,0 @@ - -import React from 'react'; -import { Switch } from "@/components/ui/switch"; -import { Label } from "@/components/ui/label"; -import { Shield } from "lucide-react"; - -interface CorsProxyToggleProps { - useProxy: boolean; - setUseProxy: (use: boolean) => void; -} - -const CorsProxyToggle: React.FC = ({ - useProxy, - setUseProxy -}) => { - return ( -
-
- -
- -
- ); -}; - -export default CorsProxyToggle; diff --git a/src/components/supabase/ProxyInfoCard.tsx b/src/components/supabase/ProxyInfoCard.tsx deleted file mode 100644 index 41e1377..0000000 --- a/src/components/supabase/ProxyInfoCard.tsx +++ /dev/null @@ -1,20 +0,0 @@ - -import React from 'react'; -import { TestResults } from '@/lib/supabase/tests/types'; - -interface ProxyInfoCardProps { - testResults: TestResults; -} - -const ProxyInfoCard: React.FC = ({ testResults }) => { - if (!testResults.usingProxy) return null; - - return ( -
-

CORS 프록시 사용 중: {testResults.proxyType || 'corsproxy.io'}

-

{testResults.proxyUrl}

-
- ); -}; - -export default ProxyInfoCard; diff --git a/src/components/supabase/ProxyTypeSelector.tsx b/src/components/supabase/ProxyTypeSelector.tsx deleted file mode 100644 index 99798f2..0000000 --- a/src/components/supabase/ProxyTypeSelector.tsx +++ /dev/null @@ -1,37 +0,0 @@ - -import React from 'react'; -import { Label } from "@/components/ui/label"; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; - -interface ProxyTypeSelectorProps { - proxyType: string; - setProxyType: (type: string) => void; -} - -const ProxyTypeSelector: React.FC = ({ - proxyType, - setProxyType -}) => { - return ( -
- - -

- Cloudflare 프록시가 가장 안정적인 성능을 제공합니다. -

-
- ); -}; - -export default ProxyTypeSelector; diff --git a/src/components/supabase/SaveSettingsButton.tsx b/src/components/supabase/SaveSettingsButton.tsx deleted file mode 100644 index 2e4ea37..0000000 --- a/src/components/supabase/SaveSettingsButton.tsx +++ /dev/null @@ -1,36 +0,0 @@ - -import React from 'react'; -import { Button } from "@/components/ui/button"; -import { Save, RefreshCw } from "lucide-react"; - -interface SaveSettingsButtonProps { - onClick: () => void; - isSaving: boolean; -} - -const SaveSettingsButton: React.FC = ({ - onClick, - isSaving -}) => { - return ( - - ); -}; - -export default SaveSettingsButton; diff --git a/src/components/supabase/SupabaseConnectionTest.tsx b/src/components/supabase/SupabaseConnectionTest.tsx deleted file mode 100644 index cc8f06a..0000000 --- a/src/components/supabase/SupabaseConnectionTest.tsx +++ /dev/null @@ -1,85 +0,0 @@ - -import React, { useState } from 'react'; -import { toast } from "@/hooks/useToast.wrapper"; -import { testSupabaseConnection } from '@/lib/supabase'; -import { TestResults } from '@/lib/supabase/tests/types'; - -// 분리된 컴포넌트들 임포트 -import ConnectionTestButton from './ConnectionTestButton'; -import TestResultItem from './TestResultItem'; -import ProxyInfoCard from './ProxyInfoCard'; -import ProxyRecommendationAlert from './ProxyRecommendationAlert'; -import ErrorMessageCard from './ErrorMessageCard'; -import TroubleshootingTips from './TroubleshootingTips'; -import DebugInfoCollapsible from './DebugInfoCollapsible'; - -const SupabaseConnectionTest: React.FC = () => { - const [testResults, setTestResults] = useState(null); - const [isTesting, setIsTesting] = useState(false); - const [showDebug, setShowDebug] = useState(false); - - const runConnectionTest = async () => { - setIsTesting(true); - try { - const results = await testSupabaseConnection(); - setTestResults(results); - - if (results.errors.length === 0 || (results.auth && results.restApi && results.database)) { - toast({ - title: "연결 테스트 성공", - description: "Supabase 서버 연결이 정상입니다.", - }); - } else { - toast({ - title: "연결 테스트 실패", - description: `오류 발생: ${results.errors[0]}`, - variant: "destructive" - }); - } - } catch (error: any) { - console.error("연결 테스트 중 오류:", error); - toast({ - title: "연결 테스트 오류", - description: "테스트 실행 중 예상치 못한 오류가 발생했습니다.", - variant: "destructive" - }); - } finally { - setIsTesting(false); - } - }; - - return ( -
-

연결 테스트

- - - - {testResults && ( -
- - - - - - - - - - - - - -
- )} -
- ); -}; - -export default SupabaseConnectionTest; diff --git a/src/components/supabase/SupabaseHelpSection.tsx b/src/components/supabase/SupabaseHelpSection.tsx deleted file mode 100644 index f65b63d..0000000 --- a/src/components/supabase/SupabaseHelpSection.tsx +++ /dev/null @@ -1,54 +0,0 @@ - -import React from 'react'; -import { AlertCircle } from 'lucide-react'; - -const SupabaseHelpSection: React.FC = () => { - return ( -
-

도움말

-

- 온프레미스 Supabase 설정은 다음과 같이 구성됩니다: -

-
    -
  • - Supabase URL: 온프레미스로 설치한 Supabase 인스턴스의 URL을 입력합니다. - (예: https://192.168.1.100:8000) -
  • -
  • - Anon Key: Supabase 대시보드의 API 설정에서 찾을 수 있는 anon/public 키를 입력합니다. -
  • -
  • - CORS 프록시: HTTP URL에 대한 브라우저 보안 제한을 우회하기 위해 사용합니다. - HTTPS가 아닌 URL에 접근 문제가 있는 경우 활성화하세요. -
  • -
  • - 가능하면 HTTPS URL을 사용하는 것이 좋습니다. HTTP URL을 사용해야 하는 경우 CORS 프록시를 활성화하세요. -
  • -
- - {/* 오류 해결 팁 추가 */} -
-

- - 연결 문제 해결 팁 -

-
    -
  • - REST API 오류: 서버의 CORS 설정을 확인해보세요. Supabase 서버에서 CORS 허용 설정이 필요할 수 있습니다. -
  • -
  • - 인증 성공, API 실패: 이 경우는 일반적으로 CORS 문제를 의미합니다. CORS 프록시를 활성화하고 서버 설정도 확인해보세요. -
  • -
  • - 데이터베이스 오류: Supabase 관리자 대시보드에서 해당 테이블이 존재하는지, 그리고 익명 접근 권한이 있는지 확인하세요. -
  • -
  • - HTTPS 필요: 로컬 개발 환경에서는 HTTP 접근이 가능하지만, 배포된 앱에서는 HTTPS Supabase URL이 필요할 수 있습니다. -
  • -
-
-
- ); -}; - -export default SupabaseHelpSection; diff --git a/src/components/supabase/SupabaseKeyInput.tsx b/src/components/supabase/SupabaseKeyInput.tsx deleted file mode 100644 index 0aa528f..0000000 --- a/src/components/supabase/SupabaseKeyInput.tsx +++ /dev/null @@ -1,40 +0,0 @@ - -import React from 'react'; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; - -interface SupabaseKeyInputProps { - supabaseKey: string; - setSupabaseKey: (key: string) => void; -} - -const SupabaseKeyInput: React.FC = ({ - supabaseKey, - setSupabaseKey -}) => { - return ( -
- -
- - - - setSupabaseKey(e.target.value)} - className="pl-10 neuro-pressed" - /> -
-
- ); -}; - -export default SupabaseKeyInput; diff --git a/src/components/supabase/SupabaseSettingsForm.tsx b/src/components/supabase/SupabaseSettingsForm.tsx deleted file mode 100644 index aed8016..0000000 --- a/src/components/supabase/SupabaseSettingsForm.tsx +++ /dev/null @@ -1,137 +0,0 @@ - -import React, { useState, useEffect } from 'react'; -import { toast } from "@/hooks/useToast.wrapper"; -import { - configureSupabase, - isCorsProxyEnabled, - getProxyType -} from "@/lib/supabase/config"; - -// 분리된 컴포넌트들 임포트 -import SupabaseUrlInput from './SupabaseUrlInput'; -import SupabaseKeyInput from './SupabaseKeyInput'; -import CorsProxyToggle from './CorsProxyToggle'; -import ProxyTypeSelector from './ProxyTypeSelector'; -import SaveSettingsButton from './SaveSettingsButton'; - -interface SupabaseSettingsFormProps { - onSaved: () => void; -} - -const SupabaseSettingsForm: React.FC = ({ onSaved }) => { - // 상태 관리 - const [formState, setFormState] = useState({ - supabaseUrl: '', - supabaseKey: '', - useProxy: true, // 기본값을 true로 변경 - proxyType: 'cloudflare', // 기본값을 cloudflare로 변경 - isSaving: false - }); - - // 상태 업데이트 핸들러 - const updateState = (update: Partial) => { - setFormState(prev => ({ ...prev, ...update })); - }; - - // 저장된 설정 불러오기 - useEffect(() => { - const savedUrl = localStorage.getItem('supabase_url'); - const savedKey = localStorage.getItem('supabase_key'); - const proxyEnabled = localStorage.getItem('use_cors_proxy') === 'true'; - const savedProxyType = getProxyType(); - - setFormState(prev => ({ - ...prev, - supabaseUrl: savedUrl || '', - supabaseKey: savedKey || '', - useProxy: proxyEnabled === false ? false : true, // 저장된 값이 명시적으로 false인 경우에만 false, 아니면 기본값 true - proxyType: savedProxyType || 'cloudflare' - })); - }, []); - - // URL 유효성 검사 - const validateUrl = (url: string): boolean => { - return /^https?:\/\/.+/.test(url); - }; - - // 폼 제출 및 설정 저장 - const handleSave = () => { - const { supabaseUrl, supabaseKey, useProxy, proxyType } = formState; - - // 입력값 검증 - if (!supabaseUrl || !supabaseKey) { - toast({ - title: "입력 오류", - description: "Supabase URL과 Anon Key를 모두 입력해주세요.", - variant: "destructive" - }); - return; - } - - if (!validateUrl(supabaseUrl)) { - toast({ - title: "URL 오류", - description: "유효한 URL 형식이 아닙니다. http:// 또는 https://로 시작하는 URL을 입력해주세요.", - variant: "destructive" - }); - return; - } - - // 저장 처리 - updateState({ isSaving: true }); - - try { - // Supabase 설정 적용 - configureSupabase(supabaseUrl, supabaseKey, useProxy, proxyType); - - toast({ - title: "설정 저장 완료", - description: "Supabase 설정이 저장되었습니다. 변경사항을 적용합니다.", - }); - - onSaved(); - } catch (error) { - console.error('Supabase 설정 저장 오류:', error); - toast({ - title: "설정 저장 실패", - description: "Supabase 설정을 저장하는 중 오류가 발생했습니다.", - variant: "destructive" - }); - updateState({ isSaving: false }); - } - }; - - return ( -
- updateState({ supabaseUrl: url })} - useProxy={formState.useProxy} - /> - - updateState({ supabaseKey: key })} - /> - - updateState({ useProxy: value })} - /> - - {formState.useProxy && ( - updateState({ proxyType: type })} - /> - )} - - -
- ); -}; - -export default SupabaseSettingsForm; diff --git a/src/components/supabase/SupabaseUrlInput.tsx b/src/components/supabase/SupabaseUrlInput.tsx deleted file mode 100644 index 71cd80b..0000000 --- a/src/components/supabase/SupabaseUrlInput.tsx +++ /dev/null @@ -1,53 +0,0 @@ - -import React from 'react'; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; -import { DatabaseIcon, AlertTriangle, Check } from "lucide-react"; - -interface SupabaseUrlInputProps { - supabaseUrl: string; - setSupabaseUrl: (url: string) => void; - useProxy: boolean; -} - -const SupabaseUrlInput: React.FC = ({ - supabaseUrl, - setSupabaseUrl, - useProxy -}) => { - const isHttpsUrl = supabaseUrl.startsWith("https://"); - const suggestProxy = supabaseUrl.startsWith("http://") && !useProxy; - - return ( -
- -
- - setSupabaseUrl(e.target.value)} - className="pl-10 neuro-pressed" - /> -
- - {/* URL 관련 경고 및 안내 추가 */} - {suggestProxy && ( -
- - HTTP URL을 사용하고 계십니다. CORS 프록시 활성화를 권장합니다. -
- )} - - {isHttpsUrl && ( -
- - HTTPS URL을 사용하고 있습니다. 권장됩니다. -
- )} -
- ); -}; - -export default SupabaseUrlInput; diff --git a/src/components/supabase/TestResultItem.tsx b/src/components/supabase/TestResultItem.tsx deleted file mode 100644 index 45d1ef6..0000000 --- a/src/components/supabase/TestResultItem.tsx +++ /dev/null @@ -1,20 +0,0 @@ - -import React from 'react'; - -interface TestResultItemProps { - label: string; - success: boolean; -} - -const TestResultItem: React.FC = ({ label, success }) => { - return ( -
- {label}: - - {success ? '✅ 성공' : '❌ 실패'} - -
- ); -}; - -export default TestResultItem; diff --git a/src/lib/supabase/client.ts b/src/lib/supabase/client.ts index 248c39e..feebc28 100644 --- a/src/lib/supabase/client.ts +++ b/src/lib/supabase/client.ts @@ -18,14 +18,7 @@ try { } }); - console.log('Supabase Cloud 클라이언트가 생성되었습니다.'); - - // 연결 테스트 - 별도 파일로 이동됨 - import('./connectionTest').then(module => { - module.testConnection(supabaseClient, supabaseUrl, supabaseAnonKey); - }).catch(err => { - console.error('연결 테스트 모듈 로딩 오류:', err); - }); + console.log('Supabase 클라이언트가 생성되었습니다.'); } catch (error) { console.error('Supabase 클라이언트 생성 오류:', error); diff --git a/src/lib/supabase/config.ts b/src/lib/supabase/config.ts index f939312..a92b817 100644 --- a/src/lib/supabase/config.ts +++ b/src/lib/supabase/config.ts @@ -1,17 +1,10 @@ -// Supabase Cloud URL과 anon key 설정 (고정값 사용) +// Supabase Cloud URL과 anon key 설정 export const getSupabaseUrl = () => { - // Supabase Cloud URL 사용 - return "https://qnerebtvwwfobfzdoftx.supabase.co"; -}; - -// 원본 URL 반환 -export const getOriginalSupabaseUrl = () => { return "https://qnerebtvwwfobfzdoftx.supabase.co"; }; export const getSupabaseKey = () => { - // Supabase Cloud anon key 사용 return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InFuZXJlYnR2d3dmb2JmemRvZnR4Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDIwNTE0MzgsImV4cCI6MjA1NzYyNzQzOH0.Wm7h2DUhoQbeANuEM3wm2tz22ITrVEW8FizyLgIVmv8"; }; @@ -19,29 +12,3 @@ export const getSupabaseKey = () => { export const isValidSupabaseKey = () => { return true; // Supabase Cloud에서는 항상 유효함 }; - -// CORS 프록시 관련 함수들 (Supabase Cloud에서는 필요 없음) -export const useCorsProxy = (enabled: boolean) => { - return false; // Supabase Cloud에서는 항상 비활성화 -}; - -export const setProxyType = (proxyType: string) => { - // Supabase Cloud에서는 아무 작업도 하지 않음 -}; - -export const getProxyType = () => { - return 'none'; // Supabase Cloud에서는 프록시 사용 안함 -}; - -export const isCorsProxyEnabled = () => { - return false; // Supabase Cloud에서는 항상 false -}; - -// 구성 도우미 함수 - Cloud 환경에서는 단순화 -export const configureSupabase = (url: string, key: string, useProxy: boolean = false, proxyType: string = 'none') => { - console.log('Supabase Cloud를 사용 중이므로 설정이 무시됩니다'); - // 실제 설정은 변경되지 않음 (Cloud URL 및 키는 고정) - - // 페이지 새로고침 - window.location.reload(); -}; diff --git a/src/lib/supabase/connectionTest.ts b/src/lib/supabase/connectionTest.ts deleted file mode 100644 index 7fadc2e..0000000 --- a/src/lib/supabase/connectionTest.ts +++ /dev/null @@ -1,69 +0,0 @@ - -import { SupabaseClient } from '@supabase/supabase-js'; - -/** - * Supabase 연결 테스트 - */ -export async function testConnection( - supabaseClient: SupabaseClient, - supabaseUrl: string, - supabaseAnonKey: string -): Promise { - // CORS 문제 확인을 위한 기본 헤더 테스트 - try { - // 기본 서버 상태 확인 (CORS 테스트) - console.log('Supabase 서버 상태 확인 중...'); - const response = await fetch(`${supabaseUrl}/auth/v1/`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - 'apikey': supabaseAnonKey, - }, - }); - - if (response.ok || response.status === 401 || response.status === 404) { - console.log('Supabase 서버 연결 성공:', response.status); - } else { - console.warn('Supabase 서버 연결 실패:', response.status, response.statusText); - // 응답 세부 정보 로깅 - try { - const errorText = await response.text(); - console.warn('Supabase 서버 응답 내용:', errorText); - } catch (e) { - console.error('응답 내용 읽기 실패:', e); - } - } - } catch (err) { - console.error('Supabase 서버 상태 확인 중 오류 (CORS 문제 가능성):', err); - } - - // Supabase 연결 테스트 - try { - console.log('Supabase 인증 테스트 시도 중...'); - const { data, error } = await supabaseClient.auth.getSession(); - if (error) { - console.warn('Supabase 연결 테스트 실패:', error.message); - } else { - console.log('Supabase 연결 성공!', data); - } - - // 추가 테스트: 공개 데이터 조회 시도 - try { - console.log('Supabase 데이터베이스 공개 테이블 조회 시도...'); - const { data: tableData, error: tableError } = await supabaseClient - .from('transactions') - .select('*') - .limit(1); - - if (tableError) { - console.warn('Supabase 데이터베이스 테스트 실패:', tableError.message); - } else { - console.log('Supabase 데이터베이스 테스트 성공:', tableData); - } - } catch (dbErr) { - console.error('Supabase 데이터베이스 테스트 중 예외 발생:', dbErr); - } - } catch (err) { - console.error('Supabase 연결 확인 중 오류:', err); - } -} diff --git a/src/lib/supabase/index.ts b/src/lib/supabase/index.ts index aa712f1..7c76d37 100644 --- a/src/lib/supabase/index.ts +++ b/src/lib/supabase/index.ts @@ -1,19 +1,15 @@ import { supabase, isValidUrl } from './client'; -import { testSupabaseConnection } from './tests'; import { createRequiredTables, checkTablesStatus } from './setup'; import { customFetch } from './customFetch'; import { modifyStorageApiRequest, getStorageApiHeaders } from './storageUtils'; -import { testConnection } from './connectionTest'; export { supabase, isValidUrl, - testSupabaseConnection, createRequiredTables, checkTablesStatus, customFetch, modifyStorageApiRequest, - getStorageApiHeaders, - testConnection + getStorageApiHeaders }; diff --git a/src/lib/supabase/setup/index.ts b/src/lib/supabase/setup/index.ts index d134694..a3c4a3c 100644 --- a/src/lib/supabase/setup/index.ts +++ b/src/lib/supabase/setup/index.ts @@ -13,7 +13,7 @@ export const createRequiredTables = async (): Promise<{ success: boolean; messag // 테이블 상태 확인 const tablesStatus = await checkTablesStatus(); - if (tablesStatus.transactions && tablesStatus.budgets) { + if (tablesStatus.transactions && tablesStatus.budgets && tablesStatus.category_budgets) { return { success: true, message: '필요한 테이블이 이미 존재합니다.' @@ -21,8 +21,8 @@ export const createRequiredTables = async (): Promise<{ success: boolean; messag } return { - success: true, - message: '테이블이 성공적으로 생성되었습니다.' + success: false, + message: '일부 필요한 테이블이 없습니다. Supabase 대시보드에서 확인해주세요.' }; } catch (error: any) { console.error('테이블 확인 중 오류 발생:', error); diff --git a/src/lib/supabase/setup/status.ts b/src/lib/supabase/setup/status.ts index af3e5ee..8fc7868 100644 --- a/src/lib/supabase/setup/status.ts +++ b/src/lib/supabase/setup/status.ts @@ -43,46 +43,3 @@ export const checkTablesStatus = async (): Promise<{ return tables; } }; - -/** - * 기존 테이블 목록을 가져옵니다. - * 참고: get_tables 함수는 사용하지 않음 - */ -export const getExistingTables = async (): Promise => { - try { - const tables = []; - - // 직접 각 테이블 확인 - const { error: transactionsError } = await supabase - .from('transactions') - .select('id') - .limit(1); - - if (!transactionsError) { - tables.push('transactions'); - } - - const { error: budgetsError } = await supabase - .from('budgets') - .select('id') - .limit(1); - - if (!budgetsError) { - tables.push('budgets'); - } - - const { error: categoryBudgetsError } = await supabase - .from('category_budgets') - .select('id') - .limit(1); - - if (!categoryBudgetsError) { - tables.push('category_budgets'); - } - - return tables; - } catch (error) { - console.error('테이블 목록 확인 중 오류 발생:', error); - return null; - } -}; diff --git a/src/lib/supabase/tests/index.ts b/src/lib/supabase/tests/index.ts deleted file mode 100644 index 1570754..0000000 --- a/src/lib/supabase/tests/index.ts +++ /dev/null @@ -1,93 +0,0 @@ - -import { testAuth } from './authTests'; -import { testRestApi } from './apiTests'; -import { testDatabaseConnection } from './databaseTests'; -import { TestResults, TestDebugInfo } from './types'; -import { supabase, isValidUrl } from '../client'; -import { getSupabaseUrl, getSupabaseKey, isCorsProxyEnabled, getProxyType } from '../config'; - -export const testSupabaseConnection = async (): Promise => { - // 기본 결과 객체 초기화 - const results: TestResults = { - url: getSupabaseUrl(), - proxyUrl: '', // 빈 문자열로 초기화 - usingProxy: isCorsProxyEnabled(), - proxyType: getProxyType(), - client: true, - restApi: false, - auth: false, - database: false, - errors: [], - debugInfo: { - originalUrl: getSupabaseUrl(), - proxyUrl: '', - usingProxy: isCorsProxyEnabled(), - proxyType: getProxyType(), - keyLength: getSupabaseKey().length, - browserInfo: navigator.userAgent, - timestamp: new Date().toISOString(), - backupProxySuccess: false, - lastErrorDetails: '' - } - }; - - try { - // 클라이언트 유효성 체크 - if (!supabase) { - results.client = false; - results.errors.push('Supabase 클라이언트 초기화 실패'); - return results; - } - - // CORS 프록시 URL 설정 - if (results.usingProxy) { - const baseUrl = getSupabaseUrl(); - const proxyType = getProxyType(); - - if (proxyType === 'corsproxy.io') { - results.proxyUrl = `https://corsproxy.io/?${encodeURIComponent(baseUrl)}`; - } else if (proxyType === 'cors-anywhere') { - results.proxyUrl = `https://cors-anywhere.herokuapp.com/${baseUrl}`; - } else { - results.proxyUrl = baseUrl; // 기본값 - } - - // debugInfo에도 proxyUrl 설정 - results.debugInfo.proxyUrl = results.proxyUrl; - } else { - results.proxyUrl = results.url; // 프록시 사용 안 함 - results.debugInfo.proxyUrl = results.url; - } - - // 테스트 실행 - // testAuth 함수에 두 번째 인자로 URL 전달 - const authResults = await testAuth(supabase, results.url); - const apiResults = await testRestApi(supabase); - const dbResults = await testDatabaseConnection(supabase); - - // 결과 업데이트 - results.auth = authResults.success; - results.restApi = apiResults.success; - results.database = dbResults.success; - - // 오류 수집 - if (!authResults.success && authResults.error) { - results.errors.push(`인증 테스트 실패: ${authResults.error}`); - results.debugInfo.lastErrorDetails += `인증: ${authResults.error}; `; - } - if (!apiResults.success && apiResults.error) { - results.errors.push(`REST API 테스트 실패: ${apiResults.error}`); - results.debugInfo.lastErrorDetails += `API: ${apiResults.error}; `; - } - if (!dbResults.success && dbResults.error) { - results.errors.push(`DB 테스트 실패: ${dbResults.error}`); - results.debugInfo.lastErrorDetails += `DB: ${dbResults.error}; `; - } - } catch (error: any) { - const errorMsg = `테스트 실행 오류: ${error.message || '알 수 없는 오류'}`; - results.errors.push(errorMsg); - results.debugInfo.lastErrorDetails = errorMsg; - } - - return results; -}; diff --git a/src/pages/SupabaseSettings.tsx b/src/pages/SupabaseSettings.tsx deleted file mode 100644 index 2ad4e6e..0000000 --- a/src/pages/SupabaseSettings.tsx +++ /dev/null @@ -1,45 +0,0 @@ - -import React, { useState } from 'react'; -import NavBar from '@/components/NavBar'; -import SupabaseSettingsForm from '@/components/supabase/SupabaseSettingsForm'; -import SupabaseConnectionTest from '@/components/supabase/SupabaseConnectionTest'; -import SupabaseHelpSection from '@/components/supabase/SupabaseHelpSection'; - -const SupabaseSettings = () => { - const [refreshCounter, setRefreshCounter] = useState(0); - - const handleSettingsSaved = () => { - // 설정이 저장될 때 테스트 컴포넌트를 다시 렌더링하기 위한 카운터 증가 - setRefreshCounter(prev => prev + 1); - }; - - return ( -
-
-
-

Supabase 설정

-

- 온프레미스 Supabase 인스턴스와 연결하기 위한 설정을 입력해주세요. -

-
- -
- -
- - {/* 연결 테스트 섹션 */} -
- -
- -
- -
-
- - -
- ); -}; - -export default SupabaseSettings; diff --git a/src/utils/sync/syncSettings.ts b/src/utils/sync/syncSettings.ts index 1af1d31..e990d8f 100644 --- a/src/utils/sync/syncSettings.ts +++ b/src/utils/sync/syncSettings.ts @@ -2,7 +2,7 @@ // 동기화 관련 모든 기능을 한 곳에서 내보내는 인덱스 파일 import { isSyncEnabled, setSyncEnabled, initSyncSettings } from './config'; import { getLastSyncTime, setLastSyncTime } from './time'; -import { syncAllData as syncData } from './data'; // 이름 충돌 방지를 위해 이름 변경 +import { syncAllData as syncData } from './data'; // 단일 진입점에서 모든 기능 내보내기 export {