thread-master/docs/product/opportunity-inbox/plan.md

22 KiB
Raw Permalink Blame History

Plan: 商機工作收件匣與產品需求搜尋

Status: approved Status note: 使用者 2026-08-11「請幫我做」視為批准 plan 並要求進入實作拆解 Source: docs/product/opportunity-inbox/spec.mdapproved 2026-08-11 Requirements: docs/product/opportunity-inbox/requirements.mdapproved 2026-08-11 Baseline: docs/product/brand-product-radar/ T700T762 done Last updated: 2026-08-11

1. 交付策略

  1. 保留已完成的產品雷達底座。 Opportunity、ProductMatch、主推產品、owner來源去重、每日巡邏、mocklive repository 均原地擴充,不另建一套商機或抓取系統。
  2. 先簡化操作,再擴大後端。 Phase A 只固定新增資料語意、跨層契約與舊資料映射Phase B 先用 mock 驗證單一收件匣、完成移除復原、時間排序、DemandMap 與成本確認。使用者未確認這套操作前,不進入 Phase C 大量業務後端。
  3. 先把免費流程做實,再接付費判定。 ReviewState、tombstone、DemandMap baseline、前處理與輕量排序先獨立可測搜尋與 AI 深判最後才接入 CostPreview、CreditCeiling、有效判定快取及既有 usage meter。
  4. 分數不互相偷換。 既有 intent_scoreproduct_fit_score 保留,新 priority_score 專門服務推薦排序;所有分頁排序由後端穩定執行,前端不只重排當頁。
  5. 用漏斗與點數對帳驗收。 每次巡邏必須能對上 hit → dedupe → prefilter → cache → judge → createdmergedtombstonedeferred以及 searchjudge 實際點數;部分完成不能顯示完整成功。
  6. 準確度與成本同時是上線閘門。 前十至少八筆具有真實需求與產品適配證據,且同候選同版本重試不重扣;任一未達標,先修召回、前處理、排序或冪等,不擴 P1 自動學習。

正式 tasks 每題預估約 100200 行 production change測試或文件可較小但不得把 API、repository、worker、頁面與品質閘塞成單一大題。

2. 里程碑

M0 — Phase A契約、相容與測試地基

  • 目標: 固定 ReviewState、DemandMap、CostPreview、PriorityScore、Sweep funnel 的跨層 shape 與舊資料讀法;尚未完成的能力明確回 not-ready不回成功空資料。
  • 完成定義:
    • 盤點並鎖定現有 OpportunityStatus、acceptdismiss、todayopportunities、ProductMatch、Sweep 與 usage 行為,建立不可退化的 baseline tests。
    • 只從 generate/api/radar.api 擴充 review state、需求地圖、cost preview、列表 query、priorityevidence 與 Sweep funnel 契約,再執行 make gen-api;不手寫 handlerroutes。
    • goctl 產生的新 logic 在業務尚未完成前回明確 not-ready不得回 102000 空物件或空陣列。
    • 前端 domain types 與 RadarRepo 加入同一契約mocklive 的方法簽名一致。
    • 建立舊資料 fixtureaccepted→completed、dismissed→removed(legacy_unknown)、其他→pendingsort=score|posted 映射新排序。
    • 定義 ownersourceproductinput/map versionjudge kind 的判定冪等測試鍵,但此里程碑不實作深判業務。
  • 建議 task 區間: T800T806
  • 驗證: spec 驗收 #1、#11、#12、#24 的契約fixture 層generated code 無手改;前後端 compilebuild。

M1 — Phase B單一商機收件匣frontend + mock

  • 目標: 先讓第一次使用者只在一個頁面完成「看證據 → 完成或移除 → 查看/復原」;不接真 API。
  • 完成定義:
    • /app/radar/opportunities 成為唯一商機入口,預設 pendingtodayrecommended/app/radar/today redirect 並保留可理解的 query。
    • 導覽移除第二個商機結果入口today7dall 只作為同頁時間範圍。
    • 卡片首層只顯示問題、主推產品、一段最強證據、分數時間、原文、完成、移除回覆、CRM、其他產品與完整理由放詳情層。
    • mock RadarRepo 支援 pendingcompletedremoved、移除原因、復原前狀態、legacy mapping、tombstone 再命中。
    • 支援 recommendednewestoldestproduct_fitdemand_intent 與穩定分頁;未知 posted_at 在 newestoldest 均置底。
    • filter、sort、time scope、page 寫 URLloading、error、各種 empty reason、操作失敗 rollback 均有明確狀態。
    • 完成、移除、復原的 mock 用量保持 0加入 CRM 成功後自動 completed但單純完成不建 Contact。
  • 建議 task 區間: T810T819
  • 驗證: spec 驗收 #1#5、#11、#12、#24頁面 keyboardmobile 走查;前端 testbuildlinttoken check。

