# 구글 그룹 연동 작업계획서 > 작성일: 2026-01-10 > 예상 기간: 1~2주 > 우선순위: 6 > 선행 작업: 4번 (Gmail OAuth 로그인) --- ## 1. 기능 개요 ### 1.1 핵심 컨셉 - 사용자가 **Google OAuth로 로그인한 상태**에서 - 본인이 속한 **Google 그룹의 게시물 조회** (가져오기) - 본인 **주간보고를 Google 그룹에 게시** (등록) - 모두 **그룹 멤버 권한**으로 동작 (관리자 권한 불필요) ### 1.2 권한 구조 ``` ┌─────────────────────────────────────────────────────────────────┐ │ Google 그룹: developers@company.com │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 멤버들: │ │ ├─ hyosung@company.com (시스템 관리자이기도 함) │ │ ├─ hyewon@company.com │ │ ├─ gildong@company.com │ │ └─ ... │ │ │ │ 멤버라면 누구나: │ │ ✅ 그룹 게시물 읽기 │ │ ✅ 그룹에 글 게시 │ │ │ └─────────────────────────────────────────────────────────────────┘ ※ 시스템 관리자 ≠ 그룹 관리자 ※ 시스템 관리자도 그냥 그룹 멤버로서 읽기/쓰기 ``` ### 1.3 기능 요약 | 기능 | 누가 | 설명 | |------|------|------| | **가져오기** | 그룹 멤버 | 그룹 게시물 목록/내용 조회 | | **등록** | 그룹 멤버 | 본인 주간보고 → 그룹에 게시 | ### 1.4 결정 사항 | # | 항목 | 결정 | |:-:|------|:----:| | 1 | 권한 | 그룹 멤버 권한만 사용 | | 2 | 가져오기 | 본인이 속한 그룹 게시물 조회 | | 3 | 등록 | Gmail API로 그룹 이메일에 발송 | | 4 | OAuth 연계 | 4번 작업(Gmail OAuth) 토큰 활용 | --- ## 2. 기능 상세 ### 2.1 가져오기 (그룹 게시물 조회) ``` [주간보고시스템] ┌─────────────────────────────────────────────────────────────────┐ │ 📬 Google 그룹 게시물 [새로고침] │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 그룹 선택: [developers@company.com ▼] │ │ ───────────────────────── │ │ developers@company.com │ │ team-leads@company.com │ │ all@company.com │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 📧 [주간보고] 2026년 2주차 - 서혜원 │ │ hyewon@company.com · 2026-01-10 09:30 │ │ │ │ 📧 [공지] 이번 주 회의 일정 변경 │ │ gildong@company.com · 2026-01-09 14:00 │ │ │ │ 📧 [주간보고] 2026년 2주차 - 홍길동 │ │ gildong@company.com · 2026-01-09 10:00 │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` **사용 API**: Gmail API (그룹 이메일 검색) ``` GET /gmail/v1/users/me/messages?q=list:developers@company.com ``` ### 2.2 등록 (주간보고 → 그룹 게시) ``` [주간보고 상세] ┌─────────────────────────────────────────────────────────────────┐ │ 2026년 2주차 주간보고 - 조효성 [수정] [삭제] │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 금주 업무: │ │ - 로그인 기능 개발 완료 │ │ - 사용자 관리 페이지 수정 │ │ ... │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 🔗 Google 그룹 공유 │ │ ─────────────────────────────────────────────────────────────── │ │ │ │ 공유할 그룹: [developers@company.com ▼] │ │ │ │ [📤 그룹에 공유하기] │ │ │ │ ─────────────────────────────────────────────────────────────── │ │ 공유 이력: │ │ ✅ developers@company.com · 2026-01-10 09:30 │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` **발송되는 이메일 형식**: ``` From: hyosung@company.com (본인) To: developers@company.com (그룹) Subject: [주간보고] 2026년 2주차 - 조효성 ──────────────────────────────────────── 2026년 2주차 주간보고 작성자: 조효성 소속: 개발팀 ──────────────────────────────────────── [금주 업무] - 로그인 기능 개발 완료 - 사용자 관리 페이지 수정 ... [차주 계획] ... ──────────────────────────────────────── ※ 주간보고시스템에서 발송됨 ``` **사용 API**: Gmail API (메일 발송) ``` POST /gmail/v1/users/me/messages/send ``` --- ## 3. 데이터 모델 ### 3.1 그룹 공유 이력 테이블 ```sql CREATE TABLE wr_report_group_share ( share_id SERIAL PRIMARY KEY, report_id INTEGER NOT NULL REFERENCES wr_weekly_report(report_id), employee_id INTEGER NOT NULL REFERENCES wr_employee_info(employee_id), group_email VARCHAR(200) NOT NULL, -- developers@company.com gmail_message_id VARCHAR(100), -- Gmail 메시지 ID shared_at TIMESTAMP DEFAULT NOW(), share_status VARCHAR(20) DEFAULT 'SENT', -- SENT, FAILED error_message TEXT ); CREATE INDEX idx_report_share_report ON wr_report_group_share(report_id); CREATE INDEX idx_report_share_employee ON wr_report_group_share(employee_id); ``` ### 3.2 사용자 테이블 - OAuth 토큰 저장 (4번 작업 확장) ```sql -- 4번 작업에서 추가 필요 ALTER TABLE wr_employee_info ADD COLUMN google_access_token TEXT, ADD COLUMN google_refresh_token TEXT, ADD COLUMN google_token_expires_at TIMESTAMP; ``` --- ## 4. API 설계 ### 4.1 그룹 관련 API | Method | Endpoint | 설명 | |--------|----------|------| | GET | /api/google-group/my-groups | 내가 속한 그룹 목록 | | GET | /api/google-group/[groupEmail]/messages | 그룹 게시물 목록 | | GET | /api/google-group/message/[messageId] | 게시물 상세 | | POST | /api/google-group/share | 주간보고 그룹에 공유 | | GET | /api/report/[id]/share-history | 공유 이력 조회 | ### 4.2 API 상세 #### GET /api/google-group/my-groups ```json // Response { "groups": [ { "email": "developers@company.com", "name": "개발팀" }, { "email": "all@company.com", "name": "전체" } ] } ``` #### POST /api/google-group/share ```json // Request { "reportId": 123, "groupEmail": "developers@company.com" } // Response { "success": true, "messageId": "18d1234567890abc", "sharedAt": "2026-01-10T09:30:00Z" } ``` --- ## 5. OAuth Scope 설정 ### 5.1 필요한 Scope (4번 작업 확장) | Scope | 용도 | |-------|------| | `openid` | 기본 인증 | | `email` | 이메일 주소 | | `profile` | 프로필 정보 | | **`https://www.googleapis.com/auth/gmail.readonly`** | 그룹 게시물 조회 | | **`https://www.googleapis.com/auth/gmail.send`** | 그룹에 메일 발송 | | **`https://www.googleapis.com/auth/gmail.labels`** | 라벨 조회 (선택) | ### 5.2 Google Cloud Console 설정 변경 1. **OAuth 동의 화면** > **범위 추가** 2. Gmail API 관련 scope 추가 3. **민감한 범위**로 분류되어 Google 검토 필요할 수 있음 ``` ⚠️ 주의: Gmail API scope는 "민감한 범위"로 분류됨 - 앱 인증 필요할 수 있음 (내부용은 대체로 OK) - Google Workspace 도메인 내 사용 시 관리자 승인으로 해결 ``` --- ## 6. 화면 설계 ### 6.1 메뉴 추가 ``` 사이드바 메뉴: ├─ 📊 대시보드 ├─ 📝 주간보고 │ ├─ 작성 │ ├─ 목록 │ └─ 통계 ├─ 📬 Google 그룹 ← 신규 │ └─ 게시물 조회 ├─ 👥 사용자 관리 └─ ⚙️ 설정 ``` ### 6.2 그룹 게시물 조회 (/google-group) ``` ┌─────────────────────────────────────────────────────────────────┐ │ 📬 Google 그룹 게시물 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 그룹: [developers@company.com ▼] [새로고침] │ │ │ │ ───────────────────────────────────────────────────────────────│ │ □ 제목 보낸 사람 날짜 │ │ ───────────────────────────────────────────────────────────────│ │ ☐ [주간보고] 2026년 2주차 - 서혜원 서혜원 01-10 09:30 │ │ ☐ [공지] 회의 일정 변경 홍길동 01-09 14:00 │ │ ☐ [주간보고] 2026년 2주차 - 홍길동 홍길동 01-09 10:00 │ │ ☐ [주간보고] 2026년 1주차 - 서혜원 서혜원 01-03 09:00 │ │ ... │ │ │ │ [1] [2] [3] ... [10] │ │ │ └─────────────────────────────────────────────────────────────────┘ ※ Google OAuth 미연결 시: ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Google 계정 연결이 필요합니다. │ │ │ │ [Google 계정 연결하기] │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 6.3 주간보고 상세 - 그룹 공유 섹션 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 2026년 2주차 주간보고 [수정] [삭제] │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ (주간보고 내용...) │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 📤 Google 그룹 공유 │ │ ─────────────────────────────────────────────────────────────── │ │ │ │ 그룹 선택: [developers@company.com ▼] [공유하기] │ │ │ │ 공유 이력: │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ ✅ developers@company.com 2026-01-10 09:30 │ │ │ │ ✅ team-leads@company.com 2026-01-10 09:35 │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## 7. 구현 상세 ### 7.1 그룹 목록 조회 Gmail API로는 직접 그룹 목록 조회가 어려움. 대안: 1. **사용자가 직접 입력** (간단) 2. **시스템 설정에서 그룹 목록 관리** (권장) 3. **Directory API 사용** (Google Workspace 필요) ```sql -- 시스템 설정 테이블에 그룹 목록 저장 CREATE TABLE wr_google_group ( group_id SERIAL PRIMARY KEY, group_email VARCHAR(200) NOT NULL UNIQUE, group_name VARCHAR(100), is_active BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT NOW() ); INSERT INTO wr_google_group (group_email, group_name) VALUES ('developers@company.com', '개발팀'), ('team-leads@company.com', '팀장단'), ('all@company.com', '전체'); ``` ### 7.2 그룹 게시물 조회 로직 ```typescript // Gmail API로 특정 그룹 메일 검색 async function getGroupMessages(accessToken: string, groupEmail: string) { const response = await fetch( `https://gmail.googleapis.com/gmail/v1/users/me/messages?q=list:${groupEmail}`, { headers: { Authorization: `Bearer ${accessToken}` } } ); const data = await response.json(); return data.messages; // [{id, threadId}, ...] } // 메시지 상세 조회 async function getMessage(accessToken: string, messageId: string) { const response = await fetch( `https://gmail.googleapis.com/gmail/v1/users/me/messages/${messageId}`, { headers: { Authorization: `Bearer ${accessToken}` } } ); return response.json(); } ``` ### 7.3 그룹에 메일 발송 로직 ```typescript async function sendToGroup(accessToken: string, to: string, subject: string, body: string) { const email = [ `To: ${to}`, `Subject: =?UTF-8?B?${Buffer.from(subject).toString('base64')}?=`, 'Content-Type: text/plain; charset=UTF-8', '', body ].join('\r\n'); const encodedEmail = Buffer.from(email) .toString('base64') .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, ''); const response = await fetch( 'https://gmail.googleapis.com/gmail/v1/users/me/messages/send', { method: 'POST', headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ raw: encodedEmail }) } ); return response.json(); } ``` --- ## 8. 작업 일정 ### Phase 1: OAuth Scope 확장 + 토큰 저장 (2일) - [ ] 시작: - [ ] 완료: - [ ] 소요시간: **작업 내용:** - [ ] Google Cloud Console OAuth scope 추가 - [ ] wr_employee_info에 토큰 저장 컬럼 추가 - [ ] OAuth 콜백에서 access/refresh 토큰 저장 - [ ] 토큰 갱신 로직 --- ### Phase 2: 그룹 게시물 조회 (3일) - [ ] 시작: - [ ] 완료: - [ ] 소요시간: **작업 내용:** - [ ] wr_google_group 테이블 생성 - [ ] 그룹 목록 API - [ ] 그룹 게시물 목록 API (Gmail API 연동) - [ ] 게시물 상세 API - [ ] 그룹 게시물 조회 페이지 --- ### Phase 3: 주간보고 그룹 공유 (3일) - [ ] 시작: - [ ] 완료: - [ ] 소요시간: **작업 내용:** - [ ] wr_report_group_share 테이블 생성 - [ ] 그룹 공유 API (Gmail 발송) - [ ] 공유 이력 API - [ ] 주간보고 상세에 공유 UI 추가 - [ ] 이메일 본문 템플릿 --- ### Phase 4: 테스트 + 마무리 (2일) - [ ] 시작: - [ ] 완료: - [ ] 소요시간: **작업 내용:** - [ ] 전체 플로우 테스트 - [ ] 토큰 만료 시 갱신 테스트 - [ ] 오류 처리 (권한 없음, 그룹 미가입 등) - [ ] 관리자 - 그룹 목록 관리 페이지 --- ## 작업 완료 결과 ### Phase별 작업 시간 | Phase | 작업 내용 | 시작 | 완료 | 소요시간 | |:-----:|----------|:----:|:----:|:--------:| | 1 | OAuth Scope 확장 + 토큰 저장 | - | - | - | | 2 | 그룹 게시물 조회 | - | - | - | | 3 | 주간보고 그룹 공유 | - | - | - | | 4 | 테스트 + 마무리 | - | - | - | | | | | **총 소요시간** | **-** | --- ### 생성/수정된 파일 | 구분 | 파일 | 작업 | |------|------|:----:| | **DB** | wr_employee_info | 수정 (토큰 컬럼 추가) | | **DB** | wr_google_group | 신규 테이블 | | **DB** | wr_report_group_share | 신규 테이블 | | **API** | backend/api/google-group/my-groups.get.ts | 신규 | | **API** | backend/api/google-group/[groupEmail]/messages.get.ts | 신규 | | **API** | backend/api/google-group/message/[id].get.ts | 신규 | | **API** | backend/api/google-group/share.post.ts | 신규 | | **API** | backend/api/report/[id]/share-history.get.ts | 신규 | | **Frontend** | frontend/pages/google-group/index.vue | 신규 | | **Frontend** | frontend/pages/report/[id].vue | 수정 (공유 UI) | | **Utils** | backend/utils/gmail-api.ts | 신규 | | **Utils** | backend/utils/google-token.ts | 신규 | --- ## 9. 기술 스택 - **Backend**: Nitro (H3) + PostgreSQL - **Frontend**: Nuxt3 + Vue3 + Bootstrap 5 - **외부 API**: Gmail API v1 - **인증**: OAuth 2.0 (4번 작업 확장) --- ## 10. 주의사항 ### 10.1 Gmail API 제한 - **일일 할당량**: 사용자당 250개 할당량 단위/일 - **메일 발송**: 건당 100 할당량 단위 - 대량 발송 시 제한 주의 ### 10.2 민감한 Scope - Gmail readonly/send는 "민감한 범위" - Google Workspace 내부 앱은 관리자 승인으로 해결 ### 10.3 토큰 보안 - access_token, refresh_token 암호화 저장 권장 - HTTPS 필수 --- ## 11. 향후 확장 고려 1. **게시물 시스템 연동**: 그룹 게시물 → 회의록/공지사항으로 저장 2. **자동 공유**: 주간보고 확정 시 자동으로 그룹 공유 3. **그룹별 자동 선택**: 프로젝트 → 그룹 매핑으로 자동 선택 4. **공유 알림**: 그룹 공유 시 시스템 알림