Files
ewoooc/CONSTITUTION.md
ogt 676c711e7a
Some checks are pending
CD Pipeline / deploy (push) Waiting to run
feat: AI 治理完備 V10.3 — 技術債清零 + DB 備份機制 + 備份 AI 監控
技術債清零 (2026-04-19):
- migrations/010: ai_insights 補 decay_exempt/avg_quality/status/ai_model/feedback 欄位
- migrations/011: embedding_retry_queue 持久化表 (ADR-009)
- migrations/012: backup_log 備份記錄表
- services/openclaw_learning_service: 記憶體 Queue → DB retry queue,時間衰減 RAG
- services/nemoton_dispatcher_service: 三個 tool 強制雙寫 ai_insights (_sink_insight_to_km)
- services/import_service: Excel 前置欄位防禦(商品名稱類 + 業績金額類)
- services/ollama_service: generate_embedding 新增 EMBEDDING_HOST env,embedding 永遠走 192.168.0.111
- SYSTEM_VERSION: V9.4 → V10.3

DB 備份機制:
- scripts/pg_backup.sh: host-level pg_dump 備份腳本,cron 每日 02:00,保留 7 天,Telegram 通知
- services/db_backup_service.py: Python 備份 service,寫入 backup_log
- scheduler: run_db_backup_task (02:00) + run_backup_monitor_task (每 6h AI Agent 監控)
- Dockerfile: 加入 postgresql-client

文件:
- CLAUDE.md: 環境架構依 ADR-008 實地重寫,含完整 SSH/Docker 部署 SOP
- PROJECT_CONSTITUTION.md: 內容已整合入 CLAUDE.md,刪除重複檔案

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 02:03:45 +08:00

