fix(edm): 修正活動看板排序 endpoint
All checks were successful
CD Pipeline / deploy (push) Successful in 1m42s
All checks were successful
CD Pipeline / deploy (push) Successful in 1m42s
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
> 本文件定義專案開發的核心準則與不可違反的規範
|
||||
> **建立日期**: 2026-01-12
|
||||
> **當前版本**: V10.23 (OpenClaw Bot Telegram helper 拆分版)
|
||||
> **當前版本**: V10.24 (EDM Dashboard blueprint endpoint 修復版)
|
||||
> **最後更新**: 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.23: OpenClaw Telegram API helper extraction
|
||||
SYSTEM_VERSION = "V10.23"
|
||||
# 🚩 2026-04-30 V10.24: EDM dashboard blueprint endpoint sort link fix
|
||||
SYSTEM_VERSION = "V10.24"
|
||||
|
||||
# ==========================================
|
||||
# 🔒 SQL Injection 防護函數
|
||||
|
||||
@@ -254,7 +254,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
|
||||
# ==========================================
|
||||
# 系統版本與路徑
|
||||
# ==========================================
|
||||
SYSTEM_VERSION = "V10.23"
|
||||
SYSTEM_VERSION = "V10.24"
|
||||
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
|
||||
public_url = PUBLIC_URL # 用於模板顯示
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
- **模組化治理守門**: 盤點 15 個超過 800 行 Python 大檔,新增 `docs/guides/modularization_governance.md` 與 `tests/test_modularization_governance.py`,防止未分類巨檔再長出來。
|
||||
- **Legacy 5888 入口清理**: 刪除 `tests/main_test.py` standalone Flask 死碼,測試與自動匯入文件改用 Port 80 `/auto_import` 入口。
|
||||
- **OpenClaw Bot 第一刀拆分**: Telegram API send/retry/file upload helper 移到 `services/openclaw_bot/telegram_api.py`,`routes/openclaw_bot_routes.py` 往 thin Blueprint 收斂。
|
||||
- **EDM Dashboard endpoint 修復**: 部署後健康檢查抓到活動看板排序連結少 `edm.` blueprint 前綴,修正模板 endpoint 推導並補 5 個活動頁排序連結回歸測試。
|
||||
|
||||
### 2026-04-28~29:Phase 3e 重構大戰 + daily_sales cache 隱形 bug 根除
|
||||
- **app.py 縮減 -10.8%**: 7,386 → 6,590 行,11 commits 全綠零 502。
|
||||
|
||||
@@ -205,7 +205,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% set current_endpoint = 'edm_dashboard' if current_promo_page == 'edm' else 'festival_dashboard' %}
|
||||
{% set current_endpoint = 'edm.' ~ current_promo_page ~ '_dashboard' %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead class="table-light">
|
||||
@@ -428,4 +428,4 @@
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
79
tests/test_edm_dashboard_template.py
Normal file
79
tests/test_edm_dashboard_template.py
Normal file
@@ -0,0 +1,79 @@
|
||||
from flask import Blueprint, Flask, render_template, url_for
|
||||
|
||||
|
||||
def _build_test_app():
|
||||
app = Flask(
|
||||
__name__,
|
||||
template_folder="../templates",
|
||||
)
|
||||
app.jinja_env.globals["csrf_token"] = lambda: ""
|
||||
app.jinja_env.filters["number_format"] = lambda value: f"{value:,}"
|
||||
|
||||
edm = Blueprint("edm", __name__)
|
||||
|
||||
for endpoint, path in {
|
||||
"edm_dashboard": "/edm",
|
||||
"festival_dashboard": "/festival",
|
||||
"mothers_day_dashboard": "/mothers_day",
|
||||
"valentine_520_dashboard": "/valentine_520",
|
||||
"labor_day_dashboard": "/labor_day",
|
||||
}.items():
|
||||
edm.add_url_rule(path, endpoint, lambda: "")
|
||||
|
||||
app.register_blueprint(edm)
|
||||
return app
|
||||
|
||||
|
||||
def test_edm_dashboard_sort_links_use_blueprint_endpoint():
|
||||
app = _build_test_app()
|
||||
page_paths = {
|
||||
"edm": "/edm",
|
||||
"festival": "/festival",
|
||||
"mothers_day": "/mothers_day",
|
||||
"valentine_520": "/valentine_520",
|
||||
"labor_day": "/labor_day",
|
||||
}
|
||||
|
||||
with app.test_request_context("/edm"):
|
||||
promo_pages = [
|
||||
{
|
||||
"url": url_for(f"edm.{page}_dashboard"),
|
||||
"name": page,
|
||||
"id": page,
|
||||
}
|
||||
for page in page_paths
|
||||
]
|
||||
|
||||
for page, path in page_paths.items():
|
||||
html = render_template(
|
||||
"edm_dashboard.html",
|
||||
promo_pages=promo_pages,
|
||||
current_promo_page=page,
|
||||
page_title=page,
|
||||
activity_time="",
|
||||
last_update="",
|
||||
total_edm_products=0,
|
||||
scheduler_stats={},
|
||||
slot_stats={
|
||||
"10:00": {
|
||||
"on_shelf": 0,
|
||||
"new": 0,
|
||||
"up": 0,
|
||||
"down": 0,
|
||||
}
|
||||
},
|
||||
grouped_items={"10:00": []},
|
||||
active_tab="10:00",
|
||||
current_sort="default",
|
||||
current_order="desc",
|
||||
slugify=lambda value: value.replace(":", ""),
|
||||
datetime_now="",
|
||||
metabase_url="",
|
||||
grist_url="",
|
||||
)
|
||||
|
||||
assert f'{path}?sort_by=name&order=desc' in html
|
||||
assert f'{path}?sort_by=price&order=desc' in html
|
||||
|
||||
if page == "edm":
|
||||
assert f'{path}?sort_by=remain_qty&order=desc' in html
|
||||
Reference in New Issue
Block a user