# Supabase Storage 檔案儲存使用指南 ## 概述 KSTools License Manager 使用 Supabase Storage 來儲存和管理插件發布檔案。系統支援 ZIP、EXE、MSI 三種檔案格式,並自動建立 `plugin-releases` bucket 用於存放版本檔案。 ## 系統架構流程圖 ```mermaid graph TD A[開發者] --> B[準備發布檔案] B --> C{選擇檔案格式} C --> D[.zip 壓縮包] C --> E[.exe 可執行檔] C --> F[.msi 安裝程式] D --> G[上傳到 Supabase Storage] E --> G F --> G G --> H[獲取公開 URL] H --> I[更新 versions 表] I --> J[用戶可下載] subgraph "Supabase Storage" K[plugin-releases bucket] L[RLS 政策] M[公開 URL] end G --> K K --> L L --> M M --> H subgraph "前端系統" N[版本管理頁面] O[下載統計] P[檔案列表] end J --> N N --> O N --> P %% 精簡配色 - 只標記關鍵步驟 style A fill:#e3f2fd style G fill:#f3e5f5 style J fill:#d4edda ``` ## 發布流程圖 ```mermaid sequenceDiagram participant Dev as 開發者 participant UI as 前端介面 participant API as 後端 API participant Storage as Supabase Storage participant DB as Supabase DB participant User as 用戶 Dev->>+UI: 1. 選擇檔案上傳 (.zip/.exe/.msi) UI->>UI: 2. 檢測檔案格式 UI->>+API: 3. POST /api/admin/release (FormData) API->>API: 4. 驗證檔案格式和大小 API->>+Storage: 5. upload(file, filename) Storage-->>-API: 6. 返回上傳結果 API->>+Storage: 7. getPublicUrl(filename) Storage-->>-API: 8. 返回公開 URL API->>+DB: 9. 插入版本記錄 (含 title, file_type) DB-->>-API: 10. 確認記錄已建立 API-->>-UI: 11. 返回完整發布結果 UI-->>-Dev: 12. 發布成功通知 User->>+UI: 13. 查看版本列表 UI->>+DB: 14. 查詢版本記錄 DB-->>-UI: 15. 返回版本資料 (含檔案類型) UI-->>-User: 16. 顯示版本列表 (顯示檔案格式圖示) User->>+Storage: 17. 點擊下載 Storage-->>-User: 18. 直接下載檔案 %% 關鍵步驟高亮 rect rgb(255, 243, 205) note over UI,API: 檔案上傳驗證階段 end rect rgb(243, 229, 245) note over API,Storage: Storage 處理階段 end rect rgb(212, 237, 218) note over API,DB: 資料庫記錄階段 end ``` ## 檔案格式決策流程圖 ```mermaid flowchart TD Start([開始發布]) --> Choose{選擇檔案格式} Choose -->|開發版本| ZIP[ZIP 壓縮包] Choose -->|便攜版本| EXE[EXE 可執行檔] Choose -->|正式安裝| MSI[MSI 安裝程式] ZIP --> CheckZip{檔案完整性} EXE --> CheckExe{可執行性測試} MSI --> CheckMsi{安裝程式測試} CheckZip -->|通過| Upload1[上傳 .zip] CheckExe -->|通過| Upload2[上傳 .exe] CheckMsi -->|通過| Upload3[上傳 .msi] CheckZip -->|失敗| Error[修復並重新打包] CheckExe -->|失敗| Error CheckMsi -->|失敗| Error Upload1 --> Success[發布成功] Upload2 --> Success Upload3 --> Success Error --> Start %% 精簡配色 - 只標記關鍵步驟 style Start fill:#e3f2fd style Success fill:#d4edda style Error fill:#f8d7da ``` ## 檔案格式說明 ### 支援的檔案格式 | 格式 | 用途 | 檔案大小 | 建議使用場景 | |-----|------|---------|-------------| | `.zip` | 壓縮包 | 小 | 開發版本、源碼發布 | | `.exe` | 可執行檔 | 中 | 便攜版本、免安裝版 | | `.msi` | 安裝程式 | 大 | 正式發布、企業部署 | ### 檔案命名規範 ``` KSTools-v{版本號}.{格式} 範例: - KSTools-v1.2.0.zip - KSTools-v1.2.0.exe - KSTools-v1.2.0.msi ``` ## 設定步驟 ### 1. 執行 SQL Schema 在你的 Supabase 版本專案中執行 `supabase-version-schema.sql`,這會: - 建立 `plugin-releases` bucket - 建立支援多格式的 `versions` 表 - 設定適當的 RLS 政策 - 允許公開讀取檔案 - 允許認證用戶上傳檔案 ### 2. 驗證 Storage 設定 1. 登入 Supabase Dashboard 2. 進入你的版本專案 3. 點選 "Storage" 頁面 4. 確認看到 `plugin-releases` bucket ## 檔案上傳方式 ### 透過後端 API 上傳 系統採用統一的後端 API 上傳方式,確保安全性和一致性。 ```javascript // 前端版本發布表單提交 async function handleRelease(formData, file) { const releaseData = new FormData(); releaseData.append('version', formData.version); releaseData.append('title', formData.title); releaseData.append('changelog', formData.changelog); releaseData.append('file', file); const response = await fetch('/api/admin/release', { method: 'POST', headers: { 'Authorization': `Bearer ${session.access_token}` }, body: releaseData }); if (!response.ok) { throw new Error('發布失敗'); } return await response.json(); } ``` ### 檔案上傳流程 1. **前端驗證** - 檔案格式、大小檢查 2. **API 呼叫** - 傳送 FormData 到 `/api/admin/release` 3. **後端處理** - 檔案上傳到 Supabase Storage 4. **資料庫更新** - 儲存版本記錄 5. **返回結果** - 完整的發布資訊 ## 後端 API 實作詳情 ### FastAPI 端點:`/api/admin/release` ```python @router.post("/admin/release") async def release_version( version: str = Form(...), title: Optional[str] = Form(None), changelog: str = Form(...), min_revit_version: Optional[str] = Form(None), file: Optional[UploadFile] = File(None), current_user = Depends(verify_admin) ): """ 發布新版本 - 統一的檔案上傳端點 支援 .zip, .exe, .msi 三種格式 """ # 1. 驗證檔案格式 allowed_extensions = ['.zip', '.exe', '.msi'] file_extension = None for ext in allowed_extensions: if file.filename.lower().endswith(ext): file_extension = ext break if not file_extension: raise HTTPException( status_code=400, detail=f"不支援的檔案格式。支援格式:{', '.join(allowed_extensions)}" ) # 2. 上傳到 Supabase Storage file_content = await file.read() file_size = len(file_content) file_path = f"KSTools-v{version}{file_extension}" # 設定正確的 MIME 類型 content_types = { '.zip': 'application/zip', '.exe': 'application/octet-stream', '.msi': 'application/x-msi' } content_type = content_types.get(file_extension, 'application/octet-stream') final_download_url = await version_db.upload_file(file_path, file_content, content_type) # 3. 儲存版本記錄 version_data = { 'version': version, 'title': title, 'changelog': changelog, 'min_revit_version': min_revit_version, 'download_url': final_download_url, 'file_size': file_size, 'file_type': file_extension.lstrip('.') if file_extension else None, 'file_name': f"KSTools-v{version}{file_extension}" if file_extension else None, 'released_by': current_user.get('email', 'Unknown'), 'is_active': True } result = client.table('versions').insert(version_data).execute() return {"success": True, "version": result.data[0]} ``` ## 自動化流程 使用此 API 端點的優勢: - ✅ **統一入口** - 所有檔案上傳都通過同一個端點 - ✅ **自動驗證** - 檔案格式、大小自動檢查 - ✅ **安全控制** - 管理員權限驗證 - ✅ **完整記錄** - 自動建立資料庫記錄 - ✅ **錯誤處理** - 統一的錯誤回應 ## 資料庫記錄範例 系統會自動建立以下格式的版本記錄: ```sql -- 新增版本記錄(包含檔案格式和標題) INSERT INTO versions ( version, title, release_date, is_active, download_url, file_size, file_type, file_name, changelog, min_revit_version, released_by ) VALUES ( '1.2.0', '重大功能更新', -- 版本標題 NOW(), true, 'https://你的專案ID.supabase.co/storage/v1/object/public/plugin-releases/KSTools-v1.2.0.msi', 25600000, -- 檔案大小(位元組) 'msi', -- 檔案類型 'KSTools-v1.2.0.msi', -- 檔案名稱 '- 新功能說明\n- 錯誤修復', '2020', 'KyrosDev' ); ``` ## 前端顯示檔案類型 ```javascript // 在版本列表中顯示檔案格式圖示 function getFileTypeIcon(fileType) { const icons = { 'zip': '📦', 'exe': '⚙️', 'msi': '💾' }; return icons[fileType] || '📄'; } function renderVersionList(versions) { return versions.map(version => `