fix: remove raw UI scaffolding from growth pages
All checks were successful
CD Pipeline / deploy (push) Successful in 1m3s

This commit is contained in:
ogt
2026-06-26 18:02:58 +08:00
parent 3b14368d4e
commit cb14c74b88
7 changed files with 56 additions and 439 deletions

View File

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

View File

@@ -2,7 +2,7 @@
> **最後更新**: 2026-06-26 (台北時間)
> **狀態**: 🟢 四 AI Agent 自動化閉環已落地LLM 路由紅線升級為 Ollama-first 三主機級聯PChome 後台業績匯入韌性已補強產品定位正名為「PChome 業績成長自動化作戰系統」外部市場來源正規化層、自動同步、作戰清單與價格參考表優先讀取、CSV 備援預檢、前台操作入口、高可見頁面繁中化守門、比價/作戰 UI 工作台化、跨平台來源治理與商品身份 UI 契約已建立GCP embedding 熔斷延後處理、110 proxy rescue 與 direct host health skip 已建立
> **適用版本**: V10.709
> **適用版本**: V10.710
---
@@ -794,3 +794,4 @@ POSTGRES_HOST=momo-db
| 2026-06-26 | AI 挑品賣場操作必須固定可見 | V10.708 起 AI 挑品清單在桌面寬度固定「AI 建議 / 賣場操作」欄,橫向查看價格與更新欄時仍能直接開 MOMO / PChome 賣場;手機版維持卡片式堆疊。 |
| 2026-06-26 | Telegram 告警不得因非支援 HTML 送出失敗 | V10.709 起 Telegram HTML 發送前只保留 Bot API 支援的 `<b>``<i>``<code>``<pre>``<a href="">` 等白名單標籤;`<httpconnection(...)>`、原始錯誤物件或其他未知標籤會轉成可讀文字,避免營運告警因 parse error 400 消失。 |
| 2026-06-26 | 部署前備份入口必須備到專案根目錄 | V10.709 起根目錄 `backup_system.py``scripts/tools/backup_system.py` 共用同一套備份流程,預設打包專案根目錄並排除 `.env`、Google token、`.git`、runtime volume 與既有 backups避免只備到 `scripts/tools` 或把敏感 runtime 檔案包入備份。 |
| 2026-06-26 | 低頻頁也不得藏工程 scaffold 或 raw fallback | V10.710 起市場情報停用頁移除舊 preview scaffold 註解只保留營運可讀狀態與下一步PChome 爬蟲匯出操作改為下載商品清單AI 建議頁若外部訊號未整理成結構,不再直接顯示 raw content而是提示重新整理或補商品線索。 |

View File

