happybell80 fe9f80d02d docs: PostgreSQL 데이터베이스 구조 문서화
- 300_architecture/database 폴더 생성
- tables.md: 모든 테이블 구조 상세 정의
- relationships.md: 테이블 관계도 및 JOIN 예시
- README.md: 데이터베이스 문서 구성 안내

주요 내용:
- 12개 테이블 구조 정리
- user_id UUID 정규화 현황
- 외래키 관계 정의
- 데이터 흐름 다이어그램
- JOIN 쿼리 예시
2025-08-20 01:01:51 +09:00

237 lines
8.5 KiB
Markdown

# PostgreSQL 테이블 구조
## 작성일: 2025-08-20
## 데이터베이스: auth_db
---
## 1. 사용자 관련 테이블
### users
- **용도**: 시스템 전체 사용자 정보
- **Primary Key**: id (UUID)
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|--------|------|------|--------|------|
| id | UUID | NO | | 사용자 고유 식별자 |
| email | VARCHAR(255) | NO | | 이메일 주소 (UNIQUE) |
| name | VARCHAR(255) | YES | | 사용자 실명 |
| username | VARCHAR(50) | YES | | 로그인 ID (UNIQUE) |
| picture | VARCHAR(500) | YES | | 프로필 이미지 URL |
| oauth_provider | VARCHAR(50) | YES | | OAuth 제공자 (google 등) |
| oauth_id | VARCHAR(255) | YES | | OAuth 고유 ID |
| is_active | BOOLEAN | YES | true | 활성 상태 |
| created_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 생성 시각 |
| updated_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 수정 시각 |
| last_login_at | TIMESTAMP | YES | | 마지막 로그인 |
---
## 2. Workspace 관련 테이블
### workspaces
- **용도**: 워크스페이스 정보
- **Primary Key**: id (UUID)
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|--------|------|------|--------|------|
| id | UUID | NO | | 워크스페이스 ID |
| name | VARCHAR(255) | NO | | 워크스페이스 이름 |
| company_id | UUID | YES | | 회사 ID (FK → companies) |
| created_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 생성 시각 |
| updated_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 수정 시각 |
### workspace_members
- **용도**: 워크스페이스 멤버 관계
- **Primary Key**: id (UUID)
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|--------|------|------|--------|------|
| id | UUID | NO | | 멤버십 ID |
| workspace_id | UUID | NO | | 워크스페이스 ID (FK → workspaces) |
| user_id | UUID | NO | | 사용자 ID (FK → users) |
| role | ENUM | YES | member | 역할 (admin/member) |
| robing_id | VARCHAR(50) | YES | | 할당된 로빙 ID |
| robing_url | VARCHAR(255) | YES | | 로빙 서비스 URL |
| is_active | BOOLEAN | YES | true | 활성 상태 |
| joined_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 가입 시각 |
| updated_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 수정 시각 |
### companies
- **용도**: 회사 정보
- **Primary Key**: id (UUID)
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|--------|------|------|--------|------|
| id | UUID | NO | | 회사 ID |
| name | VARCHAR(255) | NO | | 회사명 |
| domain | VARCHAR(255) | YES | | 도메인 |
| created_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 생성 시각 |
| updated_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 수정 시각 |
---
## 3. Slack 통합 테이블
### slack_workspaces
- **용도**: Slack 워크스페이스 정보
- **Primary Key**: id (UUID)
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|--------|------|------|--------|------|
| id | UUID | NO | | 워크스페이스 ID |
| team_id | VARCHAR(50) | NO | | Slack Team ID (UNIQUE) |
| team_name | VARCHAR(255) | YES | | 팀 이름 |
| bot_token | TEXT | YES | | Bot User OAuth Token |
| bot_user_id | VARCHAR(50) | YES | | Bot User ID |
| created_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 생성 시각 |
| updated_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 수정 시각 |
### slack_user_mapping
- **용도**: Slack 사용자와 시스템 사용자 매핑
- **Primary Key**: id (UUID)
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|--------|------|------|--------|------|
| id | UUID | NO | | 매핑 ID |
| slack_user_id | VARCHAR(50) | NO | | Slack User ID (U로 시작) |
| slack_workspace_id | UUID | YES | | Slack 워크스페이스 ID (FK → slack_workspaces) |
| user_id | UUID | NO | | 시스템 사용자 ID (FK → users) |
| workspace_member_id | UUID | YES | | 워크스페이스 멤버 ID (FK → workspace_members) |
| created_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 생성 시각 |
| updated_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 수정 시각 |
---
## 4. Gmail 관련 테이블
### gmail_tokens
- **용도**: Gmail OAuth 토큰 저장
- **Primary Key**: id (SERIAL)
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|--------|------|------|--------|------|
| id | SERIAL | NO | | 토큰 ID |
| user_id | UUID | NO | | 사용자 ID (FK → users) |
| robeing_id | VARCHAR(50) | YES | | 로빙 ID |
| token_data | JSONB | NO | | access_token, refresh_token |
| oauth_config | JSONB | YES | | client_id, client_secret, token_uri |
| scopes | JSONB | YES | | Gmail API 권한 목록 |
| metadata | JSONB | YES | | email, imported_at 등 |
| expiry | TIMESTAMP | YES | | 토큰 만료 시각 |
| is_equipped | BOOLEAN | YES | false | 장착 상태 |
| equipped_to | VARCHAR(50) | YES | | 장착된 로빙 ID |
| created_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 생성 시각 |
| updated_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 수정 시각 |
### gmail_audit_logs
- **용도**: Gmail 아이템 작업 감사 로그
- **Primary Key**: id (SERIAL)
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|--------|------|------|--------|------|
| id | SERIAL | NO | | 로그 ID |
| user_id | VARCHAR(100) | YES | | 사용자 ID (⚠️ VARCHAR - 수정 필요) |
| robeing_id | VARCHAR(50) | YES | | 로빙 ID |
| action | VARCHAR(50) | YES | | 작업 유형 (equip/unequip/reauth) |
| success | BOOLEAN | YES | | 성공 여부 |
| details | JSONB | YES | | 상세 정보 |
| created_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 생성 시각 |
---
## 5. 로빙 관련 테이블
### robeing_stats
- **용도**: 로빙 통계 및 레벨 정보
- **Primary Key**: id (SERIAL)
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|--------|------|------|--------|------|
| id | SERIAL | NO | | 통계 ID |
| user_id | UUID | YES | | 사용자 ID (FK → users) |
| robeing_id | VARCHAR(50) | YES | | 로빙 ID |
| level | INTEGER | YES | 1 | 현재 레벨 |
| experience | INTEGER | YES | 0 | 경험치 |
| email_sent_count | INTEGER | YES | 0 | 이메일 발송 횟수 |
| created_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 생성 시각 |
| updated_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 수정 시각 |
### robing_stats (구버전)
- **용도**: 구버전 로빙 통계 (사용 중단 예정)
- **설명**: robeing_stats로 마이그레이션 필요
### robing_settings
- **용도**: 로빙 설정 정보
- **Primary Key**: id (SERIAL)
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|--------|------|------|--------|------|
| id | SERIAL | NO | | 설정 ID |
| robing_id | VARCHAR(50) | NO | | 로빙 ID (UNIQUE) |
| settings | JSONB | YES | | 설정 JSON |
| created_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 생성 시각 |
| updated_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 수정 시각 |
---
## 6. 대화 로그 테이블
### conversation_logs
- **용도**: 대화 기록 저장
- **Primary Key**: id (SERIAL)
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|--------|------|------|--------|------|
| id | SERIAL | NO | | 로그 ID |
| user_id | UUID | YES | | 사용자 ID (FK → users) |
| robeing_id | VARCHAR(50) | YES | | 로빙 ID |
| channel | VARCHAR(100) | YES | | 채널 (slack/web/api) |
| message_type | VARCHAR(50) | YES | | 메시지 유형 |
| user_message | TEXT | YES | | 사용자 메시지 |
| bot_response | TEXT | YES | | 봇 응답 |
| metadata | JSONB | YES | | 추가 메타데이터 |
| created_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 생성 시각 |
---
## 인덱스 정보
### 주요 인덱스
- users: email (UNIQUE), username (UNIQUE)
- gmail_tokens: user_id, robeing_id, oauth_config (GIN), token_data (GIN)
- slack_user_mapping: slack_user_id, user_id
- workspace_members: workspace_id, user_id
- conversation_logs: user_id, robeing_id, created_at
---
## 외래키 제약
| 테이블 | 컬럼 | 참조 테이블 | 참조 컬럼 |
|--------|------|------------|----------|
| workspace_members | user_id | users | id |
| workspace_members | workspace_id | workspaces | id |
| slack_user_mapping | user_id | users | id |
| slack_user_mapping | slack_workspace_id | slack_workspaces | id |
| gmail_tokens | user_id | users | id |
| robeing_stats | user_id | users | id |
| conversation_logs | user_id | users | id |
---
## 주의사항
### 데이터 타입 일관성
- **user_id**: 모든 테이블에서 UUID 타입 사용 (gmail_audit_logs 제외)
- **robeing_id**: VARCHAR(50) 통일
- **timestamp**: TIMESTAMP WITHOUT TIME ZONE 사용
### 개선 필요 사항
1. gmail_audit_logs.user_id를 UUID로 변경 필요 (현재 VARCHAR)
2. robing_stats 테이블을 robeing_stats로 통합 필요
3. 일부 테이블의 소유자가 postgres로 되어있어 권한 조정 필요
---
**문서 끝**