diff --git a/plans/250828_slack_integration_level3_plan.md b/plans/250828_slack_integration_level3_plan.md new file mode 100644 index 0000000..ac14882 --- /dev/null +++ b/plans/250828_slack_integration_level3_plan.md @@ -0,0 +1,167 @@ +# Slack 통합 레벨 3 구현 계획 + +**작성일**: 2025-08-28 +**작성자**: 51123 서버 관리자 +**상태**: 🟢 실행 가능 +**목표**: Frontend 레벨 3 로빙을 위한 Slack 완전 통합 + +--- + +## 1. 개요 + +### 목표 +- **레벨 1-2**: 일반 로그인 (Google OAuth) +- **레벨 3+**: Slack 통합 활성화 (**확인 필요**: Frontend 레벨 3 버튼 구현 여부) + - Slack OIDC 로그인 + - Workspace 봇 설치 + - 대화 동기화 (Frontend ↔ Slack) + - 멘션(@) 및 슬래시(/) 명령 + +### 현재 상태 (DOCS 확인됨) +- **기존**: `/auth/slack/command`, `/auth/slack/login`, `/auth/slack/callback` 일부 구현됨 +- **UUID 생성**: UUID5 방식 구현됨 (namespace: 6ba7b810-9dad-11d1-80b4-00c04fd430c8) +- **테이블**: slack_workspaces, slack_user_mapping 존재 + +--- + +## 2. 구현 단계 + +### Phase 1: Sign in with Slack (즉시 1-2일) +``` +Frontend → auth-server → Slack OIDC → UUID 생성 → JWT 발급 +``` + +**구현**: +1. Slack 앱 설정에서 "Sign in with Slack" 활성화 (OpenID Connect) + - Redirect URL: `https://auth-server/auth/slack/callback` +2. User Token 스코프: `openid`, `profile`, `email` (로그인용) +3. 콜백에서 `openid.connect.userInfo` 호출하여 사용자 정보 획득 +4. DB 저장: users 테이블에 slack_user_id, slack_team_id 추가 + +**주의**: `identity.*` 레거시 스코프는 사용 금지 + +### Phase 2: Add to Slack (단기 3-5일) +``` +Frontend(레벨3) → auth-server → OAuth 2.0 → 봇 토큰 저장 +``` + +**구현**: +1. OAuth 2.0 플로우 (**별도**: Sign in with Slack과 분리) + - Add to Slack 버튼: `https://slack.com/oauth/v2/authorize?...` + - 콜백: `/auth/slack/install/callback` +2. Bot Token Scopes: + ``` + 읽기: channels:read, groups:read, channels:history, + groups:history, im:history, mpim:history + 이벤트: app_mentions:read, commands + 쓰기: chat:write, im:write + 사용자: users:read, users:read.email + ``` +3. `oauth.v2.access`로 bot_access_token 획득 → 암호화 저장 +4. 재설치 시 기존 토큰 교체, 다중 workspace 지원 + +### Phase 3: 대화 동기화 (중기 1-2주) +``` +Slack Event → rb8001 → DB → SSE/WebSocket → Frontend +``` + +**구현**: +1. Events API 구독 + - Request URL: `rb8001/slack/events` + - 이벤트: `message.channels`, `message.groups`, `message.im`, `message.mpim`, `app_mention` + - 쓰레드: 별도 이벤트 없음, `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**: 초당 30개 이벤트, Web API 분당 50-100회 + +### Phase 4: 명령 처리 (중기 1-2주) +``` +Slack → @robeing 또는 /robeing → rb8001 → 응답 +``` + +**구현**: +1. 멘션: `app_mention` 이벤트 → `chat.postMessage` 응답 +2. 슬래시 명령 (앱 설정에서 수동 등록 필요): + - `/robeing help`, `/robeing status`, `/robeing level` + - Request URL: `rb8001/slack/commands` +3. **3초 제한**: 즉시 200 OK 필수, 긴 작업은 response_url 사용 +4. 서명 검증: X-Slack-Signature, X-Slack-Request-Timestamp (5분 윈도) +5. **Rate Limits**: 메시지 전송 채널당 초당 1회 권장 + +--- + +## 3. 데이터베이스 설계 + +### 기존 테이블 활용 +- **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 + +### 필요 컬럼 추가 +```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); +``` + +--- + +## 4. 보안 및 운영 + +### 보안 +- **토큰 암호화**: bot_access_token 암호화 저장 필수 +- **서명 검증**: X-Slack-Signature로 재생공격 방지 +- **스코프 분리**: Sign in with Slack(사용자) vs Add to Slack(봇) + +### 운영 +- **3초 규칙**: Events API/Slash Commands 모두 3초 내 ACK +- **채널 접근**: 봇이 채널 초대되어야 이벤트 수신 +- **Rate Limits**: + - Events: 초당 30개 + - Web API: 분당 50-100회 + - 메시지: 채널당 초당 1회 + +--- + +## 5. 테스트 시나리오 + +### Phase 1 테스트 +- 테스트 워크스페이스에서 OIDC 로그인 +- users 테이블에 UUID 생성 확인 +- JWT 발급 및 세션 로그인 확인 + +### Phase 2 테스트 +- 워크스페이스 앱 설치 +- 토큰 암호화 저장 확인 +- chat.postMessage로 헬스체크 + +### Phase 3 테스트 +- 공개/비공개 채널, DM, 멀티DM 각각 송수신 +- Frontend 실시간 반영 확인 +- conversations.history로 초기 동기화 + +### Phase 4 테스트 +- /robeing help 호출 → ephemeral 응답 +- @robeing 멘션 → 응답 확인 +- 긴 작업 시 response_url 후속 메시지 + +--- + +## 6. 참고 문서 + +### Slack API +- [Sign in with Slack](https://api.slack.com/authentication/sign-in-with-slack) +- [OAuth v2](https://api.slack.com/authentication/oauth-v2) +- [Events API](https://api.slack.com/events-api) +- [Conversations API](https://api.slack.com/apis/conversations-api) +- [Slash Commands](https://api.slack.com/slash-commands) +- [Permission Scopes](https://api.slack.com/scopes) + +### 내부 문서 +- [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