diff --git a/src/components/supabase/SupabaseSettingsForm.tsx b/src/components/supabase/SupabaseSettingsForm.tsx index 5e16249..50bf3f3 100644 --- a/src/components/supabase/SupabaseSettingsForm.tsx +++ b/src/components/supabase/SupabaseSettingsForm.tsx @@ -19,11 +19,19 @@ interface SupabaseSettingsFormProps { } const SupabaseSettingsForm: React.FC = ({ onSaved }) => { - const [supabaseUrl, setSupabaseUrl] = useState(''); - const [supabaseKey, setSupabaseKey] = useState(''); - const [useProxy, setUseProxy] = useState(false); - const [proxyType, setProxyType] = useState('corsproxy.io'); - const [isSaving, setIsSaving] = useState(false); + // 상태 관리 + const [formState, setFormState] = useState({ + supabaseUrl: '', + supabaseKey: '', + useProxy: false, + proxyType: 'corsproxy.io', + isSaving: false + }); + + // 상태 업데이트 핸들러 + const updateState = (update: Partial) => { + setFormState(prev => ({ ...prev, ...update })); + }; // 저장된 설정 불러오기 useEffect(() => { @@ -32,18 +40,25 @@ const SupabaseSettingsForm: React.FC = ({ onSaved }) const proxyEnabled = isCorsProxyEnabled(); const savedProxyType = getProxyType(); - if (savedUrl) setSupabaseUrl(savedUrl); - if (savedKey) setSupabaseKey(savedKey); - setUseProxy(proxyEnabled); - setProxyType(savedProxyType); + setFormState(prev => ({ + ...prev, + supabaseUrl: savedUrl || '', + supabaseKey: savedKey || '', + useProxy: proxyEnabled, + proxyType: savedProxyType + })); }, []); + // URL 유효성 검사 const validateUrl = (url: string): boolean => { - // URL 유효성 검사: http:// 또는 https://로 시작하는지 확인 return /^https?:\/\/.+/.test(url); }; + // 폼 제출 및 설정 저장 const handleSave = () => { + const { supabaseUrl, supabaseKey, useProxy, proxyType } = formState; + + // 입력값 검증 if (!supabaseUrl || !supabaseKey) { toast({ title: "입력 오류", @@ -62,7 +77,8 @@ const SupabaseSettingsForm: React.FC = ({ onSaved }) return; } - setIsSaving(true); + // 저장 처리 + updateState({ isSaving: true }); try { // Supabase 설정 적용 @@ -81,38 +97,38 @@ const SupabaseSettingsForm: React.FC = ({ onSaved }) description: "Supabase 설정을 저장하는 중 오류가 발생했습니다.", variant: "destructive" }); - setIsSaving(false); + updateState({ isSaving: false }); } }; return (
updateState({ supabaseUrl: url })} + useProxy={formState.useProxy} /> updateState({ supabaseKey: key })} /> updateState({ useProxy: value })} /> - {useProxy && ( + {formState.useProxy && ( updateState({ proxyType: type })} /> )}
); diff --git a/src/lib/supabase/tests/databaseTests.ts b/src/lib/supabase/tests/databaseTests.ts index 61c97f2..8f73553 100644 --- a/src/lib/supabase/tests/databaseTests.ts +++ b/src/lib/supabase/tests/databaseTests.ts @@ -1,31 +1,35 @@ -import { supabase } from '../client'; +import { SupabaseClient } from '@supabase/supabase-js'; +import { TestResult } from './types'; -// 데이터베이스 연결 테스트 -export const testDatabaseConnection = async (): Promise<{ success: boolean; error?: any }> => { +export const testDatabaseConnection = async ( + supabase: SupabaseClient +): Promise => { try { - console.log('데이터베이스 연결 테스트 시작...'); + // 간단한 쿼리 실행으로 데이터베이스 연결 테스트 const { data, error } = await supabase - .from('transactions') + .from('_tests') .select('*') - .limit(1); - - if (error) { - let errorMsg = error.message; - - // 익명 인증 오류 처리 - if (errorMsg.includes('Auth session missing') || errorMsg.includes('JWT')) { - errorMsg += ' - 로그인이 필요하거나 권한 설정을 확인해주세요.'; - } - - console.error('데이터베이스 테스트 실패:', error); - return { success: false, error: { message: errorMsg } }; - } else { - console.log('데이터베이스 테스트 성공', data); - return { success: true }; + .limit(1) + .maybeSingle(); + + // 오류가 있으면 실패로 처리 (404 제외 - 테이블이 없는 것은 정상) + if (error && error.code !== '42P01' && error.code !== 'PGRST116') { + return { + success: false, + error: `데이터베이스 연결 오류: ${error.message}` + }; } - } catch (err) { - console.error('데이터베이스 테스트 중 예외:', err); - return { success: false, error: err }; + + // 성공 + return { + success: true, + error: null + }; + } catch (error: any) { + return { + success: false, + error: `데이터베이스 테스트 중 예외 발생: ${error.message || '알 수 없는 오류'}` + }; } }; diff --git a/src/lib/supabase/tests/index.ts b/src/lib/supabase/tests/index.ts index 1af806f..d5e9fc1 100644 --- a/src/lib/supabase/tests/index.ts +++ b/src/lib/supabase/tests/index.ts @@ -1,88 +1,55 @@ -import { supabase } from '../client'; -import { testAuthService } from './authTests'; +import { testAuth } from './authTests'; import { testRestApi } from './apiTests'; -import { testDatabase } from './databaseTests'; +import { testDatabaseConnection } from './databaseTests'; +import { TestResults } from './types'; +import { supabase, isValidUrl } from '../client'; +import { getSupabaseUrl, getSupabaseKey, isCorsProxyEnabled, getProxyType } from '../config'; -export const testSupabaseConnection = async () => { - console.log('Supabase 연결 테스트 시작...'); - - // 결과값을 저장할 객체 - const results = { - client: false, +export const testSupabaseConnection = async (): Promise => { + // 기본 결과 객체 초기화 + const results: TestResults = { + url: getSupabaseUrl(), + usingProxy: isCorsProxyEnabled(), + proxyType: getProxyType(), + client: true, restApi: false, auth: false, database: false, - url: '', // Supabase URL - usingProxy: false, // CORS 프록시 사용 여부 - proxyUrl: '', // 사용 중인 프록시 URL - errors: [] as string[], // 오류 메시지 배열 - debugInfo: { // 디버깅 정보 - proxyAttempts: [] as string[], - corsErrors: [] as string[], - timeouts: [] as string[], - backupProxySuccess: false - } + errors: [] }; try { - // 테스트 1: REST API 연결 테스트 - console.log('REST API 연결 테스트 중...'); - const apiTest = await testRestApi(); - results.restApi = apiTest.success; - - if (!apiTest.success && apiTest.error) { - results.errors.push(`REST API 예외: ${apiTest.error.message || '알 수 없는 오류'}`); + // 클라이언트 유효성 체크 + if (!supabase) { + results.client = false; + results.errors.push('Supabase 클라이언트 초기화 실패'); + return results; } - - // 테스트 2: 인증 서비스 테스트 - console.log('인증 서비스 테스트 중...'); - const authTest = await testAuthService(); - results.auth = authTest.success; - - if (!authTest.success && authTest.error) { - results.errors.push(`인증 오류: ${authTest.error.message || '알 수 없는 오류'}`); + + // 테스트 실행 + 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) { + results.errors.push(`인증 테스트 실패: ${authResults.error}`); } - - // 테스트 3: 데이터베이스 테스트 - console.log('데이터베이스 테스트 중...'); - const dbTest = await testDatabase(); - results.database = dbTest.success; - - if (!dbTest.success && dbTest.error) { - results.errors.push(`데이터베이스 오류: ${dbTest.error.message || '알 수 없는 오류'}`); + if (!apiResults.success) { + results.errors.push(`REST API 테스트 실패: ${apiResults.error}`); } - - // 테스트 결과 요약 - results.client = true; // 클라이언트가 초기화되었다면 여기까지 왔을 것임 - - // Supabase URL 및 프록시 정보 추가 - const supabaseUrl = (supabase as any).supabaseUrl || ''; - results.url = supabaseUrl; - - // CORS 프록시 감지 - const isProxied = supabaseUrl.includes('corsproxy.io') || - supabaseUrl.includes('cors-anywhere') || - supabaseUrl.includes('thingproxy.freeboard.io') || - supabaseUrl.includes('allorigins.win'); - - results.usingProxy = isProxied; - - if (isProxied) { - // 프록시 URL 추출 - const proxyMatch = supabaseUrl.match(/(https?:\/\/[^\/]+\/)/); - if (proxyMatch) { - results.proxyUrl = proxyMatch[1]; - } else { - results.proxyUrl = '알 수 없는 프록시'; - } + if (!dbResults.success) { + results.errors.push(`DB 테스트 실패: ${dbResults.error}`); } - - console.log('Supabase 연결 테스트 완료:', results); - return results; } catch (error: any) { - console.error('Supabase 연결 테스트 중 예외 발생:', error); - results.errors.push(`예상치 못한 오류: ${error.message || '알 수 없는 오류'}`); - return results; + results.errors.push(`테스트 실행 오류: ${error.message || '알 수 없는 오류'}`); } + + return results; };