442 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# EwoooC原 MOMO Pro System- 專案憲法 (CONSTITUTION)
> 本文件定義專案開發的核心準則與不可違反的規範
> **建立日期**: 2026-01-12
> **當前版本**: V10.2 (治理與安全重疊整合版)
> **最後更新**: 2026-04-18
---
## 🗣️ 第零章:溝通與語法原則
### 第 0.1 條:語言使用
- **所有溝通一律使用繁體中文**。包含程式碼註解、文檔說明、Commit 訊息、錯誤訊息、日誌輸出、使用者介面文字。
### 第 0.2 條:文檔規範
- 所有文檔使用 Markdown 格式。
- 檔案名稱優先使用英文大寫加底線(例:`CONSTITUTION.md`)。
- 重要變更需記錄在 `CLAUDE.md``walkthrough.md` 中。
---
## 📜 憲法總綱
本專案憲法旨在確保系統的**穩定性**、**一致性**與**可維護性**。所有開發者(包括 AI 助手)在進行任何程式碼修改前,**必須**詳細閱讀並嚴格遵守本憲法的所有條款。
---
## 第一章:資料庫與模型層規範
### 第 1 條:商品 ID 命名規範(絕對禁止違反)
-**正確**: 使用 `product.i_code` 作為商品唯一識別碼
-**禁止**: 使用 `product.momo_id`(此屬性不存在)
- **理由**: Product 模型定義為 `i_code = Column(String(50), unique=True)`
- **影響範圍**: 所有查詢、API、前端顯示
### 第 2 條:時間戳處理規範(絕對禁止違反)
-**正確**: 使用 `datetime.now(TAIPEI_TZ).replace(tzinfo=None)`
-**禁止**: 直接使用 `datetime.now()` 或保留 tzinfo
- **理由**: SQLite 不支援時區感知的 datetime資料庫存儲必須為 naive datetime
- **影響範圍**: 所有涉及時間比對的查詢(價格變動、統計計算)
### 第 3 條:價格變動邏輯(絕對禁止違反)
-**正確**: 比對「今日最新價格」與「今日之前的最後一筆價格」
-**禁止**: 僅查詢「昨天 00:00-23:59」的價格記錄
- **理由**: 爬蟲可能跳過某些日期,必須容錯處理
- **實作方式**:
```python
# 取得今日之前的最後一筆價格
yesterday_prices_subq = session.query(
PriceRecord.product_id,
func.max(PriceRecord.id).label('max_id')
).filter(
PriceRecord.product_id.in_(product_ids),
PriceRecord.timestamp < today_start # 不限定昨天
).group_by(PriceRecord.product_id).subquery()
```
### 第 4 條:查詢效能優化(強制要求)
- ✅ **正確**: 使用批次查詢(如 `yesterday_prices_map`
- ❌ **禁止**: N+1 查詢模式(在迴圈內執行單筆查詢)
- **理由**: 商品數量可達數千筆N+1 查詢會導致嚴重效能問題
- **影響範圍**: 儀表板、API、統計計算
---
## 第二章:爬蟲與資料採集規範
### 第 5 條:商品圖片 URL 構造(絕對禁止違反)
- ✅ **正確**: 使用 CDN 直接構造
```python
image_url = f"https://m.momoshop.com.tw/moscdn/goods/{i_code}_m.webp"
```
- ❌ **禁止**: 使用複雜的 DOM 查詢8+ CSS 選擇器)
- **理由**: CDN URL 格式固定且穩定DOM 查詢速度慢且易失效
- **效能提升**: 速度提升 20-30%
### 第 6 條:爬蟲頻率與禮貌性(強制要求)
- ✅ **正確**: 每次請求間隔至少 1 秒
- ❌ **禁止**: 高頻率無間隔爬取
- **理由**: 避免被 MOMO 封鎖 IP
### 第 7 條:錯誤處理與重試機制(強制要求)
- ✅ **正確**: 所有爬蟲函式必須使用 try-except 包裹
- ✅ **正確**: 記錄失敗原因至日誌系統
- ❌ **禁止**: 靜默失敗(吞掉例外)
---
## 第三章API 設計規範
### 第 8 條API 邏輯一致性(絕對禁止違反)
- ✅ **正確**: API 的資料處理邏輯必須與儀表板**完全一致**
- ❌ **禁止**: API 與前端使用不同的計算邏輯
- **理由**: 避免前後端資料不一致,造成使用者困惑
- **實例**: `/api/price_change_details` 必須使用與 `get_consolidated_data()` 相同的價格比對邏輯
### 第 9 條API 錯誤處理(強制要求)
- ✅ **正確**: 所有 API 必須使用 try-except-finally 結構
- ✅ **正確**: 錯誤時返回 JSON 格式: `{'products': []}, 500`
- ✅ **正確**: 記錄詳細錯誤日誌: `sys_log.error()`
- ❌ **禁止**: 返回 HTML 錯誤頁面或純文字錯誤
### 第 10 條API 效能優化(強制要求)
- ✅ **正確**: 使用批次查詢與預先計算
- ❌ **禁止**: 在迴圈中執行資料庫查詢
- **實例**: 建立 `yesterday_prices_map` 一次性查詢所有商品的歷史價格
---
## 第四章:前端 UI/UX 規範
### 第 11 條:設計系統色彩(絕對禁止違反)
- ✅ **主題色**: 紫色漸變 `#667eea` → `#764ba2`
- ✅ **漲價**: 紅色 `#dc3545` / `#ff6b6b`
- ✅ **降價**: 綠色 `#28a745` / `#51cf66`
- ❌ **禁止**: 使用其他顏色作為主題色(除非整體改版)
- **理由**: 保持與 Daily Sales 頁面視覺一致性
### 第 12 條:響應式設計(強制要求)
- ✅ **正確**: 所有頁面必須支援手機版(< 768px
- ✅ **正確**: 使用 Bootstrap 5.3.3 的響應式網格系統
- ✅ **正確**: 表格與圖表必須支援橫向滾動(手機版)
- ❌ **禁止**: 僅針對桌面版設計
### 第 13 條:互動體驗(強制要求)
- ✅ **正確**: 所有按鈕必須有 hover 效果(陰影、位移、顏色變化)
- ✅ **正確**: 所有卡片必須有 hover 動畫
- ✅ **正確**: 使用 `transition: all 0.3s ease` 實現平滑過渡
- ❌ **禁止**: 靜態無互動的 UI 元素
### 第 14 條:字體與可讀性(強制要求)
- ✅ **正確**: 主要文字顏色 `#2c3e50`(深灰)
- ✅ **正確**: 表格表頭使用白色文字 `#fff`
- ❌ **禁止**: 使用純黑色 `#000`(刺眼)
- ❌ **禁止**: 使用低對比度顏色組合
---
## 第五章:系統架構規範
### 第 15 條:服務端口(絕對禁止違反)
- ✅ **正確**: Flask 使用 **Port 80**
- ❌ **禁止**: 使用 5888 或其他端口(已廢棄)
- **配置位置**: `config.py` 的 `PUBLIC_URL`
### 第 16 條:資料庫路徑(絕對禁止違反)
- ✅ **正確**: `data/momo_database.db`
- ❌ **禁止**: 更改資料庫位置或名稱
- **配置位置**: `config.py` 的 `DATABASE_PATH`
### 第 17 條:時區設定(絕對禁止違反)
- ✅ **正確**: 使用 `TAIPEI_TZ = pytz.timezone('Asia/Taipei')`
- ❌ **禁止**: 使用 UTC 或其他時區
- **理由**: 所有業務邏輯基於台北時間
### 第 18 條:日誌系統(強制要求)
- ✅ **正確**: 使用 `sys_log.info()` / `sys_log.error()` 記錄關鍵操作
- ✅ **正確**: 日誌格式必須包含 `[模組] [功能] 狀態 | 詳細資訊`
- ❌ **禁止**: 使用 `print()` 輸出日誌
---
## 第六章:版本管理規範
### 第 19 條:版本號更新(強制要求)
- ✅ **正確**: 每次功能更新必須修改 `app.py` 的 `SYSTEM_VERSION`
- ✅ **格式**: `V主版本.次版本` (例如: V9.4)
- ❌ **禁止**: 修改功能但不更新版本號
### 第 20 條:備份系統(強制要求)
- ✅ **正確**: 重大更新前必須執行 `python backup_system.py`
- ✅ **排除目錄**: `['backups', '__pycache__', '.git', '.idea', '.vscode', 'bin', 'bin 2']`
- ❌ **禁止**: 跳過備份直接上線
### 第 21 條TODO 文件維護(強制要求)
- ✅ **正確**: 完成功能後更新 `TODO_NEXT_STEPS.txt` 標記 ✅
- ✅ **正確**: 記錄修改的檔案與行數
- ❌ **禁止**: 完成任務但不更新文件
---
## 第七章:程式碼品質規範
### 第 22 條:命名規範(強制要求)
- ✅ **函式名稱**: 使用 `snake_case` (例如: `get_price_change_details`)
- ✅ **類別名稱**: 使用 `PascalCase` (例如: `PriceRecord`)
- ✅ **變數名稱**: 使用有意義的描述性名稱
- ❌ **禁止**: 使用 `a`, `b`, `temp`, `data` 等無意義名稱
### 第 23 條:註解規範(強制要求)
- ✅ **正確**: 在複雜邏輯前加上中文註解說明「為什麼」
- ✅ **正確**: 修復 Bug 時標註 `V-Fix:`
- ✅ **正確**: 新增功能時標註 `V-New:`
- ❌ **禁止**: 完全不寫註解或寫無意義註解
### 第 24 條DRY 原則(強制要求)
- ✅ **正確**: 重複邏輯必須抽取為函式
- ❌ **禁止**: 複製貼上相同程式碼超過 2 次
- **實例**: `get_consolidated_data()` 封裝了通用的資料查詢邏輯
---
## 第八章:測試與除錯規範
### 第 25 條:修改前測試(強制要求)
- ✅ **正確**: 修改程式碼前,先了解現有功能的行為
- ✅ **正確**: 修改後必須測試相關功能是否正常
- ❌ **禁止**: 修改後直接提交,未經測試
### 第 26 條:錯誤修復流程(強制要求)
1. 閱讀錯誤日誌 (`logs/system.log`)
2. 定位問題程式碼位置
3. 理解根本原因(不是表面症狀)
4. 修復問題並添加註解
5. 測試修復是否有效
6. 檢查是否有相同問題的其他地方
### 第 27 條:日誌檢查(強制要求)
- ✅ **正確**: 修改 API 後檢查日誌是否有錯誤
- ✅ **正確**: 使用 `tail -f logs/system.log` 即時監控
- ❌ **禁止**: 盲目修改不看日誌
---
## 第九章:效能優化規範
### 第 28 條:資料庫查詢優化(強制要求)
- ✅ **正確**: 使用 subquery 與 JOIN 減少查詢次數
- ✅ **正確**: 使用 `options(joinedload())` 預載關聯資料
- ❌ **禁止**: 在迴圈中執行查詢N+1 問題)
### 第 29 條:前端效能優化(強制要求)
- ✅ **正確**: 圖表使用 CDN 載入 Chart.js
- ✅ **正確**: 大表格使用分頁或虛擬滾動
- ❌ **禁止**: 一次渲染超過 1000 筆資料
### 第 30 條:快取策略(建議執行)
- ✅ **建議**: 對不常變動的資料實作快取5-10 分鐘)
- ✅ **建議**: 使用 `get_consolidated_data()` 的結果快取
- ⚠️ **注意**: 快取必須有過期機制
---
## 第十章:安全性規範
### 第 31 條:敏感資訊保護(絕對禁止違反)
- ✅ **正確**: 所有 API Token、密碼存放於 `config.py`
- ❌ **禁止**: 硬編碼敏感資訊於程式碼中
- ❌ **禁止**: 提交 `config.py` 至公開 Git 倉庫
### 第 32 條SQL 注入防護(絕對禁止違反)
- ✅ **正確**: 使用 SQLAlchemy ORM 的參數化查詢
- ❌ **禁止**: 使用字串拼接建構 SQL 查詢
- **範例**:
```python
# ✅ 正確
session.query(Product).filter(Product.i_code == user_input)
# ❌ 禁止
session.execute(f"SELECT * FROM products WHERE i_code = '{user_input}'")
```
### 第 33 條XSS 防護(強制要求)
- ✅ **正確**: Jinja2 模板自動跳脫 HTML
- ✅ **正確**: JavaScript 中使用 `textContent` 而非 `innerHTML`
- ❌ **禁止**: 直接插入未驗證的使用者輸入
---
## 第十一章:部署與維運規範
### 第 34 條:伺服器啟動(強制要求)
- ✅ **正確**: 使用 `nohup python3 app.py > /dev/null 2>&1 &` 背景執行
- ✅ **正確**: 部署前檢查 Port 80 是否已被佔用
- ❌ **禁止**: 直接執行 `python3 app.py`(關閉終端機會停止服務)
### 第 35 條:伺服器重啟(強制要求)
- ✅ **正確步驟**:
1. `pkill -9 -f "python3 app.py"` (停止舊程序)
2. `sleep 2` (等待端口釋放)
3. `nohup python3 app.py > /dev/null 2>&1 &` (啟動新程序)
4. `ps aux | grep "[p]ython3 app.py"` (確認運行)
### 第 36 條:日誌輪替(建議執行)
- ✅ **建議**: 定期清理過大的日誌檔案 (> 100MB)
- ✅ **建議**: 使用 logrotate 自動管理日誌
---
## 第十二章:協作開發規範
### 第 37 條Git Commit 規範(強制要求)
- ✅ **正確格式**: `[版本號] 功能描述 | 修改的檔案`
- **範例**: `[V9.4] 修正彈窗無資料問題 | app.py, dashboard.html`
- ❌ **禁止**: `fix`, `update`, `修改` 等無意義訊息
### 第 38 條:程式碼審查(強制要求)
- ✅ **正確**: 重大修改前與 AI 助手討論方案
- ✅ **正確**: 提供清晰的需求描述與預期結果
- ❌ **禁止**: 直接要求 AI 「修改成...」而不解釋原因
### 第 39 條:憲法修訂(特別規定)
- ✅ **修訂權限**: 僅限專案負責人(統帥)
- ✅ **修訂流程**: 提出修訂 → 討論評估 → 更新文件 → 通知全員
- ⚠️ **重要**: 本憲法不可輕易修改,除非有重大架構變更
---
## 第十三章AI 三 Agent 自主學習架構規範2026-04-18 加入)
### 第 40 條:三 Agent 分工架構(絕對禁止違反)
- **Hermes採集層**: `192.168.0.111` Ollama負責 embedding、去重、品質分數計算。成本 = $0
- **NemoTron處理層**: NVIDIA NIM Llama 3.1 8B負責 tool calling 邏輯路由與 DB 寫入。限額 80 次/天
- **OpenClaw / Gemini應用層**: 負責最終 PPT 生成、洞察報告對外輸出。成本最高,最後動用
- ❌ **禁止**:讓 OpenClaw 做 Hermes 層的苦力工作(高算力浪費)
- ❌ **禁止**:讓 Hermes 直接生成對外報告(品質不足)
### 第 41 條AI 學習數據雙寫(絕對禁止違反)
- ✅ **正確**:所有 AI 產出PPT 洞察、競品分析、對話記錄)必須**雙寫** PostgreSQL `ai_insights` + pgvector embedding
- ❌ **禁止**:只寫 DB 不寫 KMRAG 無法語意搜尋)
- ❌ **禁止**:只寫 KM 不寫 DB精確 period/sku 查詢無法命中)
- **理由**DB 是精準命中KM 是語意搜尋兩者互補缺一不可ADR-007
- **入口**NemoTron `store_insight` tool call → 同步寫 DB → 異步排隊給 Hermes 做 embedding
### 第 42 條KM 向量庫技術選型(絕對禁止違反)
- ✅ **唯一選擇**pgvector與現有 PostgreSQL `192.168.0.188` 同一 DB
- ❌ **禁止**:引入 ChromaDB、Qdrant 等獨立向量庫
- **理由**:混合查詢(`WHERE` 結構化 + `ORDER BY embedding <->` 語意)只有 pgvector 能一條 SQL 搞定ADR-002
### 第 43 條Embedding 本地化(強制要求)
- ✅ **正確**:使用 `bge-m3`(或 `nomic-embed-text`)掛載在 Hermes 主機 `192.168.0.111` Ollama
- ❌ **禁止**:呼叫外部 Embedding API成本與隱私雙重問題
- **維度**1024 dim`vector(1024)` 欄位ADR-003
### 第 44 條NemoTron 配額 Fallback 機制(強制要求)
- ✅ **正確**:當 NIM 回傳 HTTP 429 時,立刻 fallback 至 `_hermes_rule_fallback()` rule-based 派發
- ❌ **禁止**:配額耗盡時讓告警管線中斷
- **標記**:降級模式告警須帶 `🟡` 前綴讓統帥識別ADR-004
### 第 45 條KM 品質分數時間衰減(強制要求)
- ✅ **公式**`effective_score = base_score × e^(-decay_rate × days_passed)`
- **decay_rate**`0.005`(預設);`decay_exempt=True` 用於結構性/憲法類知識
- **理由**:確保 RAG 優先抓取最新、最適用的洞察避免歷史偏誤ADR-005
---
## 第十四章Claude Code 官方遊戲規則2026-04-18 加入)
### 第 46 條:記憶架構四層必須完整(絕對禁止違反)
- **Memory**`~/.claude/projects/.../memory/*.md` — 跨 Session 持久記憶
- **ADR**`docs/adr/ADR-XXX-*.md` — 架構決策,只增不刪
- **SOT**`docs/AI_INTELLIGENCE_MODULE_SOT.md` — 當前架構事實
- **Skills**`.claude/skills/*.py` — 執行 SOP checklist
- ❌ **禁止**:任何一層缺失,都會導致後續 Session 失憶或決策矛盾
### 第 47 條Session 開始 SOP強制要求
```
每次 Claude Session 開始必做:
1. 讀 CLAUDE.md 第零章(元憲法)
2. 讀 memory/MEMORY.md 索引
3. 讀 docs/adr/README.md 索引
4. 才開始執行任務
```
### 第 48 條Session 結束沉澱 SOP強制要求
```
每次 Session 結束前必做 checklist
□ 有架構決策?→ 新建 ADR-XXX.md + 更新索引
□ 有統帥偏好?→ 更新 memory/user_profile.md
□ 有技術債?→ 更新 memory/project_tech_debt_backlog.md
□ 有 SOT 變更?→ 更新 AI_INTELLIGENCE_MODULE_SOT.md
□ 有憲法新條款?→ 更新 CONSTITUTION.md + CLAUDE.md
□ 更新 memory/MEMORY.md 索引
```
### 第 49 條:專案範圍邊界(絕對禁止違反)
- ✅ **本憲法範圍**`momo-pro-system`EwoooC**唯一**
- ❌ **禁止**:將 AWOOOI / WOOO AIOps SaaS 的決策混入本文件
- ❌ **禁止**:跨專案邊界做架構決策
---
## 附錄 A常見錯誤與解決方案
### 錯誤 1: 'Product' object has no attribute 'momo_id'
- **原因**: 使用錯誤的屬性名稱
- **解決**: 改用 `product.i_code`
### 錯誤 2: API 返回空資料
- **原因**: 價格比對邏輯錯誤(只查昨天)
- **解決**: 使用「今日之前最後一筆」邏輯
### 錯誤 3: 時間戳比對失敗
- **原因**: 時區感知 datetime 與 naive datetime 混用
- **解決**: 使用 `.replace(tzinfo=None)` 統一為 naive
### 錯誤 4: 彈窗顯示「無資料」
- **原因**: API 邏輯與前端不一致
- **解決**: 確保使用相同的 `yesterday_prices_map` 查詢
---
## 附錄 B關鍵檔案索引
| 檔案路徑 | 用途 | 禁止修改項目 |
|---------|------|------------|
| `config.py` | 系統配置 | `DATABASE_PATH`, `PUBLIC_URL` |
| `database/models.py` | 資料模型 | `Product.i_code` 定義 |
| `app.py` | 主程式 | `SYSTEM_VERSION`, `TAIPEI_TZ` |
| `dashboard.html` | 商品看板 | 主題色系、響應式設計 |
| `daily_sales.html` | 業績看板 | 行事曆邏輯、圖表配置 |
| `scheduler.py` | 排程爬蟲 | 商品圖 CDN URL 構造 |
| `backup_system.py` | 備份系統 | 排除目錄清單 |
---
## 附錄 C版本更新檢查清單
每次發布新版本前,必須確認以下項目:
- [ ] `SYSTEM_VERSION` 已更新
- [ ] 相關功能已測試正常運作
- [ ] 日誌無錯誤訊息
- [ ] `TODO_NEXT_STEPS.txt` 已更新
- [ ] 已執行系統備份
- [ ] API 邏輯與前端一致
- [ ] 響應式設計正常(手機版測試)
- [ ] 資料庫查詢效能正常(無 N+1 問題)
---
## 結語
本憲法的目的是維護專案的**長期穩定性**與**開發效率**。所有開發者(包括 AI 助手)在遇到與憲法條款衝突的需求時,應優先遵守憲法,並與專案負責人討論是否需要修訂憲法。
**記住**: 一個穩定運行的系統,遠比一個功能豐富但 Bug 頻出的系統更有價值。
---
**專案憲法版本**: 2.0
**生效日期**: 2026-01-12
**最後審核**: 2026-04-18統帥批准加入第十三、十四章