Migrate from Supabase to Appwrite with core functionality and UI components
This commit is contained in:
276
docs/02_기술_문서/Appwrite_전환_가이드.md
Normal file
276
docs/02_기술_문서/Appwrite_전환_가이드.md
Normal file
@@ -0,0 +1,276 @@
|
||||
# Appwrite 전환 가이드
|
||||
|
||||
## 개요
|
||||
|
||||
Zellyy Finance는 백엔드 서비스를 Supabase에서 Appwrite로 전환합니다. 이 문서는 전환 과정과 새로운 코드 구조에 대한 가이드를 제공합니다.
|
||||
|
||||
## 전환 이유
|
||||
|
||||
1. **더 나은 성능**: Appwrite는 경량화된 서비스로 더 빠른 응답 시간 제공
|
||||
2. **확장성**: 사용자 증가에 따른 확장성 개선
|
||||
3. **기능 세트**: Appwrite의 실시간 데이터베이스와 인증 시스템 활용
|
||||
4. **유지보수 용이성**: 단일 백엔드 서비스로 통합하여 유지보수 간소화
|
||||
|
||||
## 코드 구조
|
||||
|
||||
```
|
||||
src/
|
||||
├── lib/
|
||||
│ ├── appwrite/ (Appwrite 서비스)
|
||||
│ │ ├── index.ts (단일 진입점)
|
||||
│ │ ├── client.ts (클라이언트 설정)
|
||||
│ │ ├── config.ts (환경 설정)
|
||||
│ │ └── setup.ts (데이터베이스 설정)
|
||||
│ └── capacitor/ (네이티브 기능)
|
||||
│ ├── index.ts (단일 진입점)
|
||||
│ ├── buildInfo.ts (빌드 정보 관련)
|
||||
│ ├── notification.ts (알림 관련)
|
||||
│ └── permissions.ts (권한 관련)
|
||||
├── hooks/
|
||||
│ ├── auth/
|
||||
│ │ └── useAppwriteAuth.ts (인증 관련 훅)
|
||||
│ └── transactions/
|
||||
│ └── useAppwriteTransactions.ts (트랜잭션 관련 훅)
|
||||
├── components/
|
||||
│ ├── auth/
|
||||
│ │ └── AppwriteConnectionStatus.tsx (연결 상태 표시)
|
||||
│ ├── migration/
|
||||
│ │ └── SupabaseToAppwriteMigration.tsx (마이그레이션 도구)
|
||||
│ └── native/
|
||||
│ ├── PermissionRequest.tsx (권한 요청 UI)
|
||||
│ └── NotificationSettings.tsx (알림 설정 UI)
|
||||
└── utils/
|
||||
└── appwriteTransactionUtils.ts (트랜잭션 유틸리티)
|
||||
```
|
||||
|
||||
## 환경 설정
|
||||
|
||||
`.env` 파일에 다음 환경 변수를 설정합니다:
|
||||
|
||||
```
|
||||
# Appwrite 설정
|
||||
VITE_APPWRITE_ENDPOINT=https://a11.ism.kr/v1
|
||||
VITE_APPWRITE_PROJECT_ID=zellyy-finance
|
||||
VITE_APPWRITE_DATABASE_ID=zellyy-finance
|
||||
VITE_APPWRITE_TRANSACTIONS_COLLECTION_ID=transactions
|
||||
|
||||
# 네이티브 설정
|
||||
VITE_ANDROID_MIN_API_LEVEL=21
|
||||
VITE_ANDROID_TARGET_API_LEVEL=33
|
||||
VITE_ANDROID_NOTIFICATION_CHANNEL_ID=zellyy_finance_notifications
|
||||
```
|
||||
|
||||
## 마이그레이션 단계
|
||||
|
||||
1. **데이터베이스 설정**
|
||||
- Appwrite 데이터베이스 및 컬렉션 생성
|
||||
- 필요한 인덱스 및 권한 설정
|
||||
|
||||
2. **인증 시스템 전환**
|
||||
- Appwrite 인증 시스템 설정
|
||||
- 사용자 계정 마이그레이션
|
||||
|
||||
3. **데이터 마이그레이션**
|
||||
- 트랜잭션 데이터 마이그레이션
|
||||
- 데이터 무결성 검증
|
||||
|
||||
4. **Supabase 코드 제거**
|
||||
- 마이그레이션 완료 후 Supabase 관련 코드 제거
|
||||
- 환경 변수 정리
|
||||
|
||||
## 주요 컴포넌트 및 훅
|
||||
|
||||
### 1. Appwrite 클라이언트 설정
|
||||
|
||||
```typescript
|
||||
// src/lib/appwrite/client.ts
|
||||
import { Client, Account, Databases, Storage } from 'appwrite';
|
||||
import { config } from './config';
|
||||
|
||||
// 클라이언트 초기화
|
||||
export const client = new Client()
|
||||
.setEndpoint(config.endpoint)
|
||||
.setProject(config.projectId);
|
||||
|
||||
// 서비스 초기화
|
||||
export const account = new Account(client);
|
||||
export const databases = new Databases(client);
|
||||
export const storage = new Storage(client);
|
||||
```
|
||||
|
||||
### 2. 인증 훅
|
||||
|
||||
```typescript
|
||||
// src/hooks/auth/useAppwriteAuth.ts
|
||||
import { useState, useEffect } from 'react';
|
||||
import { account } from '../../lib/appwrite';
|
||||
|
||||
export const useAppwriteAuth = () => {
|
||||
const [user, setUser] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
// 사용자 세션 확인
|
||||
useEffect(() => {
|
||||
const checkSession = async () => {
|
||||
try {
|
||||
const session = await account.getSession('current');
|
||||
if (session) {
|
||||
const currentUser = await account.get();
|
||||
setUser(currentUser);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('세션 확인 오류:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
checkSession();
|
||||
}, []);
|
||||
|
||||
// 로그인 함수
|
||||
const login = async (email, password) => {
|
||||
try {
|
||||
await account.createEmailSession(email, password);
|
||||
const currentUser = await account.get();
|
||||
setUser(currentUser);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error('로그인 오류:', error);
|
||||
return { success: false, error };
|
||||
}
|
||||
};
|
||||
|
||||
// 로그아웃 함수
|
||||
const logout = async () => {
|
||||
try {
|
||||
await account.deleteSession('current');
|
||||
setUser(null);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error('로그아웃 오류:', error);
|
||||
return { success: false, error };
|
||||
}
|
||||
};
|
||||
|
||||
return { user, loading, login, logout };
|
||||
};
|
||||
```
|
||||
|
||||
### 3. 트랜잭션 훅
|
||||
|
||||
```typescript
|
||||
// src/hooks/transactions/useAppwriteTransactions.ts
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { databases } from '../../lib/appwrite';
|
||||
import { config } from '../../lib/appwrite/config';
|
||||
import { Query } from 'appwrite';
|
||||
|
||||
export const useAppwriteTransactions = (userId) => {
|
||||
const [transactions, setTransactions] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
// 트랜잭션 불러오기
|
||||
const fetchTransactions = useCallback(async () => {
|
||||
if (!userId) return;
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await databases.listDocuments(
|
||||
config.databaseId,
|
||||
config.transactionsCollectionId,
|
||||
[Query.equal('userId', userId)]
|
||||
);
|
||||
setTransactions(response.documents);
|
||||
} catch (error) {
|
||||
console.error('트랜잭션 불러오기 오류:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [userId]);
|
||||
|
||||
// 초기 데이터 로드
|
||||
useEffect(() => {
|
||||
fetchTransactions();
|
||||
}, [fetchTransactions]);
|
||||
|
||||
// 트랜잭션 추가
|
||||
const addTransaction = async (transaction) => {
|
||||
try {
|
||||
const newTransaction = await databases.createDocument(
|
||||
config.databaseId,
|
||||
config.transactionsCollectionId,
|
||||
'unique()',
|
||||
{
|
||||
...transaction,
|
||||
userId,
|
||||
createdAt: new Date().toISOString(),
|
||||
}
|
||||
);
|
||||
setTransactions((prev) => [...prev, newTransaction]);
|
||||
return { success: true, transaction: newTransaction };
|
||||
} catch (error) {
|
||||
console.error('트랜잭션 추가 오류:', error);
|
||||
return { success: false, error };
|
||||
}
|
||||
};
|
||||
|
||||
// 트랜잭션 업데이트
|
||||
const updateTransaction = async (id, data) => {
|
||||
try {
|
||||
const updatedTransaction = await databases.updateDocument(
|
||||
config.databaseId,
|
||||
config.transactionsCollectionId,
|
||||
id,
|
||||
data
|
||||
);
|
||||
setTransactions((prev) =>
|
||||
prev.map((t) => (t.$id === id ? updatedTransaction : t))
|
||||
);
|
||||
return { success: true, transaction: updatedTransaction };
|
||||
} catch (error) {
|
||||
console.error('트랜잭션 업데이트 오류:', error);
|
||||
return { success: false, error };
|
||||
}
|
||||
};
|
||||
|
||||
// 트랜잭션 삭제
|
||||
const deleteTransaction = async (id) => {
|
||||
try {
|
||||
await databases.deleteDocument(
|
||||
config.databaseId,
|
||||
config.transactionsCollectionId,
|
||||
id
|
||||
);
|
||||
setTransactions((prev) => prev.filter((t) => t.$id !== id));
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error('트랜잭션 삭제 오류:', error);
|
||||
return { success: false, error };
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
transactions,
|
||||
loading,
|
||||
fetchTransactions,
|
||||
addTransaction,
|
||||
updateTransaction,
|
||||
deleteTransaction,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## 마이그레이션 도구 사용법
|
||||
|
||||
1. 설정 페이지에서 "Appwrite 설정" 메뉴 선택
|
||||
2. "Supabase에서 Appwrite로 마이그레이션" 섹션에서 "마이그레이션 시작" 버튼 클릭
|
||||
3. 마이그레이션 진행 상황 확인
|
||||
4. 완료 후 데이터 검증
|
||||
|
||||
## 주의사항
|
||||
|
||||
1. 마이그레이션 중에는 데이터 변경을 최소화하세요.
|
||||
2. 마이그레이션 전에 데이터 백업을 수행하세요.
|
||||
3. 마이그레이션 후 모든 기능이 정상 작동하는지 테스트하세요.
|
||||
4. 문제 발생 시 개발팀에 즉시 보고하세요.
|
||||
Reference in New Issue
Block a user