fix(db): 補齊 action_plans schema drift
All checks were successful
CD Pipeline / deploy (push) Successful in 5m10s
All checks were successful
CD Pipeline / deploy (push) Successful in 5m10s
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
> 本文件定義專案開發的核心準則與不可違反的規範
|
||||
> **建立日期**: 2026-01-12
|
||||
> **當前版本**: V10.26 (Active blackbox target 降噪版)
|
||||
> **當前版本**: V10.27 (action_plans schema drift 修復版)
|
||||
> **最後更新**: 2026-04-30
|
||||
|
||||
---
|
||||
|
||||
4
app.py
4
app.py
@@ -95,8 +95,8 @@ except Exception as e:
|
||||
sys_log.error(f"無法檢測磁碟空間: {e}")
|
||||
|
||||
# 🚩 系統版本定義 (備份與顯示用)
|
||||
# 🚩 2026-04-30 V10.26: Active blackbox target noise reduction
|
||||
SYSTEM_VERSION = "V10.26"
|
||||
# 🚩 2026-04-30 V10.27: action_plans schema drift repair
|
||||
SYSTEM_VERSION = "V10.27"
|
||||
|
||||
# ==========================================
|
||||
# 🔒 SQL Injection 防護函數
|
||||
|
||||
@@ -254,7 +254,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
|
||||
# ==========================================
|
||||
# 系統版本與路徑
|
||||
# ==========================================
|
||||
SYSTEM_VERSION = "V10.26"
|
||||
SYSTEM_VERSION = "V10.27"
|
||||
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
|
||||
public_url = PUBLIC_URL # 用於模板顯示
|
||||
|
||||
|
||||
@@ -37,6 +37,18 @@ _metadata_initialized = False
|
||||
_POSTGRES_METADATA_LOCK_ID = 170017
|
||||
|
||||
|
||||
def _repair_postgres_schema_drift(conn):
|
||||
"""補齊 create_all 不會處理的既有 PostgreSQL schema drift。"""
|
||||
conn.execute(text("""
|
||||
ALTER TABLE IF EXISTS action_plans
|
||||
ADD COLUMN IF NOT EXISTS action_type VARCHAR(100),
|
||||
ADD COLUMN IF NOT EXISTS description TEXT,
|
||||
ADD COLUMN IF NOT EXISTS priority INTEGER DEFAULT 3,
|
||||
ADD COLUMN IF NOT EXISTS metadata_json TEXT
|
||||
"""))
|
||||
conn.execute(text("CREATE INDEX IF NOT EXISTS idx_action_plans_type ON action_plans(action_type)"))
|
||||
|
||||
|
||||
def ensure_metadata_initialized(engine, use_postgres_lock=False):
|
||||
"""冪等初始化 SQLAlchemy metadata,避免一般流程重複碰 DDL。"""
|
||||
global _metadata_initialized
|
||||
@@ -52,6 +64,7 @@ def ensure_metadata_initialized(engine, use_postgres_lock=False):
|
||||
conn.execute(text("SELECT pg_advisory_lock(:lock_id)"), {"lock_id": _POSTGRES_METADATA_LOCK_ID})
|
||||
try:
|
||||
Base.metadata.create_all(conn)
|
||||
_repair_postgres_schema_drift(conn)
|
||||
finally:
|
||||
conn.execute(text("SELECT pg_advisory_unlock(:lock_id)"), {"lock_id": _POSTGRES_METADATA_LOCK_ID})
|
||||
else:
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
- Scheduler 重要失敗路徑接入 EventRouter,減少裸 exception 漏通知。
|
||||
- ElephantAlpha 執行引擎補 sync timeout、HITL reply_markup、未知 step fail fast、code/resource action 走 AutoHeal bridge。
|
||||
- L2 `agent_actions.py` 的 `flag_for_human_review`、`route_to_km`、`mark_for_relearn` 已從 stub 改為可審計 OpenClaw memory 寫入。
|
||||
- `action_plans` 是 CodeReview / OpenClaw Group A 與 NemoTron Group B 共用表;PostgreSQL 啟動期 metadata repair 必須補齊 Group A 欄位,避免既有 DB 只有 `session_id/plan_type/sku/payload` 時讓 CodeReview action plan 寫入失敗。
|
||||
- `/metrics` 已匯出 EventRouter dispatch、latency、safe action、Telegram replay、AutoHeal action 與 duration 指標。
|
||||
- Smoke dashboard read-only 檢查 EventRouter queue、AutoHeal protected resources、NemoTron fallback、OpenClaw embedding queue、ElephantAlpha HITL,不做外部網路呼叫。
|
||||
- Smoke history 只保存精簡紀錄,不保存完整 details,避免長期檔案膨脹與敏感資訊堆積。
|
||||
@@ -69,6 +70,7 @@
|
||||
- 2026-04-30 CD rebuild cutover hardening:`tests/test_cd_health_check.py` 覆蓋 build-before-stop 順序。
|
||||
- 2026-04-30 ElephantAlpha NIM fallback hardening:新增 `tests/test_elephant_service.py`。
|
||||
- 2026-04-30 DatabaseManager pool convergence:`tests/test_database_manager_cache.py` 覆蓋 pool size/overflow 與 engine reuse。
|
||||
- 2026-04-30 action_plans schema drift:`tests/test_database_manager_cache.py` 覆蓋 PostgreSQL repair 需補 Group A 欄位與 index。
|
||||
- 2026-04-30 Ollama embedding API migration:新增 `tests/test_ollama_embedding.py`。
|
||||
- 2026-04-30 Phase 3f cleanup contracts:`tests/test_phase3f_cleanup_contracts.py` 覆蓋 orphan services、env 範例、scheduler 靜默例外。
|
||||
- 2026-04-30 AI metrics baseline:`tests/test_ai_automation_metrics.py` 覆蓋無事件 snapshot 仍匯出 `momo_ai_*` baseline。
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
- **EDM Dashboard endpoint 修復**: 部署後健康檢查抓到活動看板排序連結少 `edm.` blueprint 前綴,修正模板 endpoint 推導並補 5 個活動頁排序連結回歸測試。
|
||||
- **Monitoring exporter 修復**: Prometheus 已能 scrape `momo-app` V10.24,但 target 檢查發現 `blackbox-exporter` 未啟動、`cadvisor` 因 host `8080` 衝突未進入 monitoring DNS;改為 cAdvisor internal-only 並補 monitoring compose 守門測試。
|
||||
- **Active blackbox target 降噪**: 線上 Nginx 與 curl 驗證目前有效 MOMO 入口為 `https://mo.wooo.work`;`momo.wooo.work` 逾時、`wooo.work` DNS 不解析,先從 active UAT blackbox targets 移除,避免舊域名噪音誤導告警。
|
||||
- **action_plans schema drift 修復**: CodeReview pipeline 寫入 action plan 時發現線上表只有 NemoTron Group B 欄位;啟動期 PostgreSQL metadata repair 會補 `action_type` / `description` / `priority` / `metadata_json` 與 index,恢復 AI code review action plan 閉環。
|
||||
|
||||
### 2026-04-28~29:Phase 3e 重構大戰 + daily_sales cache 隱形 bug 根除
|
||||
- **app.py 縮減 -10.8%**: 7,386 → 6,590 行,11 commits 全綠零 502。
|
||||
|
||||
@@ -59,3 +59,22 @@ def test_database_manager_uses_bounded_postgres_pool(monkeypatch):
|
||||
assert db.engine is captured["session_bind"]
|
||||
|
||||
DatabaseManager._instance_cache.clear()
|
||||
|
||||
|
||||
def test_postgres_schema_repair_adds_action_plan_group_a_columns():
|
||||
from database.manager import _repair_postgres_schema_drift
|
||||
|
||||
captured = []
|
||||
|
||||
class FakeConnection:
|
||||
def execute(self, statement):
|
||||
captured.append(str(statement))
|
||||
|
||||
_repair_postgres_schema_drift(FakeConnection())
|
||||
ddl = "\n".join(captured)
|
||||
|
||||
assert "ADD COLUMN IF NOT EXISTS action_type VARCHAR(100)" in ddl
|
||||
assert "ADD COLUMN IF NOT EXISTS description TEXT" in ddl
|
||||
assert "ADD COLUMN IF NOT EXISTS priority INTEGER DEFAULT 3" in ddl
|
||||
assert "ADD COLUMN IF NOT EXISTS metadata_json TEXT" in ddl
|
||||
assert "CREATE INDEX IF NOT EXISTS idx_action_plans_type" in ddl
|
||||
|
||||
Reference in New Issue
Block a user