DOCS/troubleshooting/250820_happybell80_Gmail아이템UI고급화및상태영구저장.md

4.9 KiB

Gmail 아이템 UI 고급화 및 상태 영구 저장

작성일: 2025-08-20

작성자: happybell80

관련 서비스: frontend-customer, rb10508_micro, robeing-monitor


오후 3시 30분

Gmail 아이템/스킬 시스템 UI 구현

요구사항

  • 인벤토리 열기 버튼 제거, Gmail 아이템 직접 표시
  • 레벨별 권한 시스템 (Lv.5 읽기, Lv.7 보내기, Lv.11 추적)
  • 스킬 트리 UI (게임 느낌)
  • 레벨 미달 시 잠금 표시

구현 내용

  1. skills-items-panel.tsx 전면 개편

    • Gmail 스킬 3개 추가 (읽기, 보내기, 추적)
    • 레벨별 잠금/해금 시각화
    • 호버 시 툴팁으로 설명 표시
  2. 아이템 탭 개선

    // Gmail 아이템 상태
    - locked: 회색 + 자물쇠 아이콘 (레벨 5 미만)
    - available: 파란색 + "활성화" 버튼
    - equipped: 초록색 + 체크 아이콘 + 애니메이션
    
  3. 레벨별 권한 표시

    • 체크박스 형태로 권한 표시
    • 레벨 도달 시 체크 아이콘
    • 미달 시 경고 아이콘

오후 3시 50분

rb10508_micro 레벨 시스템 활성화

문제 상황

  • /api/stats/{robeing_id} 엔드포인트가 비활성화 상태
  • 빈 객체만 반환하여 프론트엔드에서 레벨 확인 불가

해결 방법

  1. endpoints.py 수정

    @router.get("/stats/{robeing_id}")
    async def get_stats(robeing_id: str):
        # PostgreSQL 직접 연결
        conn = await asyncpg.connect(...)
    
        # robeing_stats 테이블 조회
        query = """
            SELECT level, experience, stat_points,
                   memory, compute, empathy, leadership, ethics
            FROM robeing_stats
            WHERE robeing_id = $1
        """
        row = await conn.fetchrow(query, robeing_id)
    
  2. DB 레벨 설정

    • rb10508_micro: 레벨 20으로 설정
    • 모든 Gmail 스킬 해금 상태

오후 4시 00분

Gmail 아이템 상태 영구 저장 문제

문제 상황

  • Gmail 아이템 "활성화" 클릭 → 임시로 equipped 상태
  • 새로고침 시 → available로 초기화
  • 원인: React state에만 저장, DB 미연동

원인 분석

  1. 임시 처리 코드

    // 기존: 테스트용 임시 코드
    setTimeout(() => {
      setGmailStatus('equipped');
      toast({...});
    }, 2000);
    
  2. DB 구조는 준비됨

    • gmail_tokens 테이블: is_equipped, equipped_to 컬럼 존재
    • robeing-monitor 서비스: API 구현 완료 (포트 9024)

해결 방법

  1. robeing-monitor API 연동

    // 상태 조회
    const response = await fetch('/api/items/gmail', {
      headers: { 'X-User-Id': userId }
    });
    
    // 장착 처리
    const equipResponse = await fetch(`/api/items/gmail/${userId}/equip`, {
      method: 'POST',
      body: JSON.stringify({ robeing_id: 'rb10508_micro' })
    });
    
  2. OAuth 플로우 통합

    • Gmail 토큰 확인
    • 없으면 OAuth 페이지로 리다이렉트
    • 있으면 바로 장착 진행
  3. 상태 동기화

    • 마운트 시 DB 상태 조회
    • 장착/해제 시 DB 업데이트
    • 새로고침해도 상태 유지

오후 4시 10분

최종 구현 완료

구현된 기능

  1. 상태 영구 저장

    • DB에 is_equipped 상태 저장
    • 새로고침해도 상태 유지
    • robeing-monitor API와 완전 연동
  2. 사용자 경험 개선

    • 로딩 상태 표시 ("처리 중...")
    • 에러 처리 및 토스트 메시지
    • 장착/해제 버튼 동적 표시
  3. 작동 흐름

    페이지 로드
        ↓
    레벨 정보 조회 (rb10508_micro)
        ↓
    Gmail 아이템 상태 조회 (robeing-monitor)
        ↓
    UI 상태 동기화
    
    활성화 클릭
        ↓
    Gmail 토큰 확인
        ↓
    [토큰 있음] → 장착 API 호출 → DB 저장
    [토큰 없음] → OAuth 페이지로 리다이렉트
    

교훈

1. UI 상태와 DB 상태 동기화 필수

  • 프론트엔드 state는 임시 저장소
  • 영구 저장은 반드시 백엔드 DB 연동
  • 마운트 시 DB 상태 조회 필수

2. 레벨 시스템 설계 중요성

  • 레벨별 권한 명확히 정의
  • UI에서 시각적으로 구분
  • 사용자에게 명확한 피드백

3. OAuth 플로우 통합

  • 토큰 유무 확인 먼저
  • 없으면 OAuth 진행
  • 있으면 바로 기능 사용

4. API 설계 일관성

  • RESTful 패턴 준수
  • 헤더 기반 인증 (X-User-Id)
  • 명확한 에러 메시지

5. 단계별 구현의 중요성

  • UI 먼저 구현 → API 연동 → 상태 관리
  • 각 단계별 테스트
  • 점진적 개선

관련 커밋

  • frontend-customer: 1071ec2 - Gmail 아이템/스킬 시스템 구현
  • frontend-customer: b189024 - 레벨 20 반영 및 API 연동
  • frontend-customer: 9f5c7e8 - Gmail 아이템 상태 영구 저장 구현
  • rb10508_micro: (stats API 활성화)

문서 끝