# ERD 다이어그램 이 문서는 Zellyy 프로젝트의 데이터베이스 구조를 Entity-Relationship Diagram(ERD)으로 설명합니다. ## 개요 Zellyy 프로젝트는 사용자가 카드를 작성하고 관리하며 소셜 미디어에 공유하는 기능을 제공합니다. 이를 위한 데이터베이스 구조는 다음과 같은 주요 엔티티로 구성됩니다: 1. 사용자 (Users) 2. 카드 (Cards) 3. 카드 태그 (Card Tags) 4. 소셜 계정 (Social Accounts) 5. 소셜 공유 (Social Shares) 6. 구독 (Subscriptions) ## ERD 다이어그램 아래는 Zellyy 프로젝트의 ERD 다이어그램입니다. 이 다이어그램은 [dbdiagram.io](https://dbdiagram.io)를 사용하여 생성되었습니다. ``` // Zellyy 데이터베이스 ERD // 이 다이어그램은 dbdiagram.io에서 생성되었습니다. Table zellyy.users { id UUID [pk, ref: > auth.users.id] email TEXT [not null, unique] username TEXT [unique] display_name TEXT avatar_url TEXT created_at TIMESTAMP [default: `NOW()`] updated_at TIMESTAMP [default: `NOW()`] last_login TIMESTAMP is_premium BOOLEAN [default: false] premium_until TIMESTAMP } Table zellyy.cards { id UUID [pk, default: `uuid_generate_v4()`] user_id UUID [not null, ref: > zellyy.users.id] content TEXT [not null] background_color TEXT [default: '#FFFFFF'] text_color TEXT [default: '#000000'] font_family TEXT [default: 'system'] font_size INTEGER [default: 16] text_align TEXT [default: 'center'] is_public BOOLEAN [default: false] is_synced BOOLEAN [default: false] created_at TIMESTAMP [default: `NOW()`] updated_at TIMESTAMP [default: `NOW()`] deleted_at TIMESTAMP } Table zellyy.card_tags { id UUID [pk, default: `uuid_generate_v4()`] card_id UUID [not null, ref: > zellyy.cards.id] tag_name TEXT [not null] created_at TIMESTAMP [default: `NOW()`] indexes { (card_id, tag_name) [unique] } } Table zellyy.social_accounts { id UUID [pk, default: `uuid_generate_v4()`] user_id UUID [not null, ref: > zellyy.users.id] platform TEXT [not null] platform_user_id TEXT access_token TEXT refresh_token TEXT token_expires_at TIMESTAMP created_at TIMESTAMP [default: `NOW()`] updated_at TIMESTAMP [default: `NOW()`] indexes { (user_id, platform) [unique] } } Table zellyy.social_shares { id UUID [pk, default: `uuid_generate_v4()`] card_id UUID [not null, ref: > zellyy.cards.id] user_id UUID [not null, ref: > zellyy.users.id] platform TEXT [not null] share_url TEXT shared_at TIMESTAMP [default: `NOW()`] status TEXT [default: 'pending'] response_data JSONB } Table zellyy.subscriptions { id UUID [pk, default: `uuid_generate_v4()`] user_id UUID [not null, ref: > zellyy.users.id] plan_type TEXT [not null] status TEXT [not null] start_date TIMESTAMP [not null] end_date TIMESTAMP [not null] payment_provider TEXT payment_id TEXT created_at TIMESTAMP [default: `NOW()`] updated_at TIMESTAMP [default: `NOW()`] } // 참조 테이블 (Supabase Auth) Table auth.users { id UUID [pk] email TEXT [unique] // 기타 Supabase Auth 필드 } ``` ## 엔티티 설명 ### 1. 사용자 (zellyy.users) 사용자 정보를 저장하는 테이블입니다. Supabase Auth와 연동됩니다. - **id**: 사용자 고유 식별자 (UUID), Supabase Auth의 사용자 ID와 연결 - **email**: 사용자 이메일 주소 - **username**: 사용자 이름 (고유) - **display_name**: 표시 이름 - **avatar_url**: 프로필 이미지 URL - **created_at**: 계정 생성 시간 - **updated_at**: 계정 정보 업데이트 시간 - **last_login**: 마지막 로그인 시간 - **is_premium**: 프리미엄 사용자 여부 - **premium_until**: 프리미엄 구독 만료 시간 ### 2. 카드 (zellyy.cards) 사용자가 작성한 카드 정보를 저장하는 테이블입니다. - **id**: 카드 고유 식별자 (UUID) - **user_id**: 카드 작성자 ID (users 테이블 참조) - **content**: 카드 내용 - **background_color**: 배경색 (HEX 코드) - **text_color**: 텍스트 색상 (HEX 코드) - **font_family**: 폰트 패밀리 - **font_size**: 폰트 크기 - **text_align**: 텍스트 정렬 방식 ('left', 'center', 'right') - **is_public**: 공개 여부 - **is_synced**: 클라우드 동기화 여부 - **created_at**: 카드 생성 시간 - **updated_at**: 카드 업데이트 시간 - **deleted_at**: 카드 삭제 시간 (소프트 삭제) ### 3. 카드 태그 (zellyy.card_tags) 카드에 적용된 태그 정보를 저장하는 테이블입니다. - **id**: 태그 고유 식별자 (UUID) - **card_id**: 카드 ID (cards 테이블 참조) - **tag_name**: 태그 이름 - **created_at**: 태그 생성 시간 ### 4. 소셜 계정 (zellyy.social_accounts) 사용자의 소셜 미디어 계정 연동 정보를 저장하는 테이블입니다. - **id**: 소셜 계정 고유 식별자 (UUID) - **user_id**: 사용자 ID (users 테이블 참조) - **platform**: 플랫폼 이름 ('facebook', 'twitter', 'instagram' 등) - **platform_user_id**: 플랫폼에서의 사용자 ID - **access_token**: 액세스 토큰 - **refresh_token**: 리프레시 토큰 - **token_expires_at**: 토큰 만료 시간 - **created_at**: 연동 생성 시간 - **updated_at**: 연동 업데이트 시간 ### 5. 소셜 공유 (zellyy.social_shares) 카드의 소셜 미디어 공유 기록을 저장하는 테이블입니다. - **id**: 공유 기록 고유 식별자 (UUID) - **card_id**: 카드 ID (cards 테이블 참조) - **user_id**: 사용자 ID (users 테이블 참조) - **platform**: 공유된 플랫폼 이름 - **share_url**: 공유된 URL - **shared_at**: 공유 시간 - **status**: 공유 상태 ('pending', 'success', 'failed') - **response_data**: 플랫폼 응답 데이터 (JSON) ### 6. 구독 (zellyy.subscriptions) 사용자의 구독 정보를 저장하는 테이블입니다. - **id**: 구독 고유 식별자 (UUID) - **user_id**: 사용자 ID (users 테이블 참조) - **plan_type**: 구독 플랜 유형 ('monthly', 'yearly' 등) - **status**: 구독 상태 ('active', 'canceled', 'expired') - **start_date**: 구독 시작 날짜 - **end_date**: 구독 종료 날짜 - **payment_provider**: 결제 제공자 ('apple', 'google', 'stripe' 등) - **payment_id**: 결제 ID - **created_at**: 구독 생성 시간 - **updated_at**: 구독 업데이트 시간 ## 관계 설명 1. **사용자와 카드**: 일대다 관계. 한 사용자는 여러 카드를 가질 수 있습니다. 2. **카드와 태그**: 일대다 관계. 한 카드는 여러 태그를 가질 수 있습니다. 3. **사용자와 소셜 계정**: 일대다 관계. 한 사용자는 여러 소셜 계정을 연동할 수 있습니다. 4. **카드와 소셜 공유**: 일대다 관계. 한 카드는 여러 소셜 미디어에 공유될 수 있습니다. 5. **사용자와 구독**: 일대다 관계. 한 사용자는 여러 구독 기록을 가질 수 있습니다. ## 인덱스 성능 최적화를 위해 다음과 같은 인덱스를 생성합니다: 1. **zellyy.cards**: - `user_id`: 사용자별 카드 조회 최적화 - `created_at`: 시간순 정렬 최적화 - `is_public`: 공개 카드 필터링 최적화 2. **zellyy.card_tags**: - `(card_id, tag_name)`: 고유 제약 조건 및 카드별 태그 조회 최적화 - `tag_name`: 태그별 카드 검색 최적화 3. **zellyy.social_accounts**: - `(user_id, platform)`: 고유 제약 조건 및 사용자별 플랫폼 계정 조회 최적화 4. **zellyy.social_shares**: - `user_id`: 사용자별 공유 기록 조회 최적화 - `card_id`: 카드별 공유 기록 조회 최적화 ## 데이터 무결성 데이터 무결성을 보장하기 위해 다음과 같은 제약 조건을 적용합니다: 1. **외래 키 제약 조건**: 모든 관계는 외래 키로 연결되어 참조 무결성을 보장합니다. 2. **고유 제약 조건**: 이메일, 사용자 이름 등은 고유해야 합니다. 3. **NOT NULL 제약 조건**: 필수 필드는 NULL이 될 수 없습니다. 4. **기본값**: 많은 필드에 기본값을 제공하여 데이터 일관성을 유지합니다. ## 확장성 고려사항 1. **샤딩**: 사용자 수가 크게 증가할 경우, 사용자 ID를 기준으로 데이터를 샤딩하는 전략을 고려할 수 있습니다. 2. **아카이빙**: 오래된 카드 데이터는 별도의 아카이브 테이블로 이동하여 주 테이블의 성능을 유지할 수 있습니다. 3. **인덱스 최적화**: 실제 쿼리 패턴에 따라 추가 인덱스를 생성하거나 기존 인덱스를 조정할 수 있습니다. ## 결론 이 ERD는 Zellyy 프로젝트의 데이터 모델을 시각적으로 표현합니다. 이 구조는 사용자가 카드를 작성하고, 태그를 지정하며, 소셜 미디어에 공유하는 핵심 기능을 지원합니다. 또한 구독 관리와 소셜 계정 연동을 위한 테이블도 포함되어 있습니다. 프로젝트가 발전함에 따라 이 ERD는 새로운 요구사항을 반영하여 업데이트될 수 있습니다.