企業內部新聞彙整與分析系統 - 自動新聞抓取 (Digitimes, 經濟日報, 工商時報) - AI 智慧摘要 (OpenAI/Claude/Ollama) - 群組管理與訂閱通知 - 已清理 Python 快取檔案 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
411 lines
14 KiB
Markdown
411 lines
14 KiB
Markdown
# 每日報導 APP - 系統解析文檔
|
||
|
||
## 📋 系統概述
|
||
|
||
**每日報導 APP** 是一個企業內部新聞彙整與分析系統,主要功能是自動抓取多個新聞來源、使用 AI 進行智慧摘要、依產業別或議題分類,並自動生成每日報告發送給訂閱者。
|
||
|
||
---
|
||
|
||
## 🏗️ 系統架構
|
||
|
||
### 技術棧
|
||
|
||
| 層級 | 技術 | 說明 |
|
||
|------|------|------|
|
||
| **後端框架** | FastAPI 0.109.0 | 現代化的 Python Web 框架,支援異步處理 |
|
||
| **Python 版本** | Python 3.11 | 使用最新穩定版本 |
|
||
| **資料庫** | MySQL 8.0 / SQLite | 支援 MySQL(生產)和 SQLite(開發) |
|
||
| **ORM** | SQLAlchemy 2.0.25 | 資料庫操作抽象層 |
|
||
| **認證** | JWT + LDAP/AD | 支援本地帳號和企業 AD/LDAP 整合 |
|
||
| **LLM 整合** | OpenAI / Gemini / Ollama | 支援多種 AI 模型進行摘要生成 |
|
||
| **排程** | APScheduler 3.10.4 | 定時任務排程(新聞抓取、報告生成) |
|
||
| **Email** | aiosmtplib 3.0.1 | 異步 SMTP 郵件發送 |
|
||
| **PDF 生成** | WeasyPrint 60.2 | 報告 PDF 匯出功能 |
|
||
| **部署** | Docker + Docker Compose | 容器化部署,支援 1Panel |
|
||
|
||
### 系統架構圖
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 前端介面 (UI) │
|
||
│ (響應式設計,支援手機閱讀) │
|
||
└────────────────────┬────────────────────────────────────┘
|
||
│ HTTP/HTTPS
|
||
┌────────────────────▼────────────────────────────────────┐
|
||
│ FastAPI 應用程式 (app/main.py) │
|
||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
|
||
│ │ Auth API │ │ Users API│ │Groups API│ │Reports │ │
|
||
│ └──────────┘ └──────────┘ └──────────┘ └─────────┘ │
|
||
└────┬───────────────┬───────────────┬────────────────────┘
|
||
│ │ │
|
||
┌────▼────┐ ┌──────▼──────┐ ┌────▼──────┐
|
||
│ Services│ │ Models │ │ Database │
|
||
│ Layer │ │ (ORM) │ │ (MySQL) │
|
||
└────┬────┘ └──────────────┘ └───────────┘
|
||
│
|
||
┌────▼──────────────────────────────────────┐
|
||
│ 核心服務模組 │
|
||
│ • Crawler Service (新聞爬蟲) │
|
||
│ • LLM Service (AI 摘要) │
|
||
│ • Notification Service (Email 通知) │
|
||
│ • Scheduler Service (排程任務) │
|
||
└───────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 🔑 核心功能模組
|
||
|
||
### 1. 認證與授權 (`app/api/v1/endpoints/auth.py`)
|
||
- **JWT Token 認證**:使用 JWT 進行用戶認證
|
||
- **LDAP/AD 整合**:支援企業 Active Directory 統一認證
|
||
- **本地帳號**:支援本地用戶帳號密碼登入
|
||
- **角色權限**:admin(管理員)、editor(編輯)、reader(讀者)
|
||
|
||
### 2. 用戶管理 (`app/api/v1/endpoints/users.py`)
|
||
- 用戶列表查詢
|
||
- 用戶新增、編輯、停用
|
||
- 角色分配
|
||
- 最後登入時間追蹤
|
||
|
||
### 3. 群組管理 (`app/api/v1/endpoints/groups.py`)
|
||
- **群組分類**:產業別(industry)或議題(topic)
|
||
- **關鍵字管理**:為每個群組設定關鍵字,用於新聞匹配
|
||
- **AI 設定**:可為群組設定 AI 背景資訊和摘要提示
|
||
- **啟用/停用**:控制群組是否參與自動匹配
|
||
|
||
### 4. 新聞抓取 (`app/services/crawler_service.py`)
|
||
- **支援來源**:
|
||
- Digitimes(需付費帳號)
|
||
- 經濟日報(公開)
|
||
- 工商時報(公開)
|
||
- **自動排程**:每日定時抓取(預設 08:00)
|
||
- **關鍵字匹配**:根據群組關鍵字自動匹配新聞
|
||
- **防重複**:使用外部 ID 避免重複抓取
|
||
- **錯誤重試**:支援自動重試機制
|
||
|
||
### 5. 報告管理 (`app/api/v1/endpoints/reports.py`)
|
||
- **報告生成**:每日為每個群組自動生成報告
|
||
- **AI 摘要**:使用 LLM 生成綜合摘要
|
||
- **編輯功能**:專員可編輯 AI 摘要
|
||
- **文章篩選**:專員可選擇是否納入報告
|
||
- **發布流程**:草稿 → 待審核 → 已發布
|
||
- **PDF 匯出**:支援匯出 PDF 格式
|
||
|
||
### 6. 訂閱管理 (`app/api/v1/endpoints/subscriptions.py`)
|
||
- 用戶訂閱群組
|
||
- Email 通知開關
|
||
- 訂閱列表查詢
|
||
|
||
### 7. AI 摘要服務 (`app/services/llm_service.py`)
|
||
- **多 LLM 支援**:
|
||
- Google Gemini(預設)
|
||
- OpenAI GPT-4
|
||
- Ollama(本地部署)
|
||
- **摘要生成**:根據群組設定和新聞內容生成摘要
|
||
- **可配置模型**:可選擇不同模型和參數
|
||
|
||
### 8. 通知服務 (`app/services/notification_service.py`)
|
||
- **Email 通知**:報告發布時自動發送 Email
|
||
- **通知記錄**:記錄所有通知發送狀態
|
||
- **失敗重試**:支援失敗通知重試
|
||
|
||
### 9. 排程服務 (`app/services/scheduler_service.py`)
|
||
- **定時抓取**:每日定時執行新聞抓取
|
||
- **報告生成**:定時生成每日報告
|
||
- **通知發送**:定時發送通知
|
||
|
||
### 10. 系統設定 (`app/api/v1/endpoints/settings.py`)
|
||
- LLM 設定(API Key、模型選擇)
|
||
- SMTP 設定(Email 發送)
|
||
- PDF 設定(Logo、頁首頁尾)
|
||
- 系統參數設定
|
||
|
||
---
|
||
|
||
## 📊 資料庫結構
|
||
|
||
### 核心資料表
|
||
|
||
1. **用戶與權限**
|
||
- `roles`:角色表(admin, editor, reader)
|
||
- `users`:用戶表(支援 AD/LDAP 和本地帳號)
|
||
|
||
2. **新聞來源與文章**
|
||
- `news_sources`:新聞來源設定
|
||
- `news_articles`:抓取的新聞文章
|
||
- `crawl_jobs`:抓取任務記錄
|
||
|
||
3. **群組與關鍵字**
|
||
- `groups`:群組表(產業別/議題)
|
||
- `keywords`:關鍵字表
|
||
- `article_group_matches`:新聞-群組匹配關聯
|
||
|
||
4. **報告**
|
||
- `reports`:報告表
|
||
- `report_articles`:報告-新聞關聯表
|
||
|
||
5. **讀者互動**
|
||
- `subscriptions`:訂閱表
|
||
- `favorites`:收藏表
|
||
- `comments`:留言表
|
||
- `notes`:個人筆記表
|
||
|
||
6. **系統**
|
||
- `system_settings`:系統設定表
|
||
- `audit_logs`:操作日誌表
|
||
- `notification_logs`:通知記錄表
|
||
|
||
### 資料保留策略
|
||
- 預設保留 60 天資料
|
||
- 使用 MySQL Event Scheduler 自動清理過期資料
|
||
|
||
---
|
||
|
||
## 🔐 安全機制
|
||
|
||
### 1. 認證安全
|
||
- JWT Token 認證
|
||
- 密碼使用 bcrypt 雜湊
|
||
- LDAP 注入防護
|
||
- Token 過期時間控制(生產環境建議 60-120 分鐘)
|
||
|
||
### 2. 資料安全
|
||
- 敏感資訊加密儲存(API Keys、密碼)
|
||
- SQL 注入防護(使用 ORM)
|
||
- XSS 防護(輸入驗證和輸出編碼)
|
||
|
||
### 3. 環境安全
|
||
- 生產環境強制關閉 Debug 模式
|
||
- 生產環境關閉 API 文檔(/docs)
|
||
- CORS 嚴格控制(生產環境不允許 `*`)
|
||
- 密鑰長度驗證(至少 32 字元)
|
||
|
||
### 4. 日誌與審計
|
||
- 操作日誌記錄(audit_logs)
|
||
- 錯誤日誌記錄
|
||
- 通知發送記錄
|
||
|
||
---
|
||
|
||
## 📁 目錄結構說明
|
||
|
||
```
|
||
daily-news-app/
|
||
├── app/ # 應用程式主目錄
|
||
│ ├── api/v1/ # API 路由
|
||
│ │ ├── endpoints/ # API 端點實作
|
||
│ │ │ ├── auth.py # 認證相關
|
||
│ │ │ ├── users.py # 用戶管理
|
||
│ │ │ ├── groups.py # 群組管理
|
||
│ │ │ ├── reports.py # 報告管理
|
||
│ │ │ ├── subscriptions.py # 訂閱管理
|
||
│ │ │ └── settings.py # 系統設定
|
||
│ │ └── router.py # 路由總管理
|
||
│ ├── core/ # 核心設定
|
||
│ │ ├── config.py # 環境變數設定
|
||
│ │ ├── security.py # 安全相關(JWT、LDAP)
|
||
│ │ └── logging_config.py # 日誌設定
|
||
│ ├── db/ # 資料庫
|
||
│ │ └── session.py # 資料庫連線管理
|
||
│ ├── models/ # 資料模型(SQLAlchemy)
|
||
│ │ ├── user.py # 用戶模型
|
||
│ │ ├── news.py # 新聞模型
|
||
│ │ ├── group.py # 群組模型
|
||
│ │ ├── report.py # 報告模型
|
||
│ │ ├── interaction.py # 互動模型(訂閱、收藏等)
|
||
│ │ └── system.py # 系統模型
|
||
│ ├── schemas/ # Pydantic Schema(API 驗證)
|
||
│ │ ├── user.py
|
||
│ │ ├── group.py
|
||
│ │ └── report.py
|
||
│ ├── services/ # 商業邏輯服務
|
||
│ │ ├── crawler_service.py # 新聞爬蟲
|
||
│ │ ├── llm_service.py # AI 摘要
|
||
│ │ ├── notification_service.py # Email 通知
|
||
│ │ └── scheduler_service.py # 排程任務
|
||
│ ├── utils/ # 工具函數
|
||
│ └── main.py # 應用程式入口
|
||
├── scripts/ # 腳本
|
||
│ ├── init_db_sqlite.py # SQLite 初始化
|
||
│ └── init.sql # MySQL 初始化 SQL
|
||
├── templates/ # Email 模板
|
||
├── tests/ # 測試檔案
|
||
├── logs/ # 日誌目錄
|
||
├── uploads/ # 上傳檔案目錄
|
||
├── docker-compose.yml # Docker Compose 配置
|
||
├── Dockerfile # Docker 映像檔配置
|
||
├── requirements.txt # Python 依賴套件
|
||
├── run.py # 啟動腳本
|
||
└── README.md # 專案說明
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 系統流程
|
||
|
||
### 1. 新聞抓取流程
|
||
```
|
||
排程觸發 (08:00)
|
||
↓
|
||
讀取所有啟用的新聞來源
|
||
↓
|
||
對每個來源執行抓取
|
||
↓
|
||
解析文章列表
|
||
↓
|
||
取得文章內容
|
||
↓
|
||
儲存到 news_articles
|
||
↓
|
||
根據群組關鍵字匹配
|
||
↓
|
||
建立 article_group_matches 關聯
|
||
↓
|
||
記錄抓取任務狀態
|
||
```
|
||
|
||
### 2. 報告生成流程
|
||
```
|
||
每日定時觸發
|
||
↓
|
||
查詢所有啟用的群組
|
||
↓
|
||
對每個群組:
|
||
├─ 查詢匹配的新聞文章
|
||
├─ 使用 LLM 生成 AI 摘要
|
||
├─ 建立報告(狀態:draft)
|
||
└─ 關聯新聞文章
|
||
↓
|
||
專員審核與編輯
|
||
↓
|
||
發布報告(狀態:published)
|
||
↓
|
||
發送 Email 通知給訂閱者
|
||
```
|
||
|
||
### 3. 用戶登入流程
|
||
```
|
||
用戶提交帳號密碼
|
||
↓
|
||
判斷認證類型(AD/LDAP 或本地)
|
||
↓
|
||
驗證帳號密碼
|
||
↓
|
||
查詢用戶資訊和角色
|
||
↓
|
||
生成 JWT Token
|
||
↓
|
||
返回 Token 給前端
|
||
```
|
||
|
||
---
|
||
|
||
## 🌐 API 端點總覽
|
||
|
||
### 認證相關
|
||
- `POST /api/v1/auth/login` - 用戶登入
|
||
- `GET /api/v1/auth/me` - 取得當前用戶資訊
|
||
|
||
### 用戶管理
|
||
- `GET /api/v1/users` - 用戶列表
|
||
- `POST /api/v1/users` - 新增用戶
|
||
- `GET /api/v1/users/{id}` - 用戶詳情
|
||
- `PUT /api/v1/users/{id}` - 更新用戶
|
||
- `DELETE /api/v1/users/{id}` - 刪除用戶
|
||
|
||
### 群組管理
|
||
- `GET /api/v1/groups` - 群組列表
|
||
- `POST /api/v1/groups` - 新增群組
|
||
- `GET /api/v1/groups/{id}` - 群組詳情
|
||
- `PUT /api/v1/groups/{id}` - 更新群組
|
||
- `DELETE /api/v1/groups/{id}` - 刪除群組
|
||
|
||
### 報告管理
|
||
- `GET /api/v1/reports` - 報告列表
|
||
- `GET /api/v1/reports/{id}` - 報告詳情
|
||
- `POST /api/v1/reports/{id}/publish` - 發布報告
|
||
- `GET /api/v1/reports/{id}/pdf` - 匯出 PDF
|
||
|
||
### 訂閱管理
|
||
- `GET /api/v1/subscriptions` - 我的訂閱
|
||
- `POST /api/v1/subscriptions` - 新增訂閱
|
||
- `DELETE /api/v1/subscriptions/{id}` - 取消訂閱
|
||
|
||
### 系統設定
|
||
- `GET /api/v1/settings` - 取得設定
|
||
- `PUT /api/v1/settings` - 更新設定
|
||
|
||
---
|
||
|
||
## 🔧 環境變數說明
|
||
|
||
系統使用 `.env` 檔案管理環境變數,主要包含:
|
||
|
||
### 應用程式設定
|
||
- `APP_ENV`:環境(development/staging/production)
|
||
- `DEBUG`:除錯模式(生產環境必須為 false)
|
||
- `SECRET_KEY`:應用程式密鑰(至少 32 字元)
|
||
- `JWT_SECRET_KEY`:JWT 簽章密鑰(至少 32 字元)
|
||
|
||
### 資料庫設定
|
||
- `DB_HOST`:資料庫主機(或 "sqlite" 使用 SQLite)
|
||
- `DB_PORT`:資料庫埠號
|
||
- `DB_NAME`:資料庫名稱
|
||
- `DB_USER`:資料庫用戶
|
||
- `DB_PASSWORD`:資料庫密碼
|
||
|
||
### LLM 設定
|
||
- `LLM_PROVIDER`:LLM 提供者(gemini/openai/ollama)
|
||
- `GEMINI_API_KEY`:Gemini API Key
|
||
- `OPENAI_API_KEY`:OpenAI API Key
|
||
- `OLLAMA_ENDPOINT`:Ollama 端點 URL
|
||
|
||
### SMTP 設定
|
||
- `SMTP_HOST`:SMTP 伺服器
|
||
- `SMTP_PORT`:SMTP 埠號
|
||
- `SMTP_USERNAME`:SMTP 帳號
|
||
- `SMTP_PASSWORD`:SMTP 密碼
|
||
- `SMTP_FROM_EMAIL`:寄件者 Email
|
||
|
||
### LDAP/AD 設定
|
||
- `LDAP_SERVER`:LDAP 伺服器位址
|
||
- `LDAP_BASE_DN`:LDAP Base DN
|
||
|
||
### 其他設定
|
||
- `DIGITIMES_USERNAME`:Digitimes 帳號
|
||
- `DIGITIMES_PASSWORD`:Digitimes 密碼
|
||
|
||
---
|
||
|
||
## 📝 注意事項
|
||
|
||
1. **生產環境部署**
|
||
- 必須設定強隨機的 `SECRET_KEY` 和 `JWT_SECRET_KEY`
|
||
- 必須關閉 `DEBUG` 模式
|
||
- 必須明確設定 `CORS_ORIGINS`(不能使用 `*`)
|
||
- 建議設定 `JWT_ACCESS_TOKEN_EXPIRE_MINUTES` 為 60-120 分鐘
|
||
|
||
2. **資料庫選擇**
|
||
- 開發環境可使用 SQLite(設定 `DB_HOST=sqlite`)
|
||
- 生產環境建議使用 MySQL 8.0
|
||
|
||
3. **LLM 選擇**
|
||
- Gemini:需要 API Key,費用較低
|
||
- OpenAI:需要 API Key,品質較高
|
||
- Ollama:本地部署,無需 API Key,但需要 GPU 資源
|
||
|
||
4. **新聞來源**
|
||
- Digitimes 需要付費帳號
|
||
- 經濟日報和工商時報為公開來源
|
||
|
||
---
|
||
|
||
## 📚 相關文檔
|
||
|
||
- `README.md` - 專案說明
|
||
- `daily-news-SDD.md` - 系統設計文檔
|
||
- `安全修復完成報告.md` - 安全修復記錄
|
||
- `執行步驟.md` - 詳細執行步驟(見下一個文檔)
|
||
|