fix(analytics): normalize seasonality month axis
Some checks failed
CD Pipeline / deploy (push) Has been cancelled

This commit is contained in:
ogt
2026-07-15 16:06:53 +08:00
parent 5f3e88c9ca
commit 6a40d1e252
3 changed files with 24 additions and 3 deletions

View File

@@ -414,7 +414,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
# ==========================================
# 系統版本與路徑
# ==========================================
SYSTEM_VERSION = "V10.802"
SYSTEM_VERSION = "V10.803"
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
public_url = PUBLIC_URL # 用於模板顯示

View File

@@ -520,6 +520,16 @@ def _filter_growth_payload(chart_data, kpi, start_month=None, end_month=None):
return filtered, filtered_kpi, analysis_period, True
def _sorted_valid_month_labels(values):
"""Normalize mixed pandas month values before chart-axis sorting."""
labels = set()
for value in values:
parsed = parse_month(value)
if parsed:
labels.add(parsed.strftime('%Y-%m'))
return sorted(labels)
def _build_growth_kpi(kpi_row):
if not kpi_row:
return None
@@ -1889,7 +1899,7 @@ def sales_analysis():
# Y軸: 分類 (使用 top_cats_season 的索引)
# 取得所有月份並排序
all_months_sorted = sorted(target_df['_month_str'].unique())
all_months_sorted = _sorted_valid_month_labels(target_df['_month_str'].unique())
month_map = {m: i for i, m in enumerate(all_months_sorted)}
cat_map = {c: i for i, c in enumerate(top_cats_season)}

View File

@@ -14,7 +14,7 @@ from routes.monthly_routes import (
_resolve_monthly_period,
get_monthly_summary_data,
)
from routes.sales_routes import _filter_growth_payload
from routes.sales_routes import _filter_growth_payload, _sorted_valid_month_labels
from services.analysis_period_service import make_analysis_period, make_month_period
@@ -250,6 +250,17 @@ def test_growth_period_slices_every_series_and_recomputes_period_kpis():
assert period["end_month"] == "2026-05"
def test_sales_seasonality_month_axis_ignores_nan_and_invalid_values():
assert _sorted_valid_month_labels([
"2026-04",
float("nan"),
None,
"invalid",
"2025-12",
"2026-04-30",
]) == ["2025-12", "2026-04"]
def test_monthly_frontend_has_replayable_period_and_no_fixed_years():
script = (ROOT / "web/static/js/page-monthly-summary.js").read_text(encoding="utf-8")
route = (ROOT / "routes/monthly_routes.py").read_text(encoding="utf-8")