Files
ewoooc/docs/adr/ADR-022-ppt-system-v3-redesign.md
OoO 9010a4e6fa docs(adr): add ADR-022 PPT v3 redesign + warm paper + matplotlib + cache versioning
紀錄本次 PPT 全面重做的架構決策:
- 視覺:暖紙風(_BG_PAPER #F3EEE2)取代暖墨黑封面
- 圖表:matplotlib 暖色系(橫條/折線/帕雷托)取代 python-pptx 原生
- 字型:lxml 直寫 a:latin/a:ea 中英分軌(Consolas + JhengHei)
- 快取:TEMPLATE_VERSIONS 字典自動注入 cache key (tpl_ver)
- AI prompt:升級到顧問深度(市場趨勢脈絡 + SMART 框架)
- 安全:admin 白名單(OPENCLAW_ADMIN_USER_IDS)+ cleanup dry_run 預設

涵蓋 8 commit chain:38967ce → 3b0b4b352c06f61c81866b5a2b09c7b7cee92b80355a7012f

Critic 全清紀錄:0 critical / 2 HIGH / 4 medium / 3 info 全部修補。

對應 memory:
- reference_ppt_system.md(既存)已更新到 v3 實況
- project_ppt_v3_campaign_20260502.md(新建)戰役紀錄含三大踩坑
- feedback_template_version_cache_pattern.md(新建)可重用設計模式

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 00:25:09 +08:00

6.5 KiB
Raw Blame History

ADR-022: PPT 簡報系統 v3 — 暖紙風 + matplotlib 專業圖表 + 模板版本快取

  • Status: Accepted
  • Date: 2026-05-02 / 03
  • Deciders: 統帥
  • Related: 取代 ADR-014 中的 PPT 視覺/結構描述V2 → V3不影響 V2 既有「6 種報告 vs 9 種報告」校正growth/vendor/bcg 仍未落地)
  • Affects: services/ppt_generator.pyroutes/openclaw_bot_routes.pyDockerfilescripts/ppt_cleanup.sh
  • Commit chain: 38967ce3b0b4b352c06f61c81866b5a2b09c7b7cee92b80355a7012f

Context

2026-05-02 統帥檢視月報V2後指出五項視覺品質缺陷

  1. 圖表醜python-pptx 原生柱狀圖無資料標註、無顏色分級)
  2. 熱銷商品只 10 品(用戶要求 50 品)
  3. 專案 RAG 情報內容太陽春(單一 textbox 顯示靜態節日字串)
  4. 排版亂封面大面積暖墨黑、AI 頁深色 + 白字過於濃重)
  5. 字體未對齊設計系統(中英混排撞 Courier New

並要求對齊「市場上專業日報/週報/月報」的標準McKinsey/BCG 等級顧問報告)。

第一輪重做後又抓出三類延伸需求:

  • 同份 PPT 可秒回cache但模板升版時舊 cache 必須自動失效
  • AI 分析內容要詳盡且專業,能直接幫銷售/行銷做決策參考
  • 容器 CJK 字型必須真正能渲染中文

Decision

A. 視覺重做 — 暖紙風(取代暖墨黑)

封面_BG_PAPER (#F3EEE2) 米紙底取代 _BG_DARK (#2A2520),焦糖橘左寬條 + 暖墨色標題。

KPI 卡v2value 大字含右下角 △% 徽章(綠↑紅↓),含 delta_label="vs 上月" / inverse 反轉模式(用於成本類指標)。

字型分軌:透過 lxml 直寫 <a:latin>+<a:ea> (_set_run_fonts),數字/英文走 Consolas點陣等寬感中文走 Microsoft JhengHei。_insert_rpr_child 依 ECMA-376 §21.1.2.3 順序插入子元素(避免 LibreOffice/Keynote 拒絕讀取)。

B. 圖表升級 — matplotlib 暖色系(取代 python-pptx 原生)

Helper 用於 特色
_mpl_horiz_bar_png 月報品類橫條 TOP3 焦糖橘 / 4-6 蜂蜜金 / 7+ 焦土,條右標 NT$X.X萬+佔比%
_mpl_line_chart_png 日/週/月趨勢 本月實線+上月虛線+日均水平線+高低點標註N≤2 sparse 防呆
_mpl_pareto_chart_png 月報品類雙視圖 業績條80% 主力焦糖橘)+ 累計%曲線+80% 主力線

容器 CJK fallbackfonts-noto-cjk 套件 ttc 檔在 matplotlib font_manager.ttflist 只認 Noto Sans CJK JP 變體,但 ttc 內漢字字型表共用,可正常渲染中文。_mpl_setup fallback 列表必須包含 Noto Sans CJK JP

