# ADR-035: 跨平台市場活動情報系統

- **狀態**: Accepted
- **日期**: 2026-05-06
- **觸發**: 使用者提出定期掌握 MOMO / 蝦皮 / 酷澎 / PChome 等電商活動檔期、活動商品、競品價格與資料庫保存需求
- **相關 ADR**: ADR-011（跨專案資源隔離）、ADR-017（模組化收尾路線圖）、ADR-025（市場情報週報）
- **相關 Memory**: `docs/memory/code_modularization_inventory_20260430.md`

## Context

EwoooC 目前已有 MOMO EDM / 節慶活動資料、`promo_products`、PChome 競品價格 feeder、PPT 市場情報週報與多個分析頁，但跨平台活動情報尚未形成獨立資料模型與可維護爬蟲框架。

若直接把蝦皮、酷澎、PChome 等平台資料塞進既有 `promo_products`、`routes/sales_routes.py`、`scheduler.py` 或分析頁大型 template，會造成下列風險：

1. 不同平台欄位語意不同，舊表無法承載活動檔期、平台商品 ID、折扣券、銷售訊號與價格歷史。
2. 既有 `scheduler.py`、`routes/sales_routes.py`、`routes/dashboard_routes.py`、多個 crawler service 已達大檔治理門檻，新增功能會加劇技術債。
3. 新爬蟲若直接上正式排程，可能造成 DB 寫入量、外部平台 rate limit、排程阻塞與告警噪音。
4. 新市場情報頁若複製既有巨型 Jinja template 模式，會延續 UI token、字體、色彩與點陣風格不一致問題。

## Decision

建立新的 **跨平台市場活動情報系統**，採分階段落地、預設關閉、可獨立回退的方式推進。

### 1. 模組邊界

新功能必須使用獨立模組，不得塞回既有巨檔：

- `services/market_intel/`：活動探索、商品爬取、正規化、商品比對、告警摘要。
- `services/market_intel/adapters/`：各平台 adapter，例如 MOMO / PChome / Coupang / Shopee。
- `database/market_intel_models.py`：`market_*` ORM models。
- `routes/market_intel_routes.py`：市場情報頁面與 API route glue。
- `templates/market_intel/`：市場情報 UI template。
- `services/scheduler/` 或獨立 job module：市場情報排程掛載點。

### 2. 資料模型

新增 `market_*` schema 作為唯一主資料層：

- `market_platforms`
- `market_campaigns`
- `market_campaign_snapshots`
- `market_campaign_products`
- `market_product_price_history`
- `market_product_matches`
- `market_crawler_runs`
- `market_alert_review_queue`

`promo_products` 只作為既有 MOMO 活動資料的相容來源或雙寫過渡，不再承接跨平台唯一真相。

### 3. Feature Flag 與啟用策略

市場情報第一階段必須預設關閉：

- `MARKET_INTEL_ENABLED=false`
- `MARKET_INTEL_CRAWLER_ENABLED=false`
- `MARKET_INTEL_WRITE_ENABLED=false`

初期允許 dry-run：建立 run log、解析活動與商品，但不大量寫入正式商品資料。正式入庫與排程啟用需另行通過 smoke test、rate limit 驗證與 rollback drill。

### 4. 爬蟲安全邊界

市場情報爬蟲只允許抓公開頁面或公開結構化資料，不做登入、不碰會員資料、不破解反爬、不使用帳號池、不繞付費牆。

每平台 adapter 必須具備：

- rate limit
- timeout
- retry ceiling
- user-agent 與來源識別
- run log
- error classification
- dry-run mode
- 可單平台停用開關

### 5. UI / UX 邊界

市場情報 UI 不複製巨型分析頁模式，必須先抽共用元件與設計 token：

- 活動檔期看板
- 活動商品池
- 商品比對審核
- 市場機會與威脅

所有新頁必須符合 V2 暖紙、暖墨、焦糖 accent、等寬數字、點陣紋理與真實資料規範。未串接資料時只能顯示可診斷空狀態，不得使用假商品或假 KPI。

### 6. 上線與回退

部署遵守 ADR-011：

- 禁止 `docker compose ... --remove-orphans`
- 禁止影響 `momo-db` 容器生命週期
- 只用 `docker compose up -d --no-deps --force-recreate <service>` 精準重建
- health check 只打 `/health`

異常回退順序：

1. 關閉 `MARKET_INTEL_*` feature flags。
2. 停用市場情報 scheduler job。
3. 保留 `market_*` 表與 run log，不刪資料。
4. 回復上一版 route / service 程式碼。
5. 僅重啟受影響應用容器，不動 DB。

## Phased Rollout

### Phase 0：Readiness Audit

- 更新模組化 inventory。
- 確認 `scheduler.py` 無 conflict marker 且可 py_compile。
- 標記市場情報不可寫入的既有大檔。
- 完成 ADR-035。

### Phase 1：Skeleton Only

- 新增 feature flags。
- 新增 `market_intel` package skeleton。
- 新增空 route / disabled page / dry-run service。
- 不啟用正式排程，不大量入庫。

### Phase 2：DB Schema

- 新增 `market_*` ORM models。
- 補 metadata import 與 schema smoke。
- 寫入 crawler run log 與少量 dry-run snapshot。

### Phase 3：MOMO / PChome Adapter

