diff --git a/300_architecture/310_전체_시스템_구조_컨테이너와_마이크로서비스.md b/300_architecture/310_전체_시스템_구조_컨테이너와_마이크로서비스.md index 501d363..72b4edc 100644 --- a/300_architecture/310_전체_시스템_구조_컨테이너와_마이크로서비스.md +++ b/300_architecture/310_전체_시스템_구조_컨테이너와_마이크로서비스.md @@ -91,7 +91,7 @@ users: id(UUID), username, email, name, created_at -- Gmail 토큰 (아이템) -gmail_tokens: id, user_id, email, is_equipped, equipped_to +gmail_token: id, user_id, email, is_equipped, equipped_to -- Gmail 감사 로그 gmail_audit_logs: id, user_id, robeing_id, action, created_at diff --git a/300_architecture/320_Slack_기반_인터페이스_설계.md b/300_architecture/320_Slack_기반_인터페이스_설계.md index 84e3493..065c9c3 100644 --- a/300_architecture/320_Slack_기반_인터페이스_설계.md +++ b/300_architecture/320_Slack_기반_인터페이스_설계.md @@ -213,7 +213,7 @@ async def show_typing(channel: str): -- 대신 users 테이블에서 직접 관리 -- 대화 로그 -CREATE TABLE conversation_logs ( +CREATE TABLE conversation_log ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID, -- slack_user_mapping에서 조회한 UUID robeing_id VARCHAR(50), diff --git a/300_architecture/380_authentication_system.md b/300_architecture/380_authentication_system.md index 6a120d6..31a5a3c 100644 --- a/300_architecture/380_authentication_system.md +++ b/300_architecture/380_authentication_system.md @@ -61,7 +61,7 @@ - PRIMARY KEY (slack_user_id, slack_workspace_id) ``` -#### gmail_tokens 테이블 +#### gmail_token 테이블 ```sql - id: UUID - user_id: UUID (FK → users.id) @@ -114,7 +114,7 @@ sequenceDiagram - Slack도 임시 코드 방식으로 맞춤 2. **DB 스키마 불일치** - - companies vs workspaces 테이블 공존 + - company vs workspaces 테이블 공존 - relationship 주석 처리 3. **하드코딩된 값** @@ -138,7 +138,7 @@ sequenceDiagram ### 특징 - **원페이지 복귀**: OAuth 인증 후 원래 있던 페이지로 자동 복귀 - **상태 관리**: state 파라미터에 return_url 포함하여 전달 -- **토큰 저장**: gmail_tokens 테이블에 암호화 저장 +- **토큰 저장**: gmail_token 테이블에 암호화 저장 ## 보안 고려사항 @@ -185,7 +185,7 @@ DATABASE_URL=postgresql://robeings:password@localhost/main_db ## 향후 개선 계획 ### 단기 (1-2주) -1. DB 스키마 통일 (companies → workspaces) +1. DB 스키마 통일 (company → workspaces) 2. Frontend 인증 방식 통일 3. 환경변수 정리 diff --git a/300_architecture/database/250820_postgresql_ssh_tunnel_guide.md b/300_architecture/database/250820_postgresql_ssh_tunnel_guide.md index 99d16bf..3c92c3e 100644 --- a/300_architecture/database/250820_postgresql_ssh_tunnel_guide.md +++ b/300_architecture/database/250820_postgresql_ssh_tunnel_guide.md @@ -83,7 +83,7 @@ psql -h localhost -p 5432 -U robeings -d main_db \dt -- 특정 테이블 구조 보기 -\d gmail_tokens +\d gmail_token \d users -- 데이터베이스 목록 @@ -160,9 +160,9 @@ CREATE TABLE users ( ); ``` -### 2. gmail_tokens 테이블 +### 2. gmail_token 테이블 ```sql -CREATE TABLE gmail_tokens ( +CREATE TABLE gmail_token ( id SERIAL PRIMARY KEY, user_id UUID REFERENCES users(id), slack_id VARCHAR(100), -- Slack 사용자 ID (새로 추가) @@ -184,9 +184,9 @@ CREATE TABLE gmail_tokens ( ); ``` -### 3. conversation_logs 테이블 +### 3. conversation_log 테이블 ```sql -CREATE TABLE conversation_logs ( +CREATE TABLE conversation_log ( id SERIAL PRIMARY KEY, robeing_id VARCHAR, channel_id VARCHAR, @@ -235,7 +235,7 @@ query = """ g.robeing_id, g.token_data, g.scopes - FROM gmail_tokens g + FROM gmail_token g JOIN users u ON g.user_id = u.id ORDER BY g.created_at DESC """ @@ -308,7 +308,7 @@ def add_gmail_token(slack_user_id, email, access_token, refresh_token): ON CONFLICT (id) DO UPDATE SET email = EXCLUDED.email """, (user_uuid, email, slack_user_id)) - # 2. gmail_tokens 추가 또는 업데이트 + # 2. gmail_token 추가 또는 업데이트 token_data = { "access_token": access_token, "refresh_token": refresh_token, @@ -316,7 +316,7 @@ def add_gmail_token(slack_user_id, email, access_token, refresh_token): } cur.execute(""" - INSERT INTO gmail_tokens (user_id, token_data, is_equipped, robeing_id, created_at) + INSERT INTO gmail_token (user_id, token_data, is_equipped, robeing_id, created_at) VALUES (%s, %s::jsonb, true, 'rb8001', NOW()) ON CONFLICT (user_id) DO UPDATE SET token_data = EXCLUDED.token_data, diff --git a/300_architecture/database/README.md b/300_architecture/database/README.md index f3041a3..2910c32 100644 --- a/300_architecture/database/README.md +++ b/300_architecture/database/README.md @@ -42,8 +42,8 @@ psql postgresql://robeings:robeings@localhost:5433/main_db ``` ## 최근 변경사항 -- 2025-08-26: conversation_logs에 slack_user_id 추가 -- 2025-08-23: gmail_tokens 구조 변경 +- 2025-08-26: conversation_log에 slack_user_id 추가 +- 2025-08-23: gmail_token 구조 변경 - 2025-08-20: auth_db → main_db 마이그레이션 ## 최종 업데이트 diff --git a/300_architecture/database/relationships.md b/300_architecture/database/relationships.md index ab4a8af..45cdaae 100644 --- a/300_architecture/database/relationships.md +++ b/300_architecture/database/relationships.md @@ -8,22 +8,22 @@ ```mermaid erDiagram - users ||--o{ workspace_members : "has many" + users ||--o{ workspace_member : "has many" users ||--o{ slack_user_mapping : "has many" - users ||--o{ gmail_tokens : "has" + users ||--o{ gmail_token : "has" users ||--o{ robeing_stats : "has" - users ||--o{ conversation_logs : "has many" + users ||--o{ conversation_log : "has many" - workspaces ||--o{ workspace_members : "has many" - workspaces }o--|| companies : "belongs to" + workspaces ||--o{ workspace_member : "has many" + workspaces }o--|| company : "belongs to" slack_workspaces ||--o{ slack_user_mapping : "has many" - workspace_members ||--o{ slack_user_mapping : "references" + workspace_member ||--o{ slack_user_mapping : "references" - gmail_tokens }o--|| users : "belongs to" + gmail_token }o--|| users : "belongs to" robeing_stats }o--|| users : "belongs to" - conversation_logs }o--|| users : "belongs to" + conversation_log }o--|| users : "belongs to" ``` --- @@ -32,11 +32,11 @@ erDiagram ### 1. User 중심 관계 ``` -users (1) ─────┬──── (*) workspace_members +users (1) ─────┬──── (*) workspace_member ├──── (*) slack_user_mapping - ├──── (0..1) gmail_tokens + ├──── (0..1) gmail_token ├──── (0..1) robeing_stats - └──── (*) conversation_logs + └──── (*) conversation_log ``` - 한 사용자는 여러 워크스페이스의 멤버가 될 수 있음 @@ -47,8 +47,8 @@ users (1) ─────┬──── (*) workspace_members ### 2. Workspace 관계 ``` -companies (1) ──── (*) workspaces -workspaces (1) ──── (*) workspace_members +company (1) ──── (*) workspaces +workspaces (1) ──── (*) workspace_member ``` - 한 회사는 여러 워크스페이스를 가질 수 있음 @@ -58,11 +58,11 @@ workspaces (1) ──── (*) workspace_members ``` slack_workspaces (1) ──── (*) slack_user_mapping slack_user_mapping (*) ──── (1) users -slack_user_mapping (*) ──── (0..1) workspace_members +slack_user_mapping (*) ──── (0..1) workspace_member ``` - Slack 사용자 ID를 시스템 UUID로 변환하는 브릿지 역할 -- workspace_members와 선택적 연결 +- workspace_member와 선택적 연결 --- @@ -79,9 +79,9 @@ SELECT sum.slack_user_id, gt.is_equipped as gmail_equipped FROM users u -LEFT JOIN workspace_members wm ON u.id = wm.user_id +LEFT JOIN workspace_member wm ON u.id = wm.user_id LEFT JOIN slack_user_mapping sum ON u.id = sum.user_id -LEFT JOIN gmail_tokens gt ON u.id = gt.user_id +LEFT JOIN gmail_token gt ON u.id = gt.user_id WHERE u.username = 'happybell80'; ``` @@ -108,7 +108,7 @@ SELECT rs.level, gt.scopes FROM users u -JOIN gmail_tokens gt ON u.id = gt.user_id +JOIN gmail_token gt ON u.id = gt.user_id LEFT JOIN robeing_stats rs ON u.id = rs.user_id WHERE gt.is_equipped = true; ``` @@ -122,7 +122,7 @@ SELECT wm.role, wm.robeing_id FROM workspaces w -JOIN workspace_members wm ON w.id = wm.workspace_id +JOIN workspace_member wm ON w.id = wm.workspace_id JOIN users u ON wm.user_id = u.id WHERE w.name = 'Ivada Robeing'; ``` @@ -148,7 +148,7 @@ user_id (UUID) 획득 ``` User 요청 ↓ -user_id (UUID)로 gmail_tokens 조회 +user_id (UUID)로 gmail_token 조회 ↓ is_equipped 확인 ↓ @@ -202,10 +202,10 @@ BEGIN; SELECT level FROM robeing_stats WHERE user_id = ?; -- 2. 소유권 확인 -SELECT id FROM gmail_tokens WHERE user_id = ?; +SELECT id FROM gmail_token WHERE user_id = ?; -- 3. 장착 처리 -UPDATE gmail_tokens +UPDATE gmail_token SET is_equipped = true, equipped_to = ? WHERE user_id = ?; @@ -223,8 +223,8 @@ BEGIN; INSERT INTO users (id, email, name, username) VALUES (?, ?, ?, ?); --- 2. workspace_members 추가 -INSERT INTO workspace_members (user_id, workspace_id, role) +-- 2. workspace_member 추가 +INSERT INTO workspace_member (user_id, workspace_id, role) VALUES (?, ?, 'member'); -- 3. robeing_stats 초기화 diff --git a/300_architecture/sequences/auth_login_sequences.md b/300_architecture/sequences/auth_login_sequences.md index 7561b0d..bc23fb5 100644 --- a/300_architecture/sequences/auth_login_sequences.md +++ b/300_architecture/sequences/auth_login_sequences.md @@ -315,7 +315,7 @@ stateDiagram-v2 - username (사용자 정의 또는 자동 생성) 관계: - - users.id (UUID) ← gmail_tokens.user_id + - users.id (UUID) ← gmail_token.user_id - users.id (UUID) ← slack_user_mapping.user_id - users.id (UUID) ← robeing_stats.user_id diff --git a/300_architecture/sequences/chat_history_flow.md b/300_architecture/sequences/chat_history_flow.md index 40ebf5b..09d2bc2 100644 --- a/300_architecture/sequences/chat_history_flow.md +++ b/300_architecture/sequences/chat_history_flow.md @@ -20,10 +20,10 @@ sequenceDiagram F->>G: GET /gateway/api/history?limit=30
Authorization: Bearer {JWT} G->>G: JWT 검증 (서명, 만료시간) G->>G: JWT에서 sub(UUID) 추출 - G->>G: workspace_members 테이블 조회
robeing_id 확인 (rb8001) + G->>G: workspace_member 테이블 조회
robeing_id 확인 (rb8001) G->>R: GET /api/history?limit=30
Authorization: Bearer {JWT}
X-User-Id: {UUID} R->>R: JWT 검증 및 user_id 추출 - R->>DB: SELECT * FROM conversation_logs
WHERE user_id = (:user_id)::uuid + R->>DB: SELECT * FROM conversation_log
WHERE user_id = (:user_id)::uuid DB-->>R: 대화 기록 반환 R->>R: DB row를 Frontend 형식으로 변환
(user/robeing 메시지 분리) R-->>G: {"messages": [...], "has_more": true} @@ -66,8 +66,8 @@ def verify_jwt_token(token: str): ### 3.2 robeing 라우팅 ```python -# workspace_members 테이블 조회 -SELECT robeing_id FROM workspace_members +# workspace_member 테이블 조회 +SELECT robeing_id FROM workspace_member WHERE user_id = :user_id # 결과: rb8001 또는 rb10508_micro @@ -100,7 +100,7 @@ async def get_current_user(authorization: str = Header(None)): async def get_paginated_conversations(user_id: str, before: float = None, limit: int = 30): query = """ SELECT id, message, response, timestamp - FROM conversation_logs + FROM conversation_log WHERE user_id = (:user_id)::uuid AND robeing_id = 'rb8001' AND (:before::timestamp IS NULL OR timestamp < :before) @@ -175,18 +175,18 @@ CREATE TABLE users ( ); ``` -### 6.2 workspace_members 테이블 +### 6.2 workspace_member 테이블 ```sql -CREATE TABLE workspace_members ( +CREATE TABLE workspace_member ( user_id UUID REFERENCES users(id), workspace_id UUID, robeing_id VARCHAR(50) -- rb8001, rb10508_micro 등 ); ``` -### 6.3 conversation_logs 테이블 +### 6.3 conversation_log 테이블 ```sql -CREATE TABLE conversation_logs ( +CREATE TABLE conversation_log ( id INTEGER PRIMARY KEY, robeing_id VARCHAR, message VARCHAR, diff --git a/300_architecture/sequences/daily_briefing_sequences.md b/300_architecture/sequences/daily_briefing_sequences.md index 960a554..02e5d56 100644 --- a/300_architecture/sequences/daily_briefing_sequences.md +++ b/300_architecture/sequences/daily_briefing_sequences.md @@ -64,13 +64,13 @@ sequenceDiagram DM->>Email: GET /messages
?user_id={slack_id}
&limit=5
&query=category:primary %% 토큰 체크 및 갱신 - Email->>DB: SELECT * FROM gmail_tokens
WHERE user_id = ? + Email->>DB: SELECT * FROM gmail_token
WHERE user_id = ? DB-->>Email: token_data, refresh_token alt 토큰 만료 Email->>Auth: POST /api/gmail/refresh
Body: {user_id, refresh_token} Auth->>Auth: Google OAuth 토큰 갱신 - Auth->>DB: UPDATE gmail_tokens + Auth->>DB: UPDATE gmail_token Auth-->>Email: 새 access_token end @@ -127,7 +127,7 @@ sequenceDiagram rect rgb(255, 230, 230) Note over DM,Email: 이메일 수집 실패 DM->>Email: GET /messages - Email->>DB: SELECT gmail_tokens + Email->>DB: SELECT gmail_token DB-->>Email: token_data: NULL ❌ Email-->>DM: 500 Internal Server Error Note over DM: 이메일 데이터 = [] @@ -199,7 +199,7 @@ docker logs rb8001 --tail 100 | grep daily-summary docker logs skill-email --tail 50 | grep ERROR # DB 토큰 상태 -psql -U robeings -d main_db -c "SELECT user_id, token_data IS NOT NULL as has_token FROM gmail_tokens;" +psql -U robeings -d main_db -c "SELECT user_id, token_data IS NOT NULL as has_token FROM gmail_token;" ``` --- diff --git a/300_architecture/sequences/email_sequences.md b/300_architecture/sequences/email_sequences.md index f3c29aa..197b94a 100644 --- a/300_architecture/sequences/email_sequences.md +++ b/300_architecture/sequences/email_sequences.md @@ -53,7 +53,7 @@ sequenceDiagram Auth->>Google: 토큰 교환 요청 Google-->>Auth: access_token, refresh_token - Auth->>DB: gmail_tokens 테이블 저장 + Auth->>DB: gmail_token 테이블 저장 Note over DB: user_id, email,
tokens (암호화),
scopes, metadata Auth->>Auth: 리다이렉트 URL 결정 @@ -121,7 +121,7 @@ sequenceDiagram Gateway->>Monitor: 아이템 목록 요청 Note over Monitor: X-User-Id 헤더로
UUID 전달 - Monitor->>DB: gmail_tokens 조회 + Monitor->>DB: gmail_token 조회 Note over DB: user_id로 필터링 Monitor->>DB: robeing_stats 조회 @@ -153,7 +153,7 @@ sequenceDiagram Gateway-->>Front: 레벨 부족 에러 Front->>Front: "레벨 5가 되면
사용 가능해요!" 표시 else 레벨 >= 5 - Monitor->>DB: gmail_tokens 업데이트 + Monitor->>DB: gmail_token 업데이트 Note over DB: is_equipped = true
equipped_to = "rb10508_micro" Monitor->>DB: gmail_audit_logs 기록 @@ -203,7 +203,7 @@ sequenceDiagram RB->>Monitor: GET /api/items/gmail/status Note over Monitor: 장착 상태 확인 - Monitor->>DB: gmail_tokens 조회 + Monitor->>DB: gmail_token 조회 DB-->>Monitor: 장착 정보 alt Gmail 아이템 미장착 @@ -216,7 +216,7 @@ sequenceDiagram RB->>Skill: POST /send-email Note over Skill: user_id, to,
subject, body - Skill->>DB: gmail_tokens 조회 + Skill->>DB: gmail_token 조회 Note over DB: user_id와 is_equipped 확인 DB-->>Skill: access_token (복호화) @@ -232,7 +232,7 @@ sequenceDiagram Gmail-->>Skill: 발송 성공 (message_id) Skill->>DB: 발송 로그 저장 - Note over DB: conversation_logs 또는
email_send_history + Note over DB: conversation_log 또는
email_send_history Skill-->>RB: 발송 결과 RB->>DB: robeing_stats 경험치 증가 @@ -273,7 +273,7 @@ sequenceDiagram DB-->>RB: user_id, name: "김종태" RB->>Monitor: Gmail 아이템 상태 확인 - Monitor->>DB: gmail_tokens 조회 + Monitor->>DB: gmail_token 조회 alt 아이템 미장착 DB-->>Monitor: is_equipped = false @@ -293,7 +293,7 @@ sequenceDiagram RB->>Skill: POST /send-email Note over Skill: to: goeun2dc@gmail.com
subject: "회의 일정 안내"
body: LLM 생성 내용 - Skill->>DB: gmail_tokens 조회 + Skill->>DB: gmail_token 조회 DB-->>Skill: access_token Skill->>Gmail: 이메일 발송 @@ -302,7 +302,7 @@ sequenceDiagram Skill-->>RB: 발송 완료 RB->>DB: 대화 로그 저장 - Note over DB: conversation_logs에
이메일 발송 기록 + Note over DB: conversation_log에
이메일 발송 기록 RB-->>Slack: "종태님께 회의 일정 메일을
발송했습니다." end @@ -345,7 +345,7 @@ sequenceDiagram Auth->>Google: 토큰 교환 Google-->>Auth: 새 access_token, refresh_token - Auth->>DB: gmail_tokens 업데이트 + Auth->>DB: gmail_token 업데이트 Note over DB: 새 토큰으로 교체
updated_at 갱신 Auth->>DB: gmail_audit_logs 기록 @@ -372,7 +372,7 @@ sequenceDiagram Slack->>RB: 이메일 요청 RB->>Monitor: Gmail 아이템 확인 - Monitor->>DB: gmail_tokens 조회 + Monitor->>DB: gmail_token 조회 DB-->>Monitor: 결과 @@ -417,7 +417,7 @@ sequenceDiagram RB->>Skill: GET /list-emails Note over Skill: maxResults: 10
q: "is:unread" - Skill->>DB: gmail_tokens 조회 + Skill->>DB: gmail_token 조회 DB-->>Skill: access_token Skill->>Gmail: GET /gmail/v1/users/me/messages @@ -510,7 +510,7 @@ sequenceDiagram ## 데이터베이스 테이블 -### gmail_tokens +### gmail_token - id: UUID - user_id: UUID (users 테이블 참조) - robeing_id: VARCHAR (통일된 컬럼명) diff --git a/300_architecture/sequences/items_sequences.md b/300_architecture/sequences/items_sequences.md index 7b9ef64..f5a46cb 100644 --- a/300_architecture/sequences/items_sequences.md +++ b/300_architecture/sequences/items_sequences.md @@ -41,7 +41,7 @@ graph TB subgraph Database PG[(PostgreSQL)] - GT[gmail_tokens] + GT[gmail_token] RS[robeing_stats] end @@ -87,7 +87,7 @@ sequenceDiagram Note over Gateway: JWT 토큰 검증 Gateway->>Monitor: GET /api/items/gmail
Header: X-User-Id - Monitor->>DB: SELECT * FROM gmail_tokens
WHERE user_id = ? + Monitor->>DB: SELECT * FROM gmail_token
WHERE user_id = ? DB-->>Monitor: 토큰 데이터 Monitor->>Monitor: 아이템 상태 계산 @@ -152,7 +152,7 @@ sequenceDiagram Auth->>Google: 코드 → 토큰 교환 Google-->>Auth: Access Token + Refresh Token - Auth->>DB: INSERT INTO gmail_tokens + Auth->>DB: INSERT INTO gmail_token Note over DB: token_data, scopes,
metadata (email 등) Auth->>Front: 리다이렉트 /inventory?success=true @@ -192,7 +192,7 @@ sequenceDiagram Monitor->>DB: 토큰 소유권 확인 DB-->>Monitor: 토큰 존재 확인 - Monitor->>DB: UPDATE gmail_tokens
SET is_equipped = true,
equipped_to = 'rb10508_micro' + Monitor->>DB: UPDATE gmail_token
SET is_equipped = true,
equipped_to = 'rb10508_micro' DB-->>Monitor: 업데이트 완료 Monitor->>DB: INSERT INTO gmail_audit_logs @@ -222,11 +222,11 @@ sequenceDiagram DB-->>Monitor: level: 3 Monitor-->>Front: {error: "레벨 5 이상 필요"} else 토큰 없음 - Monitor->>DB: SELECT * FROM gmail_tokens + Monitor->>DB: SELECT * FROM gmail_token DB-->>Monitor: null Monitor-->>Front: {error: "Gmail 연결 필요"} else 이미 장착됨 - Monitor->>DB: SELECT is_equipped FROM gmail_tokens + Monitor->>DB: SELECT is_equipped FROM gmail_token DB-->>Monitor: is_equipped: true Monitor-->>Front: {error: "이미 장착됨"} end @@ -254,7 +254,7 @@ sequenceDiagram RB->>Monitor: GET /api/items/gmail Note over Monitor: Header: X-User-Id - Monitor->>DB: SELECT * FROM gmail_tokens
WHERE user_id = ? + Monitor->>DB: SELECT * FROM gmail_token
WHERE user_id = ? DB-->>Monitor: 토큰 데이터 Monitor-->>RB: {equipped: {is_equipped: true,
capabilities: {send: true, read: true}}} @@ -263,7 +263,7 @@ sequenceDiagram RB->>SE: POST /process Note over SE: message: "최근 이메일 확인" - SE->>DB: SELECT token_data FROM gmail_tokens + SE->>DB: SELECT token_data FROM gmail_token DB-->>SE: OAuth 토큰 SE->>SE: Gmail API 호출 @@ -314,7 +314,7 @@ sequenceDiagram User->>Front: "해제" 버튼 클릭 Front->>Monitor: POST /api/items/gmail/{userId}/unequip - Monitor->>DB: UPDATE gmail_tokens
SET is_equipped = false,
equipped_to = null + Monitor->>DB: UPDATE gmail_token
SET is_equipped = false,
equipped_to = null DB-->>Monitor: 업데이트 완료 Monitor->>DB: INSERT INTO gmail_audit_logs @@ -367,7 +367,7 @@ sequenceDiagram Note over Front: 페이지 새로고침 Front->>Monitor: GET /api/items/gmail - Monitor->>DB: SELECT * FROM gmail_tokens + Monitor->>DB: SELECT * FROM gmail_token DB-->>Monitor: is_equipped: true Monitor-->>Front: 장착 상태 반환 @@ -384,14 +384,14 @@ sequenceDiagram participant Auth as auth-server participant Google as Google OAuth - SE->>DB: SELECT token_data FROM gmail_tokens + SE->>DB: SELECT token_data FROM gmail_token DB-->>SE: 토큰 (만료됨) SE->>Auth: 토큰 갱신 요청 Auth->>Google: Refresh Token 사용 Google-->>Auth: 새 Access Token - Auth->>DB: UPDATE gmail_tokens
SET token_data = ? + Auth->>DB: UPDATE gmail_token
SET token_data = ? DB-->>Auth: 업데이트 완료 Auth-->>SE: 새 토큰 diff --git a/300_architecture/uuid_conversion_system.md b/300_architecture/uuid_conversion_system.md index 9c1963c..8668650 100644 --- a/300_architecture/uuid_conversion_system.md +++ b/300_architecture/uuid_conversion_system.md @@ -221,20 +221,20 @@ for slack_id, name in slack_ids.items(): ```sql -- 1. 임시 컬럼 추가 -ALTER TABLE gmail_tokens ADD COLUMN user_uuid UUID; +ALTER TABLE gmail_token ADD COLUMN user_uuid UUID; -- 2. UUID 매핑 -UPDATE gmail_tokens gt +UPDATE gmail_token gt SET user_uuid = u.id FROM users u WHERE gt.user_id = u.username; -- 3. 기존 컬럼 제거 및 이름 변경 -ALTER TABLE gmail_tokens DROP COLUMN user_id; -ALTER TABLE gmail_tokens RENAME COLUMN user_uuid TO user_id; +ALTER TABLE gmail_token DROP COLUMN user_id; +ALTER TABLE gmail_token RENAME COLUMN user_uuid TO user_id; -- 4. 외래키 제약 추가 -ALTER TABLE gmail_tokens +ALTER TABLE gmail_token ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users(id); ``` diff --git a/_archive/docs/architecture/auth-server-database-schema.md b/_archive/docs/architecture/auth-server-database-schema.md index 3e00e69..e4af3b5 100644 --- a/_archive/docs/architecture/auth-server-database-schema.md +++ b/_archive/docs/architecture/auth-server-database-schema.md @@ -10,10 +10,10 @@ auth-server는 개별 사용자 인증보다는 **회사별 Slack 봇 인증 및 ## 테이블 구조 -### 1. companies (회사/조직 관리) +### 1. company (회사/조직 관리) ```sql -CREATE TABLE companies ( +CREATE TABLE company ( id uuid PRIMARY KEY, name varchar(255) NOT NULL, subdomain varchar(100) NOT NULL UNIQUE, @@ -41,7 +41,7 @@ CREATE TABLE companies ( ```sql CREATE TABLE slack_workspaces ( id uuid PRIMARY KEY, - company_id uuid NOT NULL REFERENCES companies(id), + company_id uuid NOT NULL REFERENCES company(id), team_id varchar(100) NOT NULL UNIQUE, team_name varchar(255), bot_token text, @@ -71,7 +71,7 @@ CREATE TABLE slack_workspaces ( **인덱스**: - Primary Key: `id` - Unique: `team_id` -- Foreign Key: `company_id` → `companies(id)` +- Foreign Key: `company_id` → `company(id)` ## 현재 데이터 현황 diff --git a/_archive/docs/architecture/frontend-architecture-strategy.md b/_archive/docs/architecture/frontend-architecture-strategy.md index 95d11af..519b5b2 100644 --- a/_archive/docs/architecture/frontend-architecture-strategy.md +++ b/_archive/docs/architecture/frontend-architecture-strategy.md @@ -88,7 +88,7 @@ ```sql -- PostgreSQL@51123:5432 ├── main_db (기존) -│ ├── companies +│ ├── company │ └── slack_workspaces │ └── robbing_db (신규 제안) @@ -117,7 +117,7 @@ WS /ws/robbing/realtime # 실시간 상태 업데이트 **위치**: auth-server 내장 또는 별도 React 앱 **데이터 저장**: -- 회사 정보: PostgreSQL `main_db.companies` +- 회사 정보: PostgreSQL `main_db.company` - 세션 관리: JWT 토큰 - OAuth 토큰: 파일시스템 `/tokens/` diff --git a/_archive/docs/architecture/로빙_아키텍쳐_설계_경량.md b/_archive/docs/architecture/로빙_아키텍쳐_설계_경량.md index c3163c5..df71d10 100644 --- a/_archive/docs/architecture/로빙_아키텍쳐_설계_경량.md +++ b/_archive/docs/architecture/로빙_아키텍쳐_설계_경량.md @@ -119,7 +119,7 @@ async def level_up_user(user_id: str, stat: str, points: int): ```sql -- PostgreSQL 스키마 -CREATE TABLE companies ( +CREATE TABLE company ( id UUID PRIMARY KEY, name VARCHAR(255), slack_workspace_id VARCHAR(50) UNIQUE, @@ -132,7 +132,7 @@ CREATE TABLE companies ( CREATE TABLE users ( id UUID PRIMARY KEY, - company_id UUID REFERENCES companies(id), + company_id UUID REFERENCES company(id), slack_user_id VARCHAR(50), stats JSONB DEFAULT '{"연산": 0, "기억": 0, "공감": 0, "통솔": 0, "반응": 0}', level INTEGER DEFAULT 1, diff --git a/ideas/250810_auth_system_analysis.md b/ideas/250810_auth_system_analysis.md index 2c7083a..7419895 100644 --- a/ideas/250810_auth_system_analysis.md +++ b/ideas/250810_auth_system_analysis.md @@ -299,7 +299,7 @@ email ↔ slack_id ↔ username ##### 현재 테이블 구조 (5개) - **users**: 사용자 기본 정보 (email, username) - **workspaces**: 워크스페이스 정보 (로빙 할당) -- **workspace_members**: 사용자-워크스페이스 연결 +- **workspace_member**: 사용자-워크스페이스 연결 - **slack_workspaces**: Slack 워크스페이스 정보 - **slack_user_mapping**: Slack ID ↔ User ID 매핑 (3개만 존재) diff --git a/ideas/250812_claude_Slack_메시지_처리_아키텍처_분석.md b/ideas/250812_claude_Slack_메시지_처리_아키텍처_분석.md index 05cdc8c..0e3047f 100644 --- a/ideas/250812_claude_Slack_메시지_처리_아키텍처_분석.md +++ b/ideas/250812_claude_Slack_메시지_처리_아키텍처_분석.md @@ -298,16 +298,16 @@ class SlackItem(APIItem): - 워크스페이스 정보 (robeing_id, robeing_port, robeing_url 포함) - 현재 1개 워크스페이스: ivada-robeing (rb10508_micro 사용) -3. **workspace_members 테이블** +3. **workspace_member 테이블** - 사용자와 워크스페이스 연결 - robeing_id 필드로 각 멤버가 사용할 로빙 지정 가능 4. **slack_workspaces 테이블** - Slack 워크스페이스 정보 (team_id, bot_token, bot_user_id 등) - 2개 Slack 워크스페이스 등록됨 (GoodGang Labs, test) - - companies 테이블과 연결됨 + - company 테이블과 연결됨 -5. **companies 테이블** +5. **company 테이블** - 회사 정보 관리 - slack_workspaces와 1:N 관계 @@ -329,7 +329,7 @@ CREATE TABLE slack_user_mapping ( slack_user_id VARCHAR(100) NOT NULL, slack_workspace_id INTEGER REFERENCES slack_workspaces(id), user_id UUID REFERENCES users(id), - workspace_member_id UUID REFERENCES workspace_members(id), + workspace_member_id UUID REFERENCES workspace_member(id), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(slack_user_id, slack_workspace_id) @@ -345,7 +345,7 @@ slack_user_mapping 조회 ↓ user_id 획득 ↓ -workspace_members에서 robeing_id 확인 +workspace_member에서 robeing_id 확인 ↓ 해당 로빙으로 라우팅 ↓ diff --git a/ideas/250818_conversation_logs_및_robing_stats_활용_계획.md b/ideas/250818_conversation_logs_및_robing_stats_활용_계획.md index 4e15e3c..0a39749 100644 --- a/ideas/250818_conversation_logs_및_robing_stats_활용_계획.md +++ b/ideas/250818_conversation_logs_및_robing_stats_활용_계획.md @@ -1,4 +1,4 @@ -# conversation_logs 및 robeing_stats 테이블 활용 계획 +# conversation_log 및 robeing_stats 테이블 활용 계획 작성일: 2025년 8월 18일 작성자: Claude (51123 서버) @@ -9,7 +9,7 @@ ### 1.1 미사용 테이블 현황 ```sql -- main_db에 존재하지만 전혀 사용되지 않는 테이블들 -conversation_logs: 0 records (0 KB) +conversation_log: 0 records (0 KB) robeing_stats: 0 records (0 KB) robeing_settings: 0 records (0 KB) ``` @@ -25,11 +25,11 @@ robeing_settings: 0 records (0 KB) 3. **개인화 불가**: 사용자별 설정이 저장되지 않음 4. **분석 불가**: 사용 패턴, 성능 지표 추적 불가 -## 2. conversation_logs 테이블 활용 방안 +## 2. conversation_log 테이블 활용 방안 ### 2.1 테이블 구조 (현재) ```sql -CREATE TABLE conversation_logs ( +CREATE TABLE conversation_log ( id INTEGER PRIMARY KEY (auto-increment), robeing_id VARCHAR, channel_id VARCHAR, @@ -70,7 +70,7 @@ class ConversationLogger: """대화 내용을 DB에 저장""" async with asyncpg.connect(self.db_url) as conn: await conn.execute(""" - INSERT INTO conversation_logs + INSERT INTO conversation_log (id, robeing_id, user_id, message, response, created_at, metadata) VALUES ($1, $2, $3, $4, $5, $6, $7) """, @@ -307,7 +307,7 @@ skill_settings = { ## 5. 구현 우선순위 ### Phase 1: 즉시 구현 (1주일) -1. **conversation_logs 저장 기능** +1. **conversation_log 저장 기능** - 모든 대화를 DB에 저장 - 메타데이터 포함 (채널, 시간 등) @@ -337,12 +337,12 @@ skill_settings = { ### 6.1 인덱스 추가 필요 ```sql --- conversation_logs 빠른 조회 +-- conversation_log 빠른 조회 CREATE INDEX idx_conversation_user_time -ON conversation_logs(user_id, created_at DESC); +ON conversation_log(user_id, created_at DESC); CREATE INDEX idx_conversation_robeing_time -ON conversation_logs(robeing_id, created_at DESC); +ON conversation_log(robeing_id, created_at DESC); -- robeing_stats 빠른 조회 CREATE INDEX idx_robeing_stats_robeing @@ -363,7 +363,7 @@ ON robeing_stats(robeing_id); ```sql -- 일일 대화량 SELECT DATE(created_at), COUNT(*) -FROM conversation_logs +FROM conversation_log GROUP BY DATE(created_at); -- 로빙별 활동 @@ -396,7 +396,7 @@ FROM robeing_stats; ## 9. 주의사항 ### 9.1 개인정보 보호 -- conversation_logs에 민감 정보 마스킹 +- conversation_log에 민감 정보 마스킹 - GDPR 준수 (삭제 요청 처리) - 암호화 고려 diff --git a/ideas/250819_대화형_점진적_의도_구축_시스템.md b/ideas/250819_대화형_점진적_의도_구축_시스템.md index b77d9fc..09c7c05 100644 --- a/ideas/250819_대화형_점진적_의도_구축_시스템.md +++ b/ideas/250819_대화형_점진적_의도_구축_시스템.md @@ -217,7 +217,7 @@ flowchart TD ## 3.4 시간 인식 의도 처리 (신규 추가 2025-09-09) ### 3.4.1 실제 대화 로그 분석 결과 -2025년 9월 9일 PostgreSQL conversation_logs 테이블 분석 결과, 로빙의 가장 심각한 문제는 **시간 인식 부재**입니다. +2025년 9월 9일 PostgreSQL conversation_log 테이블 분석 결과, 로빙의 가장 심각한 문제는 **시간 인식 부재**입니다. ``` 실제 사례: @@ -250,7 +250,7 @@ CONTEXT_RETRIEVAL_PATTERNS = { # DB에서 과거 대화 조회 필수 if pattern_matches(CONTEXT_RETRIEVAL_PATTERNS): - past_logs = await fetch_conversation_logs( + past_logs = await fetch_conversation_log( user_id=user_id, time_range="-2 hours", limit=5 diff --git a/plans/000000_unresolved_items_matrix.md b/plans/000000_unresolved_items_matrix.md index 2fc3cf8..bd591a9 100644 --- a/plans/000000_unresolved_items_matrix.md +++ b/plans/000000_unresolved_items_matrix.md @@ -26,7 +26,7 @@ 1. **실시간 동기화** - WebSocket/폴링 미구현 (영향도 재평가 필요) (2주) [→250827](../troubleshooting/250827_frontend_backend_preferences_API_연동_완료.md) 2. **PKCE 적용** - OAuth 보안 강화 미구현 (1주) [→380](../300_architecture/380_authentication_system.md) 3. **Refresh Token** - 토큰 재발급 체계 미구현 (1주) [→380](../300_architecture/380_authentication_system.md) -4. **DB 스키마 통일** - companies→workspaces 미구현 (2주) [→250831](250831_todo_and_tech_debt.md) +4. **DB 스키마 통일** - company→workspaces 미구현 (2주) [→250831](250831_todo_and_tech_debt.md) 5. **스킬 라우팅 고도화** - Decision Engine 미구현 (3주) [→250811](../ideas/250811_claude_rb10408_vs_rb10508_비교분석.md) 6. **IntentAnalyzer 활성화** - 현재 미사용, LLM 기반 의도분석기 미연동 (1주) [→250914](../troubleshooting/250914_happybell80_IntentAnalyzer_미사용_문제.md) 7. **전역 ENV 감사** - 레포 전반 미사용/중복 ENV 정리 미구현 (2주) diff --git a/plans/250831_todo_and_tech_debt.md b/plans/250831_todo_and_tech_debt.md index f1b7493..a860cc8 100644 --- a/plans/250831_todo_and_tech_debt.md +++ b/plans/250831_todo_and_tech_debt.md @@ -16,12 +16,12 @@ ### 2. DB 스키마 불일치 **문제**: -- companies vs workspaces 테이블 공존 +- company vs workspaces 테이블 공존 - SlackWorkspace 모델 FK 오류 (company_id를 workspace_id로 참조) **해결 계획**: 1. 데이터 백업 -2. companies → workspaces 마이그레이션 +2. company → workspaces 마이그레이션 3. FK 관계 재설정 4. 모델 파일 통일 @@ -99,7 +99,7 @@ fetch('https://auth.ro-being.com/auth/verify') ## 체크리스트 - [ ] 하드코딩 URL 환경변수화 -- [ ] DB 스키마 통일 (companies → workspaces) +- [ ] DB 스키마 통일 (company → workspaces) - [ ] 임시 코드 방식 제거 - [ ] UserIdentityService 구현 - [ ] Refresh Token 구현 diff --git a/plans/250831_unified_id_system_implementation_roadmap.md b/plans/250831_unified_id_system_implementation_roadmap.md index 462b9ec..4305c64 100644 --- a/plans/250831_unified_id_system_implementation_roadmap.md +++ b/plans/250831_unified_id_system_implementation_roadmap.md @@ -50,9 +50,9 @@ SET user_uuid = ( AND sum.team_id = gp.team_id ); --- workspace_members UUID 확인 -ALTER TABLE workspace_members -ADD CONSTRAINT fk_workspace_members_user_id +-- workspace_member UUID 확인 +ALTER TABLE workspace_member +ADD CONSTRAINT fk_workspace_member_user_id FOREIGN KEY (user_id) REFERENCES users(id); ``` @@ -406,4 +406,4 @@ if not uuid_mapping: - [250828_slack_auth_integration_completed.md](../troubleshooting/250828_slack_auth_integration_completed.md) - [250828_slack_integration_level3_plan.md](./250828_slack_integration_level3_plan.md) -- [250828_conversation_logs_channel_구분_개선.md](../troubleshooting/250828_conversation_logs_channel_구분_개선.md) \ No newline at end of file +- [250828_conversation_log_channel_구분_개선.md](../troubleshooting/250828_conversation_log_channel_구분_개선.md) \ No newline at end of file diff --git a/plans/250831_workspace_unification_plan.md b/plans/250831_workspace_unification_plan.md index 170aac3..2d4bec7 100644 --- a/plans/250831_workspace_unification_plan.md +++ b/plans/250831_workspace_unification_plan.md @@ -3,21 +3,21 @@ ## 작성일: 2025년 8월 31일 ## 🎯 목표 -`companies` 테이블과 `workspaces` 테이블을 `workspaces`로 통합하여 DB 스키마 일관성 확보 +`company` 테이블과 `workspaces` 테이블을 `workspaces`로 통합하여 DB 스키마 일관성 확보 ## 📊 현재 상황 ### 테이블 구조 비교 -| 구분 | companies | workspaces | +| 구분 | company | workspaces | |------|-----------|------------| | **포트 컬럼** | `container_port` | `robeing_port` | -| **FK 참조** | `slack_workspaces.company_id` | `workspace_members.workspace_id` | +| **FK 참조** | `slack_workspaces.company_id` | `workspace_member.workspace_id` | | **추가 컬럼** | - | `robeing_id`, `robeing_url`, `max_members`, `workspace_type` | | **데이터** | 4개 레코드 | 2개 레코드 | ### 문제점 1. 중복 데이터 (Company-X가 양쪽 테이블에 존재) -2. FK 관계 불일치 (slack_workspaces → companies, workspace_members → workspaces) +2. FK 관계 불일치 (slack_workspaces → company, workspace_member → workspaces) 3. 코드에서 잘못된 참조 (`workspace.workspace`, `workspace.robeing_port`) ## 🔧 작업 계획 @@ -25,15 +25,15 @@ ### Phase 1: DB 백업 및 준비 ```bash # 백업 생성 -sudo -u postgres pg_dump -t companies -t workspaces -t slack_workspaces main_db > /home/admin/backup_workspace_$(date +%Y%m%d_%H%M%S).sql +sudo -u postgres pg_dump -t company -t workspaces -t slack_workspaces main_db > /home/admin/backup_workspace_$(date +%Y%m%d_%H%M%S).sql ``` ### Phase 2: DB 스키마 변경 ```sql --- 1. companies 데이터를 workspaces로 이동 +-- 1. company 데이터를 workspaces로 이동 INSERT INTO workspaces (id, name, subdomain, robeing_port, status, created_at, updated_at) SELECT id, name, subdomain, container_port, status, created_at, updated_at -FROM companies +FROM company WHERE id NOT IN (SELECT id FROM workspaces); -- 2. slack_workspaces 테이블 수정 @@ -48,8 +48,8 @@ ALTER TABLE slack_workspaces ADD CONSTRAINT slack_workspaces_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id); --- 3. companies 테이블 제거 -DROP TABLE companies CASCADE; +-- 3. company 테이블 제거 +DROP TABLE company CASCADE; ``` ### Phase 3: 코드 수정 @@ -123,7 +123,7 @@ curl -X POST https://auth.ro-being.com/slack/events/router \ ```bash cd /home/admin/auth-server git add -A -git commit -m "refactor: companies 테이블을 workspaces로 통합" +git commit -m "refactor: company 테이블을 workspaces로 통합" git push origin main ``` @@ -154,9 +154,9 @@ sudo -u postgres psql main_db < /home/admin/backup_workspace_YYYYMMDD_HHMMSS.sql ## 📝 체크리스트 - [ ] DB 백업 완료 -- [ ] companies → workspaces 데이터 이동 +- [ ] company → workspaces 데이터 이동 - [ ] slack_workspaces FK 변경 -- [ ] companies 테이블 삭제 +- [ ] company 테이블 삭제 - [ ] workspace.py 모델 수정 - [ ] slack_router.py 수정 - [ ] slack.py provider 수정 diff --git a/plans/250911_main_db3_migration_plan.md b/plans/250911_main_db3_migration_plan.md index e372782..1ac9eb2 100644 --- a/plans/250911_main_db3_migration_plan.md +++ b/plans/250911_main_db3_migration_plan.md @@ -9,7 +9,7 @@ ### main_db3 (삭제 예정) - 총 13개 테이블, 614개 레코드 -- 주요 데이터: users(17), companies(4), conversation_logs(555) +- 주요 데이터: users(17), company(4), conversation_log(555) - Slack/Gmail 연동 데이터 보유 ### main_db (운영 DB) @@ -22,14 +22,14 @@ | main_db3 | main_db | 비고 | |----------|---------|------| -| companies | company | 2개 중복 확인 필요 | +| company | company | 2개 중복 확인 필요 | | users | user | team_id 필수 추가 | | workspaces | team | 구조 변환 필요 | -| workspace_members | workspace_member | user_id 매핑 | +| workspace_member | workspace_member | user_id 매핑 | | slack_workspaces | slack_workspace | team_id 매핑 | | user_preferences | user_preference | slack_user_id 제거됨 | -| conversation_logs | conversation_log | robeing_id 컬럼 없음 | -| gmail_tokens | gmail_token | 구조 동일 | +| conversation_log | conversation_log | robeing_id 컬럼 없음 | +| gmail_token | gmail_token | 구조 동일 | | robeing_stats | robeing | product_id, team_id 추가 | | slack_user_mapping | - | workspace_member로 통합 | @@ -39,10 +39,10 @@ ### Phase 1: 조직 구조 (필수 선행) ```sql --- 1. companies → company (중복 제외) +-- 1. company → company (중복 제외) INSERT INTO company (id, name, url, created_at, updated_at) SELECT id, name, domain, created_at, updated_at -FROM main_db3.companies +FROM main_db3.company WHERE id NOT IN ('28f17b47-33f8-47ac-b1ae-100e77b37edb', '99d22d6b-d327-4fa4-bd2f-d228c11056e2'); -- 2. workspaces → team 변환 @@ -58,11 +58,11 @@ SELECT u.id, COALESCE(wm.workspace_id, '38bdc27d-cb01-4960-867e-41733d2f3529'), -- 기본 팀 u.email, u.name, u.username, u.oauth_provider, u.oauth_id, u.is_active FROM main_db3.users u -LEFT JOIN main_db3.workspace_members wm ON u.id = wm.user_id; +LEFT JOIN main_db3.workspace_member wm ON u.id = wm.user_id; --- 4. workspace_members → workspace_member (slack_user_id 추가 예정) +-- 4. workspace_member → workspace_member (slack_user_id 추가 예정) INSERT INTO workspace_member (id, user_id, role, is_active, joined_at) -SELECT id, user_id, role::user_role, is_active, joined_at FROM main_db3.workspace_members; +SELECT id, user_id, role::user_role, is_active, joined_at FROM main_db3.workspace_member; ``` ### Phase 3: 통합 데이터 @@ -75,16 +75,16 @@ SELECT id, workspace_id, team_id, bot_token, is_active FROM main_db3.slack_works INSERT INTO user_preference (user_id, news_keywords, email_filter, briefing_enabled) SELECT user_id, news_keywords, email_filter, briefing_enabled FROM main_db3.user_preferences; --- 7. gmail_tokens → gmail_token -INSERT INTO gmail_token SELECT * FROM main_db3.gmail_tokens; +-- 7. gmail_token → gmail_token +INSERT INTO gmail_token SELECT * FROM main_db3.gmail_token; ``` ### Phase 4: 대화 기록 ```sql --- 8. conversation_logs → conversation_log (컬럼 매핑 주의) +-- 8. conversation_log → conversation_log (컬럼 매핑 주의) INSERT INTO conversation_log (user_id, channel_id, message, response, intent, confidence, timestamp) SELECT user_id, channel_id, message, response, intent, confidence, timestamp -FROM main_db3.conversation_logs WHERE user_id IS NOT NULL; +FROM main_db3.conversation_log WHERE user_id IS NOT NULL; ``` --- diff --git a/plans/completed/250812_auth_db_테이블_단순화_방안.md b/plans/completed/250812_auth_db_테이블_단순화_방안.md index 268df28..a0a88fb 100644 --- a/plans/completed/250812_auth_db_테이블_단순화_방안.md +++ b/plans/completed/250812_auth_db_테이블_단순화_방안.md @@ -9,23 +9,23 @@ ### 1.1 현재 테이블 (5개) - **users**: 사용자 기본 정보 - **workspaces**: 워크스페이스 정보 (로빙 할당) -- **workspace_members**: 사용자-워크스페이스 연결 -- **companies**: 회사 정보 +- **workspace_member**: 사용자-워크스페이스 연결 +- **company**: 회사 정보 - **slack_workspaces**: Slack 워크스페이스 정보 ### 1.2 현재 구조의 문제점 #### 복잡도 문제 1. **과도한 관계 분리** - - companies ↔ slack_workspaces ↔ workspaces 3단계 관계 + - company ↔ slack_workspaces ↔ workspaces 3단계 관계 - 실제로는 1개 workspace만 사용 중 2. **중복 데이터** - - robeing_id가 workspaces와 workspace_members 양쪽에 존재 + - robeing_id가 workspaces와 workspace_member 양쪽에 존재 - robeing_url도 중복 저장 3. **불명확한 개념** - - companies의 실제 필요성 불분명 + - company의 실제 필요성 불분명 - workspaces가 실제로 무엇을 나타내는지 모호 4. **누락된 기능** @@ -36,8 +36,8 @@ ``` users: 3명 (happybell80, eagle0914, hhyong91) workspaces: 1개 (ivada-robeing) -workspace_members: 3개 (모두 rb10508_micro 사용) -companies: 2개 (테스트 회사) +workspace_member: 3개 (모두 rb10508_micro 사용) +company: 2개 (테스트 회사) slack_workspaces: 2개 (GoodGang Labs, test) ``` @@ -197,8 +197,8 @@ CREATE TABLE slack_config ( ```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; +CREATE TABLE backup_workspace_member AS SELECT * FROM workspace_member; +CREATE TABLE backup_company AS SELECT * FROM company; ``` #### Phase 2: 새 테이블 생성 @@ -217,7 +217,7 @@ SELECT '192.168.219.52' as robeing_host, true as is_primary, joined_at as created_at -FROM workspace_members; +FROM workspace_member; -- slack_users 테이블 생성 (빈 테이블) CREATE TABLE slack_users ( @@ -238,9 +238,9 @@ CREATE TABLE slack_users ( 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 workspace_member; DROP TABLE workspaces; -DROP TABLE companies; +DROP TABLE company; ``` ### 3.3 새로운 데이터 흐름 @@ -272,11 +272,11 @@ ChromaDB에 user_id 기반 저장 - 기존 테이블 영향 없음 2. **단계적 마이그레이션**: user_robeings 테이블 - - workspace_members 데이터 이전 + - workspace_member 데이터 이전 - 테스트 후 기존 테이블 제거 3. **정리 작업**: 불필요한 테이블 제거 - - companies, workspaces 제거 + - company, workspaces 제거 - slack_workspaces 단순화 ## 5. API 변경사항 @@ -284,7 +284,7 @@ ChromaDB에 user_id 기반 저장 ### 5.1 사용자-로빙 조회 ```python # 기존 -SELECT * FROM workspace_members WHERE user_id = ? +SELECT * FROM workspace_member WHERE user_id = ? # 변경 SELECT * FROM user_robeings WHERE user_id = ? AND is_primary = true diff --git a/plans/completed/250812_로컬개발자_Slack사용자매핑_구현계획.md b/plans/completed/250812_로컬개발자_Slack사용자매핑_구현계획.md index 5452f35..448518e 100644 --- a/plans/completed/250812_로컬개발자_Slack사용자매핑_구현계획.md +++ b/plans/completed/250812_로컬개발자_Slack사용자매핑_구현계획.md @@ -115,7 +115,7 @@ async def get_user_mapping( wm.robeing_id FROM slack_user_mapping sum JOIN users u ON sum.user_id = u.id - LEFT JOIN workspace_members wm ON u.id = wm.user_id + LEFT JOIN workspace_member wm ON u.id = wm.user_id WHERE sum.slack_user_id = :slack_user_id """ @@ -230,7 +230,7 @@ CREATE TABLE IF NOT EXISTS slack_user_mapping ( slack_user_id VARCHAR(100) NOT NULL, slack_workspace_id INTEGER REFERENCES slack_workspaces(id), user_id UUID REFERENCES users(id) NOT NULL, - workspace_member_id UUID REFERENCES workspace_members(id), + workspace_member_id UUID REFERENCES workspace_member(id), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(slack_user_id, slack_workspace_id) diff --git a/plans/completed/250819_gmail_item_detailed_tasks.md b/plans/completed/250819_gmail_item_detailed_tasks.md index b481a60..28f0fe4 100644 --- a/plans/completed/250819_gmail_item_detailed_tasks.md +++ b/plans/completed/250819_gmail_item_detailed_tasks.md @@ -16,7 +16,7 @@ - [x] 기본 데이터 삽입 (rb8001, level=5) - [x] 생성 확인 쿼리 실행 -### 1.2 gmail_tokens 테이블 수정 +### 1.2 gmail_token 테이블 수정 - [x] is_equipped 컬럼 추가 - [x] equipped_to 컬럼 추가 - [x] 기존 데이터 is_equipped=false로 초기화 @@ -232,7 +232,7 @@ - [x] Auth 서버 API 호출 - [x] 5분 캐싱 구현 - [ ] Gmail용 이메일 매핑 추가 - - [ ] workspace_members 테이블에서 email 조회 + - [ ] workspace_member 테이블에서 email 조회 - [ ] "종태님" → goeun2dc@gmail.com 변환 ### 4-1.6 테스트 시나리오 diff --git a/plans/completed/250819_gmail_item_implementation_plan.md b/plans/completed/250819_gmail_item_implementation_plan.md index 2fd44f2..9b130e7 100644 --- a/plans/completed/250819_gmail_item_implementation_plan.md +++ b/plans/completed/250819_gmail_item_implementation_plan.md @@ -19,7 +19,7 @@ Gmail 자격증명을 "API 아이템"으로 정의하고, robeing의 장착형 ### 관련 문서 - `/250817_email_skill_integration_status.md` - 현황 분석 -- `/250818_gmail_tokens_database_setup.md` - DB 구성 완료 +- `/250818_gmail_token_database_setup.md` - DB 구성 완료 - `/ideas/250818_claude_robeing_레벨업_체감_시스템_설계.md` - 아이템 시스템 설계 --- @@ -40,9 +40,9 @@ Gmail 자격증명을 "API 아이템"으로 정의하고, robeing의 장착형 ### 데이터 모델 ```typescript type GmailCredentialItem = { - id: string; // gmail_tokens.id - userId: string; // gmail_tokens.user_id - robeing_id?: string; // gmail_tokens.robeing_id (통일) + id: string; // gmail_token.id + userId: string; // gmail_token.user_id + robeing_id?: string; // gmail_token.robeing_id (통일) type: 'accessory'; slot: 'passport_gmail'; name: string; // metadata.display_name || email @@ -75,14 +75,14 @@ rb8001:8001 (메인 robeing) skill-email:8501 robeing-monitor:9024 (이메일 발송) (아이템 상태 관리) ↓ ↓ -PostgreSQL (gmail_tokens 테이블) +PostgreSQL (gmail_token 테이블) ``` ### 서비스별 역할 #### auth-server - Gmail OAuth 플로우 처리 -- gmail_tokens 테이블 관리 +- gmail_token 테이블 관리 - 토큰 갱신 로직 #### robeing-monitor (9024) @@ -125,14 +125,14 @@ sequenceDiagram Gateway-->>Front: UNAUTHORIZED else 인증 성공 Gateway->>Monitor: 장착 요청 전달 - Monitor->>DB: gmail_tokens 소유권 확인 + Monitor->>DB: gmail_token 소유권 확인 Monitor->>DB: robeing_stats 조회 (레벨 체크) DB-->>Monitor: 레벨 정보 alt 레벨 < 5 Monitor-->>Front: INSUFFICIENT_LEVEL else 레벨 >= 5 - Monitor->>DB: gmail_tokens 업데이트 + Monitor->>DB: gmail_token 업데이트 Note over DB: is_equipped=true
equipped_to=robeing_id Monitor->>DB: gmail_audit_logs 기록 Monitor-->>RB: 장착 완료 알림 @@ -155,7 +155,7 @@ sequenceDiagram User->>Front: "이메일 보내줘" 요청 Front->>RB: 메시지 전달 RB->>Monitor: Gmail 아이템 장착 확인 - Monitor->>DB: gmail_tokens 조회 + Monitor->>DB: gmail_token 조회 DB-->>Monitor: 장착 상태 & 토큰 정보 alt 아이템 미장착 @@ -195,7 +195,7 @@ sequenceDiagram Google->>Auth: 인증 코드 콜백 Auth->>Google: 토큰 교환 Google-->>Auth: access_token, refresh_token - Auth->>DB: gmail_tokens 업데이트 + Auth->>DB: gmail_token 업데이트 Auth-->>Front: 인증 완료 Front->>Front: 아이템 상태 갱신 ``` @@ -285,7 +285,7 @@ CREATE TABLE gmail_audit_logs ( - [x] 필요 테이블 생성 - robeing_stats 테이블 (레벨 관리) - gmail_audit_logs 테이블 (감사 로그) - - gmail_tokens에 is_equipped, equipped_to 컬럼 추가 + - gmail_token에 is_equipped, equipped_to 컬럼 추가 - [x] skill-email DB 연결 코드 작성 (희재) - FileCredentialsProvider → DBCredentialsProvider 전환 - PostgreSQL 연결 설정 추가 (localhost:5433 SSH 터널) @@ -361,11 +361,11 @@ DATABASE_URL=postgresql://robeings:robeings@192.168.219.45:5432/main_db ## 8. 데이터 매핑 (추후 구현) ### Slack User ID ↔ Gmail 계정 매핑 -- 위치: 추후 결정 (workspace_members 또는 별도 테이블) +- 위치: 추후 결정 (workspace_member 또는 별도 테이블) - 구조: ```sql --- 옵션 1: workspace_members 확장 -ALTER TABLE workspace_members +-- 옵션 1: workspace_member 확장 +ALTER TABLE workspace_member ADD COLUMN gmail_account VARCHAR(255); -- 옵션 2: 별도 매핑 테이블 @@ -443,7 +443,7 @@ CREATE TABLE user_gmail_mapping ( ## 12. 참고사항 ### 현재 상태 (2025-08-19) -- gmail_tokens 테이블 생성 완료 +- gmail_token 테이블 생성 완료 - rb8001 정상 작동 (GEMINI_USE_CLI=false) - skill-email 파일 기반 동작 중 (DB 전환 필요) - 프론트 인벤토리 UI 미구현 diff --git a/plans/completed/250819_rb8001_gmail_integration_completed.md b/plans/completed/250819_rb8001_gmail_integration_completed.md index f28a81c..19436e5 100644 --- a/plans/completed/250819_rb8001_gmail_integration_completed.md +++ b/plans/completed/250819_rb8001_gmail_integration_completed.md @@ -45,11 +45,11 @@ Gmail 스킬 통합을 담당하는 핵심 모듈 # PostgreSQL에서 직접 장착 상태 확인 # 5분 캐싱으로 성능 최적화 cur.execute(""" - SELECT COUNT(*) FROM gmail_tokens + SELECT COUNT(*) FROM gmail_token WHERE user_id = %s AND is_equipped = true """, (user_id,)) ``` - - gmail_tokens 테이블의 is_equipped 확인 + - gmail_token 테이블의 is_equipped 확인 - 캐시 TTL: 300초 (5분) - DB 연결 실패 시 False 반환 @@ -372,7 +372,7 @@ python3 -c " import psycopg2 conn = psycopg2.connect('postgresql://robeings:robeings@localhost:5433/main_db') cur = conn.cursor() -cur.execute('SELECT user_id, is_equipped FROM gmail_tokens') +cur.execute('SELECT user_id, is_equipped FROM gmail_token') for row in cur.fetchall(): print(f'{row[0]}: equipped={row[1]}') " diff --git a/plans/completed/250819_skill_email_db_connection_completed.md b/plans/completed/250819_skill_email_db_connection_completed.md index 0153c75..5eec3df 100644 --- a/plans/completed/250819_skill_email_db_connection_completed.md +++ b/plans/completed/250819_skill_email_db_connection_completed.md @@ -13,7 +13,7 @@ skill-email 서비스가 Gmail OAuth 토큰을 파일이 아닌 PostgreSQL 데 ### 배경 - 기존: 파일 기반 토큰 관리 (FileCredentialsProvider) -- 변경: PostgreSQL gmail_tokens 테이블 기반 관리 (DBCredentialsProvider) +- 변경: PostgreSQL gmail_token 테이블 기반 관리 (DBCredentialsProvider) - 이유: 중앙집중식 토큰 관리, 보안 강화, 다중 서비스 통합 --- @@ -56,12 +56,12 @@ LOG_LEVEL=INFO 2. **get_credentials() 메서드** ```python def get_credentials(self, user_id: str) -> Optional[Credentials]: - # gmail_tokens 테이블에서 조회 + # gmail_token 테이블에서 조회 # is_equipped=true인 토큰만 조회 # token_data + oauth_config 컬럼 모두 활용 ``` - - gmail_tokens 테이블 조회 + - gmail_token 테이블 조회 - token_data 컬럼: access_token, refresh_token - oauth_config 컬럼: client_id, client_secret, token_uri - Google Credentials 객체로 변환 @@ -117,9 +117,9 @@ def get_gmail_service() -> GmailService: ## 3. 데이터베이스 구조 -### gmail_tokens 테이블 +### gmail_token 테이블 ```sql -CREATE TABLE gmail_tokens ( +CREATE TABLE gmail_token ( id SERIAL PRIMARY KEY, user_id VARCHAR(100), robeing_id VARCHAR(50), @@ -161,7 +161,7 @@ CREATE TABLE gmail_tokens ( cd /home/heejae/skill-email && python3 test_db.py ``` - ✅ PostgreSQL 연결 성공 -- ✅ gmail_tokens 테이블 접근 가능 +- ✅ gmail_token 테이블 접근 가능 - ✅ 3개 토큰 확인 (heejae, test, unknown) ### 4.2 Provider 테스트 @@ -212,7 +212,7 @@ sshpass -p "19800508" ssh -f -N -L 5433:localhost:5432 admin@124.55.18.179 -p 51 - **문제**: 모든 토큰이 is_equipped=false 상태 - **해결**: ```sql - UPDATE gmail_tokens SET is_equipped=true WHERE user_id='heejae' + UPDATE gmail_token SET is_equipped=true WHERE user_id='heejae' ``` ### 6.3 oauth_config 누락 @@ -221,7 +221,7 @@ sshpass -p "19800508" ssh -f -N -L 5433:localhost:5432 admin@124.55.18.179 -p 51 ```python cur.execute(""" SELECT token_data, oauth_config - FROM gmail_tokens + FROM gmail_token WHERE user_id = %s AND is_equipped = true """) ``` @@ -299,7 +299,7 @@ sshpass -p "19800508" ssh -f -N -L 5433:localhost:5432 admin@124.55.18.179 -p 51 ## 12. 검증 체크리스트 - [x] PostgreSQL 연결 성공 -- [x] gmail_tokens 테이블 조회 +- [x] gmail_token 테이블 조회 - [x] 토큰 데이터 파싱 - [x] Credentials 객체 생성 - [x] oauth_config 통합 @@ -328,7 +328,7 @@ python3 -c " import psycopg2 conn = psycopg2.connect('postgresql://robeings:robeings@localhost:5433/main_db') cur = conn.cursor() -cur.execute('SELECT user_id, is_equipped FROM gmail_tokens') +cur.execute('SELECT user_id, is_equipped FROM gmail_token') for row in cur.fetchall(): print(f'{row[0]}: equipped={row[1]}') " diff --git a/plans/completed/250823_4pm_email_briefing_demo_plan.md b/plans/completed/250823_4pm_email_briefing_demo_plan.md index a46edd9..28c72e2 100644 --- a/plans/completed/250823_4pm_email_briefing_demo_plan.md +++ b/plans/completed/250823_4pm_email_briefing_demo_plan.md @@ -114,7 +114,7 @@ sequenceDiagram loop 각 사용자별 처리 Scheduler->>Monitor: Gmail 토큰 확인
(X-User-Id) - Monitor->>DB: gmail_tokens 조회 + Monitor->>DB: gmail_token 조회 DB-->>Monitor: token_data alt 토큰 유효 diff --git a/plans/completed/250828_slack_integration_level3_plan.md b/plans/completed/250828_slack_integration_level3_plan.md index 801c9fe..09da635 100644 --- a/plans/completed/250828_slack_integration_level3_plan.md +++ b/plans/completed/250828_slack_integration_level3_plan.md @@ -55,7 +55,7 @@ Frontend(Slack 아이템 획득) → auth-server → OAuth 2.0 → 봇 토큰 - `GET /auth/slack/passport/install?user_id={user_id}` - 봇 설치 OAuth 시작 - 파일: `/home/admin/auth-server/app/providers/slack.py:104` - 변경: workspace_id → user_id 파라미터 - - 처리: user_id로 workspace_members 테이블에서 workspace_id 조회 + - 처리: user_id로 workspace_member 테이블에서 workspace_id 조회 - `GET /auth/slack/passport/callback` - bot_token 저장 - `GET /auth/slack/passport/status/{workspace_id}` - 아이템 상태 확인 - `DELETE /auth/slack/passport/uninstall/{workspace_id}` - 아이템 취소 @@ -91,7 +91,7 @@ Slack Event → rb8001 → DB → SSE/WebSocket → Frontend - 이벤트: `message.channels`, `message.groups`, `message.im`, `message.mpim`, `app_mention` - 쓰레드: `message.message_replied` 이벤트 존재하나 `thread_ts` 확인 권장 2. 채널 타입: C(공개), G(비공개/그룹), D(DM) -3. conversation_logs 저장: team_id, channel_id, thread_ts +3. conversation_log 저장: team_id, channel_id, thread_ts 4. 초기 동기화: `conversations.history`로 백필 ### Phase 4: 명령 처리 @@ -116,14 +116,14 @@ Slack → @robeing 또는 /robeing → rb8001 → 응답 - **users**: id(UUID), email, slack_user_id, slack_team_id - **slack_workspaces**: team_id, team_name, bot_token(암호화), installed_by_user_id, scopes, installed_at - **slack_user_mapping**: team_id + slack_user_id 복합키, user_id(UUID) -- **conversation_logs**: team_id, channel_id, channel_type, user_id, text, ts, thread_ts +- **conversation_log**: team_id, channel_id, channel_type, user_id, text, ts, thread_ts ### 필요 컬럼 추가 ```sql ALTER TABLE users ADD COLUMN slack_user_id VARCHAR(50); ALTER TABLE users ADD COLUMN slack_team_id VARCHAR(50); -ALTER TABLE conversation_logs ADD COLUMN thread_ts VARCHAR(20); -ALTER TABLE conversation_logs ADD COLUMN channel_type VARCHAR(20); +ALTER TABLE conversation_log ADD COLUMN thread_ts VARCHAR(20); +ALTER TABLE conversation_log ADD COLUMN channel_type VARCHAR(20); ``` --- @@ -182,4 +182,4 @@ ALTER TABLE conversation_logs ADD COLUMN channel_type VARCHAR(20); ### 내부 문서 - [auth_login_sequences.md](../300_architecture/sequences/auth_login_sequences.md) - [tables.md](../300_architecture/database/tables.md) -- [250828_conversation_logs_channel_구분_개선.md](../troubleshooting/250828_conversation_logs_channel_구분_개선.md) \ No newline at end of file +- [250828_conversation_log_channel_구분_개선.md](../troubleshooting/250828_conversation_log_channel_구분_개선.md) \ No newline at end of file diff --git a/troubleshooting/250729_happybell80_서비스구축및배포복구.md b/troubleshooting/250729_happybell80_서비스구축및배포복구.md index 33ad905..9f68bf6 100644 --- a/troubleshooting/250729_happybell80_서비스구축및배포복구.md +++ b/troubleshooting/250729_happybell80_서비스구축및배포복구.md @@ -190,7 +190,7 @@ Claude가 세션 시작 시 규칙을 제대로 따르지 않음. CLAUDE.md 재 - JWT/OAuth 키 관리 상태 점검 2. **PostgreSQL main_db 스키마 분석**: - - `companies` 테이블: 회사별 서브도메인 관리 (2개 회사 등록) + - `company` 테이블: 회사별 서브도메인 관리 (2개 회사 등록) - `slack_workspaces` 테이블: Slack 봇 토큰 관리 (2개 워크스페이스 활성) - 멀티테넌트 B2B SaaS 구조 확인 diff --git a/troubleshooting/250730_happybell80_프론트백엔드연결및workspace전환.md b/troubleshooting/250730_happybell80_프론트백엔드연결및workspace전환.md index d5b7ef4..b3f4466 100644 --- a/troubleshooting/250730_happybell80_프론트백엔드연결및workspace전환.md +++ b/troubleshooting/250730_happybell80_프론트백엔드연결및workspace전환.md @@ -69,8 +69,8 @@ **필요한 DB 확장**: 1. `users` 테이블: 개별 사용자 정보 -2. `workspace_members` 테이블: 사용자-워크스페이스-로빙 매핑 -3. `workspaces` 테이블: companies 테이블 이름 변경 +2. `workspace_member` 테이블: 사용자-워크스페이스-로빙 매핑 +3. `workspaces` 테이블: company 테이블 이름 변경 **개발 우선순위**: 1. auth-server 데이터 모델 확장 @@ -103,8 +103,8 @@ CREATE TABLE users ( ... ); --- workspace_members 테이블 -CREATE TABLE workspace_members ( +-- workspace_member 테이블 +CREATE TABLE workspace_member ( workspace_id UUID REFERENCES workspaces(id), user_id UUID REFERENCES users(id), role VARCHAR(50), @@ -118,7 +118,7 @@ CREATE TABLE workspace_members ( ### Company → Workspace 변환 작업 **Sequential Design 분석으로 영향받는 파일 파악**: -1. `app/api/companies.py` → `app/api/workspaces.py` +1. `app/api/company.py` → `app/api/workspaces.py` 2. `app/providers/slack.py` - OAuth 처리 3. `app/api/slack_router.py` - Slack 이벤트 라우팅 4. `app/db/init_db.py` - DB 초기화 @@ -132,9 +132,9 @@ CREATE TABLE workspace_members ( **API 엔드포인트 변경**: ``` -/api/companies → /api/workspaces -/api/companies/{company_id} → /api/workspaces/{workspace_id} -/api/companies/subdomain/{subdomain} → /api/workspaces/subdomain/{subdomain} +/api/company → /api/workspaces +/api/company/{company_id} → /api/workspaces/{workspace_id} +/api/company/subdomain/{subdomain} → /api/workspaces/subdomain/{subdomain} ``` ## 교훈 diff --git a/troubleshooting/250730_happybell80_프론트엔드로빙연결.md b/troubleshooting/250730_happybell80_프론트엔드로빙연결.md index 171d33c..688add7 100644 --- a/troubleshooting/250730_happybell80_프론트엔드로빙연결.md +++ b/troubleshooting/250730_happybell80_프론트엔드로빙연결.md @@ -170,7 +170,7 @@ const ROBEING_API_URL = import.meta.env.VITE_ROBEING_API_URL || 'https://ro-bein 3. **auth-server DB 구축 필요**: - users 테이블 - - workspace_members 테이블 (user_id, robeing_id 매핑) + - workspace_member 테이블 (user_id, robeing_id 매핑) - 로빙 할당 API 엔드포인트 4. **ChatInterface 수정**: diff --git a/troubleshooting/250731_admin_DOCS철학섹션정제및auth서버업데이트.md b/troubleshooting/250731_admin_DOCS철학섹션정제및auth서버업데이트.md index 2bec8ba..834c124 100644 --- a/troubleshooting/250731_admin_DOCS철학섹션정제및auth서버업데이트.md +++ b/troubleshooting/250731_admin_DOCS철학섹션정제및auth서버업데이트.md @@ -41,7 +41,7 @@ git pull ``` **주요 변경 내용**: -- `companies.py` → `workspaces.py`로 이름 변경 +- `company.py` → `workspaces.py`로 이름 변경 - 새로운 마이그레이션 파일 추가 (`add_user_workspace_tables.sql`) - 사용자 모델 추가 (`user.py`) - Slack 통합 개선 diff --git a/troubleshooting/250809_happybell80_robing-gateway구현.md b/troubleshooting/250809_happybell80_robing-gateway구현.md index fb1c97b..3b15196 100644 --- a/troubleshooting/250809_happybell80_robing-gateway구현.md +++ b/troubleshooting/250809_happybell80_robing-gateway구현.md @@ -32,14 +32,14 @@ robeing-gateway/ **핵심 기능**: 1. 사용자-로빙 매핑 관리 2. 메모리 캐시로 성능 최적화 -3. 기존 main_db 테이블 활용 (workspaces, workspace_members) +3. 기존 main_db 테이블 활용 (workspaces, workspace_member) 4. 헬스체크 및 모니터링 엔드포인트 ### 23서버팀 피드백 **중요 변경사항 - 새 테이블 불필요**: -- 기존 main_db의 workspaces, workspace_members 테이블 활용 -- workspace_members에서 user_id로 robeing 정보 조회 +- 기존 main_db의 workspaces, workspace_member 테이블 활용 +- workspace_member에서 user_id로 robeing 정보 조회 - JOIN 쿼리로 사용자 → 워크스페이스 → 로빙 매핑 ## 오전 11시 00분 - 배포 문제 해결 @@ -144,7 +144,7 @@ fetch('http://localhost:8100/api/chat', { ### 2. 워크스페이스 할당 테스트 ```sql -- 사용자를 워크스페이스에 할당 -INSERT INTO workspace_members ( +INSERT INTO workspace_member ( id, user_id, workspace_id, role, robeing_id, is_active ) VALUES ( gen_random_uuid(), @@ -244,8 +244,8 @@ INSERT INTO users (id, ...) VALUES ('user-happybell80', ...); **두 번째 시도 - role 값 오류**: ```sql -- role은 대문자여야 함 -INSERT INTO workspace_members (..., role, ...) VALUES (..., 'owner', ...); -- X -INSERT INTO workspace_members (..., role, ...) VALUES (..., 'OWNER', ...); -- O +INSERT INTO workspace_member (..., role, ...) VALUES (..., 'owner', ...); -- X +INSERT INTO workspace_member (..., role, ...) VALUES (..., 'OWNER', ...); -- O ``` **최종 수정 버전**: @@ -259,7 +259,7 @@ INSERT INTO users (id, email, name) VALUES ('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'::uuid, '0914eagle@gmail.com', '전희재'), ('cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid, 'hhyong91@gmail.com', '황한용'); -INSERT INTO workspace_members (..., role, ...) VALUES +INSERT INTO workspace_member (..., role, ...) VALUES (..., 'OWNER', ...), -- 김종태 (..., 'MEMBER', ...); -- 전희재, 황한용 ``` @@ -269,7 +269,7 @@ INSERT INTO workspace_members (..., role, ...) VALUES **데이터베이스 상태**: - workspaces: 1개 (ivada-robeing) - users: 3개 (김종태, 전희재, 황한용) -- workspace_members: 3개 (모두 rb10508_micro 할당) +- workspace_member: 3개 (모두 rb10508_micro 할당) **통합 테스트 성공 (오후 2:13)**: 1. **인증 흐름**: @@ -278,7 +278,7 @@ INSERT INTO workspace_members (..., role, ...) VALUES 2. **Gateway 라우팅**: - X-User-Id 헤더로 사용자 식별 - - DB 조회: workspace_members → robeing_id 확인 + - DB 조회: workspace_member → robeing_id 확인 - rb10508_micro (192.168.219.52:10508)로 라우팅 3. **개인화된 응답**: @@ -289,7 +289,7 @@ INSERT INTO workspace_members (..., role, ...) VALUES ``` Frontend → nginx(/gateway/) → Gateway(8100) → DB 조회 ↓ - workspace_members + workspace_member ↓ rb10508_micro → 맞춤 응답 ``` diff --git a/troubleshooting/250811_happybell80_ChromaDB메모리손실.md b/troubleshooting/250811_happybell80_ChromaDB메모리손실.md index 07e05f1..4187de0 100644 --- a/troubleshooting/250811_happybell80_ChromaDB메모리손실.md +++ b/troubleshooting/250811_happybell80_ChromaDB메모리손실.md @@ -99,7 +99,7 @@ npm run build async def get_robeing_info(username: str): query = text(""" SELECT ... - FROM workspace_members wm + FROM workspace_member wm JOIN users u ON wm.user_id = u.id WHERE u.username = :username """) diff --git a/troubleshooting/250811_happybell80_Gateway필드변환문제.md b/troubleshooting/250811_happybell80_Gateway필드변환문제.md index d699d4b..3e1614e 100644 --- a/troubleshooting/250811_happybell80_Gateway필드변환문제.md +++ b/troubleshooting/250811_happybell80_Gateway필드변환문제.md @@ -34,7 +34,7 @@ async def get_robeing_info(username: str): """username으로 직접 조회""" query = text(""" SELECT ... - FROM workspace_members wm + FROM workspace_member wm JOIN users u ON wm.user_id = u.id WHERE u.username = :username """) diff --git a/troubleshooting/250812_slack_user_mapping_구현.md b/troubleshooting/250812_slack_user_mapping_구현.md index 07e8670..64f750e 100644 --- a/troubleshooting/250812_slack_user_mapping_구현.md +++ b/troubleshooting/250812_slack_user_mapping_구현.md @@ -29,7 +29,7 @@ CREATE TABLE slack_user_mapping ( slack_user_id VARCHAR(100) NOT NULL, slack_workspace_id UUID REFERENCES slack_workspaces(id), user_id UUID REFERENCES users(id) NOT NULL, - workspace_member_id UUID REFERENCES workspace_members(id), + workspace_member_id UUID REFERENCES workspace_member(id), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(slack_user_id, slack_workspace_id) @@ -57,7 +57,7 @@ CREATE TABLE slack_user_mapping ( **해결**: ```sql GRANT ALL PRIVILEGES ON TABLE slack_user_mapping TO robeings; -GRANT SELECT ON users, workspace_members TO robeings; +GRANT SELECT ON users, workspace_member TO robeings; ALTER TABLE slack_user_mapping OWNER TO robeings; ``` diff --git a/troubleshooting/250817_email_skill_integration_status.md b/troubleshooting/250817_email_skill_integration_status.md index aba81ee..fd6924b 100644 --- a/troubleshooting/250817_email_skill_integration_status.md +++ b/troubleshooting/250817_email_skill_integration_status.md @@ -63,7 +63,7 @@ User → rb8001 → skill-email → Gmail API ### 2.2 제안: PostgreSQL 기반 관리 ```sql -- Gmail 토큰 테이블 -CREATE TABLE gmail_tokens ( +CREATE TABLE gmail_token ( id SERIAL PRIMARY KEY, user_id VARCHAR(100) UNIQUE NOT NULL, robeing_id VARCHAR(50), @@ -268,7 +268,7 @@ class DBCredentialsProvider: async def get_credentials(self, user_id: str): # PostgreSQL에서 토큰 조회 token = await db.query( - "SELECT * FROM gmail_tokens WHERE user_id = %s", + "SELECT * FROM gmail_token WHERE user_id = %s", user_id ) return Credentials(**token) diff --git a/troubleshooting/250817_robeing_monitor_integration.md b/troubleshooting/250817_robeing_monitor_integration.md index 14bc96d..39c31a2 100644 --- a/troubleshooting/250817_robeing_monitor_integration.md +++ b/troubleshooting/250817_robeing_monitor_integration.md @@ -118,14 +118,14 @@ pgrep -f "ssh.*5433:localhost:5432" ### PostgreSQL 접속 ```bash # SSH를 통한 원격 실행 -sshpass -p "19800508" ssh -o StrictHostKeyChecking=no admin@124.55.18.179 -p 51123 "PGPASSWORD=robeings psql -h localhost -U robeings -d main_db -c 'SELECT * FROM gmail_tokens'" +sshpass -p "19800508" ssh -o StrictHostKeyChecking=no admin@124.55.18.179 -p 51123 "PGPASSWORD=robeings psql -h localhost -U robeings -d main_db -c 'SELECT * FROM gmail_token'" # 로컬 터널을 통한 접속 (psql 클라이언트 필요) PGPASSWORD=robeings psql -h localhost -p 5433 -U robeings -d main_db ``` ### 주요 테이블 -- `gmail_tokens`: Gmail OAuth 토큰 저장 +- `gmail_token`: Gmail OAuth 토큰 저장 - `gmail_audit_logs`: Gmail 작업 감사 로그 - `robeing_stats`: Robeing 레벨 정보 - `slack_user_mapping`: Slack-UUID 매핑 (현재 미사용) diff --git a/troubleshooting/250818_gmail_tokens_database_setup.md b/troubleshooting/250818_gmail_tokens_database_setup.md index 610bd10..7a04868 100644 --- a/troubleshooting/250818_gmail_tokens_database_setup.md +++ b/troubleshooting/250818_gmail_tokens_database_setup.md @@ -16,10 +16,10 @@ User: robeings Password: robeings ``` -### 1.2 생성된 테이블: `gmail_tokens` +### 1.2 생성된 테이블: `gmail_token` ```sql -CREATE TABLE gmail_tokens ( +CREATE TABLE gmail_token ( id SERIAL PRIMARY KEY, user_id VARCHAR(100) UNIQUE NOT NULL, robeing_id VARCHAR(50), @@ -83,12 +83,12 @@ CREATE TABLE gmail_tokens ( ```sql -- 기본 인덱스 -CREATE INDEX idx_gmail_tokens_user_id ON gmail_tokens(user_id); -CREATE INDEX idx_gmail_tokens_robeing_id ON gmail_tokens(robeing_id); +CREATE INDEX idx_gmail_token_user_id ON gmail_token(user_id); +CREATE INDEX idx_gmail_token_robeing_id ON gmail_token(robeing_id); -- JSON 검색용 GIN 인덱스 -CREATE INDEX idx_gmail_tokens_token_data ON gmail_tokens USING GIN (token_data); -CREATE INDEX idx_gmail_tokens_oauth_config ON gmail_tokens USING GIN (oauth_config); +CREATE INDEX idx_gmail_token_token_data ON gmail_token USING GIN (token_data); +CREATE INDEX idx_gmail_token_oauth_config ON gmail_token USING GIN (oauth_config); ``` --- @@ -106,8 +106,8 @@ END; $$ LANGUAGE plpgsql; -- 트리거 생성 -CREATE TRIGGER update_gmail_tokens_updated_at -BEFORE UPDATE ON gmail_tokens +CREATE TRIGGER update_gmail_token_updated_at +BEFORE UPDATE ON gmail_token FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); ``` @@ -144,19 +144,19 @@ EXECUTE FUNCTION update_updated_at_column(); ```sql -- 특정 사용자 토큰 조회 SELECT token_data->>'access_token' as access_token -FROM gmail_tokens +FROM gmail_token WHERE user_id = 'test'; -- 이메일 발송 가능한 사용자 찾기 SELECT user_id, robeing_id -FROM gmail_tokens +FROM gmail_token WHERE scopes @> '["https://www.googleapis.com/auth/gmail.send"]'; ``` ### 6.2 토큰 업데이트 ```sql -- 액세스 토큰 갱신 -UPDATE gmail_tokens +UPDATE gmail_token SET token_data = jsonb_set( token_data, '{access_token}', @@ -165,7 +165,7 @@ SET token_data = jsonb_set( WHERE user_id = 'test'; -- 스코프 추가 -UPDATE gmail_tokens +UPDATE gmail_token SET scopes = scopes || '["https://www.googleapis.com/auth/gmail.send"]'::jsonb WHERE user_id = 'heejae'; ``` @@ -173,12 +173,12 @@ WHERE user_id = 'heejae'; ### 6.3 메타데이터 활용 ```sql -- Slack 사용자와 매핑 -SELECT * FROM gmail_tokens +SELECT * FROM gmail_token WHERE metadata->>'slack_user_id' = 'U091UNVE41M'; -- 특정 로빙의 Gmail 계정 찾기 SELECT user_id, metadata->>'email' as gmail_account -FROM gmail_tokens +FROM gmail_token WHERE robeing_id = 'rb8001'; ``` @@ -207,7 +207,7 @@ with conn.cursor(cursor_factory=RealDictCursor) as cur: token_data->>'refresh_token' as refresh_token, oauth_config, scopes - FROM gmail_tokens + FROM gmail_token WHERE user_id = %s """, ('test',)) diff --git a/troubleshooting/250820_happybell80_Gmail아이템시스템통합.md b/troubleshooting/250820_happybell80_Gmail아이템시스템통합.md index 922cdac..4fc0fa7 100644 --- a/troubleshooting/250820_happybell80_Gmail아이템시스템통합.md +++ b/troubleshooting/250820_happybell80_Gmail아이템시스템통합.md @@ -16,7 +16,7 @@ - `AttributeError: 'str' object has no attribute 'get'` 에러 발생 #### 원인 분석 -- gmail_tokens 테이블의 metadata 컬럼이 JSONB 타입이지만, asyncpg가 string으로 반환하는 경우 발생 +- gmail_token 테이블의 metadata 컬럼이 JSONB 타입이지만, asyncpg가 string으로 반환하는 경우 발생 - 또는 데이터 저장 시 JSON string으로 저장된 경우 #### 해결 과정 diff --git a/troubleshooting/250820_happybell80_Gmail패스포트시스템완성.md b/troubleshooting/250820_happybell80_Gmail패스포트시스템완성.md index 52ceb9e..950cbfe 100644 --- a/troubleshooting/250820_happybell80_Gmail패스포트시스템완성.md +++ b/troubleshooting/250820_happybell80_Gmail패스포트시스템완성.md @@ -139,7 +139,7 @@ GMAIL_API_SCOPES = [ # PostgreSQL 직접 연동 await conn.execute(""" - INSERT INTO gmail_tokens (...) VALUES (...) + INSERT INTO gmail_token (...) VALUES (...) ON CONFLICT (user_id) DO UPDATE SET ... """) ``` @@ -299,7 +299,7 @@ useEffect(() => { 2. "Gmail 연결" 버튼 클릭 3. auth-server/auth/gmail/passport/ OAuth 시작 4. Google 인증 완료 -5. PostgreSQL gmail_tokens 저장 (is_equipped = true) +5. PostgreSQL gmail_token 저장 (is_equipped = true) 6. Frontend로 리다이렉트 (?gmail=success) 7. 자동 새로고침 및 성공 메시지 ``` diff --git a/troubleshooting/250820_happybell80_auth_db를_main_db로_변경.md b/troubleshooting/250820_happybell80_auth_db를_main_db로_변경.md index cc99676..88a21b1 100644 --- a/troubleshooting/250820_happybell80_auth_db를_main_db로_변경.md +++ b/troubleshooting/250820_happybell80_auth_db를_main_db로_변경.md @@ -101,7 +101,7 @@ CREATE INDEX idx_conversations_robeing ON robeing.conversations(robeing_id); 1. 51123 서버에서 서비스 재배포 확인 2. main_db에 robeing 스키마 및 테이블 생성 3. rb10508_micro에 이름→이메일 변환 로직 구현 -4. workspace_members + robeing.contacts 조합 조회 +4. workspace_member + robeing.contacts 조합 조회 ## 교훈 - 데이터베이스 이름은 용도를 명확히 반영해야 함 diff --git a/troubleshooting/250820_happybell80_skill-email_DB통합및Actions배포.md b/troubleshooting/250820_happybell80_skill-email_DB통합및Actions배포.md index 99184e0..bd51c36 100644 --- a/troubleshooting/250820_happybell80_skill-email_DB통합및Actions배포.md +++ b/troubleshooting/250820_happybell80_skill-email_DB통합및Actions배포.md @@ -169,7 +169,7 @@ on: ``` 사용자 → rb10508_micro → skill-email(DB 연동) → Gmail API ↓ ↓ - PostgreSQL (gmail_tokens 테이블) + PostgreSQL (gmail_token 테이블) ↑ robeing-monitor (아이템 관리) ``` diff --git a/troubleshooting/250820_happybell80_사용자별로빙동적할당구현.md b/troubleshooting/250820_happybell80_사용자별로빙동적할당구현.md index 151b5f7..73f6cc5 100644 --- a/troubleshooting/250820_happybell80_사용자별로빙동적할당구현.md +++ b/troubleshooting/250820_happybell80_사용자별로빙동적할당구현.md @@ -23,7 +23,7 @@ ↓ users 테이블 (UUID) ↓ -workspace_members 테이블 +workspace_member 테이블 (robeing_id 할당) ↓ 로빙 컨테이너 @@ -35,7 +35,7 @@ workspace_members 테이블 #### 핵심 테이블 관계 - **users**: 사용자 UUID 저장 -- **workspace_members**: user_id → robeing_id 매핑 +- **workspace_member**: user_id → robeing_id 매핑 - **robeing_stats**: 각 로빙의 레벨, 경험치, 스탯 #### 서비스 구조 @@ -74,7 +74,7 @@ export async function getUserRobeing(): Promise<{ robeing_id: string; robeing_url: string; } | null> { - // workspace_members에서 사용자의 로빙 조회 + // workspace_member에서 사용자의 로빙 조회 } export async function getRobeingStats(robeingId: string): Promise<{ @@ -177,7 +177,7 @@ async def get_stats(robeing_id: str): ### 1. 시스템 구조 이해의 중요성 - 단순한 레벨 표시 문제가 아닌 전체 아키텍처 이해 필요 -- users → workspace_members → robeing_stats 관계 파악 필수 +- users → workspace_member → robeing_stats 관계 파악 필수 - 다중 로빙 체계와 사용자 매핑 구조 이해 ### 2. 하드코딩 제거의 필요성 diff --git a/troubleshooting/250821_gmail_token_auto_refresh.md b/troubleshooting/250821_gmail_token_auto_refresh.md index c40c3eb..8bb3584 100644 --- a/troubleshooting/250821_gmail_token_auto_refresh.md +++ b/troubleshooting/250821_gmail_token_auto_refresh.md @@ -21,12 +21,12 @@ Gmail OAuth 토큰의 자동 갱신 기능을 auth-server에 구현하여, 만 ### 2.1 현재 DB 정보 ``` Database: main_db (auth_db 아님 주의!) -Table: gmail_tokens +Table: gmail_token ``` -### 2.2 gmail_tokens 테이블 구조 +### 2.2 gmail_token 테이블 구조 ```sql -CREATE TABLE gmail_tokens ( +CREATE TABLE gmail_token ( id SERIAL PRIMARY KEY, user_id UUID UNIQUE NOT NULL, robeing_id VARCHAR(50), @@ -222,6 +222,6 @@ docker compose down && docker compose up -d --build --- ## 10. 관련 문서 -- `/home/heejae/DOCS/250818_gmail_tokens_database_setup.md` +- `/home/heejae/DOCS/250818_gmail_token_database_setup.md` - `/home/heejae/DOCS/robeing-monitor-integration.md` - `/home/heejae/DOCS/250817_slack_user_mapping_troubleshooting.md` \ No newline at end of file diff --git a/troubleshooting/250822_happybell80_Gmail통합_UUID변환_문제해결.md b/troubleshooting/250822_happybell80_Gmail통합_UUID변환_문제해결.md index 0604609..3e2b31a 100644 --- a/troubleshooting/250822_happybell80_Gmail통합_UUID변환_문제해결.md +++ b/troubleshooting/250822_happybell80_Gmail통합_UUID변환_문제해결.md @@ -36,7 +36,7 @@ asyncpg.exceptions.DataError: invalid input for query argument $1: 'U091UNVE41M' #### 원인 - robeing-monitor가 Slack user_id를 UUID로 변환하지 않고 직접 DB 조회 -- PostgreSQL gmail_tokens 테이블의 user_id 컬럼은 UUID 타입 +- PostgreSQL gmail_token 테이블의 user_id 컬럼은 UUID 타입 ### 2.2 Gateway 프록시 문제 diff --git a/troubleshooting/250823_happybell80_Gmail_OAuth_토큰_갱신_시스템_구축.md b/troubleshooting/250823_happybell80_Gmail_OAuth_토큰_갱신_시스템_구축.md index 5a2862e..4dfa4bf 100644 --- a/troubleshooting/250823_happybell80_Gmail_OAuth_토큰_갱신_시스템_구축.md +++ b/troubleshooting/250823_happybell80_Gmail_OAuth_토큰_갱신_시스템_구축.md @@ -24,7 +24,7 @@ ### 2.1 테이블 구조 파악 ```sql -gmail_tokens 테이블: +gmail_token 테이블: - 구조 혼재: 신규 컬럼(access_token, refresh_token)과 기존 컬럼(token_data, oauth_config) - 두 가지 형식 모두 지원 필요 ``` @@ -77,7 +77,7 @@ async def refresh_gmail_token(user_id: str): cur.execute(''' SELECT access_token, refresh_token, expires_at, token_data, oauth_config, metadata, expiry - FROM gmail_tokens + FROM gmail_token WHERE user_id = %s::uuid ''', (user_id,)) @@ -90,7 +90,7 @@ async def refresh_gmail_token(user_id: str): # 4. 새 토큰으로 DB 업데이트 cur.execute(''' - UPDATE gmail_tokens + UPDATE gmail_token SET access_token = %s, expires_at = %s, ... ''') ``` @@ -108,7 +108,7 @@ oauth_config = { # INSERT 쿼리에 oauth_config 추가 await conn.execute(""" - INSERT INTO gmail_tokens ( + INSERT INTO gmail_token ( ..., oauth_config, ... ) VALUES (..., $8, ...) """, ..., json.dumps(oauth_config), ...) @@ -122,7 +122,7 @@ await conn.execute(""" **문제**: `token_data` NOT NULL 제약으로 INSERT 실패 **해결**: 51123 서버에서 직접 컬럼 제약 제거 ```sql -ALTER TABLE gmail_tokens ALTER COLUMN token_data DROP NOT NULL; +ALTER TABLE gmail_token ALTER COLUMN token_data DROP NOT NULL; ``` ### 4.2 UUID 타입 오류 @@ -144,14 +144,14 @@ database_url = os.getenv("DATABASE_URL", "postgresql://robeings:robeings@192.168 **문제**: `access_token` 컬럼 누락으로 "column does not exist" 에러 **해결**: 필요한 컬럼들 추가 ```sql -ALTER TABLE gmail_tokens +ALTER TABLE gmail_token ADD COLUMN IF NOT EXISTS access_token TEXT, ADD COLUMN IF NOT EXISTS refresh_token TEXT, ADD COLUMN IF NOT EXISTS token_type VARCHAR DEFAULT 'Bearer', ADD COLUMN IF NOT EXISTS expires_at FLOAT; -- 기존 token_data에서 새 컬럼으로 데이터 마이그레이션 -UPDATE gmail_tokens +UPDATE gmail_token SET access_token = token_data->>'access_token', refresh_token = token_data->>'refresh_token' diff --git a/troubleshooting/250825_gmail_token_expired_daily_briefing_fix.md b/troubleshooting/250825_gmail_token_expired_daily_briefing_fix.md index 065c8ca..6449017 100644 --- a/troubleshooting/250825_gmail_token_expired_daily_briefing_fix.md +++ b/troubleshooting/250825_gmail_token_expired_daily_briefing_fix.md @@ -24,7 +24,7 @@ -- 현재 DB 상태: 모든 사용자 토큰 만료 SELECT username, access_token IS NOT NULL as has_token, expires_at < extract(epoch from now()) as is_expired -FROM gmail_tokens; +FROM gmail_token; 결과: happybell80 | t (있음) | t (만료됨) @@ -49,7 +49,7 @@ sequenceDiagram Cron->>RB: POST /api/cron/daily-summary RB->>Email: GET /messages?user_id={slack_id} - Email->>DB: SELECT token_data FROM gmail_tokens + Email->>DB: SELECT token_data FROM gmail_token DB-->>Email: access_token: expired ❌ Email-->>RB: 500 Internal Server Error RB->>Slack: 불완전한 브리핑 전송
(이메일 없이 뉴스만) @@ -73,7 +73,7 @@ sequenceDiagram Google->>Auth: Callback with code Auth->>Google: Exchange code for tokens Google-->>Auth: access_token, refresh_token - Auth->>DB: UPDATE gmail_tokens
SET access_token, refresh_token + Auth->>DB: UPDATE gmail_token
SET access_token, refresh_token Auth-->>Front: 인증 완료 ``` @@ -95,7 +95,7 @@ curl -X GET "http://localhost:9000/api/gmail/auth?user_id=1e16e9d5-59f3-54da-a66 # 4. 토큰 저장 확인 export PGPASSWORD=robeings psql -h localhost -U robeings -d main_db -c \ - "SELECT user_id, access_token IS NOT NULL FROM gmail_tokens WHERE user_id = '1e16e9d5-59f3-54da-a661-8abeabff4230';" + "SELECT user_id, access_token IS NOT NULL FROM gmail_token WHERE user_id = '1e16e9d5-59f3-54da-a661-8abeabff4230';" # 5. 브리핑 수동 테스트 curl -X POST http://192.168.219.52:8001/api/cron/daily-summary \ @@ -123,7 +123,7 @@ psql -h localhost -U robeings -d main_db -c \ gt.expires_at < extract(epoch from now()) as is_expired, gt.metadata->>'email' as email FROM users u - LEFT JOIN gmail_tokens gt ON u.id = gt.user_id + LEFT JOIN gmail_token gt ON u.id = gt.user_id WHERE u.username IN ('happybell80', '0914eagle', 'cdctfm');" ``` @@ -141,7 +141,7 @@ curl -s "http://localhost:9000/api/gmail/auth?user_id=1e16e9d5-59f3-54da-a661-8a # 4. 인증 성공 확인 psql -h localhost -U robeings -d main_db -c \ "SELECT access_token IS NOT NULL as success - FROM gmail_tokens + FROM gmail_token WHERE user_id = '1e16e9d5-59f3-54da-a661-8abeabff4230';" ``` @@ -190,7 +190,7 @@ curl -s "http://localhost:9000/api/gmail/auth?user_id=69ae4ea9-a15f-5110-9f5d-65 ### 7.1 문제 상황 - **증상**: Slack DM 대화가 PostgreSQL에 저장 안됨 - **ChromaDB**: ✅ 정상 저장 -- **PostgreSQL**: ❌ 저장 실패 (conversation_logs 테이블 0 rows) +- **PostgreSQL**: ❌ 저장 실패 (conversation_log 테이블 0 rows) ### 7.2 대화 저장 플로우 (현재: State Service 사용 안 함) ```mermaid @@ -207,7 +207,7 @@ sequenceDiagram RB->>Chroma: store_memory() Chroma-->>RB: ✅ 저장 성공
ID: 2a776b26... - RB->>PG: 직접 INSERT INTO conversation_logs + RB->>PG: 직접 INSERT INTO conversation_log PG-->>RB: ✅ 저장 성공 Note over RB: State Service 없이
직접 DB 연결 diff --git a/troubleshooting/250825_happybell80_사용자별로빙연결및레벨표시문제.md b/troubleshooting/250825_happybell80_사용자별로빙연결및레벨표시문제.md index e4f6661..7ee7f41 100644 --- a/troubleshooting/250825_happybell80_사용자별로빙연결및레벨표시문제.md +++ b/troubleshooting/250825_happybell80_사용자별로빙연결및레벨표시문제.md @@ -22,7 +22,7 @@ username: happybell80 email: goeun2dc@gmail.com UUID: 1e16e9d5-59f3-54da-a661-8abeabff4230 --- workspace_members 테이블 +-- workspace_member 테이블 happybell80 → rb8001 (포트 8001) eagle0914 → rb10508_micro (포트 10508) ``` diff --git a/troubleshooting/250825_robeing_stats_display_issue.md b/troubleshooting/250825_robeing_stats_display_issue.md index 9838d54..c11d5c4 100644 --- a/troubleshooting/250825_robeing_stats_display_issue.md +++ b/troubleshooting/250825_robeing_stats_display_issue.md @@ -203,7 +203,7 @@ WHERE robeing_id = 'rb8001'; - **DB 테이블**: - `robeing_stats` - 실제 스탯 저장 - - `workspace_members` - 사용자-로빙 매핑 + - `workspace_member` - 사용자-로빙 매핑 --- diff --git a/troubleshooting/250826_frontend_rb8001_chat_endpoint_missing.md b/troubleshooting/250826_frontend_rb8001_chat_endpoint_missing.md index 70aec68..ef79405 100644 --- a/troubleshooting/250826_frontend_rb8001_chat_endpoint_missing.md +++ b/troubleshooting/250826_frontend_rb8001_chat_endpoint_missing.md @@ -142,7 +142,7 @@ Stats request from user: happybell80 for robeing: undefined ### 4.3 대화 저장 확인 ❌ ```sql -SELECT COUNT(*) FROM conversation_logs; -- 0건 +SELECT COUNT(*) FROM conversation_log; -- 0건 -- rb8001에서 DB 저장 로직 미구현 ``` diff --git a/troubleshooting/250826_happybell80_frontend_rb8001_채팅연결_계획.md b/troubleshooting/250826_happybell80_frontend_rb8001_채팅연결_계획.md index 7b7b625..0719c66 100644 --- a/troubleshooting/250826_happybell80_frontend_rb8001_채팅연결_계획.md +++ b/troubleshooting/250826_happybell80_frontend_rb8001_채팅연결_계획.md @@ -100,7 +100,7 @@ async def message_endpoint(request: MessageRequest): user_id=request.user_id or "web_user", task_type="chat", context=request.context, - channel="web" # ⚠️ Slack DM과 동일 (개선: 250828_conversation_logs_channel_구분_개선.md) + channel="web" # ⚠️ Slack DM과 동일 (개선: 250828_conversation_log_channel_구분_개선.md) ) # Frontend가 기대하는 응답 형식 @@ -195,7 +195,7 @@ rb8001(8001) → /api/message 처리 - Gateway 로그: 라우팅 성공 - rb8001 로그: 메시지 처리 - ChromaDB: 대화 저장 -- PostgreSQL: conversation_logs 기록 +- PostgreSQL: conversation_log 기록 --- diff --git a/troubleshooting/250826_happybell80_rb8001_이중저장구현.md b/troubleshooting/250826_happybell80_rb8001_이중저장구현.md index a519c9d..5cac830 100644 --- a/troubleshooting/250826_happybell80_rb8001_이중저장구현.md +++ b/troubleshooting/250826_happybell80_rb8001_이중저장구현.md @@ -43,7 +43,7 @@ grep -r "save_conversation\|store_memory" rb8001/ PGPASSWORD=robeings psql -h 192.168.219.45 -U robeings -d main_db -c "\dt" # 결과: -# - conversation_logs 테이블 존재 ✅ +# - conversation_log 테이블 존재 ✅ # - robeing_stats 테이블 존재 ✅ # - 직접 연결 가능 ``` @@ -158,18 +158,18 @@ graph LR ``` 2. **원인 분석** - - conversation_logs 테이블의 user_id가 UUID 타입 + - conversation_log 테이블의 user_id가 UUID 타입 - rb8001은 Slack user ID (문자열) 전송 - UUID 변환 불가능한 값으로 저장 실패 ### DB 스키마 수정 (51123 서버) ```sql -- slack_user_id 컬럼 추가 -ALTER TABLE conversation_logs +ALTER TABLE conversation_log ADD COLUMN slack_user_id VARCHAR(255); -- user_id를 nullable로 변경 -ALTER TABLE conversation_logs +ALTER TABLE conversation_log ALTER COLUMN user_id DROP NOT NULL; ``` @@ -191,7 +191,7 @@ conversation_log = ConversationLog( ```python class ConversationLog(Base): """대화 로그 테이블""" - __tablename__ = "conversation_logs" + __tablename__ = "conversation_log" id = Column(Integer, primary_key=True, index=True) robeing_id = Column(String, index=True) @@ -223,13 +223,13 @@ docker logs rb8001 --tail 100 | grep -E "ChromaDB|PostgreSQL|saved" ### DB 확인 ```sql -- PostgreSQL 저장 확인 -SELECT COUNT(*) FROM conversation_logs +SELECT COUNT(*) FROM conversation_log WHERE robeing_id = 'rb8001' AND timestamp > NOW() - INTERVAL '1 hour'; -- 최근 대화 확인 SELECT user_id, message, response, timestamp -FROM conversation_logs +FROM conversation_log WHERE robeing_id = 'rb8001' ORDER BY timestamp DESC LIMIT 5; diff --git a/troubleshooting/250826_id_체계_정리_및_conversation_logs_문제_해결.md b/troubleshooting/250826_id_체계_정리_및_conversation_logs_문제_해결.md index c671a02..5209181 100644 --- a/troubleshooting/250826_id_체계_정리_및_conversation_logs_문제_해결.md +++ b/troubleshooting/250826_id_체계_정리_및_conversation_logs_문제_해결.md @@ -1,4 +1,4 @@ -# ID 체계 정리 및 conversation_logs 저장 문제 해결 +# ID 체계 정리 및 conversation_log 저장 문제 해결 ## 작성일: 2025-08-26 (수정: 2025-08-28) ## 작성자: 서버 관리자 @@ -12,12 +12,12 @@ ### 1.1 발견된 문제들 1. **user_id UUID 타입 문제** - - PostgreSQL의 conversation_logs 테이블에서 user_id가 UUID 타입 + - PostgreSQL의 conversation_log 테이블에서 user_id가 UUID 타입 - "system"이나 Slack user_id (예: U0925SXQFDK)는 UUID가 아님 - UUID 변환 시도 시 오류 발생 2. **대화 저장 전혀 안됨** - - conversation_logs 테이블 완전히 비어있음 (0 rows) + - conversation_log 테이블 완전히 비어있음 (0 rows) - 게이트웨이 로그에 저장 API 호출 없음 - DB 설정 오류 (auth_db → main_db) @@ -27,28 +27,28 @@ ### 2.1 문제점 #### 다양한 ID 타입 혼재 -- **UUID**: users.id, workspace_members.id, slack_user_mapping.user_id +- **UUID**: users.id, workspace_member.id, slack_user_mapping.user_id - **VARCHAR**: robeing_id, slack_user_id, slack_id, channel_id -- **INTEGER**: conversation_logs.id, gmail_tokens.id +- **INTEGER**: conversation_log.id, gmail_token.id #### 2025-08-28 확인 -- gmail_tokens.slack_user_id: VARCHAR(100) -- gmail_tokens.user_id: UUID (FK → users.id) +- gmail_token.slack_user_id: VARCHAR(100) +- gmail_token.user_id: UUID (FK → users.id) - Slack ID와 UUID 동시 저장 #### 변환 문제 - UUID ↔ Slack ID 변환 로직 불일치 -- conversation_logs의 user_id(UUID)에 Slack ID 저장 시도로 실패 +- conversation_log의 user_id(UUID)에 Slack ID 저장 시도로 실패 ### 2.2 테이블별 ID 현황 | 테이블 | Primary Key | 외래 키/참조 ID | |--------|------------|---------------| | **users** | id (UUID) | oauth_id (VARCHAR) | -| **workspace_members** | id (UUID) | user_id (UUID), workspace_id (UUID), robeing_id (VARCHAR) | -| **gmail_tokens** | id (INT) | user_id (UUID), slack_id (VARCHAR), robeing_id (VARCHAR) | +| **workspace_member** | id (UUID) | user_id (UUID), workspace_id (UUID), robeing_id (VARCHAR) | +| **gmail_token** | id (INT) | user_id (UUID), slack_id (VARCHAR), robeing_id (VARCHAR) | | **slack_user_mapping** | id (UUID) | user_id (UUID), slack_user_id (VARCHAR), workspace_member_id (UUID) | -| **conversation_logs** | id (INT) | user_id (UUID), slack_user_id (VARCHAR)*, robeing_id (VARCHAR) | +| **conversation_log** | id (INT) | user_id (UUID), slack_user_id (VARCHAR)*, robeing_id (VARCHAR) | *slack_user_id는 이 문제 해결을 위해 새로 추가한 컬럼 @@ -60,13 +60,13 @@ ``` [Slack ID] ──┬──> [slack_user_mapping] ──> [users.id (UUID)] │ - ├──> [gmail_tokens.slack_id] + ├──> [gmail_token.slack_id] │ - └──> [conversation_logs.slack_user_id] + └──> [conversation_log.slack_user_id] -[users.id] ──┬──> [workspace_members.user_id] - ├──> [gmail_tokens.user_id] - ├──> [conversation_logs.user_id] +[users.id] ──┬──> [workspace_member.user_id] + ├──> [gmail_token.user_id] + ├──> [conversation_log.user_id] └──> [robeing_stats.user_id] ``` @@ -86,10 +86,10 @@ U092F7FQ55L | cdctfm ### 4.1 단기 해결책 (즉시 적용) ✅ 완료 ```sql -- 1. user_id를 nullable로 변경 -ALTER TABLE conversation_logs ALTER COLUMN user_id DROP NOT NULL; +ALTER TABLE conversation_log ALTER COLUMN user_id DROP NOT NULL; -- 2. slack_user_id 컬럼 추가 -ALTER TABLE conversation_logs ADD COLUMN slack_user_id VARCHAR(100); +ALTER TABLE conversation_log ADD COLUMN slack_user_id VARCHAR(100); ``` ### 4.2 중기 해결책 (표준화) @@ -100,8 +100,8 @@ ALTER TABLE conversation_logs ADD COLUMN slack_user_id VARCHAR(100); **작업 필요**: ```sql --- gmail_tokens 테이블 컬럼명 변경 -ALTER TABLE gmail_tokens RENAME COLUMN slack_id TO slack_user_id; +-- gmail_token 테이블 컬럼명 변경 +ALTER TABLE gmail_token RENAME COLUMN slack_id TO slack_user_id; ``` ### 4.3 장기 해결책 (구조 개선) @@ -124,7 +124,7 @@ SELECT DISTINCT wm.robeing_id FROM users u LEFT JOIN slack_user_mapping sum ON u.id = sum.user_id -LEFT JOIN workspace_members wm ON u.id = wm.user_id; +LEFT JOIN workspace_member wm ON u.id = wm.user_id; ``` --- @@ -163,8 +163,8 @@ DATABASE_URL=postgresql://robeings:robeings@localhost:5433/main_db ## 6. 작업 완료 현황 -1. ✅ conversation_logs에 slack_user_id 추가 (완료) -2. ✅ gmail_tokens의 slack_user_id 컬럼 확인 (이미 존재, slack_id 컬럼 없음 - 2025-08-27 확인) +1. ✅ conversation_log에 slack_user_id 추가 (완료) +2. ✅ gmail_token의 slack_user_id 컬럼 확인 (이미 존재, slack_id 컬럼 없음 - 2025-08-27 확인) 3. ✅ **뉴스 키워드 하드코딩 제거** (2025-08-26 21:00 완료) - rb8001/app/skills/dm_skill.py 수정 (커밋: aed931e) - user_preferences 테이블 활용 @@ -180,7 +180,7 @@ DATABASE_URL=postgresql://robeings:robeings@localhost:5433/main_db ### 7.1 대화 저장 확인 ```sql -- 저장된 대화 확인 -SELECT COUNT(*) FROM conversation_logs; +SELECT COUNT(*) FROM conversation_log; -- 최근 대화 로그 SELECT @@ -189,7 +189,7 @@ SELECT cl.message, cl.response, cl.timestamp -FROM conversation_logs cl +FROM conversation_log cl ORDER BY cl.timestamp DESC LIMIT 5; ``` @@ -204,7 +204,7 @@ SELECT wm.robeing_id FROM slack_user_mapping sum JOIN users u ON sum.user_id = u.id -LEFT JOIN workspace_members wm ON u.id = wm.user_id; +LEFT JOIN workspace_member wm ON u.id = wm.user_id; ``` --- diff --git a/troubleshooting/250826_rb8001_conversation_storage_failure.md b/troubleshooting/250826_rb8001_conversation_storage_failure.md index 2b41e5e..c9ea313 100644 --- a/troubleshooting/250826_rb8001_conversation_storage_failure.md +++ b/troubleshooting/250826_rb8001_conversation_storage_failure.md @@ -3,7 +3,7 @@ ## 작성일: 2025-08-26 ## 작성자: 51124 서버 담당 ## 상태: ✅ 완전 해결 (ChromaDB ✅, PostgreSQL ✅, Foreign key ✅) -## 영향: PostgreSQL conversation_logs 정상 저장 +## 영향: PostgreSQL conversation_log 정상 저장 ## 최종 업데이트: 2025-08-26 19:30 --- @@ -51,12 +51,12 @@ LINE 1: ... VALUES ('rb8001', 'test_user_123', 'web', ... ### 2.3 PostgreSQL 스키마 문제 ```sql --- conversation_logs 테이블 스키마 +-- conversation_log 테이블 스키마 user_id UUID -- 문제: UUID 타입만 허용 slack_user_id VARCHAR(100) -- 추가됨 (250826 문서) -- 실제 저장 시도 -INSERT INTO conversation_logs (user_id, ...) +INSERT INTO conversation_log (user_id, ...) VALUES ('test_user_123', ...) -- 실패: UUID 형식 아님 ``` @@ -168,7 +168,7 @@ curl -X POST http://localhost:8001/api/message \ # PostgreSQL 확인 psql -h localhost -p 5433 -U robeings -d main_db \ - -c "SELECT * FROM conversation_logs ORDER BY timestamp DESC LIMIT 1;" + -c "SELECT * FROM conversation_log ORDER BY timestamp DESC LIMIT 1;" # ChromaDB 확인 (수정 후) docker exec rb8001 python -c " @@ -204,7 +204,7 @@ print('Collections:', client.list_collections()) ### 데이터 위치 - ChromaDB: `/home/admin/ivada_project/rb8001/chroma_db/` -- PostgreSQL: `main_db.conversation_logs` 테이블 +- PostgreSQL: `main_db.conversation_log` 테이블 --- @@ -231,7 +231,7 @@ print('Collections:', client.list_collections()) ### 12.2 ⚠️ 남은 문제 1. **51124 서버 rb8001**: - - conversation_logs 저장 안됨 (최근 데이터 14시간 전) + - conversation_log 저장 안됨 (최근 데이터 14시간 전) - UUID 타입 에러로 PostgreSQL 저장 실패 중 - ChromaDB만 저장되고 PostgreSQL은 실패 diff --git a/troubleshooting/250826_slack_id_column_standardization.md b/troubleshooting/250826_slack_id_column_standardization.md index 8cb9215..da2fa20 100644 --- a/troubleshooting/250826_slack_id_column_standardization.md +++ b/troubleshooting/250826_slack_id_column_standardization.md @@ -15,7 +15,7 @@ |--------|------------|------------|------| | slack_user_mapping | slack_user_id | slack_user_id | VARCHAR(100) | | gmail_token | ~~slack_id~~ ❌ | **slack_user_id** ✅ | VARCHAR(100) | -| conversation_logs | slack_user_id | slack_user_id | VARCHAR(100) | +| conversation_log | slack_user_id | slack_user_id | VARCHAR(100) | ### ✅ 적용 완료 diff --git a/troubleshooting/250827_UUID_username_혼용_CRITICAL.md b/troubleshooting/250827_UUID_username_혼용_CRITICAL.md index 43f56df..b76511c 100644 --- a/troubleshooting/250827_UUID_username_혼용_CRITICAL.md +++ b/troubleshooting/250827_UUID_username_혼용_CRITICAL.md @@ -83,7 +83,7 @@ const userId = localStorage.getItem('user_id') || 'default_user'; ### 2.5 Database ```sql --- conversation_logs 테이블 +-- conversation_log 테이블 user_id UUID -- UUID 타입 요구 slack_user_id VARCHAR(100) -- username이 여기 저장됨 @@ -179,14 +179,14 @@ SELECT id, username FROM users WHERE username='happybell80'; # database.py:184: SELECT id::text as user_id # username → UUID 변환 정상 작동 -# conversation_logs 확인 (51124 보고) +# conversation_log 확인 (51124 보고) # user_id: NULL, slack_user_id: 'happybell80' # "Non-UUID user_id" 에러 발생 ``` ### 5.2 수정 후 검증 - JWT `sub` 필드가 UUID 형식 (36자) -- conversation_logs.user_id에 UUID 저장 +- conversation_log.user_id에 UUID 저장 - ChromaDB metadata.user_id가 UUID --- @@ -204,7 +204,7 @@ SELECT id, username FROM users WHERE username='happybell80'; ## 7. 관련 문서 -- [ID 체계 정리 (250826)](./250826_id_체계_정리_및_conversation_logs_문제_해결.md) +- [ID 체계 정리 (250826)](./250826_id_체계_정리_및_conversation_log_문제_해결.md) - [JWT 인증 구현 (250827)](./250827_JWT_인증_구현_COMPLETED.md) - [Slack ID 표준화 (250826)](./250826_slack_id_column_standardization.md) diff --git a/troubleshooting/250827_frontend_backend_preferences_API_연동_완료.md b/troubleshooting/250827_frontend_backend_preferences_API_연동_완료.md index 991298a..264832e 100644 --- a/troubleshooting/250827_frontend_backend_preferences_API_연동_완료.md +++ b/troubleshooting/250827_frontend_backend_preferences_API_연동_완료.md @@ -82,7 +82,7 @@ const activities: ActivityLog[] = [...]; // 하드코딩 const scheduledTasks: ScheduledTask[] = [...]; // 하드코딩 ``` - 실제 데이터 조회 API 없음 -- conversation_logs 테이블 조회 엔드포인트 필요 +- conversation_log 테이블 조회 엔드포인트 필요 ### 3.4 ✅ 해결됨: API 구현 - **robeing-monitor**: preferences API 완전 구현 diff --git a/troubleshooting/250827_happybell80_긴급이슈점검및코드업데이트.md b/troubleshooting/250827_happybell80_긴급이슈점검및코드업데이트.md index a0aa3bb..00be29b 100644 --- a/troubleshooting/250827_happybell80_긴급이슈점검및코드업데이트.md +++ b/troubleshooting/250827_happybell80_긴급이슈점검및코드업데이트.md @@ -148,7 +148,7 @@ rb8001이 모든 사용자 대화를 하나의 ChromaDB 컬렉션에 저장: - 자동 갱신 실패 시 알림 2. **DB 컬럼명 표준화** - - gmail_tokens.slack_id → slack_user_id + - gmail_token.slack_id → slack_user_id - 서버 작업 필요 --- diff --git a/troubleshooting/250828_UUID_통합_및_사용자_격리_계획.md b/troubleshooting/250828_UUID_통합_및_사용자_격리_계획.md index ae1eed9..1ed66e3 100644 --- a/troubleshooting/250828_UUID_통합_및_사용자_격리_계획.md +++ b/troubleshooting/250828_UUID_통합_및_사용자_격리_계획.md @@ -67,7 +67,7 @@ workspace (로빙 1개) ### Phase 3: 사용자 격리 ✅ 완료 (2025-08-28 18:15) - [x] ChromaDB 사용자별 컬렉션 (rb8001_{user_uuid}) -- [x] conversation_logs UUID 저장 구현 +- [x] conversation_log UUID 저장 구현 - [x] 완전한 사용자 대화 격리 --- @@ -108,7 +108,7 @@ async def get_uuid(slack_id: str): - rb8001: JWT 검증 구현 ✅ - rb8001: Slack ID → UUID 자동 변환 ✅ - ChromaDB: 사용자별 컬렉션 격리 ✅ -- conversation_logs: UUID 저장 ✅ +- conversation_log: UUID 저장 ✅ --- @@ -117,7 +117,7 @@ async def get_uuid(slack_id: str): ### ✅ 검증 완료 1. **JWT 인증**: UUID 추출 성공 (1e16e9d5-59f3-54da-a661-8abeabff4230) 2. **ChromaDB 격리**: rb8001_{user_uuid} 컬렉션 생성 확인 -3. **PostgreSQL**: conversation_logs에 UUID 저장 확인 +3. **PostgreSQL**: conversation_log에 UUID 저장 확인 4. **Slack 변환**: Slack ID → UUID 자동 변환 작동 5. **metadata None 처리**: Frontend 접속 시 slack_user_id=None 필터링 구현 ([250828_ChromaDB_metadata_None_error.md](250828_ChromaDB_metadata_None_error.md)) diff --git a/troubleshooting/250828_conversation_logs_channel_구분_개선.md b/troubleshooting/250828_conversation_logs_channel_구분_개선.md index 299b8b0..a54f6a4 100644 --- a/troubleshooting/250828_conversation_logs_channel_구분_개선.md +++ b/troubleshooting/250828_conversation_logs_channel_구분_개선.md @@ -1,7 +1,7 @@ -# conversation_logs 채널 구분 개선 +# conversation_log 채널 구분 개선 **날짜**: 2025-08-28 -**테이블**: conversation_logs +**테이블**: conversation_log **상태**: ✅ 해결 완료 (2025-08-28) ## 현재 상황 (DB 확인) @@ -39,7 +39,7 @@ Slack DM은 여전히 "D..."로 정상 저장됩니다. ### Phase 2: DB 스키마 개선 (선택) ```sql -ALTER TABLE conversation_logs +ALTER TABLE conversation_log ADD COLUMN thread_ts VARCHAR(20), -- 쓰레드 구분 ADD COLUMN channel_type VARCHAR(20); -- public_channel/private_channel/im/mpim ``` diff --git a/troubleshooting/250831_rb8001_context_race_condition_fix.md b/troubleshooting/250831_rb8001_context_race_condition_fix.md index e354b93..c0265e2 100644 --- a/troubleshooting/250831_rb8001_context_race_condition_fix.md +++ b/troubleshooting/250831_rb8001_context_race_condition_fix.md @@ -70,7 +70,7 @@ async def get_user_mapping(identifier: str, db: Session = Depends(get_db)): query = text(""" SELECT u.id as user_id, u.username, u.email, wm.robeing_id FROM users u - LEFT JOIN workspace_members wm ON u.id = wm.user_id + LEFT JOIN workspace_member wm ON u.id = wm.user_id WHERE u.id = :user_id """) result = db.execute(query, {"user_id": identifier}).first() @@ -144,7 +144,7 @@ async def route_message(self, message: str, user_id: str, ...): ### 2.7 Gateway 기본값 변경 **파일**: `robeing-gateway/app/database.py` ```python -# spaceboum 등 workspace_members 없는 사용자를 위해 +# spaceboum 등 workspace_member 없는 사용자를 위해 DEFAULT_ROBEING_PORT = int(os.getenv('DEFAULT_ROBEING_PORT', '8001')) # 10508 → 8001 DEFAULT_ROBEING_ID = os.getenv('DEFAULT_ROBEING_ID', 'rb8001') # rb10508_test → rb8001 ``` diff --git a/troubleshooting/250831_rb8001_postgresql_context_integration.md b/troubleshooting/250831_rb8001_postgresql_context_integration.md index 349f63d..db61719 100644 --- a/troubleshooting/250831_rb8001_postgresql_context_integration.md +++ b/troubleshooting/250831_rb8001_postgresql_context_integration.md @@ -10,7 +10,7 @@ ## 1. 문제 상황 - **현상**: rb8001이 ChromaDB 벡터 검색만 참조하여 엉뚱한 답변 -- **원인**: PostgreSQL conversation_logs의 최근 대화 미참조 +- **원인**: PostgreSQL conversation_log의 최근 대화 미참조 - **영향**: 직전 대화 컨텍스트 손실, 일관성 없는 응답 - **테스트**: "내 이름은 김종태" → "내 이름은?" → "모릅니다" 응답 diff --git a/troubleshooting/250831_slack_login_workspace_assignment_issue.md b/troubleshooting/250831_slack_login_workspace_assignment_issue.md index cdbad0a..cf435a6 100644 --- a/troubleshooting/250831_slack_login_workspace_assignment_issue.md +++ b/troubleshooting/250831_slack_login_workspace_assignment_issue.md @@ -12,8 +12,8 @@ Slack OAuth로 로그인한 사용자가 Robeing 워크스페이스에 자동 할당되지 않음 ### 테스트 케이스 -- spaceboum (Google 로그인): workspace_members 없음 → 기본값 rb8001 -- 홍태주 (Slack 로그인): workspace_members 없음 → 기본값 rb8001 +- spaceboum (Google 로그인): workspace_member 없음 → 기본값 rb8001 +- 홍태주 (Slack 로그인): workspace_member 없음 → 기본값 rb8001 --- @@ -34,7 +34,7 @@ Slack OAuth로 로그인한 사용자가 Robeing 워크스페이스에 자동 - 매핑 있으면: 기존 User 사용 - 매핑 없으면: 새 User 생성 -4. **workspace_members 추가**: ❌ **없음** +4. **workspace_member 추가**: ❌ **없음** - Robeing 워크스페이스 할당 로직 부재 - SlackWorkspace ≠ Robeing Workspace (별개 개념) @@ -45,7 +45,7 @@ Slack OAuth로 로그인한 사용자가 Robeing 워크스페이스에 자동 ### 핵심 개념: team_id = workspace_id - **Slack team_id**: Slack 워크스페이스의 고유 ID (T로 시작) -- **workspace_members.workspace_id**: team_id를 저장하는 필드 +- **workspace_member.workspace_id**: team_id를 저장하는 필드 - **즉, team_id가 그대로 workspace_id로 사용됨** #### slack_workspaces 테이블 @@ -53,7 +53,7 @@ Slack OAuth로 로그인한 사용자가 Robeing 워크스페이스에 자동 - **주요 컬럼**: team_id (Slack ID), team_name, bot_token - **현재 데이터**: GoodGang Labs (T035VFRKCN6), test (T097FCTDVEX) -#### workspace_members 테이블 +#### workspace_member 테이블 - **용도**: 사용자와 Slack 워크스페이스 연결 - **주요 컬럼**: user_id, workspace_id (=team_id), robeing_id - **문제**: Slack 로그인 시 자동 추가 안 됨 @@ -64,13 +64,13 @@ Slack OAuth로 로그인한 사용자가 Robeing 워크스페이스에 자동 | users | 사용자 정보 | ✅ 생성됨 | | slack_user_mapping | Slack ID ↔ UUID | ✅ 생성됨 | | slack_workspaces | Slack 팀 정보 | ✅ 조회됨 | -| workspace_members | **사용자-워크스페이스 멤버십** | ❌ 추가 안 됨 | +| workspace_member | **사용자-워크스페이스 멤버십** | ❌ 추가 안 됨 | --- ## 4. 영향 -- 모든 Slack 로그인 사용자가 workspace_members 없음 +- 모든 Slack 로그인 사용자가 workspace_member 없음 - Gateway가 기본값(rb8001 또는 rb10508) 사용 - 사용자별 Robeing 할당 불가능 @@ -82,10 +82,10 @@ Slack OAuth로 로그인한 사용자가 Robeing 워크스페이스에 자동 304번 줄 이후 추가: ```python -# workspace_members 추가 (team_id = workspace_id) +# workspace_member 추가 (team_id = workspace_id) if team_id and user: db.execute(text(""" - INSERT INTO workspace_members (user_id, workspace_id, robeing_id) + INSERT INTO workspace_member (user_id, workspace_id, robeing_id) VALUES (:user_id, :workspace_id, :robeing_id) ON CONFLICT (user_id, workspace_id) DO UPDATE SET robeing_id = :robeing_id @@ -98,8 +98,8 @@ if team_id and user: ### 수동 해결 SQL (참고용) ```sql --- happybell80 사용자 workspace_members 추가 -INSERT INTO workspace_members (user_id, workspace_id, robeing_id) +-- happybell80 사용자 workspace_member 추가 +INSERT INTO workspace_member (user_id, workspace_id, robeing_id) VALUES ( '1e16e9d5-59f3-54da-a661-8abeabff4230', -- happybell80 user_id 'T035VFRKCN6', -- GoodGang Labs team_id diff --git a/troubleshooting/250831_slack_oauth_login_implementation.md b/troubleshooting/250831_slack_oauth_login_implementation.md index 0128288..7c6b222 100644 --- a/troubleshooting/250831_slack_oauth_login_implementation.md +++ b/troubleshooting/250831_slack_oauth_login_implementation.md @@ -23,7 +23,7 @@ ### 1. DB 스키마 불일치 ⚠️ **문제점**: -- `companies` 테이블과 `workspaces` 테이블이 공존 +- `company` 테이블과 `workspaces` 테이블이 공존 - `SlackWorkspace` 모델이 `company_id`를 참조하는데 모델은 `workspace_id` 기대 - Relationship 주석 처리로 임시 해결 @@ -31,13 +31,13 @@ ```python # app/models/workspace.py class SlackWorkspace(Base): - company_id = Column(UUID, ForeignKey("companies.id")) # 실제 DB - # workspace_id로 되어야 하는데 companies 테이블 참조 중 + company_id = Column(UUID, ForeignKey("company.id")) # 실제 DB + # workspace_id로 되어야 하는데 company 테이블 참조 중 # relationship 주석 처리됨 ``` **해결 방안**: -1. `companies` 테이블 데이터를 `workspaces`로 마이그레이션 +1. `company` 테이블 데이터를 `workspaces`로 마이그레이션 2. FK 관계 정리 3. 모델 통일 @@ -101,7 +101,7 @@ login_callback_url = "https://auth.ro-being.com/auth/slack/login/callback" # ## 향후 작업 ### 긴급도 높음 🔴 -1. DB 스키마 통일 (companies → workspaces) +1. DB 스키마 통일 (company → workspaces) 2. Frontend 인증 방식 통일 ### 중간 우선순위 🟡 diff --git a/troubleshooting/250901_hongtaeju_slack_oauth_mapping_failure.md b/troubleshooting/250901_hongtaeju_slack_oauth_mapping_failure.md index e716426..548b0cd 100644 --- a/troubleshooting/250901_hongtaeju_slack_oauth_mapping_failure.md +++ b/troubleshooting/250901_hongtaeju_slack_oauth_mapping_failure.md @@ -17,7 +17,7 @@ ```sql -- 확인 결과: 모두 0 rows SELECT * FROM slack_user_mapping WHERE user_id = '237494f7-061c-484c-a4f7-f500611e32f1'; -- ❌ -SELECT * FROM workspace_members WHERE user_id = '237494f7-061c-484c-a4f7-f500611e32f1'; -- ❌ +SELECT * FROM workspace_member WHERE user_id = '237494f7-061c-484c-a4f7-f500611e32f1'; -- ❌ SELECT * FROM user_preferences WHERE user_id = '237494f7-061c-484c-a4f7-f500611e32f1'; -- ❌ ``` @@ -25,11 +25,11 @@ SELECT * FROM user_preferences WHERE user_id = '237494f7-061c-484c-a4f7-f500611e auth-server의 Slack OAuth 콜백(`/auth/slack/login/callback`)에서: 1. ✅ users 테이블 생성/업데이트 2. ❌ slack_user_mapping 생성 안 함 -3. ❌ workspace_members 추가 안 함 +3. ❌ workspace_member 추가 안 함 4. ❌ user_preferences 초기화 안 함 ## 4. 영향 -- workspace_members 자동 추가 구현됨(9/11), 기본 robeing 할당 정상 +- workspace_member 자동 추가 구현됨(9/11), 기본 robeing 할당 정상 - slack_user_mapping 의존 제거(9/11) → 이메일/기타 식별 병행 - 상세: [/DOCS/troubleshooting/250831_slack_login_workspace_assignment_issue.md](./250831_slack_login_workspace_assignment_issue.md) @@ -38,8 +38,8 @@ auth-server의 Slack OAuth 콜백(`/auth/slack/login/callback`)에서: -- 1. username 설정 UPDATE users SET username = 'hongtj' WHERE id = '237494f7-061c-484c-a4f7-f500611e32f1'; --- 2. workspace_members 추가 (team_id 확인 필요) -INSERT INTO workspace_members (user_id, workspace_id, robeing_id) +-- 2. workspace_member 추가 (team_id 확인 필요) +INSERT INTO workspace_member (user_id, workspace_id, robeing_id) VALUES ('237494f7-061c-484c-a4f7-f500611e32f1', 'T035VFRKCN6', 'rb8001'); ``` diff --git a/troubleshooting/250902_slack_bot_install_url_analysis.md b/troubleshooting/250902_slack_bot_install_url_analysis.md index 0b619ee..3005e28 100644 --- a/troubleshooting/250902_slack_bot_install_url_analysis.md +++ b/troubleshooting/250902_slack_bot_install_url_analysis.md @@ -127,7 +127,7 @@ state={RANDOM_STATE} **관련 테이블:** - workspaces: robeing_port, subdomain 컬럼 보유 -- workspace_members: workspace_id, user_id, robeing_id 매핑 +- workspace_member: workspace_id, user_id, robeing_id 매핑 - slack_user_mapping: 사용자 매핑 ### 5.2 Slack 설정 정보 @@ -144,7 +144,7 @@ im:read, im:history, users:read, team:read, files:read, app_mentions:read **workspace_id 하드코딩 문제 ✅ 해결:** - ~~TODO 주석만 있고 구현 안 됨~~ - ~~모든 사용자가 동일 workspace_id 사용 (550e8400-e29b-41d4-a716-446655440000)~~ -- ~~workspace_members 조회 코드 주석 처리됨~~ +- ~~workspace_member 조회 코드 주석 처리됨~~ **해결 내용:** 1. ~~WorkspaceMember 조회 로직 활성화 (Line 411-419)~~ → sqlalchemy text() 직접 쿼리로 변경 @@ -161,9 +161,9 @@ im:read, im:history, users:read, team:read, files:read, app_mentions:read **WorkspaceMember 모델 이슈:** - app/models/workspace.py에 WorkspaceMember 클래스 정의 없음 -- workspace_members 테이블 직접 쿼리로 해결 -- ~~`SELECT workspace_id FROM workspace_members WHERE user_id = :user_id::uuid AND is_active = true`~~ -- `SELECT workspace_id FROM workspace_members WHERE user_id = (:user_id)::uuid AND is_active = true` (괄호 필수) +- workspace_member 테이블 직접 쿼리로 해결 +- ~~`SELECT workspace_id FROM workspace_member WHERE user_id = :user_id::uuid AND is_active = true`~~ +- `SELECT workspace_id FROM workspace_member WHERE user_id = (:user_id)::uuid AND is_active = true` (괄호 필수) ### 5.4 추가 이슈 해결 (2025-09-02 저녁) @@ -172,10 +172,10 @@ im:read, im:history, users:read, team:read, files:read, app_mentions:read - Slack App 설정: 3개 URL 모두 등록 (callback, login/callback, passport/callback) **SlackWorkspace 모델 불일치:** -- 모델 정의: `company_id` (Line 44, ForeignKey는 companies.id) +- 모델 정의: `company_id` (Line 44, ForeignKey는 company.id) - 코드 사용: `workspace_id` 시도 → `company_id`로 수정 필요 - Line 542, 557, 631, 674, 713: workspace_id → company_id -- DB 현실: companies 테이블 없음, workspaces 테이블 사용 중 +- DB 현실: company 테이블 없음, workspaces 테이블 사용 중 **Company-X 설정 상태:** - workspace_id: 99d22d6b-d327-4fa4-bd2f-d228c11056e2 @@ -186,15 +186,15 @@ im:read, im:history, users:read, team:read, files:read, app_mentions:read ### 5.5 최종 이슈 (✅ 해결 완료) **Foreign Key 문제 해결:** -- 모델: `ForeignKey("companies.id")` 참조 -- ~~실제 DB: companies 테이블 없음~~ → **companies 테이블 존재 확인됨** +- 모델: `ForeignKey("company.id")` 참조 +- ~~실제 DB: company 테이블 없음~~ → **company 테이블 존재 확인됨** - 해결 내용: - 1. companies 테이블에 Company-X 레코드 추가 (ID: 99d22d6b-d327-4fa4-bd2f-d228c11056e2) + 1. company 테이블에 Company-X 레코드 추가 (ID: 99d22d6b-d327-4fa4-bd2f-d228c11056e2) 2. 기존 slack_workspaces 레코드의 company_id 업데이트 완료 3. Foreign Key 제약 조건 정상 작동 **최종 DB 상태 (2025-09-02 20:40):** -- companies 테이블: Company-X (8001 포트, active 상태) +- company 테이블: Company-X (8001 포트, active 상태) - workspaces 테이블: Company-X (8명 멤버) - slack_workspaces: T097FCTDVEX → Company-X 연결 완료 - 봇 설치 준비 완료 diff --git a/troubleshooting/250903_frontend_conversation_order_reversed.md b/troubleshooting/250903_frontend_conversation_order_reversed.md index 9b9de90..2f9e38a 100644 --- a/troubleshooting/250903_frontend_conversation_order_reversed.md +++ b/troubleshooting/250903_frontend_conversation_order_reversed.md @@ -68,6 +68,6 @@ response.messages // reverse() 없이 그대로 사용 - **결과**: 과거→최신 시간순 + 사용자→로빙 대화쌍 순서 모두 정상 ## 7. 추가 확인 사항 -- **DB 저장 문제**: conversation_logs 테이블에 Slack 대화 저장 안 됨 (별개 이슈) +- **DB 저장 문제**: conversation_log 테이블에 Slack 대화 저장 안 됨 (별개 이슈) - **API 엔드포인트**: /api/conversations/recent 404 에러 (51124 서버) - **테이블 컬럼**: message, response, timestamp 사용 (user_message 컬럼 없음) \ No newline at end of file diff --git a/troubleshooting/250903_gmail_token_permission_denied_issue.md b/troubleshooting/250903_gmail_token_permission_denied_issue.md index 59e49cc..9d8eea8 100644 --- a/troubleshooting/250903_gmail_token_permission_denied_issue.md +++ b/troubleshooting/250903_gmail_token_permission_denied_issue.md @@ -20,7 +20,7 @@ ## 3. 확인된 사실 (문서 기반) - 2025-08-25 DB 기반 토큰 저장으로 전환 완료 (마이그레이션 문서) -- auth-server는 gmail_tokens 테이블에만 토큰 저장 (시퀀스 다이어그램) +- auth-server는 gmail_token 테이블에만 토큰 저장 (시퀀스 다이어그램) - skill-email은 DB에서 토큰 조회하도록 설계됨 (서비스 간 직접 전달 없음) - Docker 컨테이너 /code 디렉토리 쓰기 권한 없음 (에러 메시지) - access_token, refresh_token은 TEXT 타입으로 암호화 저장 (테이블 스키마) @@ -67,5 +67,5 @@ 1. ✅ 프론트엔드 Gmail OAuth 성공 2. ✅ Permission denied 오류 없음 3. ✅ unknown_gmail.json 생성 시도 없음 -4. ✅ gmail_tokens 테이블 정상 저장 +4. ✅ gmail_token 테이블 정상 저장 5. ✅ 파일 시스템 의존성 완전 제거 \ No newline at end of file diff --git a/troubleshooting/250903_slack_chat_display_indicator.md b/troubleshooting/250903_slack_chat_display_indicator.md index 8a99c58..216a29c 100644 --- a/troubleshooting/250903_slack_chat_display_indicator.md +++ b/troubleshooting/250903_slack_chat_display_indicator.md @@ -4,7 +4,7 @@ 프론트엔드 대화창에서 슬랙/웹 대화 구분 불가 ## 해결 방법 -conversation_logs 테이블의 slack_user_id 필드(VARCHAR(100))를 활용하여 슬랙 대화 시각적 표시 +conversation_log 테이블의 slack_user_id 필드(VARCHAR(100))를 활용하여 슬랙 대화 시각적 표시 ## 수정된 파일 및 코드 @@ -15,7 +15,7 @@ conversation_logs 테이블의 slack_user_id 필드(VARCHAR(100))를 활용하 # get_recent_conversations() 함수 query = text(""" SELECT message, response, timestamp, slack_user_id # slack_user_id 추가 - FROM conversation_logs + FROM conversation_log WHERE user_id = :user_id ORDER BY timestamp DESC LIMIT :limit diff --git a/troubleshooting/250909_happybell80_gmail_refresh_token_불일치.md b/troubleshooting/250909_happybell80_gmail_refresh_token_불일치.md index 01a245d..d2a6dc8 100644 --- a/troubleshooting/250909_happybell80_gmail_refresh_token_불일치.md +++ b/troubleshooting/250909_happybell80_gmail_refresh_token_불일치.md @@ -40,7 +40,7 @@ HanYong: token_data 비어있음 (8/30 이후) -- 166번: token_data = jsonb_set(...) 사용 -- 개별 컬럼 삭제 (코드 수정 후) -ALTER TABLE gmail_tokens +ALTER TABLE gmail_token DROP COLUMN access_token, DROP COLUMN refresh_token, DROP COLUMN token_type, diff --git a/troubleshooting/250911_happybell80_PostgreSQL_테이블명_단수형_통일.md b/troubleshooting/250911_happybell80_PostgreSQL_테이블명_단수형_통일.md index 80d9c8a..9786959 100644 --- a/troubleshooting/250911_happybell80_PostgreSQL_테이블명_단수형_통일.md +++ b/troubleshooting/250911_happybell80_PostgreSQL_테이블명_단수형_통일.md @@ -35,7 +35,7 @@ | 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 | 98-112 | JOIN 쿼리 (workspace_member, 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 | 테이블 모델 정의 (avatar_url 컬럼) | @@ -48,14 +48,14 @@ |-----------|-----------|-----------| | auth-server/app/models/workspace.py | 15-31 | 테이블 모델 정의 | | auth-server/scripts/run_migration.py | 54 | SELECT id, name, subdomain, robeing_id FROM workspaces | -| auth-server/migrations/add_user_workspace_tables.sql | 25-28 | ALTER TABLE companies RENAME TO workspaces | +| auth-server/migrations/add_user_workspace_tables.sql | 25-28 | ALTER TABLE company RENAME TO workspaces | | robeing-gateway/app/database.py | 98-112 | JOIN 쿼리 | -| robeing-gateway/app/database.py | 216-230 | JOIN 쿼리 (workspace_members와 함께) | +| robeing-gateway/app/database.py | 216-230 | JOIN 쿼리 (workspace_member와 함께) | | robeing-gateway/app/models.py | 26-44 | 테이블 모델 정의 | ### 2.3 workspace_member 테이블 (실제 DB: workspace_member, 레코드 0건) **실제 DB 컬럼**: user_id(FK), role(user_role enum), created_at, updated_at -**코드 모델**: workspace_members 테이블 참조 (복수형 차이) +**코드 모델**: workspace_member 테이블 참조 (복수형 차이) | 파일 경로 | 라인 번호 | 작업 내용 | |-----------|-----------|-----------| @@ -90,13 +90,13 @@ ### 2.6 gmail_token 테이블 (실제 DB: gmail_token, 3건) **실제 DB 컬럼**: user_id(FK), token_data(jsonb), oauth_config(jsonb), created_at, updated_at -**코드 혼용**: auth-server는 gmail_tokens(복수)와 gmail_token(단수) 혼용 +**코드 혼용**: auth-server는 gmail_token(복수)와 gmail_token(단수) 혼용 | 파일 경로 | 라인 번호 | 작업 내용 | |-----------|-----------|-----------| | auth-server/app/providers/gmail_passport.py | 193 | INSERT INTO gmail_token (단수) | | auth-server/app/providers/gmail_passport.py | 264, 313, 354, 370 | gmail_token (단수) 사용 | -| auth-server/app/api/gmail_refresh.py | 36, 43, 115, 124, 173, 179 | gmail_tokens (복수) 사용 | +| auth-server/app/api/gmail_refresh.py | 36, 43, 115, 124, 173, 179 | gmail_token (복수) 사용 | | skill-email/services/db_credentials_provider.py | 60-70 | SELECT 쿼리 (is_equipped 필터) | | skill-email/services/db_credentials_provider.py | 163-177 | UPDATE 쿼리 | | skill-email/services/db_credentials_provider.py | 231-235 | COUNT 쿼리 | @@ -214,7 +214,7 @@ ## 4. 위험 요소 - 치명적 불일치 1. **테이블명 전체 불일치**: - - 코드: users, workspaces, workspace_members (복수형) + - 코드: users, workspaces, workspace_member (복수형) - DB: user, company/team, workspace_member (단수형) 2. **존재하지 않는 테이블 참조**: diff --git a/troubleshooting/250918_gmail_token_slack_user_id_column_missing.md b/troubleshooting/250918_gmail_token_slack_user_id_column_missing.md index 02e53ac..aa02929 100644 --- a/troubleshooting/250918_gmail_token_slack_user_id_column_missing.md +++ b/troubleshooting/250918_gmail_token_slack_user_id_column_missing.md @@ -11,7 +11,7 @@ ```python # 현재 코드 (잘못됨) cur.execute(""" - SELECT ... FROM gmail_tokens + SELECT ... FROM gmail_token WHERE slack_user_id = %s # 존재하지 않는 컬럼 """, (user_id,)) diff --git a/troubleshooting/250926_happybell80_UUID_원칙_위반_email_integration.md b/troubleshooting/250926_happybell80_UUID_원칙_위반_email_integration.md index f4f3560..795fa05 100644 --- a/troubleshooting/250926_happybell80_UUID_원칙_위반_email_integration.md +++ b/troubleshooting/250926_happybell80_UUID_원칙_위반_email_integration.md @@ -13,7 +13,7 @@ ### 발견된 위반 사항 #### 1. rb8001/app/skills/email_integration.py -- **잘못된 테이블명**: `gmail_tokens` → 실제는 `gmail_token` +- **잘못된 테이블명**: `gmail_token` → 실제는 `gmail_token` - **Slack ID 사용**: skill-email 호출 시 Slack ID 전달 - **미정의 변수**: `user_uuid` 변수 정의 없이 사용 (136줄) @@ -44,7 +44,7 @@ else: ``` ### 테이블명 수정 (완료) -- `gmail_tokens` → `gmail_token` +- `gmail_token` → `gmail_token` - `SELECT COUNT(*) FROM gmail_token WHERE user_id = %s` ## 남은 작업