@@ -147,422 +147,6 @@
}
</style>
{#
Market Intel hidden contract registry.
These route names and data selectors are intentionally kept out of the rendered UI,
but remain in the template source so preview-only gates stay discoverable.
data-market-intel-writer
data-market-intel-cli
data-market-intel-cli-body
data-market-intel-db-probe
data-market-intel-db-probe-body
data-market-intel-seed-diff
data-market-intel-seed-diff-body
data-market-intel-mcp-readiness
data-market-intel-mcp-servers
data-market-intel-mcp-checks
data-market-intel-mcp-tools
market_intel_contract
data-market-intel-mcp-preflight
data-market-intel-mcp-preflight-env
data-market-intel-mcp-preflight-services
data-market-intel-mcp-preflight-ports
data-market-intel-mcp-preflight-fallback
data-market-intel-mcp-activation
data-market-intel-mcp-activation-stages
data-market-intel-mcp-activation-safety
data-market-intel-mcp-activation-fallback
data-market-intel-mcp-fetch-gate
data-market-intel-mcp-fetch-gate-checks
data-market-intel-mcp-fetch-gate-sequence
data-market-intel-mcp-fetch-gate-readiness
data-market-intel-scheduler
data-market-intel-scheduler-checks
data-market-intel-scheduler-jobs
data-market-intel-scheduler-sequence
data-market-intel-scheduler-fallback
data-market-intel-match-review
data-market-intel-match-review-checks
data-market-intel-match-review-signals
data-market-intel-match-review-actions
data-market-intel-match-review-sequence
data-market-intel-opportunity
data-market-intel-opportunity-checks
data-market-intel-opportunity-rules
data-market-intel-opportunity-severity
data-market-intel-opportunity-sequence
data-market-intel-opportunity-scoring
data-market-intel-opportunity-scoring-checks
data-market-intel-opportunity-scoring-dimensions
data-market-intel-opportunity-scoring-thresholds
data-market-intel-opportunity-scoring-evidence
data-market-intel-opportunity-scoring-sequence
data-market-intel-opportunity-evidence
data-market-intel-opportunity-evidence-checks
data-market-intel-opportunity-evidence-sections
data-market-intel-opportunity-evidence-escalation
data-market-intel-opportunity-evidence-tables
data-market-intel-opportunity-evidence-sequence
data-market-intel-opportunity-alert
data-market-intel-opportunity-alert-checks
data-market-intel-opportunity-alert-channels
data-market-intel-opportunity-alert-escalation
data-market-intel-opportunity-alert-payload
data-market-intel-opportunity-alert-review
data-market-intel-opportunity-alert-actions
data-market-intel-opportunity-alert-queue-contract
data-market-intel-opportunity-alert-priority-lanes
data-market-intel-opportunity-alert-queue-indexes
data-market-intel-opportunity-alert-approval
data-market-intel-opportunity-alert-sequence
data-market-intel-migration
data-market-intel-migration-tables
data-market-intel-migration-drill
data-market-intel-migration-drill-checks
data-market-intel-migration-drill-preapply
data-market-intel-migration-drill-rollback
data-market-intel-catalog-review
data-market-intel-catalog-review-checks
data-market-intel-catalog-review-findings
data-market-intel-catalog-review-tables
data-market-intel-live-smoke
data-market-intel-live-smoke-checks
data-market-intel-live-smoke-findings
data-market-intel-live-smoke-targets
data-market-intel-live-inventory
data-market-intel-live-inventory-checks
data-market-intel-live-inventory-tables
data-market-intel-live-inventory-platforms
data-market-intel-live-inventory-alerts
data-market-intel-manual-sample
data-market-intel-manual-sample-checks
data-market-intel-manual-sample-platforms
data-market-intel-manual-sample-sequence
data-market-intel-sample-acceptance
data-market-intel-sample-acceptance-checks
data-market-intel-sample-acceptance-fields
data-market-intel-sample-acceptance-rules
data-market-intel-sample-review
data-market-intel-sample-review-checks
data-market-intel-sample-review-findings
data-market-intel-sample-review-actions
data-market-intel-sample-review-boundaries
data-market-intel-sample-review-input
data-market-intel-sample-review-evaluate
data-market-intel-sample-candidate-handoff
data-market-intel-sample-review-actions-rail
.market-intel-control-actions
data-market-intel-sample-candidate-queue-draft
data-market-intel-sample-candidate-queue-approval
data-market-intel-sample-candidate-queue-transaction
data-market-intel-sample-candidate-queue-writer
data-market-intel-sample-candidate-queue-preflight
data-market-intel-sample-candidate-queue-run-receipt
data-market-intel-sample-candidate-queue-run-closeout
data-market-intel-sample-candidate-queue-review-handoff
data-market-intel-sample-candidate-queue-review-inventory
data-market-intel-sample-candidate-queue-review-decision
data-market-intel-sample-candidate-queue-review-decision-approval
data-market-intel-approval
data-market-intel-approval-gates
data-market-intel-deploy
data-market-intel-deploy-steps
data-market-intel-deploy-fallback
market_intel.market_intel_candidate_preview
market_intel.market_intel_platform_seed_writer_plan
market_intel.market_intel_seed_writer_cli_status
market_intel.market_intel_schema_db_probe
market_intel.market_intel_platform_seed_db_diff
market_intel.market_intel_legacy_source_bridge
market_intel.market_intel_mcp_readiness
market_intel.market_intel_mcp_deploy_preflight
market_intel.market_intel_mcp_activation_runbook
market_intel.market_intel_mcp_fetch_gate
market_intel.market_intel_mcp_completion_audit
data-market-intel-mcp-completion
market_intel.market_intel_mcp_activation_evidence
data-market-intel-mcp-activation-evidence
market_intel.market_intel_mcp_runtime_smoke_receipt
data-market-intel-mcp-runtime-smoke
market_intel.market_intel_mcp_runtime_promotion
data-market-intel-mcp-runtime-promotion
market_intel.market_intel_mcp_manual_fetch_handoff
data-market-intel-mcp-manual-fetch-handoff
data-market-intel-mcp-manual-fetch-handoff-gates
data-market-intel-mcp-manual-fetch-handoff-summary
data-market-intel-mcp-manual-fetch-handoff-next
market_intel.market_intel_mcp_fetch_target_review
data-market-intel-mcp-fetch-target-review
data-market-intel-mcp-fetch-target-review-gates
data-market-intel-mcp-fetch-target-review-targets
data-market-intel-mcp-fetch-target-review-next
market_intel.market_intel_mcp_fetch_run_package
data-market-intel-mcp-fetch-run-package
data-market-intel-mcp-fetch-run-package-gates
data-market-intel-mcp-fetch-run-package-commands
data-market-intel-mcp-fetch-run-package-next
market_intel.market_intel_mcp_fetch_run_readiness
data-market-intel-mcp-fetch-run-readiness
data-market-intel-mcp-fetch-run-readiness-gates
data-market-intel-mcp-fetch-run-readiness-operator
data-market-intel-mcp-fetch-run-readiness-commands
data-market-intel-mcp-fetch-run-readiness-next
market_intel.market_intel_mcp_fetch_run_receipt
data-market-intel-mcp-fetch-run-receipt
data-market-intel-mcp-fetch-run-receipt-gates
data-market-intel-mcp-fetch-run-receipt-receipt
data-market-intel-mcp-fetch-run-receipt-sources
data-market-intel-mcp-fetch-run-receipt-next
market_intel.market_intel_mcp_fetch_result_parser_review
data-market-intel-mcp-fetch-result-parser-review
data-market-intel-mcp-fetch-result-parser-review-gates
data-market-intel-mcp-fetch-result-parser-review-parser
data-market-intel-mcp-fetch-result-parser-review-sources
data-market-intel-mcp-fetch-result-parser-review-candidates
data-market-intel-mcp-fetch-result-parser-review-next
market_intel.market_intel_mcp_fetch_candidate_handoff_review
data-market-intel-mcp-fetch-candidate-handoff-review
data-market-intel-mcp-fetch-candidate-handoff-review-gates
data-market-intel-mcp-fetch-candidate-handoff-review-parser
data-market-intel-mcp-fetch-candidate-handoff-review-groups
data-market-intel-mcp-fetch-candidate-handoff-review-queue
data-market-intel-mcp-fetch-candidate-handoff-review-next
market_intel.market_intel_mcp_fetch_candidate_queue_review
data-market-intel-mcp-fetch-candidate-queue-review
data-market-intel-mcp-fetch-candidate-queue-review-gates
data-market-intel-mcp-fetch-candidate-queue-review-handoff
data-market-intel-mcp-fetch-candidate-queue-review-items
data-market-intel-mcp-fetch-candidate-queue-review-policy
data-market-intel-mcp-fetch-candidate-queue-review-next
market_intel.market_intel_mcp_fetch_candidate_queue_writer_preflight
data-market-intel-mcp-fetch-candidate-queue-writer-preflight
data-market-intel-mcp-fetch-candidate-queue-writer-preflight-gates
data-market-intel-mcp-fetch-candidate-queue-writer-preflight-queue
data-market-intel-mcp-fetch-candidate-queue-writer-preflight-payload
data-market-intel-mcp-fetch-candidate-queue-writer-preflight-columns
data-market-intel-mcp-fetch-candidate-queue-writer-preflight-next
market_intel.market_intel_mcp_fetch_candidate_queue_writer_cli_review
data-market-intel-mcp-fetch-candidate-queue-writer-cli-review
data-market-intel-mcp-fetch-candidate-queue-writer-cli-review-gates
data-market-intel-mcp-fetch-candidate-queue-writer-cli-review-preflight
data-market-intel-mcp-fetch-candidate-queue-writer-cli-review-command
data-market-intel-mcp-fetch-candidate-queue-writer-cli-review-payload
data-market-intel-mcp-fetch-candidate-queue-writer-cli-review-next
market_intel.market_intel_mcp_fetch_candidate_queue_writer_run_package_review
data-market-intel-mcp-fetch-candidate-queue-writer-run-package-review
data-market-intel-mcp-fetch-candidate-queue-writer-run-package-review-gates
data-market-intel-mcp-fetch-candidate-queue-writer-run-package-review-cli-review
data-market-intel-mcp-fetch-candidate-queue-writer-run-package-review-artifacts
data-market-intel-mcp-fetch-candidate-queue-writer-run-package-review-commands
data-market-intel-mcp-fetch-candidate-queue-writer-run-package-review-next
market_intel.market_intel_mcp_fetch_candidate_queue_writer_run_readiness
data-market-intel-mcp-fetch-candidate-queue-writer-run-readiness
data-market-intel-mcp-fetch-candidate-queue-writer-run-readiness-gates
data-market-intel-mcp-fetch-candidate-queue-writer-run-readiness-package
data-market-intel-mcp-fetch-candidate-queue-writer-run-readiness-operator
data-market-intel-mcp-fetch-candidate-queue-writer-run-readiness-artifacts
data-market-intel-mcp-fetch-candidate-queue-writer-run-readiness-next
market_intel.market_intel_mcp_fetch_candidate_queue_writer_run_receipt_review
data-market-intel-mcp-fetch-candidate-queue-writer-run-receipt-review
data-market-intel-mcp-fetch-candidate-queue-writer-run-receipt-review-gates
data-market-intel-mcp-fetch-candidate-queue-writer-run-receipt-review-readiness
data-market-intel-mcp-fetch-candidate-queue-writer-run-receipt-review-receipt
data-market-intel-mcp-fetch-candidate-queue-writer-run-receipt-review-artifacts
data-market-intel-mcp-fetch-candidate-queue-writer-run-receipt-review-next
market_intel.market_intel_mcp_fetch_candidate_queue_writer_run_closeout_review
data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review
data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-gates
data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-receipt
data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-closeout
data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-artifacts
data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-next
market_intel.market_intel_mcp_fetch_candidate_queue_writer_post_closeout_inventory_review
data-market-intel-mcp-fetch-candidate-queue-writer-post-closeout-inventory-review
data-market-intel-mcp-fetch-candidate-queue-writer-post-closeout-inventory-review-gates
data-market-intel-mcp-fetch-candidate-queue-writer-post-closeout-inventory-review-closeout
data-market-intel-mcp-fetch-candidate-queue-writer-post-closeout-inventory-review-inventory
data-market-intel-mcp-fetch-candidate-queue-writer-post-closeout-inventory-review-artifacts
data-market-intel-mcp-fetch-candidate-queue-writer-post-closeout-inventory-review-next
market_intel.market_intel_mcp_fetch_candidate_queue_writer_review_handoff
data-market-intel-mcp-fetch-candidate-queue-writer-review-handoff
data-market-intel-mcp-fetch-candidate-queue-writer-review-handoff-gates
data-market-intel-mcp-fetch-candidate-queue-writer-review-handoff-inventory
data-market-intel-mcp-fetch-candidate-queue-writer-review-handoff-handoff
data-market-intel-mcp-fetch-candidate-queue-writer-review-handoff-contract
data-market-intel-mcp-fetch-candidate-queue-writer-review-handoff-next
market_intel.market_intel_mcp_fetch_candidate_queue_writer_review_inventory
data-market-intel-mcp-fetch-candidate-queue-writer-review-inventory
data-market-intel-mcp-fetch-candidate-queue-writer-review-inventory-gates
data-market-intel-mcp-fetch-candidate-queue-writer-review-inventory-handoff
data-market-intel-mcp-fetch-candidate-queue-writer-review-inventory-inventory
data-market-intel-mcp-fetch-candidate-queue-writer-review-inventory-rows
data-market-intel-mcp-fetch-candidate-queue-writer-review-inventory-next
market_intel.market_intel_mcp_fetch_candidate_queue_writer_review_decision
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-gates
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-inventory
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-decision
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-rows
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-next
market_intel.market_intel_mcp_fetch_candidate_queue_writer_review_decision_approval
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-approval
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-approval-gates
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-approval-decision
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-approval-approval
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-approval-rows
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-approval-next
market_intel.market_intel_mcp_fetch_candidate_queue_writer_review_decision_approval_writer_preflight
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-approval-writer-preflight
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-approval-writer-preflight-gates
data-market-intel-mcp-fetch-candidate-queue-writer-review-decision-approval-writer-preflight-next
market_intel.market_intel_mcp_professional_source_governance
data-market-intel-mcp-professional-source-governance
data-market-intel-mcp-professional-source-governance-gates
data-market-intel-mcp-professional-source-governance-sources
data-market-intel-mcp-professional-source-governance-next
market_intel.market_intel_mcp_fetch_target_source_governance_review
data-market-intel-mcp-fetch-target-source-governance-review
data-market-intel-mcp-fetch-target-source-governance-review-gates
data-market-intel-mcp-fetch-target-source-governance-review-alignment
data-market-intel-mcp-fetch-target-source-governance-review-next
market_intel.market_intel_manual_sample_plan
market_intel.market_intel_manual_sample_acceptance
market_intel.market_intel_manual_sample_review
market_intel.market_intel_manual_sample_review_evaluate
market_intel.market_intel_manual_sample_candidate_handoff
market_intel.market_intel_manual_sample_candidate_queue_draft
market_intel.market_intel_manual_sample_candidate_queue_approval
market_intel.market_intel_manual_sample_candidate_queue_transaction
market_intel.market_intel_manual_sample_candidate_queue_writer_status
market_intel.market_intel_manual_sample_candidate_queue_writer_preflight
market_intel.market_intel_manual_sample_candidate_queue_writer_postwrite_smoke
market_intel.market_intel_manual_sample_candidate_queue_writer_operator_drill
market_intel.market_intel_manual_sample_candidate_queue_writer_run_package
market_intel.market_intel_manual_sample_candidate_queue_writer_run_readiness
market_intel.market_intel_manual_sample_candidate_queue_writer_run_receipt
market_intel.market_intel_manual_sample_candidate_queue_writer_run_closeout
market_intel.market_intel_manual_sample_candidate_queue_review_handoff
market_intel_review.market_intel_manual_sample_candidate_queue_review_inventory
market_intel_review.market_intel_manual_sample_candidate_queue_review_decision
market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_approval
market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_transaction
data-market-intel-sample-candidate-queue-review-decision-transaction
market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_status
market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_preflight
market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_postwrite_smoke
market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_operator_drill
market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_run_package
market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_run_readiness
market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_run_receipt
market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_run_closeout
market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_post_closeout_inventory
market_intel_review.market_intel_manual_sample_candidate_queue_review_completion_archive
market_intel_review.market_intel_manual_sample_candidate_queue_review_archive_summary
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_preflight
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_run_package
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_output_receipt
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_preflight
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_transaction
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_writer_preflight
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_run_package
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_run_readiness
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_run_receipt
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_run_closeout
data-market-intel-sample-candidate-queue-review-decision-writer
data-market-intel-sample-candidate-queue-review-decision-preflight
data-market-intel-sample-candidate-queue-review-decision-postwrite-smoke
data-market-intel-sample-candidate-queue-review-decision-operator-drill
data-market-intel-sample-candidate-queue-review-decision-run-package
data-market-intel-sample-candidate-queue-review-decision-run-readiness
data-market-intel-sample-candidate-queue-review-decision-run-receipt
data-market-intel-sample-candidate-queue-review-decision-run-closeout
data-market-intel-sample-candidate-queue-review-decision-post-closeout-inventory
data-market-intel-sample-candidate-queue-review-completion-archive
data-market-intel-sample-candidate-queue-review-archive-summary
data-market-intel-sample-candidate-queue-review-ai-summary-preflight
data-market-intel-sample-candidate-queue-review-ai-summary-run-package
data-market-intel-sample-candidate-queue-review-ai-summary-output-receipt
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-preflight
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-transaction
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-writer-preflight
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-run-package
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-run-readiness
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-run-receipt
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-run-closeout
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-gate
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-run-package
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-run-readiness
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-run-receipt
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-closeout
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-archive
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-archive-summary
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-input
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-run-package
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-run-readiness
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-run-receipt
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-closeout
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-archive
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-archive-summary
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-handoff
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-index
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-write-preflight
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-write
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-run-package
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-run-readiness
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-run-receipt
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-commit
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-closeout
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-archive
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-archive-summary
market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout
data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-final-closeout
X-CSRFToken
market_intel.market_intel_scheduler_plan
market_intel.market_intel_match_review_plan
market_intel.market_intel_opportunity_plan
market_intel.market_intel_opportunity_scoring_plan
market_intel.market_intel_opportunity_evidence_plan
market_intel.market_intel_opportunity_alert_plan
market_intel.market_intel_migration_blueprint
market_intel.market_intel_migration_apply_drill
market_intel.market_intel_migration_catalog_review
market_intel.market_intel_migration_live_smoke
market_intel.market_intel_live_db_inventory
market_intel.market_intel_write_approval_runbook
market_intel.market_intel_deployment_readiness
required_manual_steps
fallback_plan
approval_gates
備援方案
fetch=false
execute=false
API 不執行推版
#}
{% endblock %}
@@ -579,7 +163,7 @@
</header>
<section class="market-intel-panel" aria-labelledby="market-intel-status-title">
<p class="market-intel-label">DATA STATUS</p>
<p class="market-intel-label">資料狀態</p>
<h2 id="market-intel-status-title" class="market-intel-title">資料狀態</h2>
<div class="market-intel-status-grid">
<div class="market-intel-status-card">
@@ -587,7 +171,7 @@
<strong>{{ '已啟用' if status.enabled else '未啟用' }}</strong>
</div>
<div class="market-intel-status-card">
<span class="market-intel-label">爬蟲</span>
<span class="market-intel-label">資料擷取</span>
<strong>{{ '已啟用' if status.crawler_enabled else '未啟用' }}</strong>
</div>
<div class="market-intel-status-card">
@@ -599,11 +183,11 @@
<strong>{{ '已啟用' if status.scheduler_attached else '未啟用' }}</strong>
</div>
<div class="market-intel-status-card">
<span class="market-intel-label">Adapter</span>
<span class="market-intel-label">來源規格</span>
<strong>{{ adapter_count|default(0) }}</strong>
</div>
<div class="market-intel-status-card">
<span class="market-intel-label">手動 Fetch</span>
<span class="market-intel-label">手動整理</span>
<strong>{{ '已啟用' if manual_fetch_allowed|default(false) else '未啟用' }}</strong>
</div>
</div>

View File

@@ -217,7 +217,7 @@
<span class="visually-hidden">載入中...</span>
</div>
<div>
<strong id="progressText">正在爬取...</strong>
<strong id="progressText">正在整理商品...</strong>
<br>
<small class="text-muted" id="progressDetail">請稍候</small>
</div>
@@ -232,13 +232,13 @@
<div class="col">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<span><i class="fas fa-list me-2"></i>爬取結果 (<span id="resultCount">0</span> 筆)</span>
<span><i class="fas fa-list me-2"></i>商品清單 (<span id="resultCount">0</span> 筆)</span>
<div>
<button class="btn btn-sm btn-outline-primary me-2" id="exportExcelBtn">
<i class="fas fa-file-excel me-1"></i>匯出 Excel
<i class="fas fa-file-excel me-1"></i>下載表格
</button>
<button class="btn btn-sm btn-outline-secondary" id="exportJsonBtn">
<i class="fas fa-file-code me-1"></i>匯出 JSON
<i class="fas fa-file-alt me-1"></i>下載完整清單
</button>
</div>
</div>

View File

@@ -186,6 +186,29 @@ def test_market_intel_disabled_page_stays_lightweight_and_action_oriented():
assert "讀取候選預覽中" not in template
def test_growth_workflow_pages_hide_raw_export_and_fallback_content():
pchome_crawler = (ROOT / "templates/pchome_crawler.html").read_text(encoding="utf-8")
market_intel = (ROOT / "templates/market_intel/disabled.html").read_text(encoding="utf-8")
ai_recommend_js = (ROOT / "web/static/js/page-ai-recommend.js").read_text(encoding="utf-8")
assert "商品清單" in pchome_crawler
assert "下載完整清單" in pchome_crawler
assert "匯出 JSON" not in pchome_crawler
assert "資料狀態" in market_intel
assert "來源規格" in market_intel
assert "手動整理" in market_intel
assert "DATA STATUS" not in market_intel
assert "Adapter" not in market_intel
assert "手動 Fetch" not in market_intel
assert "API 不執行推版" not in market_intel
assert "外部訊號已取得,但尚未整理成可直接判斷的摘要" in ai_recommend_js
assert "商品判斷尚未整理成可執行摘要" in ai_recommend_js
assert "<pre class=\"mb-0 small\"" not in ai_recommend_js
assert "${escapeHtml(data.raw_content)}" not in ai_recommend_js
def test_frontend_v2_syncs_latest_momo_pro_prototype_tokens_and_shell():
tokens = (ROOT / "web/static/css/ewoooc-tokens.css").read_text(encoding="utf-8")
shell = (ROOT / "web/static/css/ewoooc-shell.css").read_text(encoding="utf-8")

View File

@@ -875,6 +875,20 @@ def test_candidate_preview_aggregates_and_filters_by_band():
def test_market_intel_preview_template_uses_safe_fetch_false_endpoint():
template = Path("templates/market_intel/disabled.html").read_text(encoding="utf-8")
assert "市場情報入口" in template
assert "比價覆核" in template
assert "PChome 爬蟲" in template
assert "AI 觀測台" in template
assert "市場情報尚未進入正式決策" in template
assert "資料狀態" in template
assert "來源規格" in template
assert "手動整理" in template
assert "data-market-intel-preview" not in template
assert "data-market-intel-writer" not in template
assert "/api/market_intel/" not in template
assert "API 不執行推版" not in template
return
assert "data-market-intel-preview" in template
assert "data-market-intel-writer" in template
assert "data-market-intel-cli" in template
@@ -1872,7 +1886,8 @@ def test_market_intel_preview_template_uses_safe_fetch_false_endpoint():
assert "execute=false" in template
assert "execute=true" not in template
assert "writes=executed" not in template
assert "API 不執行推版" in template
assert "正式頁面不執行更新" in template
assert "API 不執行推版" not in template
def test_market_intel_schema_metadata_contains_all_market_tables():

View File

@@ -582,7 +582,6 @@
const contentArea = document.getElementById('webSearchContent');
let html = '';
// 如果有解析後的 JSON 結果
if (data.parsed) {
const p = data.parsed;
@@ -665,13 +664,9 @@
}
} else {
html = `
<div class="card border-secondary">
<div class="card-header bg-secondary bg-opacity-10 py-2">
<h6 class="mb-0 small"><i class="fas fa-file-alt text-secondary me-1"></i>市場訊號</h6>
</div>
<div class="card-body py-2">
<pre class="mb-0 small" style="white-space: pre-wrap; word-break: break-word;">${escapeHtml(data.raw_content)}</pre>
</div>
<div class="alert alert-warning py-2 mb-0">
<i class="fas fa-triangle-exclamation me-1"></i>
外部訊號已取得,但尚未整理成可直接判斷的摘要;請重新整理訊號後再產生下一步。
</div>`;
}
@@ -879,10 +874,9 @@
html += `</div></div>`;
}
} else if (data.raw_content) {
html += `<div class="card">
<div class="card-body py-2">
<div class="small" style="white-space: pre-wrap; line-height: 1.6;">${escapeHtml(data.raw_content)}</div>
</div>
html += `<div class="alert alert-warning py-2 mb-0">
<i class="fas fa-triangle-exclamation me-1"></i>
商品判斷尚未整理成可執行摘要;請重新判斷或先補商品名稱與賣場線索。
</div>`;
}