C. 模板版本快取template_version cache invalidation

# services/ppt_generator.py
TEMPLATE_VERSIONS = {
    'monthly': 'v3.1.3',
    'daily':   'v3.0.2',
    ...
}

# routes/openclaw_bot_routes.py
def _normalize_ppt_parameters(parameters):
    """自動把 tpl_ver 注入 cache key"""
    params['tpl_ver'] = get_template_version(report_type)
    return json.dumps(params, sort_keys=True)

Bump 規則major 設計改版 +0.1(如 v3.0 → v3.1);補丁修正 +0.01v3.1.1 → v3.1.2。bump 即觸發舊快取自動 miss。

緊急清空_invalidate_ppt_cache(report_type=None) Python helper / /cache flush Telegram 指令admin only

磁碟清理cleanup_expired_ppt_cache(days_old=7, dry_run=True) — 安全預設 dry_run=True呼叫方明確傳 False 才實刪。launchd plist 排程每日 03:15 跑macOS 開發機)。

D. AI prompt 升級到顧問深度

月報 prompt 升級_ppt_ai_analysis

  • 角色BCG/麥肯錫策略顧問 + momo 行銷主管 + 品類採購(三合一)
  • 必含「市場趨勢脈絡」段:當期檔期 + 2026 熱門賽道(永續美妝/母嬰高端/敏弱肌/銀髮保健等)+ 平台競爭(蝦皮/PChome/酷澎)
  • 行動建議走 SMART 框架Specific/Measurable/Achievable/Relevant/Time-bound分本週/本月/下月三層
  • 禁用「可能/也許/建議考慮」等模糊用詞
  • 字數 900-1200max_tokens 2400

AI 段落 parser_parse_ai_sections):丟掉空 body 段(避免顯示「本段無內容」);上限 6→10 容納 SMART 9 段。

E. 安全機制 — admin 白名單 + dry_run 預設

  • OPENCLAW_ADMIN_USER_IDS 環境變數/cache flush/cache cleanup confirm 限管理員執行;未設時退回 ALLOWED_USERS向後兼容 fail-closed
  • _CURRENT_USER_ID_CTX ContextVarwebhook 入口msg + callbacksethandle_cmd 讀取,避免改 30+ 處呼叫端簽名
  • cleanup days<1 強制乾跑(防呆)

Consequences

Positive

  1. 視覺對齊市場專業標準:與 McKinsey/BCG 月度報告一致的暖紙風+圖表標註+帕雷托雙視圖
  2. 模板升版零阻力bump TEMPLATE_VERSIONS 即生效,無需手動清快取
  3. 記憶體穩定matplotlib helpers 全部 try/finally 包好,渲染失敗不洩漏 figure
  4. AI 內容可實戰:每段含具體商品名+量化目標+期限BU 主管可直接做決策
  5. 容器化部署Dockerfile 加 fonts-noto-cjkCI/CD 自動帶字型

Negative

  1. 月報 cache miss 路徑變慢cache miss 時連續查 current/prev_month/prev_year 三次12 SQL延遲 3×。命中後正常同份秒回
  2. PPT 檔變大matplotlib PNG 取代原生 chart月報 130KB → 326KB含 3 張高品質圖)
  3. fonts-noto-cjk-extra 增加 ~100MB image 大小:可瘦身但 trade-off 字型完整度

Risks Mitigated

  • figure 洩漏 → OOMtry/finally 修復critic HIGH-1
  • 靜默實刪災難cleanup 預設 dry_run=Truecritic HIGH-2
  • 群組成員誤觸破壞性指令admin 白名單critic Medium-3
  • 未來改讀模板 .pptx schema 違反_insert_rpr_child 維護順序critic Medium-1

Alternatives Considered

  1. 保留 python-pptx 原生 chart:拒絕 — 原生不支援資料標註、顏色分級無法做到 BCG 級觀感
  2. 用 hash(ppt_generator.py 內容)[:8] 自動 cache key:拒絕 — 改個 typo 也 invalidate 全部,過度敏感
  3. 改 handle_cmd 簽名加 user_id:拒絕 — 30+ 處呼叫端要動,風險大;用 ContextVar 更乾淨

References

  • Critic 完整審查報告:見 commit 38967ce 之後的 critic agent run
  • 實戰驗證:在 188 prod 容器內生成 monthly v3.1.3AI 內容 3 頁全 SMART 行動建議
  • 原 ADR-014V2 PPT未廢止但視覺/結構/cache 部分由本 ADR 取代