Refactor supabase.ts into modules

Refactor the supabase.ts file into smaller modules, separating test functionalities and default client configurations while preserving all code functionalities.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-15 12:12:07 +00:00
parent 3a14914482
commit 2493f958de
5 changed files with 291 additions and 267 deletions

View File

@@ -1,267 +0,0 @@
import { createClient } from '@supabase/supabase-js';
// 온프레미스 Supabase URL과 anon key 설정
const getSupabaseUrl = () => {
// 로컬 스토리지에서 설정된 URL을 우선 사용
const storedUrl = localStorage.getItem('supabase_url');
if (storedUrl) return storedUrl;
// 환경 변수 또는 기본값 사용
return process.env.SUPABASE_URL || 'http://a11.ism.kr:8000';
};
const getSupabaseKey = () => {
// 로컬 스토리지에서 설정된 키를 우선 사용
const storedKey = localStorage.getItem('supabase_key');
if (storedKey) return storedKey;
// 환경 변수 또는 기본값 사용
return process.env.SUPABASE_ANON_KEY || 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzQyMDM5MzU4LCJleHAiOjQ4OTU2MzkzNTh9.XK0vetdwv_H2MHj4ewTfZGtSbrbSNDaV5xJhNo_Hdp8';
};
const supabaseUrl = getSupabaseUrl();
const supabaseAnonKey = getSupabaseKey();
// 유효한 URL이 설정되었는지 확인
const isValidUrl = supabaseUrl && supabaseAnonKey &&
!supabaseUrl.includes('your-onpremise-supabase-url') &&
!supabaseAnonKey.includes('your-onpremise-anon-key');
let supabaseClient;
try {
console.log(`Supabase 클라이언트 생성 시도: ${supabaseUrl}`);
// Supabase 클라이언트 생성
supabaseClient = createClient(supabaseUrl, supabaseAnonKey, {
auth: {
autoRefreshToken: true,
persistSession: true,
// 온프레미스 설치를 위한 추가 설정
flowType: 'implicit',
},
global: {
fetch: (url, options) => {
// CORS 디버깅을 위한 사용자 정의 fetch
console.log('Supabase fetch 요청:', url);
return fetch(url, options).then(response => {
console.log('Supabase 응답 상태:', response.status);
return response;
}).catch(err => {
console.error('Supabase fetch 오류:', err);
throw err;
});
}
}
});
// CORS 문제 확인을 위한 기본 헤더 테스트
(async () => {
try {
// 기본 서버 상태 확인 (CORS 테스트)
console.log('Supabase 서버 상태 확인 중...');
const response = await fetch(`${supabaseUrl}/rest/v1/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'apikey': supabaseAnonKey,
},
});
if (response.ok) {
console.log('Supabase REST API 연결 성공:', response.status);
} else {
console.warn('Supabase REST API 연결 실패:', response.status, response.statusText);
// 응답 세부 정보 로깅
try {
const errorText = await response.text();
console.warn('Supabase REST API 오류 응답:', errorText);
} catch (e) {
console.error('응답 내용 읽기 실패:', e);
}
}
} catch (err) {
console.error('Supabase 서버 상태 확인 중 오류 (CORS 문제 가능성):', err);
}
})();
// Supabase 연결 테스트
(async () => {
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);
}
})();
// Supabase 연결 로그
console.log('Supabase 클라이언트가 생성되었습니다.');
// 유효성 검사 로그
if (!isValidUrl) {
console.warn('경고: 기본 Supabase URL 또는 Anon Key가 감지되었습니다. Supabase 설정 페이지에서 온프레미스 설정을 구성하세요.');
}
} catch (error) {
console.error('Supabase 클라이언트 생성 오류:', error);
// 더미 클라이언트 생성 (앱이 완전히 실패하지 않도록)
supabaseClient = {
auth: {
getUser: () => Promise.resolve({ data: { user: null } }),
getSession: () => Promise.resolve({ data: { session: null } }),
signInWithPassword: () => Promise.reject(new Error('Supabase 설정이 필요합니다')),
signUp: () => Promise.reject(new Error('Supabase 설정이 필요합니다')),
signOut: () => Promise.resolve({ error: null }),
onAuthStateChange: () => ({ data: { subscription: { unsubscribe: () => {} } } }),
},
from: () => ({
select: () => ({ eq: () => ({ data: null, error: new Error('Supabase 설정이 필요합니다') }) }),
insert: () => ({ error: new Error('Supabase 설정이 필요합니다') }),
delete: () => ({ eq: () => ({ error: new Error('Supabase 설정이 필요합니다') }) }),
}),
};
}
export const supabase = supabaseClient;
// 온프레미스 연결을 위한 설정 도우미 함수
export const configureSupabase = (url: string, key: string) => {
// 로컬 스토리지에 설정 저장
localStorage.setItem('supabase_url', url);
localStorage.setItem('supabase_key', key);
// 페이지 새로고침 - 새로운 설정으로 Supabase 클라이언트 초기화
window.location.reload();
};
// 테스트용 직접 로그인 함수 (디버깅 전용)
export const testSupabaseLogin = async (email: string, password: string) => {
try {
console.log('테스트 로그인 시도:', email);
const { data, error } = await supabaseClient.auth.signInWithPassword({
email,
password
});
if (error) {
console.error('테스트 로그인 오류:', error);
return { success: false, error };
}
console.log('테스트 로그인 성공:', data);
return { success: true, data };
} catch (err) {
console.error('테스트 로그인 중 예외 발생:', err);
return { success: false, error: err };
}
};
// API 테스트 도우미 함수
export const testSupabaseConnection = async () => {
const results = {
url: supabaseUrl,
client: !!supabaseClient,
restApi: false,
auth: false,
database: false,
errors: [] as string[]
};
try {
// 1. REST API 접근 테스트
try {
console.log('REST API 테스트 시작...');
const response = await fetch(`${supabaseUrl}/rest/v1/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'apikey': supabaseAnonKey,
},
});
results.restApi = response.ok;
if (!response.ok) {
const errorBody = await response.text();
results.errors.push(`REST API 오류(${response.status} ${response.statusText}): ${errorBody || '응답 없음'}`);
console.error('REST API 테스트 실패:', response.status, errorBody);
} else {
console.log('REST API 테스트 성공');
}
} catch (err: any) {
results.errors.push(`REST API 예외: ${err.message || '알 수 없는 오류'}`);
console.error('REST API 테스트 중 예외:', err);
}
// 2. 인증 서비스 테스트
try {
console.log('인증 서비스 테스트 시작...');
const { data, error } = await supabaseClient.auth.getSession();
results.auth = !error;
if (error) {
results.errors.push(`인증 오류: ${error.message}`);
console.error('인증 테스트 실패:', error);
} else {
console.log('인증 테스트 성공');
}
} catch (err: any) {
results.errors.push(`인증 예외: ${err.message || '알 수 없는 오류'}`);
console.error('인증 테스트 중 예외:', err);
}
// 3. 데이터베이스 연결 테스트
try {
console.log('데이터베이스 연결 테스트 시작...');
const { data, error } = await supabaseClient
.from('transactions')
.select('*')
.limit(1);
results.database = !error;
if (error) {
results.errors.push(`데이터베이스 오류: ${error.message}`);
console.error('데이터베이스 테스트 실패:', error);
} else {
console.log('데이터베이스 테스트 성공', data);
}
} catch (err: any) {
results.errors.push(`데이터베이스 예외: ${err.message || '알 수 없는 오류'}`);
console.error('데이터베이스 테스트 중 예외:', err);
}
// 오류가 없는 경우 메시지 추가
if (results.errors.length === 0) {
results.errors.push('모든 테스트 통과! 연결 상태가 정상입니다.');
}
} catch (err: any) {
results.errors.push(`테스트 실행 예외: ${err.message || '알 수 없는 오류'}`);
console.error('전체 테스트 실행 중 예외:', err);
}
console.log('Supabase 연결 테스트 결과:', results);
return results;
};

