# Google Drive 證據同步 — Implementation Plan (主索引)

> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:subagent-driven-development` (recommended) or `superpowers:executing-plans` to implement each phase plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Spec:** [`design.md`](./design.md)

**Goal:** 讓使用者透過 Google Drive 上傳 AO evidence 檔案，自動同步進系統。完整覆蓋 OAuth 連線、資料夾自動建立、改名同步、Drive→系統雙向偵測、UI 來源辨識。

**Architecture:** 三階段獨立交付：(1) OAuth 設定頁、(2) 資料夾建立 & 改名同步、(3) Drive→系統檔案/刪除同步。每階段都能獨立驗收與 demo。

**Tech Stack:** Python 3.11 / Flask / SQLAlchemy / dependency-injector / google-api-python-client / google-auth-oauthlib / cryptography (Fernet) / APScheduler / Vue3 (Composition API) / PrimeVue / Pinia / Playwright (verification)

---

## Phase Plans

| Phase | 標題 | 文件 | 主要交付 | 估時 |
|-------|------|------|---------|------|
| 1 | OAuth 連線 & 整合設定頁 | [`implementation-plan-phase-1-oauth.md`](./implementation-plan-phase-1-oauth.md) | admin 可連 Drive，UI 顯示連線狀態 | 3-5 天 |
| 2 | 資料夾建立 & 改名同步 | [`implementation-plan-phase-2-folders.md`](./implementation-plan-phase-2-folders.md) | PM 啟動 project → Drive 出現完整 6 層資料夾結構（含 task 層）；entity 改名同步到 Drive | 5-7 天 |
| 3 | Drive → 系統 同步 | [`implementation-plan-phase-3-sync.md`](./implementation-plan-phase-3-sync.md) | user 在 Drive task folder 上傳 → 系統 evidence 出現；Drive 刪除 → 系統軟刪 | 7-10 天 |

> **v0.2 變更（2026-04-24）**：folder structure 從 5 層改為 6 層（加入 Task 層）。原因：1 AO 對應 N task（job_execution），evidence 必須綁特定 task 才能正確記錄。Phase 2 已完成 5 層實作，6 層支援的補強寫在 Phase 2 plan 各 Task 的「v0.2 Addendum」區塊與 Task #59；Phase 3 plan 同步調整（Task 9.5 變為不必要、handler payload 改用 task_mapping_uid、`RECONCILE_AO_FOLDER` → `RECONCILE_TASK_FOLDER`）。詳見 design.md v0.2 修訂與 changelog `2026-04-24-google-drive-folder-init-and-rename-sync.md` 的「後續變更」段。

---

## Dependencies

```
Phase 1 (foundation)
    │
    ▼
Phase 2 (uses tenant_drive_integrations + adds folder mappings + worker infra)
    │
    ▼
