diff --git a/ideas/250812_auth_db_테이블_단순화_방안.md b/ideas/250812_auth_db_테이블_단순화_방안.md new file mode 100644 index 0000000..2942ffd --- /dev/null +++ b/ideas/250812_auth_db_테이블_단순화_방안.md @@ -0,0 +1,344 @@ +# Auth DB 테이블 구조 단순화 방안 + +작성일: 2025년 8월 12일 +작성자: Claude (51123 서버) +요청자: happybell80 + +## 1. 현재 테이블 구조 분석 + +### 1.1 현재 테이블 (5개) +- **users**: 사용자 기본 정보 +- **workspaces**: 워크스페이스 정보 (로빙 할당) +- **workspace_members**: 사용자-워크스페이스 연결 +- **companies**: 회사 정보 +- **slack_workspaces**: Slack 워크스페이스 정보 + +### 1.2 현재 구조의 문제점 + +#### 복잡도 문제 +1. **과도한 관계 분리** + - companies ↔ slack_workspaces ↔ workspaces 3단계 관계 + - 실제로는 1개 workspace만 사용 중 + +2. **중복 데이터** + - robing_id가 workspaces와 workspace_members 양쪽에 존재 + - robing_url도 중복 저장 + +3. **불명확한 개념** + - companies의 실제 필요성 불분명 + - workspaces가 실제로 무엇을 나타내는지 모호 + +4. **누락된 기능** + - Slack user_id와 시스템 user_id 매핑 테이블 없음 + - 사용자가 여러 로빙을 사용할 때 관리 방법 불명확 + +### 1.3 현재 데이터 현황 +``` +users: 3명 (happybell80, eagle0914, hhyong91) +workspaces: 1개 (ivada-robeing) +workspace_members: 3개 (모두 rb10508_micro 사용) +companies: 2개 (테스트 회사) +slack_workspaces: 2개 (GoodGang Labs, test) +``` + +## 2. 단순화 방안 + +### 방안 1: 최소 구조 (3개 테이블) + +```sql +-- 사용자 테이블 +CREATE TABLE users ( + id UUID PRIMARY KEY, + email VARCHAR(255) UNIQUE NOT NULL, + username VARCHAR(50) UNIQUE, + name VARCHAR(255), + oauth_provider VARCHAR(50), + oauth_id VARCHAR(255), + created_at TIMESTAMP, + updated_at TIMESTAMP +); + +-- 사용자별 로빙 할당 +CREATE TABLE user_robings ( + id UUID PRIMARY KEY, + user_id UUID REFERENCES users(id), + robing_id VARCHAR(100) NOT NULL, -- rb10508_micro, rb8001 등 + robing_port INTEGER, + is_primary BOOLEAN DEFAULT false, + created_at TIMESTAMP, + UNIQUE(user_id, robing_id) +); + +-- Slack 사용자 매핑 +CREATE TABLE slack_user_mapping ( + id UUID PRIMARY KEY, + slack_user_id VARCHAR(100) NOT NULL, -- U04KJHGLS + slack_team_id VARCHAR(100), -- T035VFRKCN6 + user_id UUID REFERENCES users(id), + bot_token TEXT, -- 워크스페이스별 봇 토큰 + created_at TIMESTAMP, + UNIQUE(slack_user_id, slack_team_id) +); +``` + +**장점**: 매우 단순, 최소한의 테이블 +**단점**: Slack workspace 정보 관리 어려움, 확장성 제한 + +### 방안 2: 중간 단계 (4개 테이블) ⭐ 권장 + +```sql +-- 기존 users 테이블 유지 +CREATE TABLE users ( + id UUID PRIMARY KEY, + email VARCHAR(255) UNIQUE NOT NULL, + username VARCHAR(50) UNIQUE, + name VARCHAR(255), + picture VARCHAR(500), + oauth_provider VARCHAR(50), + oauth_id VARCHAR(255), + is_active BOOLEAN DEFAULT true, + created_at TIMESTAMP, + updated_at TIMESTAMP, + last_login_at TIMESTAMP +); + +-- Slack 워크스페이스 (단순화) +CREATE TABLE slack_workspaces ( + id UUID PRIMARY KEY, + team_id VARCHAR(100) UNIQUE NOT NULL, + team_name VARCHAR(255), + bot_token TEXT, + bot_user_id VARCHAR(100), + app_id VARCHAR(100), + scopes JSON, + is_active BOOLEAN DEFAULT true, + installed_at TIMESTAMP, + updated_at TIMESTAMP +); + +-- 사용자-로빙 연결 +CREATE TABLE user_robings ( + id UUID PRIMARY KEY, + user_id UUID REFERENCES users(id), + robing_id VARCHAR(100) NOT NULL, + robing_port INTEGER, + robing_host VARCHAR(255) DEFAULT '192.168.219.52', + is_primary BOOLEAN DEFAULT false, + created_at TIMESTAMP, + UNIQUE(user_id, robing_id) +); + +-- Slack-시스템 사용자 매핑 +CREATE TABLE slack_users ( + id UUID PRIMARY KEY, + slack_user_id VARCHAR(100) NOT NULL, + slack_team_id VARCHAR(100) REFERENCES slack_workspaces(team_id), + user_id UUID REFERENCES users(id), + robing_id VARCHAR(100), -- 이 Slack 사용자가 대화할 로빙 + created_at TIMESTAMP, + updated_at TIMESTAMP, + UNIQUE(slack_user_id, slack_team_id) +); +``` + +**장점**: +- 명확한 관심사 분리 +- 다중 로빙 지원 +- 다중 Slack workspace 지원 +- 기존 users 테이블 최소 변경 + +**단점**: +- 여전히 4개 테이블 필요 + +### 방안 3: 통합 단순 구조 (2개 테이블) + +```sql +-- 사용자 (모든 정보 통합) +CREATE TABLE users ( + id UUID PRIMARY KEY, + email VARCHAR(255) UNIQUE NOT NULL, + username VARCHAR(50) UNIQUE, + name VARCHAR(255), + robing_id VARCHAR(100), -- 기본 로빙 + robing_port INTEGER, + slack_user_id VARCHAR(100), -- Slack ID (있으면) + slack_team_id VARCHAR(100), -- Slack workspace (있으면) + oauth_provider VARCHAR(50), + oauth_id VARCHAR(255), + created_at TIMESTAMP, + updated_at TIMESTAMP +); + +-- Slack 설정 (앱 레벨) +CREATE TABLE slack_config ( + team_id VARCHAR(100) PRIMARY KEY, + team_name VARCHAR(255), + bot_token TEXT, + bot_user_id VARCHAR(100), + app_id VARCHAR(100), + is_active BOOLEAN DEFAULT true +); +``` + +**장점**: 매우 단순 +**단점**: 확장성 없음, 다중 로빙/workspace 지원 불가 + +## 3. 권장 방안: 방안 2 (4개 테이블) + +### 3.1 선택 이유 +1. **적절한 균형**: 단순함과 확장성의 균형 +2. **명확한 분리**: 각 테이블의 역할이 명확 +3. **유연성**: 향후 요구사항 변경에 대응 가능 +4. **호환성**: 기존 시스템과의 호환성 유지 + +### 3.2 마이그레이션 계획 + +#### Phase 1: 데이터 백업 +```sql +-- 기존 데이터 백업 +CREATE TABLE backup_workspaces AS SELECT * FROM workspaces; +CREATE TABLE backup_workspace_members AS SELECT * FROM workspace_members; +CREATE TABLE backup_companies AS SELECT * FROM companies; +``` + +#### Phase 2: 새 테이블 생성 +```sql +-- user_robings 생성 및 데이터 이전 +CREATE TABLE user_robings AS +SELECT + gen_random_uuid() as id, + user_id, + robing_id, + CASE robing_id + WHEN 'rb10508_micro' THEN 10508 + WHEN 'rb8001' THEN 8001 + WHEN 'rb10408' THEN 10408 + END as robing_port, + '192.168.219.52' as robing_host, + true as is_primary, + joined_at as created_at +FROM workspace_members; + +-- slack_users 테이블 생성 (빈 테이블) +CREATE TABLE slack_users ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + slack_user_id VARCHAR(100) NOT NULL, + slack_team_id VARCHAR(100), + user_id UUID REFERENCES users(id), + robing_id VARCHAR(100), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE(slack_user_id, slack_team_id) +); +``` + +#### Phase 3: 기존 테이블 정리 +```sql +-- Foreign key 제약 제거 후 테이블 삭제 +ALTER TABLE slack_workspaces DROP CONSTRAINT slack_workspaces_company_id_fkey; +ALTER TABLE slack_workspaces DROP COLUMN company_id; + +DROP TABLE workspace_members; +DROP TABLE workspaces; +DROP TABLE companies; +``` + +### 3.3 새로운 데이터 흐름 + +#### 사용자 로그인 +``` +OAuth 로그인 → users 테이블 조회/생성 +↓ +user_robings에서 기본 로빙 확인 +↓ +로빙 서비스 연결 +``` + +#### Slack 메시지 처리 +``` +Slack 이벤트 수신 (slack_user_id 포함) +↓ +slack_users 테이블에서 user_id, robing_id 조회 +↓ +해당 로빙으로 메시지 라우팅 +↓ +ChromaDB에 user_id 기반 저장 +``` + +## 4. 구현 우선순위 + +1. **즉시 필요**: slack_users 테이블 생성 + - Slack 사용자 매핑 기능 구현 가능 + - 기존 테이블 영향 없음 + +2. **단계적 마이그레이션**: user_robings 테이블 + - workspace_members 데이터 이전 + - 테스트 후 기존 테이블 제거 + +3. **정리 작업**: 불필요한 테이블 제거 + - companies, workspaces 제거 + - slack_workspaces 단순화 + +## 5. API 변경사항 + +### 5.1 사용자-로빙 조회 +```python +# 기존 +SELECT * FROM workspace_members WHERE user_id = ? + +# 변경 +SELECT * FROM user_robings WHERE user_id = ? AND is_primary = true +``` + +### 5.2 Slack 사용자 조회 +```python +# 신규 +SELECT u.*, sr.robing_id +FROM slack_users sr +JOIN users u ON sr.user_id = u.id +WHERE sr.slack_user_id = ? AND sr.slack_team_id = ? +``` + +## 6. 예상 효과 + +### 6.1 복잡도 감소 +- 테이블 수: 5개 → 4개 +- 관계 복잡도: 3단계 → 2단계 +- 중복 데이터 제거 + +### 6.2 기능 개선 +- Slack 사용자 매핑 지원 +- 다중 로빙 지원 +- 명확한 데이터 모델 + +### 6.3 유지보수성 +- 각 테이블 역할 명확 +- 확장 가능한 구조 +- 마이그레이션 경로 명확 + +## 7. 리스크 및 대응 + +### 7.1 데이터 손실 위험 +- 대응: 모든 변경 전 백업 테이블 생성 +- 롤백 계획 수립 + +### 7.2 서비스 중단 +- 대응: 단계적 마이그레이션 +- 새 테이블 먼저 생성, 테스트 후 전환 + +### 7.3 애플리케이션 호환성 +- 대응: API 래퍼 함수로 하위 호환성 유지 +- 점진적 코드 업데이트 + +## 8. 결론 + +현재의 복잡한 5개 테이블 구조를 4개 테이블로 단순화하여: +- 데이터 모델의 명확성 향상 +- Slack 통합 기능 지원 +- 유지보수성 개선 + +방안 2 (4개 테이블)를 채택하여 단계적으로 마이그레이션하는 것을 권장합니다. + +--- + +*이 문서는 2025년 8월 12일 51123 서버에서 작성되었습니다.* \ No newline at end of file