PostgreSQL 테이블 구조
작성일: 2025-08-20
최종 수정일: 2025-09-24
데이터베이스: main_db
1. 조직 관련 테이블
company
- 용도: 회사 정보
- Primary Key: id (UUID)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
UUID |
NO |
|
회사 ID |
| name |
VARCHAR(255) |
NO |
|
회사명 |
| url |
VARCHAR(255) |
YES |
|
회사 URL |
| created_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
생성 시각 |
| updated_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
수정 시각 |
team
- 용도: 팀 정보
- Primary Key: id (UUID)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
UUID |
NO |
|
팀 ID |
| company_id |
UUID |
NO |
|
회사 ID (FK → company) |
| name |
VARCHAR(32) |
NO |
|
팀 이름 |
| created_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
생성 시각 |
| updated_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
수정 시각 |
user
- 용도: 시스템 사용자 정보
- Primary Key: id (UUID)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
UUID |
NO |
|
사용자 ID |
| team_id |
UUID |
NO |
|
팀 ID (FK → team) |
| email |
VARCHAR(255) |
NO |
|
이메일 (UNIQUE) |
| name |
VARCHAR(255) |
YES |
|
사용자명 |
| picture |
VARCHAR(500) |
YES |
|
프로필 이미지 |
| oauth_provider |
VARCHAR(50) |
YES |
|
OAuth 제공자 |
| oauth_id |
VARCHAR(255) |
YES |
|
OAuth ID |
| is_active |
BOOLEAN |
YES |
|
활성 상태 |
| last_login_at |
TIMESTAMPTZ |
YES |
|
마지막 로그인 |
| created_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
생성 시각 |
| updated_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
수정 시각 |
| username |
VARCHAR(64) |
YES |
|
사용자명 |
workspace_member
- 용도: 워크스페이스 멤버십
- Primary Key: id (UUID)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
UUID |
NO |
|
멤버십 ID |
| user_id |
UUID |
NO |
|
사용자 ID (FK → user) |
| role |
user_role |
NO |
GUEST |
역할 (OWNER/MEMBER/GUEST) |
| is_active |
BOOLEAN |
YES |
|
활성 상태 |
| joined_at |
TIMESTAMP |
YES |
CURRENT_TIMESTAMP |
가입 시각 |
| updated_at |
TIMESTAMP |
YES |
CURRENT_TIMESTAMP |
수정 시각 |
2. 제품 및 로빙 테이블
product
- 용도: 제품 정보
- Primary Key: id (UUID)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
UUID |
NO |
|
제품 ID |
| name |
VARCHAR(32) |
NO |
|
제품명 |
| app_id |
VARCHAR(16) |
YES |
|
앱 ID |
| scope |
JSON |
YES |
|
권한 범위 |
| description |
VARCHAR(256) |
YES |
|
설명 |
| created_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
생성 시각 |
| updated_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
수정 시각 |
robeing
- 용도: 로빙 엔티티 정보
- Primary Key: id (UUID)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
UUID |
NO |
|
로빙 ID |
| product_id |
UUID |
NO |
|
제품 ID (FK → product) |
| team_id |
UUID |
NO |
|
팀 ID (FK → team) |
| name |
VARCHAR(32) |
YES |
|
로빙 이름 |
| level |
INTEGER |
YES |
1 |
레벨 |
| experience |
INTEGER |
YES |
0 |
경험치 |
| memory |
INTEGER |
YES |
10 |
메모리 스탯 |
| compute |
INTEGER |
YES |
10 |
연산 스탯 |
| react |
INTEGER |
YES |
10 |
반응 스탯 |
| empathy |
INTEGER |
YES |
10 |
공감 스탯 |
| leadership |
INTEGER |
YES |
10 |
리더십 스탯 |
| updated_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
수정 시각 |
| created_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
생성 시각 |
| robeing_container_id |
VARCHAR(64) |
YES |
|
컨테이너 ID |
| robeing_container_url |
VARCHAR(128) |
YES |
|
컨테이너 URL |
3. Slack 통합 테이블
slack_workspace
- 용도: Slack 워크스페이스 정보
- Primary Key: id (UUID)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
UUID |
NO |
|
워크스페이스 ID |
| team_id |
UUID |
NO |
|
팀 ID (FK → team) |
| slack_team_id |
VARCHAR(32) |
YES |
|
Slack 팀 ID |
| bot_token |
VARCHAR(255) |
YES |
|
봇 토큰 |
| is_enterprise_install |
BOOLEAN |
YES |
|
엔터프라이즈 설치 |
| is_active |
BOOLEAN |
YES |
|
활성 상태 |
| installed_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
설치 시각 |
| updated_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
수정 시각 |
| created_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
생성 시각 |
4. 사용자 설정 및 토큰 테이블
user_preference
- 용도: 사용자 개인 설정
- Primary Key: id (INTEGER)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
INTEGER |
NO |
|
설정 ID |
| user_id |
UUID |
NO |
|
사용자 ID (FK → user) |
| slack_user_id |
VARCHAR(32) |
YES |
|
Slack 사용자 ID |
| news_keywords |
VARCHAR(128)[] |
YES |
|
뉴스 키워드 |
| email_filter |
VARCHAR(128)[] |
YES |
|
이메일 필터 |
| briefing_enabled |
BOOLEAN |
YES |
true |
브리핑 활성화 |
| briefing_time |
TIME |
YES |
09:00:00 |
브리핑 시간 |
| updated_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
수정 시각 |
| created_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
생성 시각 |
gmail_token
- 용도: Gmail OAuth 토큰
- Primary Key: id (UUID)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
UUID |
NO |
|
토큰 ID |
| user_id |
UUID |
NO |
|
사용자 ID (FK → user) |
| token_data |
JSONB |
YES |
|
토큰 데이터 |
| oauth_config |
JSONB |
YES |
|
OAuth 설정 |
| scopes |
JSONB |
YES |
|
권한 범위 |
| metadata |
JSONB |
YES |
|
메타데이터 |
| expiry |
TIMESTAMP |
YES |
|
만료 시각 |
| is_equipped |
BOOLEAN |
YES |
false |
장착 상태 |
| equipped_to |
VARCHAR(50) |
YES |
|
장착 대상 |
| token_type |
VARCHAR |
YES |
Bearer |
토큰 타입 |
| expires_at |
DOUBLE PRECISION |
YES |
|
만료 시간 |
| created_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
생성 시각 |
| updated_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
수정 시각 |
5. 로그 및 데이터 테이블
conversation_log
- 용도: 대화 기록
- Primary Key: id (INTEGER)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
INTEGER |
NO |
|
로그 ID |
| user_id |
UUID |
NO |
|
사용자 ID (FK → user) |
| channel_id |
VARCHAR(16) |
YES |
|
채널 ID |
| message |
VARCHAR |
YES |
|
사용자 메시지 |
| response |
VARCHAR |
YES |
|
응답 메시지 |
| intent |
VARCHAR(256) |
YES |
|
의도 분석 |
| confidence |
DOUBLE PRECISION |
YES |
|
신뢰도 |
| thread_ts |
VARCHAR(128) |
YES |
|
스레드 타임스탬프 |
| timestamp |
TIMESTAMPTZ |
YES |
|
대화 시각 |
| channel_type |
VARCHAR(32) |
YES |
|
채널 타입 |
news
- 용도: 뉴스 데이터
- Primary Key: id (UUID)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
UUID |
NO |
|
뉴스 ID |
| user_id |
UUID |
YES |
|
사용자 ID (FK → user) |
| data |
JSONB |
YES |
|
뉴스 데이터 |
| created_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
생성 시각 |
| updated_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
수정 시각 |
rb_news
- 용도: 뉴스 발행 관리
- Primary Key: id (UUID)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
UUID |
NO |
gen_random_uuid() |
뉴스 ID |
| title |
TEXT |
NO |
|
뉴스 제목 |
| url |
TEXT |
NO |
|
뉴스 URL (UNIQUE) |
| summary |
TEXT |
YES |
|
뉴스 요약 |
| slack_message_ts |
VARCHAR(100) |
YES |
|
Slack 메시지 타임스탬프 |
| slack_channel_id |
VARCHAR(100) |
YES |
|
Slack 채널 ID |
| is_published |
BOOLEAN |
YES |
false |
발행 상태 |
| published_at |
TIMESTAMPTZ |
YES |
|
발행 시각 |
| created_at |
TIMESTAMPTZ |
YES |
now() |
생성 시각 |
인덱스:
rb_news_pkey: PRIMARY KEY (id)
rb_news_url_key: UNIQUE (url)
idx_rb_news_url: btree (url)
idx_rb_news_slack_message_ts: btree (slack_message_ts)
idx_rb_news_created_at: btree (created_at DESC)
team_document
- 용도: 팀 문서 RAG 시스템
- Primary Key: id (UUID)
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
UUID |
NO |
gen_random_uuid() |
문서 ID |
| team_id |
UUID |
NO |
|
팀 ID (FK → team) |
| filename |
VARCHAR(255) |
NO |
|
파일명 |
| file_hash |
VARCHAR(64) |
NO |
|
SHA256 해시 |
| file_size |
BIGINT |
YES |
|
파일 크기 (bytes) |
| mime_type |
VARCHAR(100) |
YES |
|
MIME 타입 |
| storage_path |
TEXT |
NO |
|
저장 경로 (/mnt/hdd/uploads/{team_id}/) |
| text_content |
TEXT |
YES |
|
추출된 텍스트 |
| chunk_count |
INTEGER |
YES |
0 |
ChromaDB 청크 수 |
| processing_status |
VARCHAR(20) |
YES |
'pending' |
처리 상태 (pending/completed/failed) |
| metadata |
JSONB |
YES |
'{}' |
메타데이터 (uploaded_by, tags, summary 등) |
| created_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
생성 시각 |
| updated_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
수정 시각 |
인덱스:
idx_team_doc_hash: UNIQUE (team_id, file_hash) - 팀별 파일 중복 방지
naverworks_token
- 용도: NAVER WORKS OAuth 토큰 및 Passport 정보
- Primary Key: id (UUID)
- Unique: user_id
- Foreign Key: user_id → user(id) ON DELETE CASCADE
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| id |
UUID |
NO |
gen_random_uuid() |
토큰 ID |
| user_id |
UUID |
NO |
|
사용자 ID (FK → user) |
| access_token |
TEXT |
YES |
|
액세스 토큰 (개별 저장용) |
| refresh_token |
TEXT |
YES |
|
리프레시 토큰 (개별 저장용) |
| token_type |
VARCHAR(50) |
YES |
'Bearer' |
토큰 타입 |
| expires_at |
TIMESTAMP |
YES |
|
토큰 만료 시각 |
| scopes |
JSONB |
YES |
|
OAuth 스코프 목록 |
| domain_id |
VARCHAR(255) |
YES |
|
NAVER WORKS 도메인 ID |
| service_account |
VARCHAR(255) |
YES |
|
서비스 계정 |
| metadata |
JSONB |
YES |
|
사용자 메타데이터 |
| created_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
생성 시각 |
| updated_at |
TIMESTAMPTZ |
YES |
CURRENT_TIMESTAMP |
수정 시각 |
| username |
VARCHAR(255) |
YES |
|
사용자명 |
| account_id |
VARCHAR(255) |
YES |
|
NAVER WORKS 계정 ID |
| token_data |
JSONB |
YES |
|
토큰 데이터 (통합 저장용) |
| oauth_config |
JSONB |
YES |
|
OAuth 설정 정보 |
| is_equipped |
BOOLEAN |
YES |
false |
Passport 장착 여부 |
인덱스:
- idx_naverworks_token_user_id (user_id)
- idx_naverworks_token_expires_at (expires_at)
트리거:
- update_naverworks_token_updated_at: updated_at 자동 갱신
6. 기타 정보
Custom Types
- user_role: ENUM (OWNER, MEMBER, GUEST)
Functions
- update_column_updated_at: 모든 테이블의 updated_at 자동 갱신 트리거
외래키 관계
| 테이블 |
컬럼 |
참조 테이블 |
참조 컬럼 |
| team |
company_id |
company |
id |
| user |
team_id |
team |
id |
| robeing |
product_id |
product |
id |
| robeing |
team_id |
team |
id |
| slack_workspace |
team_id |
team |
id |
| workspace_member |
user_id |
user |
id |
| conversation_log |
user_id |
user |
id |
| gmail_token |
user_id |
user |
id |
| news |
user_id |
user |
id |
| user_preference |
user_id |
user |
id |
| team_document |
team_id |
team |
id |
7. 감정 분석 테이블 (robeing_metrics DB)
emotion_readings
- 용도: 사용자 및 로빙 감정 분석 시계열 데이터
- 데이터베이스: robeing_metrics (TimescaleDB)
- 특징: 시계열 하이퍼테이블, Top-p 기반 복합 감정 저장
| 컬럼명 |
타입 |
NULL |
기본값 |
설명 |
| created_at |
TIMESTAMPTZ |
NO |
|
분석 시각 (파티션 키) |
| user_id |
UUID |
YES |
|
사용자 ID (user 테이블 참조) |
| company_id |
UUID |
YES |
|
회사 ID |
| robeing_id |
VARCHAR(50) |
YES |
|
로빙 ID |
| emotion_type |
VARCHAR(20) |
YES |
|
'user' 또는 'robeing' |
| probs |
JSONB |
NO |
|
7개 감정 확률 분포 |
| entropy |
DOUBLE PRECISION |
YES |
|
감정 엔트로피 값 |
| model_version |
VARCHAR(50) |
YES |
|
모델 버전 (예: onnx-7emotions-v1) |
| meta |
JSONB |
YES |
|
메타데이터 (source, message_length 등) |
| text_hash |
VARCHAR(64) |
YES |
|
텍스트 SHA256 해시 |
| top_emotions |
JSONB |
YES |
|
Top-p 복합 감정 배열 [{"label", "probability"}] |
| cumulative_p |
DOUBLE PRECISION |
YES |
|
누적 확률 (Top-p 70%) |
인덱스:
emotion_readings_created_at_idx: btree (created_at DESC)
idx_emotion_user_time: btree (user_id, created_at DESC)
idx_emotion_company_time: btree (company_id, created_at DESC)
idx_emotion_robeing_time: btree (robeing_id, created_at DESC)
idx_emotion_type: btree (emotion_type, created_at DESC)
제약 조건:
emotion_readings_emotion_type_check: emotion_type IN ('user', 'robeing')
트리거:
ts_insert_blocker: TimescaleDB 하이퍼테이블 삽입 제어
예시 데이터:
{
"top_emotions": [
{"label": "fear", "probability": 0.499},
{"label": "neutral", "probability": 0.335}
],
"cumulative_p": 0.833,
"probs": {
"fear": 0.499, "neutral": 0.335, "anger": 0.056,
"sadness": 0.048, "disgust": 0.032, "surprise": 0.018, "happiness": 0.012
},
"entropy": 1.234
}
주의사항
데이터베이스 정보
- main_db: 주요 서비스 데이터 (PostgreSQL)
- 소유자: robeings
- 테이블: user, team, robeing, conversation_log 등
- robeing_metrics: 시계열 메트릭 데이터 (TimescaleDB)
- 테이블: emotion_readings
- 특징: 시간 기반 파티셔닝, 자동 압축, retention 정책
- 타임스탬프: TIMESTAMPTZ 사용 (WITH TIME ZONE)
- 자동 갱신: update_column_updated_at 트리거로 updated_at 자동 관리
- UUID 기반: 주요 테이블 모두 UUID 사용
문서 끝