Phase 3 (uses worker infra + adds webhook + change processing)
```

- **Phase 2 不可在 Phase 1 完成前開始**：需要 OAuth token 才能 call Drive API
- **Phase 3 不可在 Phase 2 完成前開始**：需要 worker queue + APScheduler + folder mappings 已存在

---

## 開發規範遵守 Checklist（每個 task 都需檢查）

來自 `CLAUDE.md`：

### 後端

- [ ] **DDD 層級嚴格分隔**
  - `api/` 不直接呼叫 `get_session()`、不 import ORM model；只負責 HTTP 邊界
  - `app/` 不直接 import ORM model；DB 操作必須走 domain service → repository
  - `domain/` 定義 repository interface (abstract)，不依賴 infra
  - `infra/` 是唯一可以 `self.session` / ORM query 的地方
- [ ] **DI**：新 service / repo 透過 `__init__` 注入，並在對應 `di_containers/` wire 起來
- [ ] **權限檢查**：寫入 / 狀態轉換 API 必須在 app service 層用 domain service 查角色（manager / auditor），不在 route 層查 DB
- [ ] **狀態前置條件驗證**：例如「未連 Drive 不能觸發 sync」「token revoked 不可手動 sync」
- [ ] **Error code**：使用 `jedi_common.handler.exception` 內例外 + 模組專屬 ErrorCode；命名 `GRC_<HTTP><序號>`；新 code 加在 `common/code/grc_error_code.py`
- [ ] **不裸 raise ValueError(...)**
- [ ] **API URL kebab-case**，單筆操作單數 / 列表複數
- [ ] **審計欄位**：response 含 `created_user` 必須同時帶 `created_user_name`（在 app service 層批次查 nickname）
- [ ] **SQL migration**：每段加日期註解 `-- N. 說明 (YYYY-MM-DD)`，檔案開頭 `-- Date: YYYY-MM-DD`；新 table 加 `GRANT SELECT, INSERT, UPDATE, DELETE ON <table> TO cm_app;` + `GRANT USAGE, SELECT ON SEQUENCE <table>_id_seq TO cm_app;`
- [ ] **不直接 import infra ORM model 到 app/route 層**
- [ ] **新模組需註冊到 `config/app_modules.py REGISTERED_APPS`**
- [ ] **新 module 需實作 `api/<module>/__init__.py` 的 `create_module()`** 回傳 Blueprint

### 前端

- [ ] **API 端點常數集中在 `src/config/api/api.js`**
- [ ] **Service 繼承 `src/service/BaseService.js`**
- [ ] **Composition API + `<script setup>` 風格與 Vue 3 慣例一致**
- [ ] **PrimeVue 元件，跟既有頁面（`AuditControlRef.vue`、`MyTasksView.vue`、`UserProfileForm.vue`）視覺風格一致**
- [ ] **i18n key 新增到 `src/lang/<locale>.js`**（中英）
- [ ] **避免 inline style，用 utility class（PrimeFlex / Tailwind 風）**

### Changelog & 文件

- [ ] **每個獨立修改主題建一份 changelog**：`docs/changelog/YYYY-MM-DD-<簡述>.md`
  - Phase 1 完成 → 寫一份
  - Phase 2 完成 → 寫一份（或拆 INIT_FOLDERS / RENAME_SYNC 兩份）
  - Phase 3 完成 → 寫一份（或拆 WEBHOOK / IMPORT / UI 多份）
- [ ] **內容必含**：需求說明、變更範圍（檔案清單）、API 變更（request/response 差異）、參考資訊
- [ ] **Subagent 平行任務也要產生對應 changelog**

---

## Pre-Implementation 共通準備（Phase 1 開始前必完成）

### 後端

- [ ] 在 `pyproject.toml` 新增依賴：
  ```toml
  google-api-python-client = "^2.130.0"
  google-auth-oauthlib = "^1.2.0"
  google-auth-httplib2 = "^0.2.0"
  cryptography = "^42.0.0"   # 已有則跳過
  apscheduler = "^3.10.0"   # Phase 2 才會 import，Phase 1 可一起加
  ```
  執行 `poetry install`。
- [ ] 註冊新模組 `cloud_integration` 到 `config/app_modules.py REGISTERED_APPS`。
- [ ] 在 `config/config.py` 各環境 class 新增 attribute（先 placeholder，實際值由 ops 提供）：
  ```python
  GOOGLE_DRIVE_OAUTH_CLIENT_ID = os.getenv("GOOGLE_DRIVE_OAUTH_CLIENT_ID", "")
  GOOGLE_DRIVE_OAUTH_CLIENT_SECRET = os.getenv("GOOGLE_DRIVE_OAUTH_CLIENT_SECRET", "")
  GOOGLE_DRIVE_OAUTH_REDIRECT_URI = os.getenv("GOOGLE_DRIVE_OAUTH_REDIRECT_URI", "")
  DRIVE_TOKEN_ENCRYPTION_KEY = os.getenv("DRIVE_TOKEN_ENCRYPTION_KEY", "")
  DRIVE_WEBHOOK_PUBLIC_BASE_URL = os.getenv("DRIVE_WEBHOOK_PUBLIC_BASE_URL", "")
  DRIVE_SYNC_WORKER_POOL_SIZE = int(os.getenv("DRIVE_SYNC_WORKER_POOL_SIZE", "4"))
  DRIVE_FILE_SIZE_LIMIT_MB = int(os.getenv("DRIVE_FILE_SIZE_LIMIT_MB", "20"))
  ```

### 環境變數產生

- [ ] **產生 Fernet key** 給每個環境（dev / staging / prod 各一把獨立 key）：
  ```bash
  python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
  ```
  寫入該環境的 secret manager。

### Google Cloud 設定（per env）

- [ ] 在 GCP Console 建立 project（如 `guidant-ai-staging`、`guidant-ai-prod`）
- [ ] 啟用 Google Drive API
- [ ] 建立 **OAuth 2.0 Client ID（Web application）**
  - Authorized redirect URIs：每環境一條，例如 `https://staging.example.com/api/integrations/google-drive/callback`
- [ ] 設定 OAuth consent screen
  - Scopes: `https://www.googleapis.com/auth/drive` + `userinfo.email`
  - 把 dev / demo 環境的測試 admin 加入 test users
- [ ] 將 client_id / client_secret 寫入該環境 secret manager

### Domain / DDNS（Phase 3 才需要，可預先準備）

- [ ] Production：確認有正式 domain + HTTPS
- [ ] Dev / demo：選擇方案
  - 自有 domain CNAME → DDNS IP（推薦）
  - 或 Cloudflare Tunnel
  - 或 ngrok（暫時測試用）
- [ ] 在 GCP Console 完成 domain verification（DNS TXT 或 HTML 檔）

### 共用 Drive 帳號（客戶配合）

- [ ] 客戶端建立 dedicated Google 帳號（如 `compliance@<customer>.com`）
- [ ] 確認該帳號 Drive 容量充足
- [ ] 客戶 IT 確認允許該帳號做 OAuth 授權

---

## Open Items（spec §18 同步追蹤）

1. OAuth verification 啟動時程 — 需要 product team 決定
2. KMS 升級時程 — 第一版 Fernet，何時遷移
3. 多 tenant unverified 100 user 上限是否足夠
4. Drive 帳號儲存空間配額耗盡通知機制
5. `drive_last_modifying_user_email` 匯出顯示位置

這些不阻擋 Phase 1-3 開發，但要在上 production 前收掉。

---

## 執行方式

3 份 plan 都建議用 **subagent-driven-development**：
- 每個 task 派一個 fresh subagent 執行（避免 context 污染）
- 我（主 agent）負責 review 每個 task 的產出與 commit
- Phase 與 phase 之間有 checkpoint，可以做 demo 給 user