M2 — Phase B需求地圖、探索成本與巡邏漏斗frontend + mock

  • 目標: 在任何付費後端開發前,驗證使用者能看懂「系統準備找什麼、可能花幾點、結果為何被排除或延後」。
  • 完成定義:
    • /app/radar/watches 或其產品詳情提供 DemandMap 五類內容、來源 basis、完整度、AIuserproduct origin 與 stale待確認狀態。
    • 免費 baseline、人工新增啟停 phrase 與版本衝突用 mock 完整走通;產品只有名稱時明確 incomplete 並阻擋新巡邏。
    • QueryPlan 摘要顯示 16 組使用者語言;純品牌/產品名不能單獨成查詢組。
    • AI enrichment、手動 sweepexplore 與回覆按鈕在需要的位置顯示固定點數或範圍;變動成本先開 CostPreview 確認。
    • mock CostPreview 覆蓋 platformBYOK、過期、版本變動、餘額不足與 ceiling 小於固定成本。
    • mock Sweep 結果顯示 hit、dedupe、prefilter passreviewreject、cache、judge、createdmergedtombstone、deferred 與 credit breakdown。
    • complete / partial_budget / blocked_budget / failed 的文案與下一步可辨識,不用成功空畫面代替。
  • 建議 task 區間: T820T829
  • 驗證: spec 驗收 #6、#7、#13#15、#19、#20、#22人工走查能在執行前回答最多花幾點完成後回答點數花在哪裡。
  • 硬閘門: M1M2 未取得使用者 UX 批准前,不得開始 M3M6 的業務後端。

M3 — Phase CReviewState、軟移除與穩定列表

  • 目標: 把 Phase B 已批准的收件匣工作狀態接到可信 domain、repository 與 live API保持既有業務狀態相容。
  • 完成定義:
    • Opportunity domain 加 ReviewState、previous state、移除欄位與 review auditOpportunityStatus 保留原語意。
    • memoryMongo repository 實作 idempotent 狀態更新、append-only audit、duplicate target owner 驗證與 tombstone merge。
    • 缺 review 欄位的舊文件讀時映射,不要求全庫回填;首次更新才持久化。
    • accept 在 Contact binding 與 completed 之間維持一致成功邊界;舊 dismiss 保存 reason 或 legacy_unknown。
    • list 支援 review state、time scopefrom-to、新五種 sort、priority band 與 server-side 穩定 pagination未知時間置底。
    • /today 使用新列表語意提供相容結果;新 UI 不再依賴 today 專屬商業邏輯。
    • migration索引只加入必要查詢與 audit 支援,保留 owner來源唯一性。
  • 建議 task 區間: T830T839
  • 驗證: domainmemoryMongo parity、owner isolation、race 與 API integrationspec 驗收 #1#5、#11、#12、#24。

M4 — Phase CDemandMap、版本與 CostPreview

  • 目標: 以產品真相建立可追溯需求地圖,並在 provider 執行前完成成本預估、版本確認與 ceiling gate。
  • 完成定義:
    • DemandMap domain 定義五類 phrase、basis、origin、enabled、inputmap version、readyincompletestale 不變量。
    • baseline 只讀 BrandProduct 受眾、痛點、情境、能力、匹配與排除內容,免費建立;不得因開頁或排程自動呼叫 AI。
    • input version 只對實質搜尋內容變更名稱圖片等顯示修改不改版。產品內容變更後AI phrases 失效、user phrases 標待確認。
    • memoryMongo repository 支援 current map、舊版本解釋、optimistic version conflict 與 owner 隔離。
    • QueryPlan 產生 16 組合法短詞與排除訊號,保存使用版本與摘要。
    • CostPreview 對 enrichment、manual sweepexplore、批次判定與回覆回固定範圍、key mode、餘額、期限及依據取得 preview 不扣點。
    • preview 使用時驗證 owner、action、context version、expiry、remaining credits 與 ceiling不合格時 provider 不被呼叫。
    • AI enrichment 走既有 meter 與新 radar.demand_map source結構basis 驗證成功才切 current map 並 commit失敗保留舊 map 且不重複扣。
  • 建議 task 區間: T840T849
  • 驗證: spec 驗收 #6、#7、#13、#17、#20#22usage event 可與 action 對帳BYOK credits=0。

