문서 파일 정리

This commit is contained in:
hansoo
2025-03-21 16:08:43 +09:00
parent 86c0035561
commit 2d08a7962b
64 changed files with 8460 additions and 45 deletions

View File

@@ -0,0 +1,298 @@
# 적자 탈출 가계부 - 데이터베이스 스키마 구현
## 1. 개요
적자 탈출 가계부 애플리케이션의 데이터베이스 스키마 구현에 대한 문서입니다. 이 문서는 Supabase 자체 호스팅 환경에서 PostgreSQL 데이터베이스를 사용하여 구현된 데이터베이스 스키마를 설명합니다.
## 2. 마이그레이션 파일 구조
데이터베이스 스키마는 다음과 같은 마이그레이션 파일로 구성되어 있습니다:
1. `01_users.sql`: 사용자 정보 관리
2. `02_categories.sql`: 지출 카테고리 관리
3. `03_expenses.sql`: 지출 내역 관리
4. `04_budgets.sql`: 예산 관리
5. `05_cards.sql`: 카드 정보 관리
6. `06_limits.sql`: 지출 한도 관리
7. `07_templates.sql`: 템플릿 관리
8. `08_notifications.sql`: 알림 시스템
9. `09_analysis_settings.sql`: 분석 설정
각 마이그레이션 파일은 테이블 생성, 인덱스 생성, RLS(Row Level Security) 정책 설정, 관련 함수 및 트리거를 포함합니다.
## 3. 테이블 구조
### 3.1 사용자(users) 테이블
```sql
CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
name VARCHAR(100) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now()
);
```
- **주요 기능**: 사용자 정보 저장
- **RLS 정책**: 사용자는 자신의 정보만 조회/수정 가능
- **관련 트리거**: Supabase Auth와 연동하여 사용자 생성 시 프로필 자동 생성
### 3.2 카테고리(categories) 테이블
```sql
CREATE TABLE IF NOT EXISTS categories (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(50) NOT NULL,
icon VARCHAR(50) NOT NULL,
color VARCHAR(20) NOT NULL,
parent_id UUID REFERENCES categories(id),
is_income BOOLEAN DEFAULT FALSE,
is_default BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT now()
);
```
- **주요 기능**: 지출/수입 카테고리 관리
- **RLS 정책**: 모든 사용자가 조회 가능, 수정은 관리자만 가능
- **기본 데이터**: 40개 이상의 기본 카테고리 제공 (지출 및 수입 카테고리)
- **계층 구조**: 부모-자식 관계를 통한 카테고리 계층화
### 3.3 지출(expenses) 테이블
```sql
CREATE TABLE IF NOT EXISTS expenses (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
amount NUMERIC(12,2) NOT NULL,
date DATE NOT NULL,
category_id UUID REFERENCES categories(id),
memo TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now()
);
```
- **주요 기능**: 사용자의 지출/수입 내역 저장
- **RLS 정책**: 사용자는 자신의 지출 데이터만 접근 가능
- **관련 함수**: 월별 지출 합계 조회 함수 제공
### 3.4 예산(budgets) 테이블
```sql
CREATE TABLE IF NOT EXISTS budgets (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
amount NUMERIC(12,2) NOT NULL,
month INTEGER NOT NULL CHECK (month BETWEEN 1 AND 12),
year INTEGER NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
UNIQUE(user_id, month, year)
);
```
- **주요 기능**: 사용자의 월별 예산 관리
- **RLS 정책**: 사용자는 자신의 예산 데이터만 접근 가능
- **관련 함수**: 예산 대비 지출 비율 조회 함수 제공
### 3.5 카드(cards) 테이블
```sql
CREATE TABLE IF NOT EXISTS cards (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
name VARCHAR(100) NOT NULL,
card_type VARCHAR(20) NOT NULL CHECK (card_type IN ('credit', 'debit', 'prepaid')),
card_number_last4 VARCHAR(4),
issuer VARCHAR(50),
color VARCHAR(20),
payment_day INTEGER CHECK (payment_day BETWEEN 1 AND 31),
monthly_limit NUMERIC(12,2),
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT now()
);
```
- **주요 기능**: 사용자의 카드 정보 관리
- **RLS 정책**: 사용자는 자신의 카드 데이터만 접근 가능
- **관련 함수**: 사용자별 카드 목록 조회 함수 제공
### 3.6 한도(limits) 테이블
```sql
CREATE TABLE IF NOT EXISTS limits (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
card_id UUID REFERENCES cards(id) ON DELETE CASCADE,
category_id UUID REFERENCES categories(id) ON DELETE SET NULL,
amount NUMERIC(12,2) NOT NULL CHECK (amount > 0),
period VARCHAR(20) NOT NULL CHECK (period IN ('daily', 'weekly', 'monthly')),
start_date DATE NOT NULL,
end_date DATE,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
CONSTRAINT card_or_category_required CHECK (card_id IS NOT NULL OR category_id IS NOT NULL),
CONSTRAINT valid_date_range CHECK (end_date IS NULL OR end_date >= start_date)
);
```
- **주요 기능**: 카드 또는 카테고리별 지출 한도 관리
- **RLS 정책**: 사용자는 자신의 한도 데이터만 접근 가능
- **관련 함수**: 활성화된 한도 조회 및 사용량 계산 함수 제공
### 3.7 템플릿(templates) 테이블
```sql
CREATE TABLE IF NOT EXISTS templates (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
name VARCHAR(100) NOT NULL,
card_id UUID REFERENCES cards(id) ON DELETE SET NULL,
category_id UUID REFERENCES categories(id) ON DELETE SET NULL,
amount NUMERIC(12,2) NOT NULL CHECK (amount > 0),
description TEXT,
location VARCHAR(255),
is_income BOOLEAN DEFAULT FALSE,
is_favorite BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
UNIQUE(user_id, name)
);
```
- **주요 기능**: 자주 사용하는 지출/수입 템플릿 관리
- **RLS 정책**: 사용자는 자신의 템플릿 데이터만 접근 가능
- **관련 함수**: 템플릿으로 지출 생성 함수 제공
### 3.8 알림(notifications) 테이블
```sql
CREATE TABLE IF NOT EXISTS notifications (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
title VARCHAR(100) NOT NULL,
message TEXT NOT NULL,
type VARCHAR(20) NOT NULL CHECK (type IN ('limit_warning', 'payment_due', 'tip', 'system')),
related_id UUID,
related_type VARCHAR(50),
is_read BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
read_at TIMESTAMP WITH TIME ZONE
);
```
- **주요 기능**: 사용자 알림 관리 (한도 경고, 결제일 알림 등)
- **RLS 정책**: 사용자는 자신의 알림 데이터만 접근 가능
- **관련 트리거**: 지출 한도 초과 시 자동 알림 생성
### 3.9 분석 설정(analysis_settings) 테이블
```sql
CREATE TABLE IF NOT EXISTS analysis_settings (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
budget_period VARCHAR(20) DEFAULT 'monthly' CHECK (budget_period IN ('daily', 'weekly', 'monthly')),
saving_goal NUMERIC(12,2),
analysis_period INTEGER DEFAULT 3 CHECK (analysis_period > 0),
notification_frequency VARCHAR(20) DEFAULT 'weekly' CHECK (notification_frequency IN ('daily', 'weekly', 'monthly', 'none')),
created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
UNIQUE(user_id)
);
```
- **주요 기능**: 사용자별 분석 설정 관리
- **RLS 정책**: 사용자는 자신의 분석 설정 데이터만 접근 가능
- **관련 트리거**: 사용자 생성 시 기본 분석 설정 자동 생성
- **관련 함수**: 지출 분석 및 추세 분석 함수 제공
## 4. Row Level Security(RLS) 정책
모든 테이블에는 Row Level Security 정책이 적용되어 있습니다. 이를 통해 사용자는 자신의 데이터만 접근할 수 있으며, 다른 사용자의 데이터에는 접근할 수 없습니다.
기본적인 RLS 정책 패턴:
```sql
-- 테이블에 RLS 활성화
ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;
-- 조회 정책
CREATE POLICY "select_policy" ON table_name
FOR SELECT USING (auth.uid() = user_id);
-- 삽입 정책
CREATE POLICY "insert_policy" ON table_name
FOR INSERT WITH CHECK (auth.uid() = user_id);
-- 수정 정책
CREATE POLICY "update_policy" ON table_name
FOR UPDATE USING (auth.uid() = user_id);
-- 삭제 정책
CREATE POLICY "delete_policy" ON table_name
FOR DELETE USING (auth.uid() = user_id);
```
## 5. 인덱스
성능 최적화를 위해 각 테이블에 적절한 인덱스가 생성되어 있습니다:
- 외래 키 컬럼에 대한 인덱스
- 자주 조회되는 컬럼에 대한 인덱스
- 복합 인덱스 (예: `user_id``date` 조합)
## 6. 함수 및 트리거
다양한 비즈니스 로직을 지원하기 위해 여러 함수와 트리거가 구현되어 있습니다:
### 6.1 주요 함수
- `get_monthly_expenses`: 월별 지출 합계 조회
- `get_budget_usage`: 예산 대비 지출 비율 조회
- `get_user_cards`: 사용자별 카드 목록 조회
- `get_active_limits`: 활성화된 한도 및 사용량 조회
- `create_expense_from_template`: 템플릿으로 지출 생성
- `mark_notification_as_read`: 알림 읽음 표시
- `get_expense_analysis`: 카테고리별 지출 분석
- `get_monthly_expense_trend`: 월별 지출 추세 분석
### 6.2 주요 트리거
- `update_updated_at_column`: 레코드 업데이트 시 `updated_at` 자동 갱신
- `create_user_profile`: Supabase Auth 사용자 생성 시 프로필 자동 생성
- `create_limit_warning_notification`: 지출 한도 초과 시 알림 자동 생성
- `create_default_analysis_settings`: 사용자 생성 시 기본 분석 설정 자동 생성
## 7. 마이그레이션 실행 방법
마이그레이션 파일을 실행하기 위한 스크립트가 제공됩니다:
```bash
# 실행 권한 부여
chmod +x run_migrations.sh
# 스크립트 실행
./run_migrations.sh
```
환경 변수를 통해 데이터베이스 연결 정보를 설정할 수 있습니다:
```bash
DB_HOST=localhost DB_PORT=5432 DB_NAME=postgres DB_USER=postgres DB_PASSWORD=postgres ./run_migrations.sh
```
## 8. 향후 확장 계획
1. **데이터 동기화**: 오프라인 모드 지원을 위한 동기화 메커니즘 구현
2. **데이터 분석**: 더 다양한 분석 함수 및 뷰 추가
3. **데이터 마이그레이션**: 버전 관리 및 롤백 메커니즘 개선
4. **성능 최적화**: 대규모 데이터셋에 대한 쿼리 성능 최적화
## 9. 참고 사항
- 모든 날짜/시간 데이터는 타임존 정보를 포함합니다 (`TIMESTAMP WITH TIME ZONE`).
- 금액 데이터는 `NUMERIC(12,2)` 타입을 사용하여 정확한 소수점 계산을 보장합니다.
- UUID를 기본 키로 사용하여 분산 환경에서의 확장성을 고려했습니다.
- 모든 테이블에는 생성 시간(`created_at`)이 자동으로 기록됩니다.