# Gmail 패스포트 시스템 완성 및 Frontend UX 개선 ## 작성일: 2025-08-20 ## 작성자: happybell80 ## 관련 서비스: auth-server, skill-email, rb10508_micro, frontend-customer --- ## 오전 9시 00분 ### 작업 배경 및 목표 **배경**: - skill-email의 DBCredentialsProvider가 구현되었지만 환경변수 미설정으로 비활성화 상태 - rb10508_micro에서 Gmail 아이템 장착 확인 없이 skill-email 호출하여 에러 발생 - Gmail OAuth 인증을 통한 아이템 장착 플로우 필요 **목표**: 1. Gmail 아이템 장착 시스템 완성 2. 사용자 친화적인 OAuth 플로우 구현 3. Frontend 아이템 관리 페이지 개선 --- ## 오전 9시 10분 ### 1. skill-email DBCredentialsProvider 활성화 #### 문제 상황 - DBCredentialsProvider 클래스는 구현되어 있으나 미사용 - docker-compose.yml에 TOKEN_PROVIDER 환경변수 누락 #### 해결 과정 ```yaml # skill-email/docker-compose.yml 수정 environment: - TOKEN_PROVIDER=database # 추가 - POSTGRES_CONNECTION_STRING=${POSTGRES_CONNECTION_STRING} # 추가 ``` #### Gitea Actions 배포 문제 - 51124 서버 배포를 위한 SSH 방식 필요 - 초기 시도: 로컬 경로 사용 (실패) - 해결: SSH로 51124 서버 접속 후 git pull ```yaml # .gitea/workflows/deploy.yml - name: Deploy to 51124 Server run: | ssh -p 51124 -i ~/.ssh/deploy_key admin@${{ secrets.SSH_HOST_51124 }} << 'EOF' cd /home/admin/ivada_project/skill-email git pull origin main --rebase docker compose up -d --build EOF ``` #### 결과 - ✅ DBCredentialsProvider 활성화 - ✅ PostgreSQL 기반 토큰 관리로 전환 --- ## 오전 9시 20분 ### 2. rb10508_micro Gmail 아이템 확인 미들웨어 구현 #### 문제 상황 - "최근 받은 메일 확인해줘" 요청 시 아이템 장착 확인 없이 skill-email 호출 - 토큰 없으면 에러 발생 #### 해결 과정 ##### growth.py에 아이템 관리 함수 추가 ```python # rb10508_micro/app/core/growth.py async def check_item_equipped(user_id: str, item_type: str) -> bool: """특정 아이템 장착 여부 확인""" async with httpx.AsyncClient() as client: response = await client.get( f"http://localhost:8090/api/items/{item_type}", params={"user_id": user_id} ) if response.status_code == 200: items = response.json() return any(item.get('is_equipped') for item in items) return False async def get_item_capabilities(user_id: str, item_type: str) -> List[str]: """아이템의 권한 목록 조회""" # send, read, modify 등 권한 반환 ``` ##### brain.py 수정 ```python if intent == "email": # Gmail 아이템 장착 확인 is_equipped = await check_item_equipped(think_input.user_id, "gmail") if not is_equipped: response = f"{user_name}님, Gmail을 먼저 연결해주세요!" else: # 권한 확인 후 skill-email 호출 capabilities = await get_item_capabilities(think_input.user_id, "gmail") # ... ``` #### 테스트 결과 - 요청: "최근 받은 이메일 확인해줘" - 응답: "사용자님, Gmail을 먼저 연결해주세요! 설정 > 아이템에서 Gmail을 장착하면 이메일 기능을 사용할 수 있습니다." - ✅ 정상 작동 --- ## 오전 9시 30분 ### 3. auth-server Gmail Passport 엔드포인트 구현 #### 구현 내용 새 파일: `app/providers/gmail_passport.py` **엔드포인트 구조**: - `GET /auth/gmail/passport/` - 패스포트 발급 (OAuth 시작) - `GET /auth/gmail/passport/callback` - OAuth 콜백 - `GET /auth/gmail/passport/status` - 패스포트 상태 확인 - `POST /auth/gmail/passport/activate` - 패스포트 활성화 (장착) - `POST /auth/gmail/passport/deactivate` - 패스포트 비활성화 (해제) - `DELETE /auth/gmail/passport/` - 패스포트 취소 **주요 특징**: ```python # Gmail API 전체 권한 scope GMAIL_API_SCOPES = [ "https://www.googleapis.com/auth/gmail.send", "https://www.googleapis.com/auth/gmail.readonly", "https://www.googleapis.com/auth/gmail.modify", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile" ] # PostgreSQL 직접 연동 await conn.execute(""" INSERT INTO gmail_token (...) VALUES (...) ON CONFLICT (user_id) DO UPDATE SET ... """) ``` #### Gitea Actions 배포 이슈 1. **import 에러**: `app.core.config` 모듈 없음 - 해결: 환경변수 직접 사용 2. **Redis 컨테이너 충돌**: 이미 실행 중 - 해결: auth-server만 재시작하도록 수정 3. **배포 속도**: 너무 느림 - 해결: 헬스체크 단순화, rsync 최적화 --- ## 오전 10시 00분 ### 4. Frontend 아이템 관리 페이지 분석 #### 현재 구현 상태 **위치**: `/src/pages/inventory.tsx` **구조**: ``` inventory.tsx (메인 페이지) └── inventory-grid.tsx (아이템 그리드) └── gmail-passport-card.tsx (Gmail 카드 컴포넌트) ``` **기능**: - ✅ 아이템 목록 표시 - ✅ 장착/해제/재인증/철회 버튼 - ✅ 레벨 제한 체크 (레벨 5 이상) - ✅ ItemContext로 상태 관리 #### UX 문제점 분석 1. **잘못된 OAuth URL** ```tsx // 현재 (inventory.tsx line 105) window.open('https://auth.ro-being.com/oauth/gmail', '_blank') // 수정 필요 window.open('https://auth.ro-being.com/auth/gmail/passport/', '_blank') ``` 2. **새 창 열기 방식의 UX 단절** - 새 탭에서 OAuth 진행 - 완료 후 원래 탭으로 돌아와야 함 - 수동 새로고침 필요 3. **레벨 정보 하드코딩** ```tsx const [currentLevel, setCurrentLevel] = useState(5); // 항상 5 ``` 4. **피드백 부족** - 장착/해제 성공 시 시각적 피드백 없음 - 에러 발생 시 사용자 안내 미흡 --- ## 오전 10시 30분 ### 5. Frontend UX 개선 방안 #### 1. OAuth 플로우 개선 ```tsx // 현재 창에서 리다이렉트 (UX 연속성) const connectGmail = () => { const userId = getUserId(); // 실제 사용자 ID const returnUrl = encodeURIComponent(window.location.href); // 현재 창에서 이동 window.location.href = `https://auth.ro-being.com/auth/gmail/passport/?user_id=${userId}&return_url=${returnUrl}`; }; ``` #### 2. OAuth 성공 감지 자동화 ```tsx useEffect(() => { const params = new URLSearchParams(location.search); // auth-server가 ?gmail=success&email=user@gmail.com 으로 리다이렉트 if (params.get('gmail') === 'success') { const email = params.get('email'); // 토스트 메시지 toast.success(`Gmail 연결 성공! (${email})`); // 아이템 목록 자동 새로고침 fetchItems(); // URL 파라미터 제거 window.history.replaceState({}, '', '/inventory'); } }, [location]); ``` #### 3. 시각적 피드백 강화 ```tsx // 장착 버튼 클릭 시 const handleEquip = async (itemId: string) => { setLoading(true); try { const result = await equipItem(itemId, robeingId); if (result?.success) { // 성공 애니메이션 confetti(); toast.success('Gmail 아이템 장착 완료!'); // 상태 업데이트 await fetchItems(); } } catch (error) { toast.error('장착에 실패했습니다. 다시 시도해주세요.'); } finally { setLoading(false); } }; ``` #### 4. 실제 레벨 연동 ```tsx // 실제 사용자 레벨 가져오기 useEffect(() => { const fetchUserLevel = async () => { const response = await fetch('/api/user/stats'); const data = await response.json(); setCurrentLevel(data.level); }; fetchUserLevel(); }, []); ``` #### 5. 모바일 UX 개선 - 카드 크기 반응형 조정 - 터치 타겟 크기 44px 이상 확보 - 스와이프 제스처 지원 --- ## 최종 시스템 아키텍처 ``` 사용자 요청 흐름: 1. "이메일 확인해줘" → rb10508_micro 2. Gmail 아이템 장착 확인 (robeing-monitor API) 3. 미장착 시: "Gmail을 먼저 연결해주세요!" 안내 4. 장착 시: skill-email 호출 → Gmail API 사용 아이템 장착 흐름: 1. Frontend /inventory 페이지 2. "Gmail 연결" 버튼 클릭 3. auth-server/auth/gmail/passport/ OAuth 시작 4. Google 인증 완료 5. PostgreSQL gmail_token 저장 (is_equipped = true) 6. Frontend로 리다이렉트 (?gmail=success) 7. 자동 새로고침 및 성공 메시지 ``` --- ## 성과 ### ✅ 완료된 작업 1. **Gmail 패스포트 시스템 완성** - auth-server에 passport 엔드포인트 구현 - OAuth → PostgreSQL 저장 → 자동 장착 2. **아이템 장착 확인 미들웨어** - rb10508_micro에 Gmail 체크 로직 추가 - 미장착 시 친절한 안내 메시지 3. **DB 기반 토큰 관리 전환** - skill-email DBCredentialsProvider 활성화 - 파일 기반에서 PostgreSQL로 마이그레이션 4. **Gitea Actions 최적화** - 51124 서버 SSH 배포 설정 - 배포 속도 개선 (Redis 유지, 헬스체크 단순화) ### 📊 시스템 상태 - auth-server: 정상 작동 (37시간+) - skill-email: DB 연동 완료 - rb10508_micro: 아이템 확인 기능 추가 - frontend-customer: 인벤토리 페이지 구현됨 (개선 필요) --- ## 교훈 ### 1. 트러블슈팅 문서의 중요성 - 기존 문서 참고로 Actions 설정 한번에 성공 - SSH 방식, 경로 구조 등 검증된 패턴 재사용 ### 2. 점진적 통합 - 각 서비스 개별 테스트 후 통합 - 로그를 통한 데이터 흐름 추적 ### 3. UX 연속성 - OAuth 플로우에서 새 창 열기는 UX 단절 - 현재 창 리다이렉트가 더 자연스러움 ### 4. 환경변수 확인 - 코드 구현되어도 환경변수 없으면 무용지물 - docker-compose.yml과 .env 동기화 필수 --- ## 다음 단계 1. **Frontend UX 개선 구현** - OAuth URL 수정 - 성공 감지 자동화 - 토스트 메시지 추가 2. **실제 사용자 테스트** - E2E 시나리오 검증 - 에러 케이스 처리 3. **다른 아이템 확장** - Slack passport - Calendar passport --- **문서 끝**