M5 — Phase C候選前處理、推薦排序與判定快取

  • 目標: 把昂貴 AI 判定縮到真正高價值或不確定候選,並讓推薦排序比產品名/關鍵字命中更貼近產品痛點。
  • 完成定義:
    • 建立可純測試的 candidate preprocessing來源正規化去重、基本有效性、產品排除、provider廣告公告雜訊、DemandEvidence 抽取、產品證據與 passreviewreject。
    • 每個 rejectreview 保存 machine reason 與 Sweep counterreject 不進 AI不建立高低商機。
    • 輕量 ranking 在 provider 呼叫前排序review 只可低順位或在 ceiling 內抽樣深判,不能直接進 high。
    • AI judge 輸出可驗證原文 excerpt、DemandMap產品 basis、風險與 priority factors缺欄位、找不到引文或 basis 不存在即失敗。
    • priority_score=45 pain fit + 25 demand intent + 15 evidence quality + 15 freshness,並落實 high hard gates。
    • JudgmentResult 以 ownersourceproductinput/map versionkind 唯一;有效 acceptedrejected 都可復用,失敗不進快取。
    • 逐筆 usage commit 與結果保存具冪等關聯;同候選跨 watchquery、HTTP 重試或 worker 重跑不重扣。
    • 建立口語改寫、純名稱、同業銷售、公告、泛討論、未知時間、重複來源與真正求助的固定 fixture。
  • 建議 task 區間: T850T859
  • 驗證: tablefixtureAI structured outputconcurrency testsspec 驗收 #8#12、#15#18、#21、#23。

M6 — Phase C巡邏整合、續跑、live UI 與完整點數對帳

  • 目標: 把 DemandMap、前處理、快取、深判與新收件匣接回每日手動巡邏完成真實可操作的 P0。
  • 完成定義:
    • radar_sweep 保存 system preview、DemandMapQueryPlan 版本按搜尋→前處理→cache→judge→persist 執行。
    • API search 成功 0 hit 仍按既有規則計 search前處理 reject 不計 AI有效 rejected judge 正常計 AI無效 AI 結果走失敗退點語意。
    • 每完成一筆保存 guarded checkpoint中斷後只續未完成唯一鍵。Redis lock value 保持 workerID晚到 worker 不覆寫終態。
    • CreditCeiling方案額度用完後停止新 provider 呼叫,保留已完成結果並寫 deferredwatch 不刪除、不封存。
    • removed tombstone 再命中只合併來源Sweep 增加 tombstone count不新建、不恢復、不重判。
    • Sweep API 與 UI 可對帳所有 funnel counts、status、faileddeferred reason 與 searchdemand mapjudgereply credits。
    • Phase B 頁面切 live repositorymocklive contract tests 使用同一組 fixturesloading、not-ready、conflict、quota、partial、empty reason 行為一致。
    • 完成跨層流程:產品資料 → DemandMap → previewceiling → sweep → prefilterjudge → 收件匣排序 → 完成/移除/復原 → usage 對帳。
  • 建議 task 區間: T860T869
  • 驗證: spec 驗收 #1#22、#24 的 live pathintegration、race、restart tests前後端全套 buildtest。

M7 — Phase D品質閘、成本回歸與安全上線

  • 目標: 以代表性資料證明搜尋更貼近產品且成本可控,再收斂相容路徑、文件與既有回歸。
  • 完成定義:
    • 建立人工標註集與可重跑 evaluation有效需求、口語同義、產品不適合、provider、廣告、公告、泛討論、stale、unknown time、duplicate。
    • recommended 前十至少八筆同時具備 DemandEvidence 與產品證據provider公告純名稱命中不得為 high。
    • 比較 baseline 關鍵字排序與新 pipeline 的 precision@10、AI judged ratio、每筆有效商機平均 credits未達品質或成本閘不宣告完成。
    • 多 worker、provider retry、HTTP retry、跨 watchquery、產品僅改名與產品實質改版的防重扣回歸全部通過。
    • 回歸 generic radar、ProductMatch、主推產品、回覆、CRM、Scout、Outbox、usage soft caps、BYOK、通知與舊 Opportunity。
    • /today redirect 與舊 API 相容性保留一個版本週期;文件記錄移除條件,不在本周期直接刪 API。
    • 更新 testinggaps操作說明明列 P1批次操作、每產品 ceiling、移除原因調校、產品成本報表。
    • brand-product-radar T773T775 共用 accuracyraceregression 驗收資產tasks 階段交叉引用一次實作,不複製兩套 fixture 與指令。
  • 建議 task 區間: T870T879
  • 驗證: spec 驗收 #16#23、requirements 成功標準全表;全 repo testbuildlinttoken check 綠。

