작업계획서대로 진행
This commit is contained in:
545
claude_temp/06_구글그룹_연동_작업계획서.md
Normal file
545
claude_temp/06_구글그룹_연동_작업계획서.md
Normal file
@@ -0,0 +1,545 @@
|
||||
# 구글 그룹 연동 작업계획서
|
||||
|
||||
> 작성일: 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. **공유 알림**: 그룹 공유 시 시스템 알림
|
||||
Reference in New Issue
Block a user