Some checks failed
CD Pipeline / deploy (push) Failing after 59s
- 建立 Gitea Actions CD pipeline (.gitea/workflows/cd.yaml) - 部署模式: rsync Python 檔案至 188 → docker restart (volume mount) - Dockerfile/requirements 變動時自動重建 Docker image - 部署通知: Telegram (開始/成功/失敗) - 健康檢查: https://mo.wooo.work/health (最多 5 次重試) - 同步最新 CLAUDE.md / ADR-008 / memory (2026-04-19) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
347 lines
10 KiB
Markdown
347 lines
10 KiB
Markdown
# app.py 重構計畫
|
||
|
||
## 文件資訊
|
||
- **建立日期**: 2026-01-18
|
||
- **目標檔案**: app.py (7,253 行)
|
||
- **目標**: 模組化拆分,提高可維護性
|
||
|
||
---
|
||
|
||
## 一、現況分析
|
||
|
||
### 1.1 檔案規模
|
||
- **總行數**: 7,253 行
|
||
- **路由數量**: 49 個
|
||
- **函數數量**: 約 70 個
|
||
|
||
### 1.2 最大函數 (需優先拆分)
|
||
|
||
| 排名 | 函數名稱 | 行數 | 所屬模組建議 |
|
||
|------|----------|------|--------------|
|
||
| 1 | `sales_analysis()` | 1,020 行 | sales_routes.py |
|
||
| 2 | `get_monthly_summary_data()` | 388 行 | monthly_routes.py |
|
||
| 3 | `import_excel()` | 288 行 | import_routes.py |
|
||
| 4 | `get_sales_table_data()` | 267 行 | sales_routes.py |
|
||
| 5 | `export_top_detail()` | 256 行 | sales_routes.py |
|
||
| 6 | `get_top_detail()` | 252 行 | sales_routes.py |
|
||
| 7 | `edm_dashboard()` | 244 行 | edm_routes.py |
|
||
| 8 | `index()` | 190 行 | dashboard_routes.py |
|
||
|
||
### 1.3 現有路由分類
|
||
|
||
```
|
||
頁面路由 (12個):
|
||
├── / (首頁/商品看板)
|
||
├── /settings (設定)
|
||
├── /system_settings (系統設定)
|
||
├── /brand_assets (品牌資源)
|
||
├── /edm (EDM 儀表板)
|
||
├── /festival (節慶儀表板)
|
||
├── /abc_analysis/detail (ABC 分析詳情)
|
||
├── /logs (系統日誌)
|
||
├── /monthly_summary_analysis (月結分析)
|
||
├── /sales_analysis (業績分析)
|
||
├── /growth_analysis (成長分析)
|
||
└── /daily_sales (當日業績)
|
||
|
||
API 路由 (37個):
|
||
├── 系統 API (3個): /health, /metrics, /api/logs
|
||
├── 分類管理 API (4個): /api/categories/*
|
||
├── 匯出 API (11個): /api/export/*
|
||
├── 任務觸發 API (6個): /api/run_*, /api/trigger_*
|
||
├── 匯入 API (2個): /api/import_excel, /api/import/monthly_summary
|
||
├── 備份 API (2個): /api/backup, /api/backup/download/*
|
||
├── 業績分析 API (5個): /api/sales_analysis/*
|
||
├── 月結分析 API (1個): /api/monthly_summary_data
|
||
├── 其他 API (3個): /api/test_url, /api/history/*, /api/price_change_details
|
||
└── 當日業績匯出 (2個): /daily_sales/export*
|
||
```
|
||
|
||
---
|
||
|
||
## 二、重構架構設計
|
||
|
||
### 2.1 目標目錄結構
|
||
|
||
```
|
||
momo_pro_system/
|
||
├── app.py # 主應用程式 (精簡後約 500 行)
|
||
├── config.py # 配置檔 (保持不變)
|
||
├── auth.py # 認證模組 (保持不變)
|
||
│
|
||
├── routes/ # 🆕 路由模組目錄
|
||
│ ├── __init__.py # Blueprint 註冊中心
|
||
│ ├── dashboard_routes.py # 商品看板 (首頁)
|
||
│ ├── sales_routes.py # 業績分析相關
|
||
│ ├── daily_sales_routes.py # 當日業績相關
|
||
│ ├── monthly_routes.py # 月結分析相關
|
||
│ ├── edm_routes.py # EDM 儀表板
|
||
│ ├── export_routes.py # 匯出功能
|
||
│ ├── import_routes.py # 匯入功能
|
||
│ ├── system_routes.py # 系統管理 (設定、日誌、備份)
|
||
│ └── api_routes.py # 通用 API (健康檢查、任務觸發等)
|
||
│
|
||
├── services/ # 服務層 (現有)
|
||
│ ├── __init__.py
|
||
│ ├── cache_service.py # 🆕 快取服務 (從 app.py 抽出)
|
||
│ ├── sales_service.py # 🆕 業績計算服務
|
||
│ ├── dashboard_service.py # 🆕 看板數據服務
|
||
│ └── ... (現有服務)
|
||
│
|
||
├── utils/ # 工具函數 (現有)
|
||
│ ├── __init__.py
|
||
│ ├── validators.py # 🆕 驗證函數 (從 app.py 抽出)
|
||
│ ├── formatters.py # 🆕 格式化函數
|
||
│ └── ... (現有工具)
|
||
│
|
||
├── database/ # 資料庫層 (保持不變)
|
||
├── vendor_routes.py # 廠商缺貨路由 (已存在)
|
||
└── auto_import_routes.py # 自動匯入路由 (已存在)
|
||
```
|
||
|
||
### 2.2 模組劃分詳情
|
||
|
||
#### 模組 1: `routes/dashboard_routes.py` (~400 行)
|
||
```python
|
||
# 包含路由:
|
||
- GET / # index() - 商品看板首頁
|
||
- GET /brand_assets # brand_assets()
|
||
|
||
# 包含函數:
|
||
- get_consolidated_data() # 153 行
|
||
- get_full_dashboard_data() # 148 行
|
||
- get_dashboard_stats() # 16 行
|
||
```
|
||
|
||
#### 模組 2: `routes/sales_routes.py` (~2,000 行)
|
||
```python
|
||
# 包含路由:
|
||
- GET /sales_analysis # sales_analysis() - 1,020 行
|
||
- GET /api/sales_analysis/table_data # get_sales_table_data() - 267 行
|
||
- GET /api/sales_analysis/table_data_pandas
|
||
- GET /api/sales_analysis/top_detail # get_top_detail() - 252 行
|
||
- GET /api/sales_analysis/export_top_detail
|
||
- GET /api/sales_analysis/yoy_comparison
|
||
|
||
# 包含函數:
|
||
- _get_filtered_sales_data()
|
||
```
|
||
|
||
#### 模組 3: `routes/daily_sales_routes.py` (~800 行)
|
||
```python
|
||
# 包含路由:
|
||
- GET /daily_sales # daily_sales() - 161 行
|
||
- GET /daily_sales/export # export_daily_sales_category()
|
||
- GET /daily_sales/export_marketing
|
||
- GET /growth_analysis # growth_analysis()
|
||
|
||
# 包含函數:
|
||
- preprocess_daily_sales_data()
|
||
- calculate_daily_kpis()
|
||
- calculate_dod()
|
||
- calculate_wow()
|
||
- prepare_daily_charts()
|
||
- prepare_category_summary()
|
||
- prepare_marketing_summary()
|
||
- get_taiwan_holiday()
|
||
- prepare_calendar_data()
|
||
```
|
||
|
||
#### 模組 4: `routes/monthly_routes.py` (~500 行)
|
||
```python
|
||
# 包含路由:
|
||
- GET /monthly_summary_analysis
|
||
- GET /api/monthly_summary_data # 388 行
|
||
- POST /api/import/monthly_summary
|
||
```
|
||
|
||
#### 模組 5: `routes/edm_routes.py` (~400 行)
|
||
```python
|
||
# 包含路由:
|
||
- GET /edm # edm_dashboard() - 244 行
|
||
- GET /festival # festival_dashboard() - 148 行
|
||
```
|
||
|
||
#### 模組 6: `routes/export_routes.py` (~800 行)
|
||
```python
|
||
# 包含路由:
|
||
- GET /api/export/all_categories
|
||
- GET /api/export/excel/all
|
||
- GET /api/export/excel/changes
|
||
- GET /api/export/excel/delisted
|
||
- GET /api/export/price_changes # 156 行
|
||
- GET /api/export/low_prices
|
||
- GET /api/export/changes
|
||
- GET /api/export/excel/abc # 175 行
|
||
- GET /api/export/excel/vendor # 135 行
|
||
- GET /api/export/excel/seasonality_detail
|
||
```
|
||
|
||
#### 模組 7: `routes/import_routes.py` (~350 行)
|
||
```python
|
||
# 包含路由:
|
||
- POST /api/import_excel # import_excel() - 288 行
|
||
```
|
||
|
||
#### 模組 8: `routes/system_routes.py` (~400 行)
|
||
```python
|
||
# 包含路由:
|
||
- GET /settings
|
||
- GET /system_settings
|
||
- GET /logs
|
||
- GET /api/logs
|
||
- POST /api/backup
|
||
- GET /api/backup/download/<path:filename>
|
||
- POST /api/categories (CRUD)
|
||
- POST /api/test_url
|
||
|
||
# 包含函數:
|
||
- load_categories()
|
||
- save_categories()
|
||
- load_scheduler_stats()
|
||
```
|
||
|
||
#### 模組 9: `routes/api_routes.py` (~300 行)
|
||
```python
|
||
# 包含路由:
|
||
- GET /health
|
||
- GET /metrics
|
||
- POST /api/run_task
|
||
- POST /api/run_edm_task
|
||
- POST /api/run_festival_task
|
||
- POST /api/trigger_momo_notification
|
||
- POST /api/trigger_edm_notification
|
||
- POST /api/test_notification
|
||
- GET /api/history/<int:product_id>
|
||
- GET /api/price_change_details
|
||
- GET /abc_analysis/detail
|
||
|
||
# 包含函數:
|
||
- track_query_time()
|
||
```
|
||
|
||
---
|
||
|
||
## 三、重構執行步驟
|
||
|
||
### 階段 1: 準備工作 (風險: 低)
|
||
1. ✅ 完整備份現有程式碼
|
||
2. 建立 `routes/` 目錄結構
|
||
3. 建立 `routes/__init__.py` Blueprint 註冊中心
|
||
|
||
### 階段 2: 抽取共用模組 (風險: 低)
|
||
1. 建立 `services/cache_service.py` - 抽取快取相關變數和函數
|
||
2. 建立 `utils/validators.py` - 抽取驗證函數
|
||
3. 建立 `utils/formatters.py` - 抽取格式化函數
|
||
|
||
### 階段 3: 拆分路由模組 (風險: 中)
|
||
**執行順序 (由簡單到複雜):**
|
||
|
||
| 順序 | 模組 | 路由數 | 複雜度 | 依賴關係 |
|
||
|------|------|--------|--------|----------|
|
||
| 1 | system_routes.py | 8 | 低 | 無外部依賴 |
|
||
| 2 | api_routes.py | 10 | 低 | scheduler |
|
||
| 3 | export_routes.py | 10 | 中 | DatabaseManager, Exporter |
|
||
| 4 | import_routes.py | 1 | 中 | DatabaseManager |
|
||
| 5 | edm_routes.py | 2 | 中 | DatabaseManager |
|
||
| 6 | monthly_routes.py | 3 | 中 | DatabaseManager |
|
||
| 7 | dashboard_routes.py | 2 | 高 | cache_service, DatabaseManager |
|
||
| 8 | daily_sales_routes.py | 4 | 高 | 多個輔助函數 |
|
||
| 9 | sales_routes.py | 6 | 高 | cache_service, 複雜邏輯 |
|
||
|
||
### 階段 4: 整合測試 (風險: 低)
|
||
1. 本機測試所有路由
|
||
2. UAT 環境部署測試
|
||
3. 回歸測試所有功能
|
||
|
||
---
|
||
|
||
## 四、安全措施
|
||
|
||
### 4.1 備份策略
|
||
```bash
|
||
# 重構前完整備份
|
||
cp -r /Users/ogt/momo_pro_system /Users/ogt/momo_pro_system_backup_$(date +%Y%m%d_%H%M%S)
|
||
|
||
# 資料庫備份
|
||
cp /Users/ogt/momo_pro_system/data/momo_database.db /Users/ogt/momo_pro_system/backups/
|
||
```
|
||
|
||
### 4.2 漸進式部署
|
||
1. 每拆分一個模組後立即測試
|
||
2. 使用 feature flag 控制新舊路由切換
|
||
3. 保留原始 app.py 直到所有模組穩定
|
||
|
||
### 4.3 回滾方案
|
||
```bash
|
||
# 如發生嚴重問題,立即回滾
|
||
cp /Users/ogt/momo_pro_system_backup_YYYYMMDD/app.py /Users/ogt/momo_pro_system/app.py
|
||
rm -rf /Users/ogt/momo_pro_system/routes/
|
||
# 重新部署
|
||
```
|
||
|
||
---
|
||
|
||
## 五、預期效益
|
||
|
||
### 5.1 程式碼品質
|
||
| 指標 | 重構前 | 重構後 |
|
||
|------|--------|--------|
|
||
| app.py 行數 | 7,253 | ~500 |
|
||
| 最大函數行數 | 1,020 | ~200 |
|
||
| 模組數量 | 1 | 10 |
|
||
| 可測試性 | 低 | 高 |
|
||
|
||
### 5.2 維護性改善
|
||
- **問題定位**: 從搜尋 7000 行 → 搜尋 300-800 行
|
||
- **功能擴展**: 只需修改相關模組
|
||
- **團隊協作**: 可並行開發不同模組
|
||
- **部署風險**: 可單獨部署/回滾特定模組
|
||
|
||
---
|
||
|
||
## 六、時程規劃
|
||
|
||
| 階段 | 工作項目 | 預估工作量 |
|
||
|------|----------|------------|
|
||
| 1 | 準備工作 + 共用模組 | 1-2 小時 |
|
||
| 2 | system_routes + api_routes | 2-3 小時 |
|
||
| 3 | export_routes + import_routes | 2-3 小時 |
|
||
| 4 | edm_routes + monthly_routes | 2-3 小時 |
|
||
| 5 | dashboard_routes | 2-3 小時 |
|
||
| 6 | daily_sales_routes | 3-4 小時 |
|
||
| 7 | sales_routes (最複雜) | 4-5 小時 |
|
||
| 8 | 整合測試 + 修復 | 2-3 小時 |
|
||
| **總計** | | **18-26 小時** |
|
||
|
||
---
|
||
|
||
## 七、注意事項
|
||
|
||
### 7.1 已知問題需修復
|
||
1. **datetime 重複導入**: 多處函數內有 `from datetime import datetime`,需統一移除
|
||
2. **快取變數**: `_SALES_DF_CACHE` 等全域變數需移至 cache_service.py
|
||
3. **循環依賴**: 拆分時需注意模組間的 import 順序
|
||
|
||
### 7.2 不動的部分
|
||
- `config.py` - 配置檔保持不變
|
||
- `auth.py` - 認證模組保持不變
|
||
- `vendor_routes.py` - 已是 Blueprint,保持不變
|
||
- `auto_import_routes.py` - 已是 Blueprint,保持不變
|
||
- `database/` 目錄 - 資料庫層保持不變
|
||
- `services/` 目錄 - 現有服務保持不變
|
||
|
||
---
|
||
|
||
## 八、執行確認
|
||
|
||
重構開始前,請確認:
|
||
- [ ] 已完成完整備份
|
||
- [ ] 已確認 UAT 環境可正常運作
|
||
- [ ] 已預留足夠時間進行測試
|
||
- [ ] 已準備好回滾方案
|
||
|
||
---
|
||
|
||
*文件結束*
|