3. 依賴與硬閘門

brand-product-radar T700T762已完成底座
  └─► M0 Phase A 契約/相容
       └─► M1 Phase B 收件匣 mock
            └─► M2 Phase B DemandMap成本 mock ──【使用者 UX 批准】
                 ├─► M3 Phase C ReviewState列表
                 └─► M4 Phase C DemandMapCostPreview
                       M3 ─┐
                       M4 ─┴─► M5 Phase C 前處理/排名/快取
                                  └─► M6 Phase C sweeplive ──【P0 live 驗收】
                                       └─► M7 Phase D 品質/成本/回歸
關係 原因
baseline → M0 新能力沿用現有 ProductMatch、主推產品、去重與 usage不重做底座
M0 → M1M2 mock 與 UI 必須使用批准後的共用 shape、legacy mapping 與錯誤語意
M1M2 → M3M6 硬性: 前端mock 操作未批准,不大寫業務後端
M3 ↔ M4 可在 UX gate 後分開進行;兩者只透過已凍結契約相遇,不互相直接依賴 repository
M3M4 → M5 前處理結果需保存到商機/判定快取,且需要 DemandMap 版本與 basis
M5 → M6 worker 不可自己重寫另一套前處理、排序或計費判斷
M6 → M7 accuracy 與成本只能用真 pipeline、真 funnel 語意驗證
T773T775 ↔ M7 舊待辦與本計畫最後閘門範圍重疊;正式 tasks 只建立一次共用輸出並同步兩邊狀態

4. 風險與緩解

風險 緩解
ReviewState 與既有 accepteddismissed 混義 M0 鎖 legacy mappingM1 先驗證用語M3 保持兩個狀態機獨立accept 只做明確同步
合併頁面反而塞更多資訊 M1 首層固定七項資訊,其餘進詳情;以第一次使用者走查作 Phase B 硬閘
removed 後相同貼文再次出現 M3 tombstone 沿用 owner來源唯一鍵M6 sweep 專測再命中只 merge
移除一次就污染後續搜尋 P0 只保存原因,不立即 AI 調校P1 批次建議仍需人工確認
DemandMap 成為第二份產品真相 phrase 必須有 basisbaseline 由 Product 建立AIuser 只作可辨識擴充;產品實質變更會改版
產品改名造成重判重扣 DemandInputVersion 排除顯示欄位M4M7 專測名稱修改不改版
廣召回造成 AI 成本暴增 M5 先免費前處理與 cache再在 ceiling 內 shortlistM7 比較 judged ratio 與每筆有效商機成本
前處理過嚴造成完全找不到 reject 與 review 分開review 可低順位保留或抽樣深判Sweep 保存每階段原因供抽查
CostPreview 顯示假精準 固定成本顯示確值,候選未知顯示 min/max 與依據;版本或餘額變動即失效重估
provider 成功但後續中斷造成雙扣 M5 有效判定唯一鍵usage 關聯M6 逐筆 checkpoint重跑只續未完成鍵
ceiling 競態被多 watch 突破 owner 當日額度在 provider 前 guarded 檢查M6M7 多 worker race 測試
server 與前端排序不一致 M0 共用 enumM3 server-side stable sortmocklive contract 使用相同 fixture
goctl 產生空 logic 被當成功 M0 每個新 logic 先明確 not-ready只改 .api 後 gen業務只在 logicmodule
舊工作樹已有相關修改 tasks 實作前逐檔比對現況,保留使用者變更;禁止用 resetcheckout 覆蓋,重疊無法安全拆分時停下回報

5. 刻意不做(本 plan 週期內)

  • 不實作 P1 的批次完成/移除、每產品 CreditCeiling、移除原因自動調校與產品成本儀表板。
  • 不因每次完成或移除即時呼叫 AI也不自動修改 Product、Brand 或 DemandMap。
  • 不提供 Opportunity 不可逆硬刪除,不封鎖作者,不刪除來源內容。
  • 不新增 usage meter、不修改 FreeStarterPro 售價,不重做 StripeBYOKprovider 抽象。
  • 不重做 Threads APIcrawler、排程器、CRM、Outbox、通知或成果歸因。
  • 不用 priority score 取代既有 intentproduct fit 歷史欄位。
  • 不保證公開發文者有預算、身分真實或一定購買;只判斷公開需求與產品證據。
  • 不在本週期移除舊 /api/v1/radar/today 或 dismiss API只提供相容映射與 UI redirect。

