專案雲端整合(Project Cloud Integration)
功能群:證據管理|Drive 連線 / 儲存後端共用概念先讀 功能群總覽;租戶層 Drive 連線管理見 雲端整合
事實基準:2026-07-06 從 FE / BE code 掃出;表結構對
db_schema.json、endpoint 對routes.json逐條核
1. 功能描述
專案雲端整合是單一專案層級的 Drive 資料夾維護面板:當某個專案的 Drive 資料夾結構損壞(被使用者在 Drive 端手動刪掉、改動)時,manager 在此觸發「驗證並修復」——逐一檢查該專案樹各層資料夾是否還在,把失聯的標記起來並排程重建。
與租戶層 雲端整合
的分工:租戶層做的是 OAuth 連線 / 中斷 /
全租戶重建(is_admin);本面板只處理單一專案的資料夾驗證修復(專案
manager)。兩者同屬 api/cloud_integration
模組、共用 CloudIntegrationService,但 endpoint
與權限不同。
這是一個可重用面板(ProjectCloudIntegrationsPanel.vue),現掛在專案規劃頁
Tab5「雲端整合」(?tab=5)。(原「專案設定」頁 Tab
雲端亦掛此面板,該頁已整併進規劃頁、route 已無入口。)
主要使用者:專案 manager。
角色速覽(完整定義見 _overview):
| 角色 | 一句話 |
|---|---|
| manager | 專案經理 — 唯一能觸發驗證修復者(嚴格 manager-only,owner / admin 皆無 bypass) |
| 其他參與者 | 面板可見但按鈕不可用(FE canEdit 關;BE 亦強制擋) |
1.1 功能總覽(本頁全部功能)
| # | 功能 | 說明 | 位置 | 詳述 |
|---|---|---|---|---|
| 1 | 標題 / 說明區 | 「雲端空間整合」+ Google Drive 卡片與說明 | 面板頂 | §5 |
| 2 | 重新同步資料夾 | 觸發驗證並修復本專案 Drive 資料夾(confirm → 執行 → 結果 dialog) | 主按鈕(限 manager) | UC-PC-01 |
| 3 | 驗證確認 Dialog | 執行前確認框(含耗時提示:視專案大小數秒至數十秒) | Modal | UC-PC-01 |
| 4 | 驗證結果 Dialog | 三分支:Drive 未連線 / 全部正常(verified)/
發現失效已排程重建(broken) |
Modal | §10 |
UC(§2)展開本頁唯一操作路徑 UC-PC-01(驗證並修復);標題 / 說明 / 結果呈現屬純顯示見 §5 / §10。
2. Use Case
角色速覽(同 §1):
| 角色 | 一句話 |
|---|---|
| manager | 專案經理 — 唯一能觸發驗證修復者 |
| 其他參與者 | 面板可見、按鈕不可用 |
流程圖視覺慣例:菱形 = 判斷、橘底 = 例外 / 擋下、紅框 = 錯誤(標 error code)、綠框 = 成功終點、虛線 = 可選路徑。
UC-PC-01 驗證並修復專案 Drive 資料夾
| 項目 | 內容 |
|---|---|
| 角色 | 專案 manager(嚴格 manager-only;owner / admin 無 bypass) |
| 前置條件 | 已登入;為該專案 manager;tenant 已連 Drive(未連則軟 no-op,非錯誤) |
| 產出 / 後置條件 | 失聯資料夾在 drive_folder_mappings 標
is_unlinked=true;有失效則 enqueue
INIT_PROJECT_FOLDERS job(實際重建由背景 worker
非同步做) |
3. 權限矩陣
| 操作 | FE 判定 | BE 強制 | BE 檢查位置 |
|---|---|---|---|
| 進面板 / 讀 | 隨父頁(規劃頁參與者即可) | — | — |
| 驗證並修復 | canEdit:本人 role=manager 才啟用按鈕 |
嚴格
manager-only:participant.role != "manager" →
GRC_403002;專案不存在 → GRC_404001(owner /
admin 皆無 bypass) |
app/cloud_integration/service/drive_project_verify_service.py:122-130 |
⚠️ 對比:同源功能
init-folders(專案清單頁「同步至 Drive」按鈕)刻意無角色守門(避免誤擋非 admin 的專案 manager,見 雲端整合 §12);而 verify-and-repair 因涉及寫入(標 unlinked + enqueue)故嚴格檢查 manager。另專案規劃頁 Tab2/3 的PUT /grc/project反而無角色守門(見 規劃頁 §12 坑 11)——同一專案不同寫入面守門強度不一,維護時注意。
4. 狀態機與前置條件
本頁無輪次狀態機。相關前置:
| 條件 | 效果 | 出處 |
|---|---|---|
tenant
tenant_drive_integrations.status == CONNECTED |
才實際執行檢查;否則軟
no-op(drive_status:"disconnected",非錯誤) |
drive_project_verify_service.py:132-134 |
| 使用者為專案 manager | 否則 GRC_403002 |
同檔 :122-130 |
| 專案存在 | 否則 GRC_404001 |
同檔 :125 |
5. UI 設計
📸 實際畫面截圖待補(一律亮色模式拍攝):規劃頁 Tab5 面板
projcloud-panel.png+ 驗證結果 Dialog 三態projcloud-result.png。
版面骨架與區塊職責(規劃頁 Tab5 單卡片面板;彩色區塊可點跳本頁小節錨點,API 僅標代表性):
版面(單卡片:Google Drive 標題 + 說明 + 「重新同步資料夾」按鈕;確認 Dialog + 結果 Dialog)。
狀態呈現:按鈕
disabled = !canEdit || verifyLoading;執行中
loading;結果以 Dialog 顯示;無
socket、無輪詢——結果同步 inline 回傳即顯示。
6. API 規格
Envelope:成功 {"status": true, "data": …}、失敗
{"error_code": "…", "msg": "…"}。
6.1 總清單(本頁呼叫的全部 endpoint)
| 分類 | Method + Path | 說明 | 完整規格 |
|---|---|---|---|
| 雲端 | POST
/integrations/google-drive/projects/{project_uid}/verify-and-repair-folders |
驗證並修復本專案 Drive 資料夾對應 | §6.2 |
6.2 核心 endpoint
[POST] /integrations/google-drive/projects/{project_uid}/verify-and-repair-folders
無 body。嚴格 manager-only(否則
GRC_403002;找不到專案
GRC_404001)。三階段:Phase
1(@transaction)檢權 + 蒐集該專案全部 folder mappings(9
種 scope:ROOT / PROJECT / AP / CONTROL_GROUP / CONTROL / AO / TASK /
ARCHIVE / EVIDENCES);Phase 2(無 transaction)逐一呼 Drive API 查
folder 是否存在(每個 200-500ms);Phase
3(@transaction)失效者標
is_unlinked=true,有失效則 enqueue
INIT_PROJECT_FOLDERS。
Response data:
| 欄位 | 型別 | 說明 |
|---|---|---|
| verified | int | 檢查過的 folder 總數 |
| broken | int | 失效(Drive 端已不存在)的 folder 數 |
| rebuild_enqueued | bool | 是否已排程重建 job |
| drive_status | string | "connected";tenant 未連 Drive 時回
"disconnected"(其餘欄位為 0 / false,軟 no-op) |
出處:api/cloud_integration/routes/google_drive_sync_route.py::DriveProjectVerifyAndRepairRoute.post(:120-149)、app/cloud_integration/service/drive_project_verify_service.py::verify_and_repair(:85-188)
7. 前端檔案地圖(compliance-manager-fe/)
| 檔案 | 角色 |
|---|---|
src/components/grc/project/ProjectCloudIntegrationsPanel.vue |
本面板(131 行:按鈕 + 確認 Dialog + 結果 Dialog) |
src/views/project/ProjectPlanningView.vue |
掛載點:規劃頁 Tab5「雲端整合」 |
src/service/CloudIntegrationService.js |
verifyAndRepairProjectFolders(projectUid)(:65-66) |
8. 後端檔案地圖(本頁核心鏈路)
| 鏈路 | Route | App Service | 底層 |
|---|---|---|---|
| 驗證修復 | api/cloud_integration/routes/google_drive_sync_route.py::DriveProjectVerifyAndRepairRoute.post(:136) |
app/cloud_integration/service/drive_project_verify_service.py::verify_and_repair(:85;_collect_for_verify
+ _apply_repair) |
public.drive_folder_mappings(讀 + 標
unlinked);GoogleDriveApiClient.get_folder(Phase
2);Drive worker 佇列(Phase 3 enqueue) |
DDD 提醒:Phase 2 的 Drive API 呼叫刻意不在
@transaction 內(不佔 DB session),權限檢查與 DB
讀寫分屬 Phase 1 / 3 各自的 @transaction——長時間外部 I/O
不鎖 DB 的正確樣板。
9. DB
9.1 資料表總清單(本頁讀寫的全部表)
| 表 | 讀寫 | 說明 | 詳述 |
|---|---|---|---|
| public.drive_folder_mappings | 讀 / 寫(is_unlinked) |
專案樹各層 ↔︎ Drive folder 對應;失效標記在此 | §9.3 |
| public.tenant_drive_integrations | 讀 | tenant Drive 連線狀態(須 CONNECTED 才實際執行) | GAI-SD-03 |
| public.drive_sync_jobs | 寫(enqueue) | 有失效時 enqueue INIT_PROJECT_FOLDERS 重建 job |
GAI-SD-03 |
9.2 ER 圖(本頁讀寫範圍)
本頁讀寫範圍單純(見 §9.1),與 雲端整合 §9 共用同一組 Drive 表,ER 不另繪。
9.3 核心表欄位(取自 DEV DB dump)
public.drive_folder_mappings
| 欄位 | 型別 | 說明 |
|---|---|---|
| scope_type | varchar(20) | 資料夾層級(ROOT / PROJECT / AP / CONTROL_GROUP / CONTROL / AO / TASK / ARCHIVE / EVIDENCES) |
| scope_uid | uuid|null | 對應層級的實體 uid |
| drive_folder_id | varchar(100) | Drive 端 folder id(Phase 2 拿去查存在性) |
| display_name_snapshot | varchar(255) | 建立時的資料夾名快照 |
| is_unlinked | bool | 失效標記(Phase 3 修復時設 true) |
10. 頁面邏輯與資料對應
點按鈕 → 確認 Dialog → runVerifyAndRepair() → POST →
結果存 verifyResult → 結果 Dialog 依
drive_status / broken 三分支渲染:
| 結果 | 條件 | 顯示 |
|---|---|---|
| 未連線 | drive_status === 'disconnected' |
橘色「Drive 尚未連線,無法執行檢查」 |
| 全部正常 | broken === 0 |
綠色「所有 {verified} 個資料夾都正常」 |
| 已修復 | broken > 0 |
橘色「檢查 {verified},發現 {broken} 失效,已排程重建」 |
錯誤對應:GRC_404001 /
GRC_403002 →
toast(e.response.data.msg)。
11. 背景行為與外部依賴
| 類型 | 內容 |
|---|---|
| socket / 輪詢 | 無——結果同步 inline 回傳 |
| job | 有失效時 enqueue
INIT_PROJECT_FOLDERS;實際建資料夾由背景
DriveSyncWorker 非同步做(不在本頁鏈路) |
| 外部依賴 | Google Drive API(Phase 2 逐 folder 查存在性,每個 200-500ms) |
| store | 無(純 component ref +
computed) |
12. 邊界情況與已知坑
- 嚴格 manager-only 對比 init-folders 無守門:同模組
init-folders(專案清單頁)刻意無角色檢查、本 verify-and-repair 嚴格 manager;同專案規劃頁 Tab2/3 的PUT /grc/project又無守門——三個 Drive / 專案寫入面守門強度不一,見 規劃頁 §12 坑 11 與 雲端整合 §12。 - 未連 Drive 是軟 no-op:回
drive_status:"disconnected"+ 全 0,不是錯誤——FE 據此顯示「未連線」提示而非 toast error。 - 重建非即時:Phase 3 只 enqueue,實際資料夾由背景 worker 重建;按鈕回來不代表資料夾已好。
- 耗時隨專案大小線性成長:Phase 2 逐 folder 打 Drive API,大專案可達數十秒;confirm dialog 有耗時提示。
13. 開發與驗證
- 跑起來:起 BE + FE;登入見
.env/ 部署文件測試帳號(需該專案 manager) - 導航:專案規劃頁 →
Tab5「雲端整合」(
/project/projects/:id/planning?tab=5) - 前置資料:tenant 需已連 Google Drive(否則只驗得到軟 no-op 分支);可先在 Drive 端手動刪一個專案資料夾,再回來按「重新同步」驗修復
- 相關:租戶層連線見 雲端整合;per-project init-folders 在專案清單頁