From ce1a2a92e4698f2874a3a263c195b9fcd7e3abb3 Mon Sep 17 00:00:00 2001 From: happybell80 Date: Wed, 10 Sep 2025 21:23:53 +0900 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20PostgreSQL=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=EB=B3=80=EA=B2=BD=20=EA=B3=84=ED=9A=8D=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 작성일 형식 수정 (2025-09-10 → 250910) - users 테이블: picture vs avatar_url 모델 차이 명시 - slack_user_mapping: slack_workspace_id 컬럼 추가 - slack_workspaces: company_id → workspace_id 마이그레이션 충돌 명시 - conversation_logs: rb8001과 robeing-monitor 모델 차이 명시 - 개별 로빙 DB 추측 내용 제거 - 위험 요소에 모델 불일치 항목 추가 --- ...ll80_PostgreSQL_테이블_변경_계획.md | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/300_architecture/plans/250910_happybell80_PostgreSQL_테이블_변경_계획.md b/300_architecture/plans/250910_happybell80_PostgreSQL_테이블_변경_계획.md index e58521d..a7522c2 100644 --- a/300_architecture/plans/250910_happybell80_PostgreSQL_테이블_변경_계획.md +++ b/300_architecture/plans/250910_happybell80_PostgreSQL_테이블_변경_계획.md @@ -1,7 +1,7 @@ # PostgreSQL 데이터베이스 테이블 변경 계획 ## 작성 정보 -- **작성일**: 2025-09-10 +- **작성일**: 250910 - **작성자**: happybell80 - **목적**: PostgreSQL 테이블 구조 대대적 변경에 따른 영향 범위 파악 및 수정 계획 @@ -10,7 +10,6 @@ ### 메인 데이터베이스 - **main_db**: `postgresql://robeings:robeings@192.168.219.45:5432/main_db` - **robeing_metrics**: `postgresql://postgres:@172.17.0.1:5432/robeing_metrics` -- **개별 로빙 DB**: `postgresql://postgres:postgres@localhost/{ROBEING_ID}_db` ### 사용 라이브러리 | 저장소 | 라이브러리 | @@ -26,17 +25,19 @@ ## 2. 테이블별 사용 위치 상세 ### 2.1 users 테이블 -**컬럼**: id(UUID), username, email, name, avatar_url, oauth_provider, oauth_id, is_active, created_at, updated_at, last_login_at +**컬럼**: +- auth-server 모델: id(UUID), username, email, name, **picture**, oauth_provider, oauth_id, is_active, created_at, updated_at, last_login_at +- robeing-gateway 모델: id(UUID), username, email, name, **avatar_url**, oauth_provider, oauth_id, is_active, created_at, updated_at, last_login_at | 파일 경로 | 라인 번호 | 작업 내용 | |-----------|-----------|-----------| -| auth-server/app/models/user.py | 21-35 | 테이블 모델 정의 | +| auth-server/app/models/user.py | 21-35 | 테이블 모델 정의 (picture 컬럼) | | auth-server/app/providers/gmail_passport.py | 178 | SELECT id FROM users WHERE username = $1 | | auth-server/app/providers/gmail_passport.py | 187 | SELECT username FROM users WHERE id = $1 | | robeing-gateway/app/database.py | 98-112 | JOIN 쿼리 (workspace_members, workspaces와 함께) | | robeing-gateway/app/database.py | 182-191 | SELECT * FROM users WHERE username = $1 | | robeing-gateway/app/database.py | 321-328 | SELECT * FROM users (전체 조회) | -| robeing-gateway/app/models.py | 11-24 | 테이블 모델 정의 | +| robeing-gateway/app/models.py | 11-24 | 테이블 모델 정의 (avatar_url 컬럼) | ### 2.2 workspaces 테이블 **컬럼**: id(UUID), name, subdomain, robeing_id, robeing_port, robeing_url, max_members, workspace_type, status, created_at, updated_at @@ -64,22 +65,24 @@ | robeing-gateway/app/models.py | 46-60 | 테이블 모델 정의 | ### 2.4 slack_user_mapping 테이블 -**컬럼**: slack_user_id, user_id +**컬럼**: slack_user_id, slack_workspace_id, user_id +**주의**: (slack_user_id, slack_workspace_id) 조합이 고유 키 | 파일 경로 | 라인 번호 | 작업 내용 | |-----------|-----------|-----------| -| auth-server/app/providers/slack.py | 266 | SELECT user_id FROM slack_user_mapping WHERE slack_user_id = :slack_user_id | -| auth-server/app/providers/slack.py | 308-312 | INSERT INTO slack_user_mapping ... DO UPDATE SET | +| auth-server/app/providers/slack.py | 266 | SELECT user_id FROM slack_user_mapping WHERE slack_user_id = :slack_user_id AND slack_workspace_id = :slack_workspace_id | +| auth-server/app/providers/slack.py | 308-312 | INSERT INTO slack_user_mapping ... DO UPDATE SET (slack_user_id, slack_workspace_id 조합 기준) | | rb8001/app/router/router.py | 92 | SELECT user_id FROM slack_user_mapping WHERE slack_user_id = :slack_id | | robeing-gateway/app/main.py | 479-486 | SELECT user_id FROM slack_user_mapping WHERE slack_user_id = $1 | ### 2.5 slack_workspaces 테이블 -**컬럼**: id(UUID), company_id(UUID), team_id, team_name, bot_token, bot_user_id, app_id, scopes(JSON), is_enterprise_install, is_active, installed_at, updated_at +**컬럼**: id(UUID), workspace_id(UUID), team_id, team_name, bot_token, bot_user_id, app_id, scopes(JSON), is_enterprise_install, is_active, installed_at, updated_at +**주의**: 마이그레이션에서 company_id → workspace_id로 컬럼명 변경 정의됨 | 파일 경로 | 라인 번호 | 작업 내용 | |-----------|-----------|-----------| -| auth-server/app/models/workspace.py | 43-62 | 테이블 모델 정의 | -| auth-server/migrations/add_user_workspace_tables.sql | 60-76 | ALTER TABLE 정의 | +| auth-server/app/models/workspace.py | 43-62 | 테이블 모델 정의 (현재 company_id로 정의됨) | +| auth-server/migrations/add_user_workspace_tables.sql | 60-76 | ALTER TABLE 정의 (company_id → workspace_id 변경) | | robeing-gateway/app/main.py | 522-525 | SELECT bot_token FROM slack_workspaces WHERE team_id = $1 | | robeing-gateway/app/main.py | 567-570 | SELECT bot_token FROM slack_workspaces WHERE team_id = $1 | @@ -136,17 +139,19 @@ | robeing-monitor/app/state/state_service.py | 133 | SELECT 쿼리 | ### 2.10 conversation_logs 테이블 -**컬럼**: id, robeing_id, user_id, slack_user_id, channel_id, message, response, intent, confidence, timestamp +**컬럼**: +- rb8001 모델: id, robeing_id, user_id, **slack_user_id**, channel_id, message, response, intent, confidence, timestamp +- robeing-monitor 모델: id, robeing_id, user_id, channel_id, message, response, intent, confidence, timestamp (slack_user_id 없음) | 파일 경로 | 라인 번호 | 작업 내용 | |-----------|-----------|-----------| -| rb8001/app/state/database.py | 52-65 | 테이블 모델 정의 | -| rb8001/app/state/database.py | 86-92 | SELECT 쿼리 (최근 대화) | -| rb8001/app/router/router.py | 464-496 | INSERT 쿼리 | -| robeing-monitor/app/state/database.py | 47-59 | 테이블 모델 정의 | -| robeing-monitor/app/state/state_service.py | 156-159 | INSERT 쿼리 | -| robeing-monitor/app/state/state_service.py | 173-177 | SELECT 쿼리 (최근 로그) | -| robeing-monitor/app/state/state_service.py | 194-203 | SELECT 쿼리 (7일간) | +| rb8001/app/state/database.py | 52-65 | 테이블 모델 정의 (slack_user_id 포함) | +| rb8001/app/state/database.py | 86-92 | SELECT 쿼리 (최근 대화, slack_user_id 포함) | +| rb8001/app/router/router.py | 464-496 | INSERT 쿼리 (slack_user_id 포함) | +| robeing-monitor/app/state/database.py | 47-59 | 테이블 모델 정의 (slack_user_id 없음) | +| robeing-monitor/app/state/state_service.py | 156-159 | INSERT 쿼리 (slack_user_id 없음) | +| robeing-monitor/app/state/state_service.py | 173-177 | SELECT 쿼리 (최근 로그, slack_user_id 없음) | +| robeing-monitor/app/state/state_service.py | 194-203 | SELECT 쿼리 (7일간, slack_user_id 없음) | ### 2.11 user_preferences 테이블 **컬럼**: user_id, slack_user_id, news_keywords, email_filter, briefing_enabled, briefing_time @@ -204,6 +209,8 @@ 3. **JSON 컬럼**: preferences, scopes, oauth_config 등 JSON 타입 컬럼 처리 주의 4. **외래키 관계**: workspace_members의 workspace_id, user_id FK 관계 유지 5. **gen_random_uuid()**: PostgreSQL 함수 사용 부분 확인 필요 +6. **모델 불일치**: 같은 테이블에 대한 서로 다른 모델 정의 (users의 picture vs avatar_url, conversation_logs의 slack_user_id 유무) +7. **마이그레이션 충돌**: slack_workspaces의 company_id → workspace_id 변경이 모델과 불일치 ## 5. 작업 우선순위 From 55e2b7e103e4d8c57628cd60a0387dc409f04c5c Mon Sep 17 00:00:00 2001 From: happybell80 Date: Wed, 10 Sep 2025 21:30:36 +0900 Subject: [PATCH 2/3] =?UTF-8?q?docs:=20PostgreSQL=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=EB=B3=80=EA=B2=BD=20=EA=B3=84=ED=9A=8D=20=EB=88=84?= =?UTF-8?q?=EB=9D=BD=20=EC=82=AC=ED=95=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - gmail_tokens: username 컬럼 및 token_data(JSON) 병행 사용 명시 - users: provider/provider_id vs oauth_provider/oauth_id 차이 명시 - workspace_members: role 타입 차이 (Enum vs String) 명시 - slack_user_mapping: 완전한 제약조건 (UNIQUE, FK) 명시 - 위험 요소에 모델 불일치 상세 내용 추가 --- ...ll80_PostgreSQL_테이블_변경_계획.md | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/300_architecture/plans/250910_happybell80_PostgreSQL_테이블_변경_계획.md b/300_architecture/plans/250910_happybell80_PostgreSQL_테이블_변경_계획.md index a7522c2..afa3f8f 100644 --- a/300_architecture/plans/250910_happybell80_PostgreSQL_테이블_변경_계획.md +++ b/300_architecture/plans/250910_happybell80_PostgreSQL_테이블_변경_계획.md @@ -26,8 +26,8 @@ ### 2.1 users 테이블 **컬럼**: -- auth-server 모델: id(UUID), username, email, name, **picture**, oauth_provider, oauth_id, is_active, created_at, updated_at, last_login_at -- robeing-gateway 모델: id(UUID), username, email, name, **avatar_url**, oauth_provider, oauth_id, is_active, created_at, updated_at, last_login_at +- auth-server 모델: id(UUID), username, email, name, **picture**, **oauth_provider**, **oauth_id**, is_active, created_at, updated_at, last_login_at +- robeing-gateway 모델: id(UUID), email, name, **avatar_url**, **provider**, **provider_id**, created_at, updated_at (username 없음) | 파일 경로 | 라인 번호 | 작업 내용 | |-----------|-----------|-----------| @@ -53,6 +53,7 @@ ### 2.3 workspace_members 테이블 **컬럼**: id(UUID), workspace_id(FK), user_id(FK), role, robeing_id, robeing_url, is_active, joined_at, updated_at +**주의**: role 타입이 auth-server는 Enum(UserRole), robeing-gateway는 String(50) | 파일 경로 | 라인 번호 | 작업 내용 | |-----------|-----------|-----------| @@ -65,8 +66,8 @@ | robeing-gateway/app/models.py | 46-60 | 테이블 모델 정의 | ### 2.4 slack_user_mapping 테이블 -**컬럼**: slack_user_id, slack_workspace_id, user_id -**주의**: (slack_user_id, slack_workspace_id) 조합이 고유 키 +**컬럼**: slack_user_id, slack_workspace_id, user_id, created_at, updated_at +**제약조건**: UNIQUE(slack_user_id, slack_workspace_id), FK(user_id → users.id), FK(slack_workspace_id → slack_workspaces.id) | 파일 경로 | 라인 번호 | 작업 내용 | |-----------|-----------|-----------| @@ -87,7 +88,8 @@ | robeing-gateway/app/main.py | 567-570 | SELECT bot_token FROM slack_workspaces WHERE team_id = $1 | ### 2.6 gmail_tokens 테이블 -**컬럼**: id, user_id, slack_user_id, robeing_id, access_token, refresh_token, oauth_config, scopes, expiry, is_equipped, equipped_to, created_at, updated_at +**컬럼**: id, user_id, username, slack_user_id, robeing_id, token_data(JSON), access_token, refresh_token, oauth_config, scopes, expiry, is_equipped, equipped_to, created_at, updated_at +**주의**: token_data(JSON) 컬럼과 개별 토큰 컬럼(access_token, refresh_token)이 병행 사용 중 | 파일 경로 | 라인 번호 | 작업 내용 | |-----------|-----------|-----------| @@ -206,11 +208,16 @@ 1. **다중 라이브러리 사용**: SQLAlchemy, asyncpg, psycopg2를 혼용하고 있어 일관성 있는 수정 필요 2. **UUID 처리**: 일부는 문자열로, 일부는 UUID 타입으로 처리 -3. **JSON 컬럼**: preferences, scopes, oauth_config 등 JSON 타입 컬럼 처리 주의 +3. **JSON 컬럼**: preferences, scopes, oauth_config, token_data 등 JSON 타입 컬럼 처리 주의 4. **외래키 관계**: workspace_members의 workspace_id, user_id FK 관계 유지 5. **gen_random_uuid()**: PostgreSQL 함수 사용 부분 확인 필요 -6. **모델 불일치**: 같은 테이블에 대한 서로 다른 모델 정의 (users의 picture vs avatar_url, conversation_logs의 slack_user_id 유무) +6. **모델 불일치 - 심각**: + - users: picture vs avatar_url, oauth_provider/oauth_id vs provider/provider_id + - workspace_members: role이 Enum vs String(50) + - conversation_logs: slack_user_id 유무 + - gmail_tokens: token_data(JSON) vs 개별 컬럼 병행 7. **마이그레이션 충돌**: slack_workspaces의 company_id → workspace_id 변경이 모델과 불일치 +8. **복합 고유키**: slack_user_mapping의 (slack_user_id, slack_workspace_id) 조합 처리 ## 5. 작업 우선순위 From a12aa2c6eb7ab59ece2b6f161e441120ede86a0f Mon Sep 17 00:00:00 2001 From: happybell80 Date: Wed, 10 Sep 2025 23:35:35 +0900 Subject: [PATCH 3/3] =?UTF-8?q?docs:=20PostgreSQL=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=EB=B3=80=EA=B2=BD=20=EC=9E=91=EC=97=85=20=EC=A7=84?= =?UTF-8?q?=ED=96=89=20=EC=83=81=ED=99=A9=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - auth-server 완료 - robeing-gateway 완료 --- .../250910_happybell80_PostgreSQL_테이블_변경_계획.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/300_architecture/plans/250910_happybell80_PostgreSQL_테이블_변경_계획.md b/300_architecture/plans/250910_happybell80_PostgreSQL_테이블_변경_계획.md index afa3f8f..218f056 100644 --- a/300_architecture/plans/250910_happybell80_PostgreSQL_테이블_변경_계획.md +++ b/300_architecture/plans/250910_happybell80_PostgreSQL_테이블_변경_계획.md @@ -190,11 +190,11 @@ - [ ] API 응답 필드명 확인 ### 3.3 저장소별 작업 -- [ ] auth-server: SQLAlchemy 모델 + asyncpg 쿼리 수정 +- [x] auth-server: SQLAlchemy 모델 + asyncpg 쿼리 수정 - [ ] rb8001: SQLAlchemy 모델 + text() 쿼리 수정 - [ ] rb10508_micro: asyncpg 직접 쿼리 수정 - [ ] frontend-base: asyncpg 직접 쿼리 수정 -- [ ] robeing-gateway: SQLAlchemy 모델 + asyncpg 쿼리 수정 +- [x] robeing-gateway: SQLAlchemy 모델 + asyncpg 쿼리 수정 - [ ] robeing-monitor: SQLAlchemy 모델 + asyncpg 쿼리 수정 - [ ] skill-email: psycopg2 쿼리 수정