6. 驗證策略與指令

6.1 前端里程碑

cd apps/web
npm run test
npm run build
npm run lint
npm run check:tokens

6.2 API 契約或 generated code 變更

cd apps/backend
make gen-api
go test ./internal/logic/radar/... ./internal/module/radar/... -count=1
make build

6.3 Phase C 整合與競態

cd apps/backend
make test-integration
go test ./internal/module/radar/... -race -count=1
go test ./... -count=1

6.4 Migration 驗證

只使用明確的獨立測試資料庫,不對預設開發資料庫執行:

cd apps/backend
RADAR_INBOX_TEST_MONGO_URL=mongodb://127.0.0.1:27017/thread_master_opportunity_inbox_test
MONGO_URL="$RADAR_INBOX_TEST_MONGO_URL" make migrate-up
MONGO_URL="$RADAR_INBOX_TEST_MONGO_URL" make init

6.5 品質與成本閘

正式 task 需提供固定 evaluation 指令,至少輸出:

precision_at_10
high_without_required_evidence
provider_or_announcement_in_high
ai_judged_ratio
credits_per_valid_opportunity
duplicate_judgment_or_charge_count

通過條件:precision_at_10 >= 0.8、兩種 high 違規數皆為 0、重複判定扣點數為 0AI judged ratio 與每筆有效商機 credits 先記 baseline再由實際成本資料決定 P1 預算優化目標,不在 P0 捏造門檻。

6.6 里程碑驗收摘要

M 額外驗收
M0 舊 fixture 可讀;新 logic 未完成不回成功空資料goctl 產出乾淨
M1 一個頁面完成處理流程today redirect五種排序與 URL 狀態正確;操作不扣點
M2 DemandMap 與 QueryPlan 看得懂執行前知道成本範圍partialblocked 不裝完整成功;取得 UX 批准
M3 reviewbusiness state 不混tombstone 不重建memoryMongoAPI 行為一致
M4 inputmap version 正確preview 免費且會過期provider 前 ceiling gateenrichment 失敗不覆蓋
M5 provider公告純名稱不進 highreject 不問 AI有效 acceptedrejected 都能防重復用
M6 中斷可續、budget partial 可對帳mocklive 行為一致;完整 P0 流程可展示
M7 precision@10 過 0.8high 違規 0duplicate charge 0全 repo 回歸綠

7. Task 號段總表(供下一階段拆 task

區間 Phase / Milestone 內容
T800T806 A / M0 baseline tests、goctl 契約、not-ready、FE typesrepo、legacysort fixtures、冪等鍵契約
T810T819 B / M1 單一入口、收件匣 layout、review mock、完成移除復原、時間排序、URLemptymobile tests
T820T829 B / M2 DemandMap mock、phrase editor、QueryPlan、CostPreview、付費確認、Sweep funnel點數、UX gate tests
T830T839 C / M3 review domainaudit、memoryMongo、migration、tombstone、acceptdismiss 相容、列表 API排序
T840T849 C / M4 DemandMap domainrepo、版本、baselineQueryPlan、CostPreview、enrichment、meterBYOK
T850T859 C / M5 preprocessor、evidence、disposition、priority scorer、AI judge、JudgmentResult cache、冪等計點、fixtures
T860T869 C / M6 sweep pipeline、checkpointresume、budget partial、counters、live repopages、跨層 P0 integration
T870T879 D / M7 標註集、precision成本 evaluation、raceretry、相容與全回歸、文件rollout

正式拆 tasks 時,每題必須包含 Goal、Depends on、Inputs、Outputs實際路徑行為、Out of scope、Acceptance commands、對應 spec 驗收編號。M1M2 tasks 只能做 frontendmockM3 之後才可寫業務後端。與 brand-product-radar T773T775 重疊的測試輸出只能建立一份並由兩邊索引交叉引用。

8. 批准

  • Plan 已批准2026-08-11使用者
  • 批准後下一步:建立 tasks/INDEX.md 與各 T8xx task 文件;不在同一輪開始實作。