diff --git a/300_architecture/sequences/auth_login_sequences.md b/300_architecture/sequences/auth_login_sequences.md
index 26ba7da..7561b0d 100644
--- a/300_architecture/sequences/auth_login_sequences.md
+++ b/300_architecture/sequences/auth_login_sequences.md
@@ -143,23 +143,25 @@ sequenceDiagram
SlackAPI-->>Auth: access_token, user info
Note over Auth: Slack User ID: U0925SXQFDK
- Auth->>Auth: UUID5 생성
- Note over Auth: namespace: 6ba7b810-9dad-11d1-80b4-00c04fd430c8
name: Slack User ID
UUID5 = uuid5(namespace, slack_id)
+ Auth->>DB: SELECT user_id FROM slack_user_mapping WHERE slack_user_id=?
+ Note over DB: Slack ID로 매핑 테이블 조회
- Auth->>DB: SELECT * FROM users WHERE id=?
- Note over DB: UUID5로 직접 조회
- alt 신규 사용자
+ alt 매핑 존재
+ DB-->>Auth: user_id (UUID)
+ Auth->>DB: SELECT * FROM users WHERE id=?
+ Note over DB: UUID로 사용자 정보 조회
+ DB-->>Auth: 사용자 정보
+ Auth->>DB: UPDATE users SET last_login=NOW()
+ else 매핑 없음 (신규)
+ Auth->>Auth: UUID 생성 (uuid.uuid4())
Auth->>Auth: username 생성
Note over Auth: slack_{slack_id[:8]}
Auth->>DB: INSERT INTO users
- Note over DB: id: UUID5
username: slack_U0925SXQ
email: slack.email
- else 기존 사용자
- Auth->>DB: UPDATE users
+ Note over DB: id: UUID
username: slack_U0925SXQ
email: slack.email
+ Auth->>DB: INSERT INTO slack_user_mapping
+ Note over DB: slack_user_id, user_id(UUID), workspace_id
end
- Auth->>DB: INSERT INTO slack_users
- Note over DB: slack_user_id, user_id(UUID), team_id
-
Auth-->>Slack: 로그인 성공 메시지
```
@@ -216,10 +218,10 @@ flowchart TD
D -->|No| F["uuid.uuid4() 생성"]
B -->|Slack OAuth| G[Slack ID 받음]
- G --> H["UUID5 생성
uuid5(namespace, slack_id)"]
- H --> I{기존 UUID 존재?}
+ G --> H[slack_user_mapping 테이블 조회]
+ H --> I{매핑 존재?}
I -->|Yes| E
- I -->|No| J[UUID5로 새 사용자]
+ I -->|No| J["uuid.uuid4() 생성
매핑 테이블에 저장"]
B -->|테스트 사용자| K[수동 UUID 할당]
K --> L["하드코딩 UUID
aaaaaaaa-aaaa..."]
@@ -307,7 +309,7 @@ stateDiagram-v2
식별 체계:
Primary Key: UUID (36자)
- Google 사용자: uuid4() 랜덤 생성
- - Slack 사용자: uuid5(namespace, slack_id) 결정적 생성
+ - Slack 사용자: uuid4() 랜덤 생성 후 매핑 테이블 저장
Unique Keys:
- email (OAuth provider에서 제공)
- username (사용자 정의 또는 자동 생성)
@@ -317,8 +319,8 @@ stateDiagram-v2
- users.id (UUID) ← slack_user_mapping.user_id
- users.id (UUID) ← robeing_stats.user_id
-UUID5 Namespace:
- 6ba7b810-9dad-11d1-80b4-00c04fd430c8
+매핑 방식:
+ slack_user_mapping 테이블을 통한 Slack ID → UUID 직접 조회
```
---
diff --git a/300_architecture/uuid_conversion_system.md b/300_architecture/uuid_conversion_system.md
index cda7043..9c1963c 100644
--- a/300_architecture/uuid_conversion_system.md
+++ b/300_architecture/uuid_conversion_system.md
@@ -7,7 +7,7 @@
## 1. 개요
-RO-BEING 시스템의 UUID 변환 체계 문서입니다. Google OAuth는 UUID4, Slack은 51123 DB 매핑 API를 사용합니다.
+RO-BEING 시스템의 UUID 변환 체계 문서입니다. Google OAuth와 Slack 모두 UUID4를 생성하며, Slack은 slack_user_mapping 테이블을 통해 매핑합니다.
---
@@ -18,7 +18,7 @@ RO-BEING 시스템의 UUID 변환 체계 문서입니다. Google OAuth는 UUID4,
| 타입 | 생성 방식 | 용도 | 특징 |
|------|----------|------|------|
| UUID4 | 랜덤 생성 | Google OAuth 사용자 | auth-server에서 생성 |
-| UUID5 | 네임스페이스 해시 | robeing-monitor 사용 중 | namespace 확인 필요 |
+| UUID | 매핑 테이블 조회 | Slack 사용자 | slack_user_mapping 테이블 사용 |
| DB 매핑 | slack_user_mapping | Slack 사용자 매핑 | 실제 사용 여부 확인 필요 |
### 2.2 네임스페이스
@@ -70,12 +70,12 @@ class GoogleAuthHandler:
return new_user_id
```
-### 3.2 Slack 사용자 (UUID5)
+### 3.2 Slack 사용자 (UUID 매핑)
```mermaid
flowchart LR
A[Slack 이벤트] --> B[Slack User ID]
- B --> C[UUID5 생성]
+ B --> C[slack_user_mapping 조회]
C --> D[네임스페이스 + Slack ID]
D --> E[SHA-1 해시]
E --> F[결정적 UUID]
@@ -92,11 +92,12 @@ class SlackUserHandler:
NAMESPACE = uuid.UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
def get_user_uuid(self, slack_user_id: str) -> str:
- """Slack User ID를 UUID5로 변환"""
- return str(uuid.uuid5(self.NAMESPACE, slack_user_id))
+ """Slack User ID를 UUID로 변환 (매핑 테이블 조회)"""
+ # slack_user_mapping 테이블에서 조회
+ return get_uuid_from_mapping(slack_user_id)
async def get_or_create_user(self, slack_user_id: str, slack_user_info: dict):
- # UUID5 생성 (항상 같은 결과)
+ # UUID 매핑 조회 (테이블에서 조회)
user_uuid = self.get_user_uuid(slack_user_id)
# 기존 사용자 확인
@@ -197,18 +198,18 @@ INSERT INTO users (id, username, email, name) VALUES
('cccccccc-cccc-cccc-cccc-cccccccccccc', 'test_user', 'test@example.com', 'Test User');
```
-### 5.2 Slack 테스트 사용자 UUID5 예시
+### 5.2 Slack 테스트 사용자 UUID 예시
```python
# Slack User ID 예시
slack_ids = {
- "U0925SXQFDK": "종태", # UUID5: 생성된 값
- "U0123ABCDEF": "테스트" # UUID5: 생성된 값
+ "U0925SXQFDK": "종태", # UUID: 매핑 테이블 조회
+ "U0123ABCDEF": "테스트" # UUID: 매핑 테이블 조회
}
-# UUID5 생성 예시
+# UUID 매핑 조회 예시
for slack_id, name in slack_ids.items():
- user_uuid = uuid.uuid5(NAMESPACE, slack_id)
+ user_uuid = get_uuid_from_mapping(slack_id) # DB 조회
print(f"{name} ({slack_id}): {user_uuid}")
```
@@ -321,7 +322,7 @@ async def debug_uuid(username: str):
| 문제 | 원인 | 해결 방법 |
|------|------|----------|
-| UUID 불일치 | Slack ID 변경 | UUID5는 결정적이므로 같은 Slack ID는 항상 같은 UUID |
+| UUID 불일치 | Slack ID 변경 | 매핑 테이블을 통해 일관된 UUID 관리 |
| 중복 UUID | UUID4 충돌 (매우 드물음) | 재생성 또는 UNIQUE 제약 확인 |
| 변환 실패 | username 없음 | users 테이블 username 필드 확인 |
| 캐시 불일치 | TTL 만료 전 DB 변경 | 캐시 무효화 또는 TTL 단축 |
@@ -333,7 +334,7 @@ async def debug_uuid(username: str):
SELECT
CASE
WHEN id::text LIKE '________-____-4___-____-____________' THEN 'UUID4 (Google)'
- WHEN id::text LIKE '________-____-5___-____-____________' THEN 'UUID5 (Slack)'
+ WHEN source = 'slack' THEN 'UUID (Slack 매핑)'
ELSE 'Other'
END as uuid_type,
COUNT(*) as count
@@ -345,12 +346,12 @@ SELECT username, id, oauth_provider
FROM users
WHERE username = 'happybell80';
--- Slack 사용자 UUID5 검증
+-- Slack 사용자 UUID 검증
SELECT
username,
id,
id = uuid_generate_v5('6ba7b810-9dad-11d1-80b4-00c04fd430c8'::uuid,
- SUBSTRING(username FROM 7)) as is_valid_uuid5
+ SUBSTRING(username FROM 7)) as is_valid_uuid
FROM users
WHERE oauth_provider = 'slack';
```
@@ -379,7 +380,7 @@ class SecureUUIDHandler:
### 10.2 UUID 추측 방지
- UUID4: 122비트 랜덤 엔트로피로 추측 불가능
-- UUID5: Slack ID를 모르면 생성 불가능
+- UUID 매핑: Slack ID로 테이블 조회 필요
- 네임스페이스 비공개 유지 (소스코드에서만 관리)
---
diff --git a/plans/250828_frontend_slack_login_mockup_plan.md b/plans/250828_frontend_slack_login_mockup_plan.md
index 86475ac..7282f1a 100644
--- a/plans/250828_frontend_slack_login_mockup_plan.md
+++ b/plans/250828_frontend_slack_login_mockup_plan.md
@@ -9,37 +9,41 @@
## 1. 개요
-Google OAuth 외에 Slack으로도 처음 회원가입/로그인 가능하도록 Frontend 목업 구현.
+Google OAuth와 Slack 로그인 모두 레벨과 무관하게 제공. Frontend 목업 구현.
+- **모든 레벨**: Google OAuth + Slack 로그인 (둘 다 사용 가능)
+- **레벨 2**: Gmail 권한 아이템 획득
+- **레벨 3**: Slack 아이템 획득 (봇 설치, 대화 동기화 등)
- **회원가입**: Slack 계정으로 처음 로그인하는 사용자도 자동 가입
-- **Slack 권한(스코프)**: 추후 아이템으로 별도 관리 예정
- **현재 목표**: Frontend 목업만 구현, auth-server 연동은 향후 과제
### 확인된 설정 (auth-server/.env)
- **Slack Client ID**: `9073915808149.9085704341778`
- **Slack Client Secret**: `5f8701a3c97a9e0b406817f44f5dbb5f`
-- **Redirect URI**: `https://auth.ro-being.com/auth/slack/callback`
+- **Redirect URI**: `https://auth.ro-being.com/auth/slack/login/callback`
---
-## 2. 목업 구현 (Phase 1)
+## 2. 백엔드 통합 계획
-### 2.1 UI 컴포넌트
-```typescript
-// components/slack-login-button.tsx
-const SlackLoginButton = () => {
- return (
-
- );
-};
-```
+상세 구현은 [250828_slack_integration_level3_plan.md](./250828_slack_integration_level3_plan.md) 참조
-### 2.2 목업 로그인 핸들러
+**핵심 요약**:
+- Phase 1: Sign in with Slack (OIDC 로그인)
+ - `/auth/slack/login/`: OAuth URL 생성 및 리다이렉트
+ - `/auth/slack/login/callback`: 토큰 교환, UUID 매핑, JWT 발급
+- Phase 2: Slack 패스포트 (레벨 3 아이템)
+ - `/auth/slack/passport/*`: Gmail과 동일한 패스포트 구조
+ - 봇 설치, workspace 토큰 저장, 활성화/비활성화
+- Phase 3: 대화 동기화 (Slack ↔ Frontend)
+
+---
+
+## 3. Frontend 목업 구현
+
+### 3.1 UI 컴포넌트
+Slack 로그인 버튼 추가
+
+### 3.2 목업 로그인 핸들러
```typescript
const handleMockLogin = () => {
// Slack이 제공하는 사용자 정보 시뮬레이션
@@ -76,8 +80,8 @@ const handleMockLogin = () => {
exp: Date.now() + 86400000
}));
- // localStorage 키 (문서 확인됨)
- localStorage.setItem('token', mockToken); // 또는 'auth_token'
+ // localStorage 키 통일
+ localStorage.setItem('token', mockToken); // 'token'으로 통일
localStorage.setItem('authProvider', 'slack'); // Google과 구분
// 로그인 후 원래 페이지로 복귀
@@ -101,20 +105,20 @@ VITE_AUTH_SERVER_URL=https://auth.ro-being.com
```
### 3.2 OAuth URL 생성
+state 생성 → sessionStorage 저장 → Slack OAuth URL 생성
+
+### 3.3 auth-server 연동
+
```typescript
-const generateSlackAuthUrl = () => {
- const state = crypto.randomUUID();
- sessionStorage.setItem('slack_oauth_state', state);
-
- return `https://slack.com/oauth/v2/authorize?` +
- `client_id=${SLACK_CLIENT_ID}&` +
- `scope=openid,profile,email&` +
- `redirect_uri=${encodeURIComponent(REDIRECT_URI)}&` +
- `state=${state}`;
-};
+- OAuth 로그인: `${VITE_AUTH_SERVER_URL}/auth/slack/login/` 직접 연결
+- API 호출: `/api/auth/slack/passport/*` Gateway 경유
```
-### 3.3 auth-server 연동
+### 3.4 JWT 및 Storage 정책
+- **localStorage**: `token` 키로 통일 (auth_token 사용 안함)
+- **JWT 만료**: 24시간, refresh token 없음
+- **OAuth State**: sessionStorage 사용
+- **User ID**: UUID 형식으로 저장
**현재 구현된 엔드포인트:**
- **Slack 매핑 API**: `GET /api/slack/mapping/{slack_user_id}` ✅ 동작 확인
- 반환: `{ user_id, username, email, robeing_id }`
diff --git a/plans/250828_slack_integration_level3_plan.md b/plans/250828_slack_integration_level3_plan.md
index d6f86f3..fe78f01 100644
--- a/plans/250828_slack_integration_level3_plan.md
+++ b/plans/250828_slack_integration_level3_plan.md
@@ -10,16 +10,17 @@
## 1. 개요
### 목표
-- **레벨 1-2**: 일반 로그인 (Google OAuth)
-- **레벨 3+**: Slack 통합 활성화 (**확인 필요**: Frontend 레벨 3 버튼 구현 여부)
- - Slack OIDC 로그인
+- **모든 레벨**: Google OAuth + Slack 로그인 (둘 다 사용 가능)
+- **레벨 2**: Gmail 권한 아이템 획득 (Gmail API 접근)
+- **레벨 3**: Slack 아이템 획득 (**확인 필요**: Frontend 레벨 3 버튼 구현 여부)
- Workspace 봇 설치
- 대화 동기화 (Frontend ↔ Slack)
- 멘션(@) 및 슬래시(/) 명령
-### 현재 상태 (DOCS 확인됨)
-- **기존**: `/auth/slack/command`, `/auth/slack/login`, `/auth/slack/callback` 일부 구현됨
-- **UUID 생성**: UUID5 방식 구현됨 (namespace: 6ba7b810-9dad-11d1-80b4-00c04fd430c8)
+### 현재 상태 및 정책
+- **엔드포인트**: `/auth/slack/login/`, `/auth/slack/login/callback` 구조
+- **localStorage**: `token` 키 통일, JWT 24시간, refresh 없음
+- **OAuth**: auth-server 직접, API는 Gateway 경유
- **테이블**: slack_workspaces, slack_user_mapping 존재
---
@@ -31,24 +32,37 @@
Frontend → auth-server → Slack OIDC → UUID 생성 → JWT 발급
```
-**구현**:
+**백엔드 엔드포인트**:
+- `GET /auth/slack/login/` - OAuth 시작
+- `GET /auth/slack/login/callback` - 토큰 교환, UUID 매핑, JWT 발급
+- `GET /api/slack/mapping/{slack_user_id}` - UUID 조회
+
+**구현 상세**:
1. Slack 앱 설정에서 "Sign in with Slack" 활성화 (OpenID Connect)
- - Redirect URL: `https://auth-server/auth/slack/callback`
+ - Redirect URL: `https://auth.ro-being.com/auth/slack/login/callback`
2. User Token 스코프: `openid`, `profile`, `email` (로그인용)
3. 콜백에서 `openid.connect.userInfo` 호출하여 사용자 정보 획득
-4. DB 저장: users 테이블에 slack_user_id, slack_team_id 추가
+4. DB 저장: users 테이블 UUID, slack_user_mapping 매핑 저장
**주의**: `identity.*` 레거시 스코프는 사용 금지
### Phase 2: Add to Slack (단기 3-5일)
```
-Frontend(레벨3) → auth-server → OAuth 2.0 → 봇 토큰 저장
+Frontend(Slack 아이템 획득) → auth-server → OAuth 2.0 → 봇 토큰 저장
```
+**Slack 패스포트 엔드포인트**:
+- `GET /auth/slack/passport/` - 봇 설치 OAuth 시작
+- `GET /auth/slack/passport/callback` - bot_token 저장
+- `GET /auth/slack/passport/status` - 아이템 상태 확인
+- `POST /auth/slack/passport/activate` - 아이템 장착
+- `POST /auth/slack/passport/deactivate` - 아이템 해제
+- `DELETE /auth/slack/passport/` - 아이템 취소
+
**구현**:
1. OAuth 2.0 플로우 (**별도**: Sign in with Slack과 분리)
- Add to Slack 버튼: `https://slack.com/oauth/v2/authorize?...`
- - 콜백: `/auth/slack/install/callback`
+ - 콜백: `/auth/slack/passport/callback`
2. Bot Token Scopes:
```
읽기: channels:read, groups:read, channels:history,
@@ -70,11 +84,9 @@ Slack Event → rb8001 → DB → SSE/WebSocket → Frontend
- Request URL: `rb8001/slack/events`
- 이벤트: `message.channels`, `message.groups`, `message.im`, `message.mpim`, `app_mention`
- 쓰레드: `message.message_replied` 이벤트 존재하나 `thread_ts` 확인 권장
-2. **3초 규칙**: challenge 검증 및 이벤트 ACK 3초 내 필수
-3. 채널 타입: C(공개), G(비공개/그룹), D(DM)
-4. conversation_logs 저장: team_id, channel_id, thread_ts
-5. 초기 동기화: `conversations.history`로 백필
-6. **Rate Limits**: Events API 시간당 30,000건 (초당 ~8건), Web API는 메서드별 상이
+2. 채널 타입: C(공개), G(비공개/그룹), D(DM)
+3. conversation_logs 저장: team_id, channel_id, thread_ts
+4. 초기 동기화: `conversations.history`로 백필
### Phase 4: 명령 처리 (중기 1-2주)
```
diff --git a/troubleshooting/250827_UUID_username_혼용_CRITICAL.md b/troubleshooting/250827_UUID_username_혼용_CRITICAL.md
index e04fd69..43f56df 100644
--- a/troubleshooting/250827_UUID_username_혼용_CRITICAL.md
+++ b/troubleshooting/250827_UUID_username_혼용_CRITICAL.md
@@ -55,7 +55,7 @@ SELECT id::text as user_id # PostgreSQL UUID를 문자열로 변환
```
**확인된 사항**:
- username → UUID 변환은 DB 조회로만 수행 (계산된 변환 없음)
-- UUID4 형식만 사용 (UUID5 사용 안 함)
+- UUID4 형식만 사용 (UUID 표준 형식)
- users 테이블에 username 없으면 변환 실패
### 2.3 rb8001 (51124) - 확인 완료
diff --git a/troubleshooting/250828_UUID_통합_및_사용자_격리_계획.md b/troubleshooting/250828_UUID_통합_및_사용자_격리_계획.md
index 3f228f0..ae1eed9 100644
--- a/troubleshooting/250828_UUID_통합_및_사용자_격리_계획.md
+++ b/troubleshooting/250828_UUID_통합_및_사용자_격리_계획.md
@@ -63,7 +63,7 @@ workspace (로빙 1개)
- [x] slack_user_mapping 테이블 활성화 (확인됨)
- [x] Gateway API /api/slack/{slack_id}/uuid 구현
- [x] rb8001에서 Slack ID → UUID 변환 구현
-- [ ] robeing-monitor UUID5 제거 (선택사항)
+- [ ] robeing-monitor UUID 변환 개선 (선택사항)
### Phase 3: 사용자 격리 ✅ 완료 (2025-08-28 18:15)
- [x] ChromaDB 사용자별 컬렉션 (rb8001_{user_uuid})
diff --git a/troubleshooting/250828_slack_auth_integration_completed.md b/troubleshooting/250828_slack_auth_integration_completed.md
index ae67bc2..4cb8efd 100644
--- a/troubleshooting/250828_slack_auth_integration_completed.md
+++ b/troubleshooting/250828_slack_auth_integration_completed.md
@@ -41,7 +41,7 @@
### rb8001 ID 처리 ✅ 완료
| 기존 방식 | 개선 완료 | 상태 |
|----------|----------|------|
-| UUID5(DNS namespace, slack_id) | 51123 매핑 API 호출 | ✅ 완료 |
+| UUID 생성(DNS namespace, slack_id) | 51123 매핑 API 호출 | ✅ 완료 |
| 로컬 변환으로 UUID 생성 | 실제 DB 매핑 사용 | ✅ 완료 |
| skill-email에 Slack ID 전달 | UUID 전달로 통일 | ✅ 완료 |
@@ -62,10 +62,10 @@ echo "JWT_SECRET_KEY=[REDACTED]" >> \
docker restart skill-email
```
-### 단계 2: rb8001 UUID5 → API 매핑 전환
+### 단계 2: rb8001 UUID → API 매핑 전환
```python
# /rb8001/app/skills/email_integration.py 수정
-# 기존: user_uuid = str(uuid.uuid5(namespace, user_id))
+# 기존: user_uuid = str(uuid.uuid(namespace, user_id))
# 변경:
async def get_uuid_from_slack(slack_id: str):
response = await httpx.get(
@@ -88,7 +88,7 @@ await http_client.post(url, json=data, headers=headers)
| 우선순위 | 작업 | 위치 | 상태 |
|---------|------|------|------|
| 1 | ~~skill-email JWT_SECRET_KEY 설정~~ | ~~51124 서버~~ | ✅ 완료 |
-| 2 | ~~UUID5 → 매핑 API 전환~~ | ~~rb8001~~ | ✅ 완료 |
+| 2 | ~~UUID → 매핑 API 전환~~ | ~~rb8001~~ | ✅ 완료 |
| 3 | ~~서비스 간 인증 헤더 추가~~ | ~~rb8001, skill-email~~ | ✅ 완료 |
| 4 | Slack OAuth auth-server 경유 | auth-server, frontend | 🔜 향후 |
@@ -110,7 +110,7 @@ curl http://192.168.219.45:9000/api/slack/mapping/U0925SXQFDK
- rb8001, skill-email INTERNAL_API_KEY 설정 완료
#### 2단계: ID 체계 통합 ✅
-- rb8001 UUID5 → 51123 매핑 API 전환 완료
+- rb8001 UUID → 51123 매핑 API 전환 완료
- 실제 DB 매핑으로 데이터 일관성 확보
#### 3단계: 서비스 간 인증 ✅