# skill-calendar 멀티플랫폼 캘린더 통합 스킬 **작성일**: 2025-11-14 **작성자**: Claude **목적**: Google/Slack/네이버웍스 캘린더 통합 일정 관리 --- ## 1. 비즈니스 시나리오 ### 사용자 대화 플로우 ``` 사용자: "11월 24일 검진 인천 연수구 갯벌로156 한국생산기술연구원 200명(의사2인) 07:40~약12시" 로빙: "11월 24일 07:40~12시 검진 일정을 구글 캘린더에 등록해드릴까요?" 사용자: "그래" 로빙: "구글 캘린더에 등록 완료했습니다. 제목: 한국생산기술연구원 검진 일시: 2025-11-24 07:40~12:00 장소: 인천 연수구 갯벌로156" ``` ### 요구사항 1. 사용자(김종태, UUID: 53529291-5050-4daa-89fb-008b546feb63) 식별 2. 51123 서버 DB에서 gmail_token 테이블 조회 → Google OAuth 토큰 획득 3. Google Calendar API로 일정 등록 4. rb8001 ChromaDB에 메모리 저장 (이후 "11월 24일 뭐하지?" 질문에 답변 가능) --- ## 2. 아키텍처 ### 서비스 구조 ``` rb8001 (51124) ↓ POST /api/events skill-calendar (51124, 포트 8512) ↓ SELECT * FROM gmail_token WHERE user_id=? PostgreSQL main_db (51123) ↓ Google Calendar API Google Calendar (외부) ``` ### 멀티 프로바이더 지원 - GoogleCalendarService: gmail_token 테이블 사용 - SlackCalendarService: slack_token 테이블 사용 (Slack 타임라인 기능) - NaverWorksCalendarService: naverworks_token 테이블 사용 --- ## 3. DB 스키마 (51123 서버 main_db) ### 기존 테이블 활용 - gmail_token: Google OAuth 토큰 (Calendar API scope 포함) - slack_token: Slack OAuth 토큰 - naverworks_token: 네이버웍스 OAuth 토큰 ### 신규 테이블 (선택) ```sql -- 캘린더 이벤트 메타데이터 (선택사항, 동기화 추적용) CREATE TABLE IF NOT EXISTS calendar_events ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES "user"(id), provider VARCHAR(50) NOT NULL, -- 'google', 'slack', 'naverworks' external_event_id VARCHAR(255) NOT NULL, -- 외부 API의 event_id title TEXT, start_time TIMESTAMP NOT NULL, end_time TIMESTAMP NOT NULL, location TEXT, description TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(user_id, provider, external_event_id) ); ``` --- ## 4. skill-calendar API 설계 ### 포트 및 환경변수 - PORT: 8512 - DATABASE_URL: postgresql://robeings:robeings@192.168.219.45:5432/main_db ### API 엔드포인트 #### POST /api/events 일정 등록 **요청**: ```json { "user_id": "53529291-5050-4daa-89fb-008b546feb63", "provider": "google", // "google", "slack", "naverworks" "title": "한국생산기술연구원 검진", "start": "2025-11-24T07:40:00", "end": "2025-11-24T12:00:00", "location": "인천 연수구 갯벌로156", "attendees": ["lee.jh@example.com"] // 선택 } ``` **응답**: ```json { "event_id": "abc123xyz", "provider": "google", "calendar_url": "https://calendar.google.com/calendar/event?eid=..." } ``` #### GET /api/events 일정 조회 (날짜 범위) **쿼리**: `?user_id=UUID&provider=google&start_date=2025-11-24&end_date=2025-11-24` #### DELETE /api/events/{event_id} 일정 삭제 --- ## 5. rb8001 통합 ### 의도 감지 - app/brain/decision_engine.py: "calendar_event" 의도 추가 - 키워드: "일정", "캘린더", "등록", 날짜 패턴 (YYYY-MM-DD, MM월 DD일) ### 스킬 호출 - app/skills/calendar_skill.py (신규 생성) - rb8001 → skill-calendar API 호출 - 환경변수: SKILL_CALENDAR_URL=http://localhost:8512 ### 메모리 저장 - ChromaDB: "11월 24일 검진 일정 등록됨" 저장 - Neo4j: event 노드 생성 (선택) --- ## 6. TDD 테스트 계획 ### 테스트 파일 - skill-calendar/tests/test_google_calendar_integration.py - rb8001/tests/test_calendar_intent_detection.py ### 시나리오 1: 구글 캘린더 일정 등록 ```python Given: 김종태(user_id)의 gmail_token 존재 When: POST /api/events (제목, 날짜, 시간, 장소) Then: - Google Calendar API 호출 성공 - event_id 반환 - calendar_events 테이블 저장 (선택) ``` ### 시나리오 2: rb8001 의도 감지 및 2단계 대화 ```python Given: "11월 24일 검진..." 메시지 입력 When: rb8001 의도 분석 Then: - intent="calendar_event" 감지 - entities={날짜, 시간, 장소} 추출 - "일정 등록해드릴까요?" 응답 - 다음 메시지 "그래" 입력 시 skill-calendar 호출 ``` --- ## 7. 구현 순서 ### Phase 1: skill-calendar 기본 뼈대 (2시간) 1. skill-calendar 디렉토리 생성 (Gitea 레포 연동) 2. FastAPI 앱 구조 생성 3. GoogleCalendarService 클래스 구현 4. POST /api/events 엔드포인트 구현 5. DB 연결 (51123 main_db) ### Phase 2: Google Calendar API 통합 (1시간) 1. gmail_token 테이블 조회 로직 2. google-api-python-client로 Calendar API 호출 3. 토큰 갱신 로직 (skill_email 패턴 참조) 4. 에러 처리 (401, 403, 429) ### Phase 3: rb8001 통합 (1시간) 1. app/skills/calendar_skill.py 생성 2. app/brain/decision_engine.py에 calendar_event 의도 추가 3. 2단계 대화 플로우 (확인 → 실행) 4. ChromaDB 메모리 저장 ### Phase 4: TDD 테스트 (1시간) 1. test_google_calendar_integration.py 작성 2. Mock 테스트 (Calendar API) 3. E2E 테스트 (실제 토큰 사용) ### Phase 5: 배포 및 검증 (30분) 1. docker-compose.yml 작성 2. Gitea Actions 설정 3. 실제 시나리오 테스트 (김종태 계정) --- ## 8. 참고 문서 - DOCS/troubleshooting/250917_네이버웍스_캘린더_API_연동_가이드.md - DOCS/troubleshooting/250820_happybell80_Gmail패스포트시스템완성.md - skill_email/services/gmail_service.py:38-83 (Gmail API 패턴) - rb8001/app/services/naverworks_file_processor.py (스킬 호출 패턴) --- ## 9. 제약사항 ### Google Calendar API - Scope: calendar.events (gmail_token에 이미 포함 여부 확인 필요) - Quota: 무료 tier 하루 1백만 요청 (충분) - Auth: OAuth 2.0 (skill_email과 동일 토큰 공유) ### 보안 - 51123 DB 접근: read-only 권장 (gmail_token 조회만) - 토큰 갱신: skill_email 패턴 따름 - CORS: rb8001에서만 호출 (내부 네트워크) --- --- ## 10. 구현 현황 ### Phase 1: 기본 뼈대 구현 완료 (2025-11-14) **Git 레포**: https://git.ro-being.com/ivada_Ro-being/skill-calendar.git **커밋**: 15bcd9c **구현 파일**: - services/google_calendar_service.py: Gmail 토큰 조회 + Calendar API - routers/calendar.py: POST/GET/DELETE /api/events - tests/test_google_calendar_integration.py: TDD 테스트 (Red Phase) - main.py: FastAPI 앱 (포트 8512) - docker-compose.yml: 51123 DB 연결 **TDD 상태**: - ✅ Import 성공 - ✅ gmail_token 조회 성공 - ❌ Calendar API 호출: invalid_grant (토큰 만료 또는 calendar scope 부족) **다음 단계**: 1. Gmail Passport 재연동 (calendar scope 부여) 2. 토큰 갱신 → Green Phase 달성 3. Docker 빌드 및 배포 4. rb8001 통합 (calendar_skill.py, decision_engine.py)