- 先接成本最低且已有脈絡的平台。
- 只抓公開活動入口與活動商品。
- 建立活動與商品正規化規則。
- 2026-05-06 起先落地 read-only adapter skeleton：只註冊平台入口與安全策略，不發 HTTP request、不寫 DB、不掛 scheduler。
- 2026-05-06 追加手動 dry-run discovery runner：`fetch=false` 只回 planned；`fetch=true` 需 `MARKET_INTEL_ENABLED` 與 `MARKET_INTEL_CRAWLER_ENABLED` 同時開啟，且仍禁止 DB write 與 scheduler attach。
- 2026-05-06 追加 parser 診斷層：成功手動 fetch 後只輸出 title、page_hash、link counts 與 campaign link candidates；不得建立正式 campaign/product。
- 2026-05-06 追加平台別 scorer：MOMO/PChome adapter 可對 URL/text 加權，diagnostics 需保留 `generic_score` 與 `platform_score` 供人工判讀，不得自動建檔期。
- 2026-05-06 追加 confidence bands：候選連結只可標記 `high` / `medium` / `low` 與 `confidence_reason` 作為人工審核提示，不得自動建立 campaign。
- 2026-05-06 追加 candidate preview API：只聚合本次 diagnostics 的候選連結並支援 `min_band` / `limit`，不得入庫或自動建立活動。
- 2026-05-06 追加 UI preview panel：市場情報頁只讀同站 `/api/market_intel/candidate_preview?fetch=false` 顯示安全空狀態，不得自動外部 fetch。
- 2026-05-06 追加 platform seed plan：`/api/market_intel/platform_seed_plan` 只把 adapter registry 轉為可審核 seed rows；正式 upsert `market_platforms` 仍需 migration、schema smoke、feature flag 與人工批准。
- 2026-05-06 追加 Coupang read-only adapter：以官方台灣站 `https://www.tw.coupang.com/` 與 `https://www.tw.coupang.com/np/coupangglobal` 作為公開 discovery 起點；預設仍不發 request、不寫 DB、不掛 scheduler。
- 2026-05-07 追加 Shopee read-only adapter：以 `https://shopee.tw/` 與 `https://shopee.tw/mall` 作為公開 discovery 起點；不得登入、處理會員券/購物車、使用帳號池或繞過反爬。
- 2026-05-07 追加 Phase 12 UI QA：本機 harness 載入 `/market_intel`，確認 4 adapter planned、console error 0、窄版 in-app browser 未水平爆版；真 390px 截圖需後續使用可設定 viewport 的 runner 補驗。
- 2026-05-07 追加 platform seed write guard：`/api/market_intel/platform_seed_write_guard` 只回報 feature flag、migration、schema smoke、人工批准 gate 狀態，預設永遠不寫 DB。
- 2026-05-07 追加 platform seed writer dry-run：`/api/market_intel/schema_smoke` 實際檢查 ORM metadata；`/api/market_intel/platform_seed_writer_plan` 只產生 parameterized `market_platforms` upsert preview，不建立 session、不 commit。
- 2026-05-07 追加 writer preview panel：市場情報頁讀取同站 `/api/market_intel/platform_seed_writer_plan`，顯示 schema smoke、upsert preview 與 blocked reasons；仍不得寫 DB。
- 2026-05-07 追加 deployment readiness panel：`/api/market_intel/deployment_readiness` 與 UI 明確回報尚未正式推版、尚未 commit/push、部署 SOP 與 production smoke 尚待人工執行。
- 2026-05-07 追加 deployment handoff checklist：readiness API/UI 顯示人工推版步驟、備援方案、安全部署邊界、production smoke targets 與 `python backup_system.py` 備份要求；此階段仍不執行 git、部署、DB 或外部爬取動作。
- 2026-05-07 追加 write approval runbook：`/api/market_intel/write_approval_runbook` 與 UI 顯示正式 seed write 前 gate、operator sequence、rollback plan 與硬性安全邊界；預設不建立 DB session、不 commit、不連外、不掛 scheduler。
- 2026-05-07 追加 migration blueprint：`/api/market_intel/migration_blueprint` 與 UI 顯示 `migrations/032_market_intel_core_schema.sql` 草案、migration apply command shape 與 seed writer command design；此階段仍不建立 migration 檔、不執行 SQL、不寫 seed rows。
- 2026-05-07 追加 migration file draft：建立本地 `migrations/032_market_intel_core_schema.sql` 草稿檔；blueprint API 會檢查檔案存在且內容與草案相符，但仍不執行 SQL、不建立 DB session、不寫 seed rows。
- 2026-05-12 追加 seed writer CLI skeleton：`scripts/market_intel_seed_writer.py` 與 `/api/market_intel/seed_writer_cli_status` 只輸出 blocked plan；即使收到 `--execute` 與一次性 approval token 也不建立 DB session、不 commit、不寫 seed rows。
- 2026-05-12 追加 app-only release gate：`/api/market_intel/deployment_readiness` 區分「安全檢查可進 app-only 推版」與「API 不執行部署」；即使 `ready_for_production_deploy=true`，仍不得由 API 執行 git、備份、scp、ssh、container recreate、migration 或 DB write。
- 2026-05-12 追加 seed transaction preview：`/api/market_intel/seed_writer_cli_status` 會輸出 `transaction_preview`，包含 idempotent upsert SQL template、parameter payload hash 與 diff 狀態；此預覽不得載入既有 DB rows、不得開 transaction、不得 commit。
- 2026-05-12 追加 read-only DB schema probe：`/api/market_intel/schema_db_probe` 預設只回 planned，不連 DB；人工 smoke 才能以明確參數查正式 DB catalog。探針不得使用 `DatabaseManager()`，避免觸發 metadata `create_all()`；不得建立 ORM session、不得寫入、不得 commit。
- 2026-05-12 追加 platform seed DB diff probe：`/api/market_intel/platform_seed_db_diff` 預設只回 planned，不連 DB；人工 smoke 才能以明確參數只讀查詢 `market_platforms`，比對 adapter seed 是否 missing / differs / matches。探針不得使用 `DatabaseManager()`、不得建立 ORM session、不得寫入、不得 commit。
- 2026-05-13 追加 platform seed CLI writer：`scripts/market_intel_seed_writer.py` 可在 CLI 明確帶入 `--execute`、`--apply-real-write` 與確認 token 時，以 SQLAlchemy Core 短 transaction upsert `market_platforms`；API 仍不得替使用者執行 DB 寫入，不建立 ORM session、不連外、不掛 scheduler。
- 2026-05-18 追加 legacy source bridge preview：`/api/market_intel/legacy_source_bridge` 預設 `execute=false` 只回 planned，不連 DB；人工 smoke 才能以 `execute=true` 只讀盤點 `promo_products`、`competitor_prices`、`competitor_price_history`，產生舊資料導入 `market_*` 的 mapping、dedupe 與 blocked operation preview。此橋接不得寫入 DB、不得建立 ORM session、不得把 PChome 比價快取冒充為活動頁商品、不得掛 scheduler。
- 2026-05-18 追加 MCP readiness preview：`/api/market_intel/mcp_readiness` 預設 `execute=false` 只回 planned，盤點 ADR-031 外部 MCP server、`services.mcp_router` feature flag、tool registry、`mcp_calls` telemetry 與 market_intel tool contract 缺口。人工 smoke 才能以 `execute=true` 做只讀 health / telemetry probe；此探針不得寫 DB、不得建立 ORM session、不得替市場情報自動啟用 MCP 或外部爬取。
- 2026-05-18 追加 internal MCP tool contract preview：`services.market_intel.mcp_contract` 與 `/api/market_intel/mcp_tool_contract` 定義 `market_campaign_search`、`market_campaign_scrape`、`market_product_match_lookup` 三個 read-only contract，並在 `services.mcp_router.TOOL_REGISTRY` 註冊 `market_intel` caller 白名單。此階段只建立可審核合約與 readiness 檢查，不啟用 `MCP_ROUTER_ENABLED`、不呼叫 MCP server、不寫 DB、不掛 scheduler。
- 2026-05-18 追加 external MCP deploy preflight preview：`services.market_intel.mcp_deploy_preflight` 與 `/api/market_intel/mcp_deploy_preflight` 只讀檢查 `docker-compose.mcp.yml`、必要 env、localhost-only ports、read-only volume、Firecrawl resource guard 與 fallback plan。`docker-compose.mcp.yml` 需以 read-only bind mount 進 app 容器供 preflight 審核。此 preflight 不執行 docker/SSH、不建立 `mcp_readonly` role、不啟用 `MCP_ROUTER_ENABLED`、不寫 DB、不掛 scheduler；外部 MCP stack 須等 env 與 operator smoke 全過後另行批准。
- 2026-05-18 追加 MCP activation runbook preview：`services.market_intel.mcp_activation_runbook` 與 `/api/market_intel/mcp_activation_runbook` 只輸出人工啟用順序與 gate：補必要 env、人工建立/驗證 `mcp_readonly`、啟動外部 MCP stack、四個 health 全過、最後才允許 `MCP_ROUTER_ENABLED=true`。此 runbook 不執行 docker/SSH、不寫 env、不建立 DB role、不跑 health、不啟用 router、不寫 DB、不掛 scheduler。
- 2026-05-18 追加 MCP fetch gate preview：`services.market_intel.mcp_fetch_gate` 與 `/api/market_intel/mcp_fetch_gate` 將人工 discovery fetch 改成必須先通過市場情報 feature flags、MCP readiness、router、外部 MCP health 與 tool contract gate；`run_manual_discovery(fetch=true)` 即使 flags 開啟也會先被此 gate 阻擋，直到 MCP 條件全過。此 gate 不抓電商頁、不寫 DB、不掛 scheduler、不執行 deployment，UI 預設只呼叫 `fetch=false&execute=false`。
- 2026-05-24 追加 MCP manual fetch handoff gate：`services.market_intel.mcp_manual_fetch_handoff` 與 `/api/market_intel/mcp_manual_fetch_handoff` 將 runtime promotion package 與操作員安全確認合併成可審核 handoff，只放行到人工 fetch gate operator review；API/UI 不保存 payload、不打 health、不開 DB、不抓外站、不掛 scheduler，也不會自動打開 manual fetch。
- 2026-05-24 追加 MCP fetch target review gate：`services.market_intel.mcp_fetch_target_review` 與 `/api/market_intel/mcp_fetch_target_review` 在 manual fetch handoff 後審核 adapter registry 公開入口白名單、平台來源、每平台 delay / timeout / max pages / sample_limit、rollback plan 與操作員確認；API/UI 不保存 payload、不發外部 request、不開 DB、不寫入、不掛 scheduler，也不會自動打開 manual fetch，只放行到後續人工 fetch run package review。
- 2026-05-24 追加 MCP fetch run package gate：`services.market_intel.mcp_fetch_run_package` 與 `/api/market_intel/mcp_fetch_run_package` 將已通過的 target review 轉成 command argv preview、receipt path 與操作員 run controls 審核包；路由拆至 `routes.market_intel_mcp_run_routes`，主 Blueprint 僅掛 extension import。此階段不執行 CLI、不發外部 request、不寫 artifact、不開 DB、不掛 scheduler，只放行到後續 run readiness review。
- 2026-05-24 追加 MCP fetch run readiness gate：`services.market_intel.mcp_fetch_run_readiness` 與 `/api/market_intel/mcp_fetch_run_readiness` 在 run package 後檢查 command preview、receipt path、artifact path、節流/timeout/dry-run-first、secret payload 與操作員 shell-only 邊界；此階段不執行 CLI、不發外部 request、不寫 artifact、不開 DB、不掛 scheduler，只放行到人工 shell dry-run 與後續 receipt review。
- 2026-05-29 追加 MCP fetch run receipt gate：`services.market_intel.mcp_fetch_run_receipt` 與 `/api/market_intel/mcp_fetch_run_receipt` 在操作員 shell 完成 dry-run fetch 後審核 receipt id、artifact path、platform/source/receipt path 對帳、公開 URL、request/error budget、secret 外洩與 API/DB/scheduler 副作用旗標；API/UI 不執行 CLI、不發外部 request、不保存 receipt、不開 DB、不寫入、不掛 scheduler，只放行到後續 result parser review。
- 2026-05-31 追加 MCP fetch result parser review gate：`services.market_intel.mcp_fetch_result_parser_review` 與 `/api/market_intel/mcp_fetch_result_parser_review` 在 receipt 通過後審核操作員貼回的 parser 結構化摘要，檢查 receipt source/receipt path 對帳、parser artifact path、活動/商品候選必要欄位、公開 URL、小批次候選上限、raw HTML/secret 外洩與 API/DB/scheduler 副作用旗標；API/UI 不讀 artifact、不執行 parser CLI、不發外部 request、不保存 parser result、不寫入、不掛 scheduler，只放行到候選 handoff review。
- 2026-05-31 追加 MCP fetch candidate handoff review gate：`services.market_intel.mcp_fetch_candidate_handoff_review` 與 `/api/market_intel/mcp_fetch_candidate_handoff_review` 在 parser review 通過後審核候選交接包，檢查 source/candidate key 對齊、queue policy 是否仍是 `manual_candidate_review` / `preview_only`、小批次候選上限、操作員無寫入/無連外/無排程確認、raw HTML/secret 外洩與 side-effect flags；API/UI 不建立 queue、不讀 artifact、不寫 DB、不掛 scheduler，只放行到人工 candidate queue review。
- 2026-05-31 追加 MCP fetch candidate queue review gate：`services.market_intel.mcp_fetch_candidate_queue_review` 與 `/api/market_intel/mcp_fetch_candidate_queue_review` 在 handoff review 通過後審核人工 queue review 草案，檢查候選 key 對齊、`review_state=needs_review`、allowed actions 人工限定、`queue_write_status=not_persisted`、操作員無寫入/無連外/無排程確認、raw HTML/secret 外洩與 side-effect flags；API/UI 不建立 queue、不更新 review_state、不讀 artifact、不寫 DB、不掛 scheduler，只放行到 writer preflight。
- 2026-05-31 追加 MCP fetch candidate queue writer preflight gate：`services.market_intel.mcp_fetch_candidate_queue_writer_preflight` 與 `/api/market_intel/mcp_fetch_candidate_queue_writer_preflight` 在 queue review 通過後審核 writer preflight 草案，檢查 `target_table=market_alert_review_queue`、`write_mode=cli_only_later`、dedupe strategy、insert columns、payload rows、候選 key 對齊、小批次上限、操作員無寫入/無連外/無 CLI/無排程確認、raw HTML/secret 外洩與 side-effect flags；API/UI 不開 DB、不執行 CLI、不建立 queue、不更新 review_state、不寫 DB、不掛 scheduler，只放行到 CLI writer review。
- 2026-05-31 追加 MCP fetch candidate queue writer CLI review gate：`services.market_intel.mcp_fetch_candidate_queue_writer_cli_review` 與 `/api/market_intel/mcp_fetch_candidate_queue_writer_cli_review` 在 writer preflight 通過後審核 CLI review 草案，檢查 script path、target table、preflight id、payload row count、candidate/dedupe keys、`--sample-json`、`--read-only-preflight` 與 forbidden flags；API/UI 不執行 CLI、不讀 approval token、不寫檔、不開 DB、不寫 queue、不掛 scheduler，只放行到 operator run package review。
- 2026-05-31 追加 MCP fetch candidate queue writer run package review gate：`services.market_intel.mcp_fetch_candidate_queue_writer_run_package_review` 與 `/api/market_intel/mcp_fetch_candidate_queue_writer_run_package_review` 在 CLI review 通過後審核 operator run package 草案，檢查 package identity、artifact manifest、operator shell command sequence、candidate/dedupe keys、CLI review id 與 preflight id；API/UI 不產檔、不讀 approval token、不執行 CLI、不開 DB、不寫 queue、不掛 scheduler，只放行到 run readiness review。
- 2026-05-31 追加 MCP fetch candidate queue writer run readiness gate：`services.market_intel.mcp_fetch_candidate_queue_writer_run_readiness` 與 `/api/market_intel/mcp_fetch_candidate_queue_writer_run_readiness` 在 run package review 通過後審核 operator readiness 證據，檢查 run readiness artifact、reviewed sample、備份、read-only preflight、post-write smoke 路徑、操作員覆核確認、CLI-only 與 approval token shell-only 邊界；API/UI 不產檔、不讀 approval token、不執行 CLI、不開 DB、不寫 queue、不掛 scheduler，只放行到後續 run receipt review。
- 2026-05-31 追加 MCP fetch candidate queue writer run receipt review gate：`services.market_intel.mcp_fetch_candidate_queue_writer_run_receipt_review` 與 `/api/market_intel/mcp_fetch_candidate_queue_writer_run_receipt_review` 在 run readiness 通過後審核 operator shell writer run 的 receipt 摘要，檢查 readiness linkage、run package id、候選/dedupe keys、writer output artifact、post-write smoke artifact、backup path、operator confirmations 與 token redaction；API/UI 不讀 receipt 原文、不讀 approval token、不執行 CLI、不開 DB、不寫 queue、不做 post-write query、不掛 scheduler，只放行到 closeout review。
- 2026-05-31 追加 MCP fetch candidate queue writer run closeout review gate：`services.market_intel.mcp_fetch_candidate_queue_writer_run_closeout_review` 與 `/api/market_intel/mcp_fetch_candidate_queue_writer_run_closeout_review` 在 receipt review 通過後審核 operator closeout 摘要，檢查 receipt linkage、closeout artifact、receipt review artifact、post-closeout inventory plan、writer output / post-write smoke / backup manifest、rollback note 與 operator confirmations；API/UI 不讀 receipt 原文、不讀 approval token、不執行 CLI、不開 DB、不寫 queue、不做 post-closeout query、不掛 scheduler，只放行到 read-only post-closeout inventory review。
- 2026-05-31 追加 MCP fetch candidate queue writer post-closeout inventory review gate：`services.market_intel.mcp_fetch_candidate_queue_writer_post_closeout_inventory_review` 與 `/api/market_intel/mcp_fetch_candidate_queue_writer_post_closeout_inventory_review` 在 closeout review 通過後審核 operator live inventory read-only 摘要，檢查 closeout linkage、row count、inventory artifact、closeout review artifact、read-only query result、missing/duplicate rows 與 operator confirmations；API/UI 不讀 approval token、不執行 CLI、不開 DB、不寫 queue、不做 inventory query、不掛 scheduler，只放行到 candidate queue review handoff。
- 2026-05-31 追加 MCP fetch candidate queue writer review handoff gate：`services.market_intel.mcp_fetch_candidate_queue_writer_review_handoff` 與 `/api/market_intel/mcp_fetch_candidate_queue_writer_review_handoff` 在 post-closeout inventory review 通過後審核 operator candidate queue review handoff 摘要，檢查 inventory linkage、handoff identity、target table、row count、artifact paths、review contract、forbidden API actions 與 operator confirmations；API/UI 不讀 approval token、不執行 CLI、不開 DB、不寫 queue、不更新 review_state、不掛 scheduler，只放行到人工 candidate queue review。
- 2026-05-31 追加 MCP fetch candidate queue writer review inventory gate：`services.market_intel.mcp_fetch_candidate_queue_writer_review_inventory`、`services.market_intel.mcp_fetch_candidate_queue_writer_review_inventory_gates`、`services.market_intel.mcp_fetch_candidate_queue_writer_review_inventory_sample` 與 `/api/market_intel/mcp_fetch_candidate_queue_writer_review_inventory` 在 writer review handoff 通過後審核 operator read-only candidate queue inventory 摘要，檢查 handoff identity、target table、row count、dedupe keys、review_state、artifact paths、read-only query result、missing/duplicate rows 與 operator confirmations；API/UI 不讀 approval token、不執行 CLI、不開 DB、不寫 queue、不更新 review_state、不做 inventory query、不掛 scheduler，只放行到後續人工 candidate queue review。
- 2026-05-31 追加 MCP fetch candidate queue writer review decision gate：`services.market_intel.mcp_fetch_candidate_queue_writer_review_decision`、`services.market_intel.mcp_fetch_candidate_queue_writer_review_decision_gates`、`services.market_intel.mcp_fetch_candidate_queue_writer_review_decision_sample` 與 `/api/market_intel/mcp_fetch_candidate_queue_writer_review_decision` 在 review inventory 通過後審核 operator candidate queue review decision 摘要，檢查 decision identity、target table、row count、dedupe keys、`needs_review` 現態、允許決策集合、evidence refs、matched row exact-identity/variant/overwrite guard、operator confirmations 與 forbidden API actions；API/UI 不讀 approval token、不執行 CLI、不開 DB、不寫 decision record、不更新 review_state、不寫 match result、不補 queue、不掛 scheduler，只放行到 decision approval / writer preflight 設計。
- 2026-05-31 追加 MCP fetch candidate queue writer review decision approval gate：`services.market_intel.mcp_fetch_candidate_queue_writer_review_decision_approval`、`services.market_intel.mcp_fetch_candidate_queue_writer_review_decision_approval_gates`、`services.market_intel.mcp_fetch_candidate_queue_writer_review_decision_approval_sample` 與 `/api/market_intel/mcp_fetch_candidate_queue_writer_review_decision_approval` 在 review decision 通過後只審核 operator human approval 摘要，確認 decision linkage、approval identity、target table、row count、dedupe keys、`approved_for_writer_preflight` approval result、decision/approval evidence refs、artifact paths、matched row exact-identity/variant/overwrite guard、operator confirmations 與 forbidden API actions；API/UI 不讀 approval token、不執行 CLI、不開 DB、不寫 approval record、不寫 decision record、不更新 review_state、不寫 match result、不補 queue、不掛 scheduler，只放行到後續 writer preflight 設計。此 endpoint 已拆入 `routes.market_intel_mcp_review_routes`，避免 `routes.market_intel_mcp_run_routes` 超過 800 行治理門檻。
- 2026-05-31 追加 MCP fetch candidate queue writer review decision approval writer preflight gate：`services.market_intel.mcp_fetch_candidate_queue_writer_review_decision_approval_writer_preflight`、對應 gates/sample 與 `/api/market_intel/mcp_fetch_candidate_queue_writer_review_decision_approval_writer_preflight` 在 human approval 通過後只審核 operator writer preflight 摘要，確認 approval linkage、writer_preflight_id、target operation、row count、dedupe keys、approved decision 到 target review_state 的逐列映射、decision/approval/preflight evidence refs、matched row exact-identity/variant/overwrite guard 與 operator boundary；API/UI 不讀 approval token、不執行 CLI、不開 DB、不寫 preflight/approval/decision/match、不更新 review_state、不補 queue、不掛 scheduler，只放行到後續 CLI review / run package 設計。
- 2026-06-01 追加 Professional Source Governance gate：`services.market_intel.mcp_professional_source_governance`、對應 gates/sample 與 `/api/market_intel/mcp_professional_source_governance` 將 robots/REP、sitemap/lastmod、JSON-LD / schema.org structured data、canonical URL、rate limit、公開資料邊界、provenance、snapshot hash 與 idempotency key 整理為 source contract。此 gate 只審核 operator source governance 摘要，不抓外站、不讀 robots/sitemap、不開 DB、不寫檔、不掛 scheduler；後續 fetch target review 才能引用通過治理的公開來源。
- 2026-06-03 追加 Source Governance → Fetch Target bridge：`services.market_intel.mcp_fetch_target_source_governance_review` 與 `/api/market_intel/mcp_fetch_target_source_governance_review` 只交叉審核已通過治理的 source contract 與 MCP Fetch Target Review，要求每個 target `platform_code/source_key` 都命中治理摘要；仍不執行外部 fetch、不讀 robots/sitemap、不開 DB、不寫檔、不執行 CLI、不掛 scheduler。
- 2026-05-18 追加 scheduler attach plan preview：`services.market_intel.scheduler_plan` 與 `/api/market_intel/scheduler_plan` 描述未來 `campaign_discovery_daily`、`campaign_product_probe`、`product_match_review_seed` 三個 job 的 cadence、gate、fallback 與安全邊界。此階段不註冊 scheduler job、不啟動 crawler、不連外、不寫 DB；排程掛載必須等 migration、seed、MCP fetch gate、manual sample 與人工批准全過。
- 2026-05-18 追加 match review plan preview：`services.market_intel.match_review_plan` 與 `/api/market_intel/match_review_plan` 定義商品比對訊號、分數門檻、`needs_review → confirmed/rejected` HITL 流程與安全邊界。此階段不建立 review queue、不自動 confirmed、不寫 `market_product_matches`、不呼叫 MCP；價格只能作為輔助訊號，不能單獨決定同品比對。
- 2026-05-18 追加 opportunity plan preview：`services.market_intel.opportunity_plan` 與 `/api/market_intel/opportunity_plan` 定義競品低價威脅、促銷缺口、深折重疊、活動即將結束四類規則與分級策略。此階段不建立 opportunity queue、不派送 Telegram、不產生 AI 摘要、不寫 DB；高風險項必須先有 confirmed match 與 DB evidence 才能升級。
- 2026-05-18 追加 opportunity scoring plan preview：`services.market_intel.opportunity_scoring` 與 `/api/market_intel/opportunity_scoring_plan` 定義價差、折扣深度、比對可信度、活動急迫性與資料新鮮度五個 scoring dimensions、分級門檻、evidence tables 與人工升級順序。此階段不計分、不產生 sample scores、不建立 scoring job、不寫 DB、不派送 Telegram、不產生 AI 摘要。
- 2026-05-18 追加 opportunity evidence plan preview：`services.market_intel.opportunity_evidence` 與 `/api/market_intel/opportunity_evidence_plan` 定義 scoring / alert / AI 摘要必須攜帶的 campaign、market product、match review、MOMO reference、scoring trace 五段 evidence bundle contract。此階段不查 DB、不產生 sample evidence、不建立 alert candidate、不派送 Telegram、不產生 AI 摘要。
- 2026-05-18 追加 opportunity alert plan preview：`services.market_intel.opportunity_alerts` 與 `/api/market_intel/opportunity_alert_plan` 定義人工審核、每日摘要、Telegram 候選、AI 摘要候選四種 channel 的最低門檻、去重節流、payload contract 與操作順序。此階段不建立 alert queue、不派送 Telegram、不呼叫 LLM、不寫 DB；所有告警必須先有 evidence bundle、dedupe key 與人工批准。
- 2026-05-18 追加 opportunity alert review preview：`/api/market_intel/opportunity_alert_plan` 擴充人工審核狀態與操作，定義 `draft → needs_review → approved_for_digest / approved_for_telegram / rejected / deferred` 流程、審核理由、審核者身分與派送前二次 gate。此階段不建立 review queue、不執行審核動作、不寫 approval record、不派送 Telegram、不呼叫 LLM。
- 2026-05-18 追加 deployment readiness modularization：將 `/api/market_intel/deployment_readiness` 的大型 app-only release gate 組裝邏輯由 `services.market_intel.service` 拆至 `services.market_intel.deployment_readiness`，主服務保留薄入口，避免後續 crawler / MCP / 審核功能推進時超過 800 行治理線；行為仍維持 preview-only，不執行 git、部署、SSH、migration 或 DB write。
- 2026-05-18 追加 alert review queue contract：`/api/market_intel/opportunity_alert_plan` 補上 `market_alert_review_queue` 的 preview contract、required / audit / forbidden fields、priority lanes 與索引規劃。此階段只定義資料契約，不建立 review table、不寫 queue contract、不執行審核、不派送 Telegram、不呼叫 LLM。
- 2026-05-18 追加 alert review queue migration blueprint：`market_alert_review_queue` 納入 `database/market_intel_models.py`、`migrations/032_market_intel_core_schema.sql` 與 migration blueprint，補齊 additive CREATE TABLE / index / grant / rollback draft。此階段仍不執行 migration、不連 DB、不建立 review queue、不寫入審核資料。
- 2026-05-18 追加 migration apply drill preview：`services.market_intel.migration_drill` 與 `/api/market_intel/migration_apply_drill` 集中正式 migration 前的只讀 schema probe、platform seed diff、人工套用清單、post-apply smoke、回滾演練與風險清單。預設 `execute=false` 不連 DB；人工 smoke 可用 `execute=true` 觸發只讀 catalog / seed diff probe，但仍不執行 psql、不跑 rollback、不寫 DB、不重啟容器、不掛 scheduler。
- 2026-05-18 追加 migration catalog review preview：`services.market_intel.migration_catalog_review` 與 `/api/market_intel/migration_catalog_review` 將 schema_db_probe 與 platform_seed_db_diff 的只讀結果歸納為 `planned_no_probe` / `not_applied` / `partial_schema` / `already_applied` / `probe_error`，並輸出 risk level、apply path、finding 與下一步。預設 `execute=false` 不連 DB；`execute=true` 仍只查 catalog / seed diff，不執行 psql、不寫 DB、不跑 rollback、不掛 scheduler。
- 2026-05-18 追加 migration live smoke preview：`services.market_intel.migration_live_smoke` 與 `/api/market_intel/migration_live_smoke` 將 `execute=true` 的正式 DB 只讀探測整理成 smoke result，例如 `passed_not_applied_seed_table_missing`、`attention_partial_schema`、`passed_already_applied` 或 `failed_catalog_probe_error`。UI 預設仍只呼叫 `execute=false`；人工 smoke 可用 `execute=true` 只讀查 catalog，不執行 migration、不寫 DB、不跑 rollback、不掛 scheduler。
- 2026-05-18 追加 live DB inventory preview：`services.market_intel.live_db_inventory` 與 `/api/market_intel/live_db_inventory` 預設 `execute=false` 只回 planned，不連 DB；人工 smoke 可用 `execute=true` 對 `market_*` tables 執行只讀 count / group by，產生平台、活動狀態、商品活躍度、比對狀態、告警審核佇列與 crawler run 基準總覽。此探針不建立 ORM session、不寫 DB、不執行 migration、不連外、不掛 scheduler。
- 2026-05-19 追加 manual sample fetch plan preview：`services.market_intel.manual_sample_plan` 與 `/api/market_intel/manual_sample_plan` 定義第一次人工 sample fetch 的平台順序、每平台 1 個公開入口、MCP fetch gate、正式 DB 庫存基準、操作員步驟與備援。此階段只產生計畫，不抓外部網站、不寫 DB、不建立 crawler run、不掛 scheduler、不繞反爬。
- 2026-05-19 追加 manual sample acceptance contract：`services.market_intel.manual_sample_acceptance` 與 `/api/market_intel/manual_sample_acceptance` 定義 sample fetch 結果回來後的必要欄位、診斷欄位、驗收門檻、拒收條件、人工決策與升級順序。此階段不載入 sample result、不抓外部網站、不允許候選導入、不寫 DB、不掛 scheduler。
- 2026-05-19 追加 manual sample result review：`services.market_intel.manual_sample_review` 與 `/api/market_intel/manual_sample_review` 以純函式評估操作員提供的 sample result 是否通過 Phase 48 驗收門檻並可進候選預覽。API/UI 預設不載入 sample result，不抓外站、不存檔、不寫 DB、不允許候選導入、不掛 scheduler；即使審核通過也只開 candidate preview gate，正式 market_* 寫入仍需後續獨立批准。
- 2026-05-19 追加 manual sample review evaluate：`/api/market_intel/manual_sample_review/evaluate` 提供 POST-only 即時審核入口，操作員可貼入單筆 sample result JSON 取得 PASS/BLOCK 與 candidate preview readiness。此入口不保存 payload、不回吐完整 HTML、不連外、不寫 DB、不建立候選活動、不允許候選導入、不掛 scheduler；invalid JSON 只回診斷錯誤。
- 2026-05-19 追加 manual sample candidate handoff：`/api/market_intel/manual_sample_review/candidate_handoff` 將已通過審核的 sample result 轉成只讀候選活動 handoff payload，包含 candidate key、平台、來源、URL、信心分級、排序與人工審核狀態。此入口保持 CSRF 保護，不保存 handoff、不建立 review queue、不寫 market_*、不允許候選導入、不掛 scheduler。
- 2026-05-19 追加 manual sample candidate queue draft：`services.market_intel.manual_sample_candidate_queue` 與 `/api/market_intel/manual_sample_review/candidate_queue_draft` 將 handoff 候選轉成只讀人工審核 queue draft，包含 queue item key、review priority、review state 與 approval_required。此入口保持 CSRF 保護，不建立正式 queue、不保存草案、不寫 market_*、不自動核准候選、不掛 scheduler。
- 2026-05-19 追加 manual sample candidate queue approval：`/api/market_intel/manual_sample_review/candidate_queue_approval` 將 queue draft 對齊既有 `market_alert_review_queue` 契約，輸出 row preview、必填欄位 gate、寫入 flags、備份與人工批准 gate。此入口保持 CSRF 保護，不建立 approval record、不寫 review queue、不開 DB transaction、不掛 scheduler。
- 2026-05-19 追加 manual sample candidate queue transaction：`/api/market_intel/manual_sample_review/candidate_queue_transaction` 將 queue row preview 轉成 idempotent insert statement preview、payload hash、runtime order 與 rollback plan。此入口保持 CSRF 保護，不開 DB connection、不開 transaction、不 commit、不建立 approval record、不寫 `market_alert_review_queue`。
- 2026-05-19 追加 candidate queue writer CLI gate：`services.market_intel.candidate_queue_writer_cli`、`scripts/market_intel_candidate_queue_writer.py` 與 `/api/market_intel/manual_sample_review/candidate_queue_writer_status` 定義 `MARKET_INTEL_QUEUE_WRITE_APPROVAL` 一次性 token、execute/apply flags、備份、migration smoke 與 rollback gate。此階段只回 writer status，不開 DB connection、不啟用實際 writer、不寫 `market_alert_review_queue`、不掛 scheduler。
- 2026-05-19 追加 candidate queue writer preflight：`services.market_intel.candidate_queue_writer_preflight` 與 `/api/market_intel/manual_sample_review/candidate_queue_writer_preflight` 檢查 transaction preview payload key 到 `market_alert_review_queue` 欄位映射、缺欄與 dedupe unique index。UI 預設 `execute=false` 不連 DB；CLI 明確 `--read-only-preflight` 時也只查 catalog，不寫 DB、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue writer CLI transaction：`scripts/market_intel_candidate_queue_writer.py` 在 CLI-only 情境支援受控 idempotent insert transaction，必須同時通過 transaction payload、read-only preflight、`--execute`、`--apply-real-write`、一次性 approval token、備份確認與 migration live smoke。API/UI 仍不得讀取 approval token、不得開 DB connection、不得寫 `market_alert_review_queue`、不得掛 scheduler；部署 smoke 不執行正式 DB 寫入。
- 2026-05-19 追加 candidate queue writer post-write smoke：`services.market_intel.candidate_queue_writer_postwrite_smoke` 與 `/api/market_intel/manual_sample_review/candidate_queue_writer_postwrite_smoke` 依 transaction preview dedupe key 只讀查詢 `market_alert_review_queue`，供 CLI 真寫入後確認 row 是否落地。UI 預設 `execute=false` 不連 DB；人工 smoke 即使 `execute=true` 也只讀查詢，不寫 DB、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue writer operator drill：`services.market_intel.candidate_queue_writer_operator_drill` 與 `/api/market_intel/manual_sample_review/candidate_queue_writer_operator_drill` 組裝 reviewed sample、備份、read-only preflight、CLI writer、post-write smoke 的操作員順序與 gate。此 drill 只輸出可稽核操作計畫；API/UI 不讀 approval token、不執行 CLI、不連 DB、不寫 queue、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue writer run package：`services.market_intel.candidate_queue_writer_run_package` 與 `/api/market_intel/manual_sample_review/candidate_queue_writer_run_package` 整理正式 CLI 小流量寫入前的 payload manifest、required artifacts、command bundle、operator signoff 與 rollback plan。此 package 只輸出可稽核證據包預覽；API/UI 不產檔、不讀 approval token、不執行 CLI、不連 DB、不寫 queue、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue writer run readiness：`services.market_intel.candidate_queue_writer_run_readiness` 與 `/api/market_intel/manual_sample_review/candidate_queue_writer_run_readiness` 檢查正式 CLI 小流量寫入前的 reviewed sample 路徑、備份路徑、preflight 輸出、migration live smoke、shell-only token acknowledgement 與禁止 token 進 API。此 readiness 只輸出操作員證據缺口；API/UI 不產檔、不讀 approval token、不執行 CLI、不連 DB、不寫 queue、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue writer run receipt：`services.market_intel.candidate_queue_writer_run_receipt` 與 `/api/market_intel/manual_sample_review/candidate_queue_writer_run_receipt` 審核 CLI 小流量寫入後的 writer output、post-write smoke、dedupe key 一致性、artifact 路徑與 token 外洩風險。此 receipt 只輸出安全摘要；API/UI 不回吐 receipt 原文、不讀 approval token、不執行 CLI、不連 DB、不寫 queue、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue writer run closeout：`services.market_intel.candidate_queue_writer_run_closeout` 與 `/api/market_intel/manual_sample_review/candidate_queue_writer_run_closeout` 在 receipt 通過後整理 closeout gate、人工確認與下一階段 promotion 摘要。此 closeout 只允許放行到人工 queue review / read-only inventory；API/UI 不回吐原始 receipt、不讀 approval token、不執行 CLI、不連 DB、不寫 queue、不掛 scheduler。
- 2026-05-19 追加 candidate queue review handoff：`services.market_intel.candidate_queue_review_handoff` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_handoff` 將 closeout 後的 expected dedupe key、review contract、人工操作順序與 forbidden API actions 整理為交接包。此 handoff 不查 DB、不更新 `review_state`、不補寫 missing queue row、不讀 approval token、不掛 scheduler。
- 2026-05-19 追加 candidate queue review inventory：`services.market_intel.candidate_queue_review_inventory` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_inventory` 將 handoff、post-write smoke 與 live DB inventory 串成只讀人工審核庫存檢查。預設不連 DB；人工明確要求只讀查詢時仍不更新 `review_state`、不補寫 queue row、不讀 approval token、不掛 scheduler。
- 2026-05-19 追加 candidate queue review decision：`services.market_intel.candidate_queue_review_decision` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_decision` 將通過 inventory 的 queue row 整理成人工決策草案，限制 next state 為 `confirmed` / `rejected` / `deferred`。此階段不更新 `review_state`、不寫 decision record、不讀 approval token、不掛 scheduler。
- 2026-05-19 追加 candidate queue review decision approval：`services.market_intel.candidate_queue_review_decision_approval` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_decision_approval` 檢查人工決策草案是否可進入下一個 CLI-only transaction preview。此階段不更新 `review_state`、不寫 decision record、不建立 approval record、不讀 approval token、不掛 scheduler。
- 2026-05-19 追加 candidate queue review decision transaction：`services.market_intel.candidate_queue_review_decision_transaction` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_decision_transaction` 將已批准的人工決策整理成 `review_state` update statement preview、payload hash、runtime order 與 rollback plan。此階段不連 DB、不開 transaction、不 commit、不更新 `review_state`、不讀 approval token、不執行 CLI、不掛 scheduler；真正更新只允許後續人工 shell/CLI 寫入窗口。
- 2026-05-19 追加 candidate queue review decision writer CLI gate：`services.market_intel.candidate_queue_review_decision_writer_cli`、`scripts/market_intel_review_decision_writer.py` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_decision_writer_status` 先建立 review_state writer 的 shell-only gate、一次性 token env var、command bundle 與 rollback plan。此階段 writer implementation 保持 disabled；API/UI 不讀 approval token、不執行 CLI、不連 DB、不開 transaction、不 commit、不更新 `review_state`、不掛 scheduler。
- 2026-05-19 追加 candidate queue review decision writer preflight：`services.market_intel.candidate_queue_review_decision_writer_preflight` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_decision_writer_preflight` 檢查 writer status、review_state update payload、狀態轉換與 token 外洩風險。API/UI 即使收到 `execute=true` 或 `apply_real_write=true` 也只回 blocked preview，不連 DB、不執行 CLI、不更新 `review_state`、不 commit、不讀 approval token、不掛 scheduler。
- 2026-05-19 追加 candidate queue review decision writer post-write smoke：`services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_decision_writer_postwrite_smoke` 依 review_state transaction preview 的 dedupe key 只讀查詢 `market_alert_review_queue`，確認人工 CLI 更新後的 `review_state` 是否符合預期。UI 預設 `execute=false` 不連 DB；人工 smoke 即使 `execute=true` 也只讀查詢，不更新 `review_state`、不 commit、不讀 approval token、不掛 scheduler。
- 2026-05-19 追加 candidate queue review decision writer operator drill：`services.market_intel.candidate_queue_review_decision_writer_operator_drill` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_decision_writer_operator_drill` 整理 review_state CLI 更新前後的操作員順序、preflight、post-write smoke、gate 與 rollback plan。此 drill 只輸出可稽核操作計畫；API/UI 不讀 approval token、不執行 CLI、不連 DB、不更新 `review_state`、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue review decision writer run package：`services.market_intel.candidate_queue_review_decision_writer_run_package` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_decision_writer_run_package` 將 review_state transaction、preflight、operator drill、writer gate、post-write smoke、必要 artifact 與 rollback plan 組成正式 CLI 更新前的可稽核 package。此 package 只輸出預覽；API/UI 不寫檔、不讀 approval token、不執行 CLI、不連 DB、不更新 `review_state`、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue review decision writer run readiness：`services.market_intel.candidate_queue_review_decision_writer_run_readiness` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_decision_writer_run_readiness` 檢查 review_state CLI 更新前的 transaction JSON、備份、preflight、shell-only token 與 post-write smoke 計畫是否齊備。此 readiness 只輸出操作員 gate 預覽；API/UI 不寫檔、不讀 approval token、不執行 CLI、不連 DB、不更新 `review_state`、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue review decision writer run receipt：`services.market_intel.candidate_queue_review_decision_writer_run_receipt` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_decision_writer_run_receipt` 審核 review_state CLI 更新後的 writer output、post-write smoke、dedupe key 一致性、artifact 路徑與 token 外洩風險。此 receipt 只輸出安全摘要；API/UI 不回吐 receipt 原文、不讀 approval token、不執行 CLI、不連 DB、不更新 `review_state`、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue review decision writer run closeout：`services.market_intel.candidate_queue_review_decision_writer_run_closeout` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_decision_writer_run_closeout` 在 review_state receipt 通過後整理 closeout gate、操作員 closeout artifact、post-closeout read-only inventory 確認與 promotion 摘要。此 closeout 只允許放行到後續人工/只讀檢查；API/UI 不回吐 receipt 原文、不讀 approval token、不執行 CLI、不連 DB、不更新 `review_state`、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue review decision post-closeout inventory：`services.market_intel.candidate_queue_review_decision_post_closeout_inventory`、`routes.market_intel_review_post_routes` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_decision_post_closeout_inventory` 在 review_state closeout 後整理 post-write smoke、live inventory、dedupe key 與 review_state 結果。此 inventory 只允許只讀驗證；API/UI 不讀 approval token、不執行 CLI、不更新 `review_state`、不寫 DB、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue review completion archive：`services.market_intel.candidate_queue_review_completion_archive` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_completion_archive` 在 post-closeout inventory 後整理 receipt、closeout、inventory、dedupe key、review_state row snapshot 與 artifact path manifest。此 archive gate 只輸出封存預覽；API/UI 不寫檔、不讀 approval token、不執行 CLI、不更新 `review_state`、不寫 DB、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue review archive summary：`services.market_intel.candidate_queue_review_archive_summary` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_archive_summary` 在 review completion archive 後整理可供摘要/報表審核的結構化輸入。此 summary gate 不產生 AI 摘要；API/UI 不呼叫 LLM、不派送 Telegram、不寫檔、不讀 approval token、不執行 CLI、不更新 `review_state`、不寫 DB、不 commit、不掛 scheduler。
- 2026-05-19 追加 candidate queue review AI summary preflight：`services.market_intel.candidate_queue_review_ai_summary_preflight` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_preflight` 在 archive summary 後檢查未來 AI 摘要前置條件、Ollama-first 三主機級聯與 Gemini 備援邊界。此 preflight 不產生 AI 摘要；API/UI 不呼叫 LLM、不派送 Telegram、不寫檔、不讀 approval token、不執行 CLI、不更新 `review_state`、不寫 DB、不 commit、不掛 scheduler；188 不可作為 Ollama 節點。
- 2026-05-19 追加 candidate queue review AI summary run package：`services.market_intel.candidate_queue_review_ai_summary_run_package` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_run_package` 在 AI summary preflight 後整理手動 Ollama 摘要任務包、prompt contract、輸出 schema 與 artifact path contract。此 package gate 不產生 AI 摘要；API/UI 不呼叫 LLM、不派送 Telegram、不寫檔、不讀 approval token、不執行 CLI、不更新 `review_state`、不寫 DB、不 commit、不掛 scheduler；Gemini 僅能作為 Ollama cascade 全失敗後的備援。
- 2026-05-19 追加 candidate queue review AI summary output receipt：`services.market_intel.candidate_queue_review_ai_summary_output_receipt` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_output_receipt` 在 run package 後驗收人工 Ollama 摘要輸出的 schema、`evidence_refs` 與 `model_route`。此 receipt gate 不產生 AI 摘要；API/UI 不呼叫 LLM、不派送 Telegram、不寫檔、不讀 approval token、不執行 CLI、不更新 `review_state`、不寫 DB、不 commit、不掛 scheduler；摘要持久化與 Telegram 派送必須另開後續 gate。
- 2026-05-19 追加 candidate queue review AI summary persistence preflight：`services.market_intel.candidate_queue_review_ai_summary_persistence_preflight` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_preflight` 在 output receipt 後整理未來 CLI-only `market_alert_review_queue.metadata_json.ai_summary_review` persistence contract、payload hash 與 metadata patch preview。此 preflight 不產生 transaction、不寫 summary record、不寫 `metadata_json`、不呼叫 LLM、不派送 Telegram、不讀 approval token、不執行 CLI、不更新 `review_state`、不寫 DB、不 commit、不掛 scheduler；真正持久化與 Telegram dispatch 必須另開後續 gate。
- 2026-05-19 追加 candidate queue review AI summary persistence transaction：`services.market_intel.candidate_queue_review_ai_summary_persistence_transaction` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_transaction` 在 persistence preflight 後產生未來 CLI-only `metadata_json` UPDATE statement preview、parameter preview 與 rollback plan。此 transaction gate 不開 DB、不執行 SQL、不寫 transaction、不寫 summary record、不寫 `metadata_json`、不讀 approval token、不執行 CLI、不更新 `review_state`、不派送 Telegram、不呼叫 LLM、不 commit、不掛 scheduler；真正寫入必須另開 CLI writer gate 與 post-write smoke。
- 2026-05-19 追加 candidate queue review AI summary persistence writer preflight：`services.market_intel.candidate_queue_review_ai_summary_persistence_writer_preflight` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_writer_preflight` 在 transaction preview 後檢查 CLI-only writer contract、`metadata_json` backup requirement、post-write smoke requirement 與 artifact path gate。此 writer preflight 不開 DB、不執行 SQL、不寫 preflight、不寫 summary record、不寫 `metadata_json`、不讀 approval token、不執行 CLI、不更新 `review_state`、不派送 Telegram、不呼叫 LLM、不 commit、不掛 scheduler；真正寫入必須另開 CLI run package、operator readiness、receipt 與 post-write smoke。
- 2026-05-19 追加 candidate queue review AI summary persistence run package：`services.market_intel.candidate_queue_review_ai_summary_persistence_run_package` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_run_package` 在 writer preflight 後整理 payload manifest、CLI command bundle、required artifacts、operator signoff 與 rollback plan。此 run package 不開 DB、不執行 SQL、不寫 run package、不寫 summary record、不寫 `metadata_json`、不讀 approval token、不執行 CLI、不更新 `review_state`、不派送 Telegram、不呼叫 LLM、不 commit、不掛 scheduler；真正寫入必須另開 operator readiness、CLI receipt、post-write smoke 與 closeout。
- 2026-05-20 追加 candidate queue review AI summary persistence run readiness：`services.market_intel.candidate_queue_review_ai_summary_persistence_run_readiness` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_run_readiness` 在 run package 後檢查操作員 artifact path、metadata_json backup、read-only preflight、shell-only token acknowledgement 與 post-write smoke 計畫。此 readiness 不開 DB、不執行 SQL、不寫 readiness artifact、不寫 summary record、不寫 `metadata_json`、不讀 approval token、不執行 CLI、不更新 `review_state`、不派送 Telegram、不呼叫 LLM、不 commit、不掛 scheduler；真正寫入必須由後續人工 CLI 與 receipt/post-write smoke gate 驗收。
- 2026-05-20 追加 candidate queue review AI summary persistence run receipt：`services.market_intel.candidate_queue_review_ai_summary_persistence_run_receipt` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_run_receipt` 審核 metadata_json CLI 寫入後的 writer output、post-write smoke、dedupe key、summary payload hash、artifact path 與 token 外洩風險。此 receipt 只輸出安全摘要；API/UI 不回吐 receipt 原文、不讀 approval token、不執行 CLI、不開 DB、不寫 `metadata_json`、不更新 `review_state`、不派送 Telegram、不 commit、不掛 scheduler。
- 2026-05-20 追加 candidate queue review AI summary persistence run closeout：`services.market_intel.candidate_queue_review_ai_summary_persistence_run_closeout` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_run_closeout` 在 receipt 通過後整理 closeout gate、操作員 closeout artifact、Telegram dispatch separate-gate 確認與 promotion 摘要。此 closeout 只允許放行到後續 Telegram dispatch gate；API/UI 不回吐 receipt 原文、不讀 approval token、不執行 CLI、不開 DB、不寫 `metadata_json`、不更新 `review_state`、不派送 Telegram、不呼叫 LLM、不 commit、不掛 scheduler。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch gate：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate` 在 closeout 後整理 Telegram message contract、channel label、artifact path、token 外洩檢查與下一階段 run package promotion。此 gate 只允許放行到後續 Telegram dispatch run package；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不開 DB、不寫檔、不派送 Telegram、不更新 `review_state`、不 commit、不掛 scheduler。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch run package：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package` 在 dispatch gate 後整理 message contract snapshot、command plan、artifact checklist 與下一階段 readiness promotion。此 run package 只允許放行到後續 Telegram dispatch run readiness；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不開 DB、不寫檔、不派送 Telegram、不更新 `review_state`、不 commit、不掛 scheduler。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch run readiness：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness` 在 dispatch run package 後檢查 message preview、run package、dispatch receipt artifact path、manual command review、Telegram token shell-only 與 no-side-effect 確認。此 readiness 只允許放行到人工 Telegram dispatch 後的 receipt review；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不開 DB、不寫檔、不派送 Telegram、不更新 `review_state`、不 commit、不掛 scheduler。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch run receipt：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt` 審核人工 Telegram 派送後貼回的 message id、channel、summary hash、receipt artifact 與 token 外洩風險。此 receipt 只允許放行到後續 Telegram dispatch closeout；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不補發或重送 Telegram、不開 DB、不寫檔、不更新 `review_state`、不 commit、不掛 scheduler。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch closeout：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout` 在人工 Telegram receipt 通過後整理 closeout artifact、receipt archive、message visibility、duplicate dispatch 與 post-closeout monitoring gate。此 closeout 只允許放行到後續封存/報表 gate；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不補發或重送 Telegram、不開 DB、不寫檔、不更新 `review_state`、不 commit、不掛 scheduler。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch archive：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive` 在 closeout 通過後整理 message id、channel、summary hash、receipt/closeout/message preview/archive artifact path 與 duplicate/monitoring audit manifest。此 archive 只輸出封存預覽並放行到後續 archive summary / 報表輸入 gate；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不補發或重送 Telegram、不開 DB、不寫檔、不更新 `review_state`、不 commit、不掛 scheduler。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch archive summary：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary` 在 archive 通過後整理 message identity、dispatch audit、artifact manifest 與後續 report input 所需 sections。此 archive summary 只準備報表/summary input；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不補發或重送 Telegram、不開 DB、不寫檔、不更新 `review_state`、不 commit、不掛 scheduler，後續報表輸入必須另開 gate。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch report input：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input`、`routes.market_intel_review_report_routes` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input` 在 archive summary 通過後整理 report input sections、report contract、message evidence 與 dispatch audit traceability。此 report input 只準備後續報表 run package；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不補發或重送 Telegram、不開 DB、不寫檔、不產報表、不更新 `review_state`、不 commit、不掛 scheduler，真正報表產製必須另開 gate。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch report run package：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package`、`routes.market_intel_review_report_routes` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package` 在 report input 通過後整理 run package contract、evidence refs、package sections 與後續 report run readiness gate。此 run package 只準備報表執行審核包；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不補發或重送 Telegram、不開 DB、不寫檔、不產報表、不更新 `review_state`、不 commit、不掛 scheduler，真正報表產製必須另開 readiness gate。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch report run readiness：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness`、`routes.market_intel_review_report_routes` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness` 在 report run package 通過後整理 report generation readiness manifest、manual report command boundary、artifact path gate 與後續 report run receipt gate。此 run readiness 只檢查可否進入後續人工/獨立 job 報表產製；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不補發或重送 Telegram、不開 DB、不寫檔、不產報表、不更新 `review_state`、不 commit、不掛 scheduler，真正產出結果必須另開 receipt gate。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch report run receipt：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt`、`routes.market_intel_review_report_routes` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt` 在 report run readiness 通過後審核人工/獨立 job 產出的 report receipt、report artifact path/hash、必要章節、summary hash 與 runtime boundary。此 receipt 只允許放行到後續 market intel report closeout；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不補產報表、不補發或重送 Telegram、不開 DB、不寫檔、不更新 `review_state`、不 commit、不掛 scheduler。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch report closeout：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout`、`routes.market_intel_review_report_routes` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout` 在 report run receipt 通過後審核 closeout artifact、receipt/report artifact path、hash 與章節覆核、archive separate gate 與 runtime boundary。此 closeout 只允許放行到後續 market intel report archive；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不補產報表、不補發或重送 Telegram、不開 DB、不寫檔、不更新 `review_state`、不 commit、不掛 scheduler，後續 report archive 必須另開 gate。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch report archive：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive`、`routes.market_intel_review_report_routes` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive` 在 report closeout 通過後審核 archive/closeout/receipt/report output artifact path、hash 與章節、archive manifest、retention policy 與後續 archive summary separate gate。此 archive 只允許放行到後續 market intel report archive summary；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不補產報表、不補發或重送 Telegram、不開 DB、不寫檔、不更新 `review_state`、不 commit、不掛 scheduler，後續 archive summary 必須另開 gate。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch report archive summary：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary`、`routes.market_intel_review_report_routes` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary` 在 report archive 通過後整理 report identity、archive traceability、integrity review 與 runtime safety sections，僅放行到後續 report catalog handoff gate；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不補產報表、不補發或重送 Telegram、不開 DB、不寫檔、不更新 `review_state`、不 commit、不掛 scheduler，後續 catalog handoff 必須另開 gate。
- 2026-05-20 追加 candidate queue review AI summary persistence Telegram dispatch report catalog handoff：`services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff`、`routes.market_intel_review_report_routes` 與 `/api/market_intel/manual_sample_review/candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff` 在 report archive summary 通過後整理 catalog identity、artifact manifest、section keys 與 hash traceability，僅放行到後續 report catalog index gate；API/UI 不讀 approval/Telegram token、不呼叫 LLM、不補產報表、不補發或重送 Telegram、不開 DB、不寫 catalog record、不更新 `review_state`、不 commit、不掛 scheduler，後續 catalog index / write preflight 必須另開 gate。