132
src/lib/supabase/client.ts Normal file
View File

@@ -0,0 +1,132 @@
import { createClient } from '@supabase/supabase-js';
import { getSupabaseUrl, getSupabaseKey } from './config';
const supabaseUrl = getSupabaseUrl();
const supabaseAnonKey = getSupabaseKey();
// 유효한 URL이 설정되었는지 확인
const isValidUrl = supabaseUrl && supabaseAnonKey &&
!supabaseUrl.includes('your-onpremise-supabase-url') &&
!supabaseAnonKey.includes('your-onpremise-anon-key');
let supabaseClient;
try {
console.log(`Supabase 클라이언트 생성 시도: ${supabaseUrl}`);
// Supabase 클라이언트 생성
supabaseClient = createClient(supabaseUrl, supabaseAnonKey, {
auth: {
autoRefreshToken: true,
persistSession: true,
// 온프레미스 설치를 위한 추가 설정
flowType: 'implicit',
},
global: {
fetch: (url, options) => {
// CORS 디버깅을 위한 사용자 정의 fetch
console.log('Supabase fetch 요청:', url);
return fetch(url, options).then(response => {
console.log('Supabase 응답 상태:', response.status);
return response;
}).catch(err => {
console.error('Supabase fetch 오류:', err);
throw err;
});
}
}
});
// CORS 문제 확인을 위한 기본 헤더 테스트
(async () => {
try {
// 기본 서버 상태 확인 (CORS 테스트)
console.log('Supabase 서버 상태 확인 중...');
const response = await fetch(`${supabaseUrl}/rest/v1/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'apikey': supabaseAnonKey,
},
});
if (response.ok) {
console.log('Supabase REST API 연결 성공:', response.status);
} else {
console.warn('Supabase REST API 연결 실패:', response.status, response.statusText);
// 응답 세부 정보 로깅
try {
const errorText = await response.text();
console.warn('Supabase REST API 오류 응답:', errorText);
} catch (e) {
console.error('응답 내용 읽기 실패:', e);
}
}
} catch (err) {
console.error('Supabase 서버 상태 확인 중 오류 (CORS 문제 가능성):', err);
}
})();
// Supabase 연결 테스트
(async () => {
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);
}
})();
// Supabase 연결 로그
console.log('Supabase 클라이언트가 생성되었습니다.');
// 유효성 검사 로그
if (!isValidUrl) {
console.warn('경고: 기본 Supabase URL 또는 Anon Key가 감지되었습니다. Supabase 설정 페이지에서 온프레미스 설정을 구성하세요.');
}
} catch (error) {
console.error('Supabase 클라이언트 생성 오류:', error);
// 더미 클라이언트 생성 (앱이 완전히 실패하지 않도록)
supabaseClient = {
auth: {
getUser: () => Promise.resolve({ data: { user: null } }),
getSession: () => Promise.resolve({ data: { session: null } }),
signInWithPassword: () => Promise.reject(new Error('Supabase 설정이 필요합니다')),
signUp: () => Promise.reject(new Error('Supabase 설정이 필요합니다')),
signOut: () => Promise.resolve({ error: null }),
onAuthStateChange: () => ({ data: { subscription: { unsubscribe: () => {} } } }),
},
from: () => ({
select: () => ({ eq: () => ({ data: null, error: new Error('Supabase 설정이 필요합니다') }) }),
insert: () => ({ error: new Error('Supabase 설정이 필요합니다') }),
delete: () => ({ eq: () => ({ error: new Error('Supabase 설정이 필요합니다') }) }),
}),
};
}
export const supabase = supabaseClient;
export { isValidUrl };

View File

@@ -0,0 +1,29 @@
// 온프레미스 Supabase URL과 anon key 설정
export const getSupabaseUrl = () => {
// 로컬 스토리지에서 설정된 URL을 우선 사용
const storedUrl = localStorage.getItem('supabase_url');
if (storedUrl) return storedUrl;
// 환경 변수 또는 기본값 사용
return process.env.SUPABASE_URL || 'http://a11.ism.kr:8000';
};
export const getSupabaseKey = () => {
// 로컬 스토리지에서 설정된 키를 우선 사용
const storedKey = localStorage.getItem('supabase_key');
if (storedKey) return storedKey;
// 환경 변수 또는 기본값 사용
return process.env.SUPABASE_ANON_KEY || 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzQyMDM5MzU4LCJleHAiOjQ4OTU2MzkzNTh9.XK0vetdwv_H2MHj4ewTfZGtSbrbSNDaV5xJhNo_Hdp8';
};
// 온프레미스 연결을 위한 설정 도우미 함수
export const configureSupabase = (url: string, key: string) => {
// 로컬 스토리지에 설정 저장
localStorage.setItem('supabase_url', url);
localStorage.setItem('supabase_key', key);
// 페이지 새로고침 - 새로운 설정으로 Supabase 클라이언트 초기화
window.location.reload();
};

11
src/lib/supabase/index.ts Normal file
View File

@@ -0,0 +1,11 @@
// 메인 내보내기 파일
// Supabase 클라이언트 내보내기
export { supabase } from './client';
// 설정 관련 유틸리티 내보내기
export { configureSupabase } from './config';
// 테스트 도구 내보내기
export { testSupabaseLogin, testSupabaseConnection } from './tests';

119
src/lib/supabase/tests.ts Normal file
View File

@@ -0,0 +1,119 @@
import { supabase } from './client';
// 테스트용 직접 로그인 함수 (디버깅 전용)
export const testSupabaseLogin = async (email: string, password: string) => {
try {
console.log('테스트 로그인 시도:', email);
const { data, error } = await supabase.auth.signInWithPassword({
email,
password
});
if (error) {
console.error('테스트 로그인 오류:', error);
return { success: false, error };
}
console.log('테스트 로그인 성공:', data);
return { success: true, data };
} catch (err) {
console.error('테스트 로그인 중 예외 발생:', err);
return { success: false, error: err };
}
};
// API 테스트 도우미 함수
export const testSupabaseConnection = async () => {
const results = {
url: getSupabaseUrl(),
client: !!supabase,
restApi: false,
auth: false,
database: false,
errors: [] as string[]
};
try {
// 1. REST API 접근 테스트
try {
console.log('REST API 테스트 시작...');
const response = await fetch(`${results.url}/rest/v1/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'apikey': getSupabaseKey(),
},
});
results.restApi = response.ok;
if (!response.ok) {
const errorBody = await response.text();
results.errors.push(`REST API 오류(${response.status} ${response.statusText}): ${errorBody || '응답 없음'}`);
console.error('REST API 테스트 실패:', response.status, errorBody);
} else {
console.log('REST API 테스트 성공');
}
} catch (err: any) {
results.errors.push(`REST API 예외: ${err.message || '알 수 없는 오류'}`);
console.error('REST API 테스트 중 예외:', err);
}
// 2. 인증 서비스 테스트
try {
console.log('인증 서비스 테스트 시작...');
const { data, error } = await supabase.auth.getSession();
results.auth = !error;
if (error) {
results.errors.push(`인증 오류: ${error.message}`);
console.error('인증 테스트 실패:', error);
} else {
console.log('인증 테스트 성공');
}
} catch (err: any) {
results.errors.push(`인증 예외: ${err.message || '알 수 없는 오류'}`);
console.error('인증 테스트 중 예외:', err);
}
// 3. 데이터베이스 연결 테스트
try {
console.log('데이터베이스 연결 테스트 시작...');
const { data, error } = await supabase
.from('transactions')
.select('*')
.limit(1);
results.database = !error;
if (error) {
results.errors.push(`데이터베이스 오류: ${error.message}`);
console.error('데이터베이스 테스트 실패:', error);
} else {
console.log('데이터베이스 테스트 성공', data);
}
} catch (err: any) {
results.errors.push(`데이터베이스 예외: ${err.message || '알 수 없는 오류'}`);
console.error('데이터베이스 테스트 중 예외:', err);
}
// 오류가 없는 경우 메시지 추가
if (results.errors.length === 0) {
results.errors.push('모든 테스트 통과! 연결 상태가 정상입니다.');
}
} catch (err: any) {
results.errors.push(`테스트 실행 예외: ${err.message || '알 수 없는 오류'}`);
console.error('전체 테스트 실행 중 예외:', err);
}
console.log('Supabase 연결 테스트 결과:', results);
return results;
};
// 필요한 함수 불러오기
function getSupabaseUrl() {
return localStorage.getItem('supabase_url') || process.env.SUPABASE_URL || 'http://a11.ism.kr:8000';
}
function getSupabaseKey() {
return localStorage.getItem('supabase_key') || process.env.SUPABASE_ANON_KEY || 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzQyMDM5MzU4LCJleHAiOjQ4OTU2MzkzNTh9.XK0vetdwv_H2MHj4ewTfZGtSbrbSNDaV5xJhNo_Hdp8';
}