### Phase 4：Coupang / Shopee Adapter

- Coupang 先做保守 adapter，初始版本只註冊官方公開入口。
- Shopee 因動態資料與反爬風險較高，初始版本只註冊公開入口並維持更嚴格節流。

### Phase 5：Product Matching + HITL

- 用品牌、規格、容量、關鍵字與現有商品資料計算 match score。
- 低信心進人工審核，不自動合併。

### Phase 6：AI Insight / Telegram

- 只基於 DB 實證資料產生摘要與告警。
- 不做空泛 LLM 建議。
- 高風險告警需包含平台、活動、商品、價差、資料時間與可追溯 run id。

## Alternatives Considered

### 方案 A：直接擴充 `promo_products`

不採用。`promo_products` 偏 MOMO 活動商品語境，無法乾淨承載跨平台活動、商品快照、價格歷史、比對審核與 crawler run log。

### 方案 B：直接塞進 `scheduler.py` 與既有 crawler service

不採用。`scheduler.py` 與多個 crawler service 已達大檔治理門檻，新增跨平台 adapter 會讓排程與錯誤隔離更脆弱。

### 方案 C：先做完整 UI 再補資料

不採用。違反真實資料與真實頁面規範，容易產生假 KPI、假商品與不可診斷狀態。

## Consequences

**正面**

- 市場情報可以獨立演進，不污染業績分析、dashboard、scheduler 既有技術債。
- 每平台 adapter 可單獨停用、測試與回退。
- `market_*` schema 可保留歷史、做趨勢與商品比對。
- AI 告警能基於可追溯 DB run log，降低空泛推論。

**負面**

- 初期開發量比「直接塞舊表」更高。
- 需要新增 schema、service、route、UI 與 scheduler registry。
- Shopee 等平台可能因公開資料穩定性與 rate limit 需要較長探索期。

## Acceptance Criteria

- Phase 0 完成後，不改 runtime 行為。
- Phase 1 完成後，`MARKET_INTEL_ENABLED=false` 時所有新功能完全不影響既有頁面與排程。
- 任一 crawler adapter 失敗不得阻塞既有 MOMO 排程。
- 新市場情報 route 不新增到 `app.py`。
- 任一新 Python 檔若超過 600 行需提出拆分理由，超過 800 行需更新模組化 inventory。
