thread-master/docs/product/demand-radar/spec.md

32 KiB
Raw Blame History

Spec: 商機雷達+成交 CRM

Status: approved
Status note: 使用者 2026-07-31「好」spec 通過)
Source: docs/product/demand-radar/requirements.mdapproved 2026-07-31
Last updated: 2026-07-31
底座:docs/product/haixun-backend/spec.md海巡雙路徑、Outbox、用量 BYOKdocs/product/growth-loop/spec.mdOutcomeEvent 歸因、AccountHealth 送出閘);本 run 為加值層
決策對齊requirements §6 命名決策、§7 決策 #1#12

1. 摘要

本規格定義「服務者每天收到一份『正在找你的人』名單,並追到成交」的對外行為契約

P0 服務檔案 → 雷達訂閱與每日自動巡 → 商機五問判定與意向分數 → 今日商機頁 → AI 回覆五版本 → 聯絡人與 CRM 七階段(+待追蹤標記)→ 追蹤提醒 → 轉換統計 → 方案配額掛載。 P1 手動匯入商機、報價與成交金額、價格帶校準。 P2只鎖邊界 LINE 官方帳號、Google 商家評論、網站表單、自有留言私訊收斂、空檔媒合。 不做: 重做海巡抓取與發文主流程、重做付費流程、重量級 CRM、自動判定成交。

2. 名詞與實體

名詞 定義
ServiceProfile 服務檔案:服務項目、價格區間、代表案例、不能說的內容、常見問題、服務地區、可接案空檔。判定與回覆生成的共同輸入
RadarWatch 雷達訂閱:常駐關鍵字監控設定(關鍵字、地區條件、排除詞、啟用狀態)
RadarSweep 一次每日巡的執行紀錄:對應一個 Job記錄掃描詞、命中數、判定數、成本與截斷情形
Opportunity 商機:一筆經五問判定、值得跟進的需求訊號,帶 intent_scoreintent_band、判定理由
ReplyVariant 商機下的一個回覆版本(公開留言/私訊/不帶銷售感/專業/幽默)
Contact 聯絡人:跨貼文聚合的人,鍵為(來源平台+作者帳號+擁有者)
ContactTouch 聯絡人時間軸上的一則接觸紀錄(狀態變更、送出回覆、備註、成交回報)
FollowUp 追蹤提醒:到期未回應時進站內通知,可產生 AI 追蹤訊息
五問 需求真實性、購買意圖、地區符合、需求時效、服務匹配度

沿用底座(不重定義): Member、ThreadsAccount、ScoutPostoutreach_status、BrandProduct、OutboxBundle/Step、Persona、Usage/PlanFreeStarterPro、Job、Notification、OutcomeEventAttributionLink、AccountHealth。

命名紅線: 全域禁用 lead 指稱銷售線索(既有語意為 ThreadPlay 主帳號)。

3. 狀態機

3.1 RadarWatch

active --> paused      : 使用者暫停(不再排入每日巡)
paused --> active      : 恢復
active|paused --> archived : 軟刪;歷史商機保留
  • archived 的 watch 不再產生新商機,但既有商機與統計不刪除
  • 超過方案 watch 上限時禁止新增 active(明確錯誤),既有超額者維持不變不強制降級。

3.2 Opportunity判定與收單

(sweep 命中) --> judging      : 進入五問判定
judging --> qualified          : 通過硬否決,得 intent_score 與 band
judging --> rejected           : 硬否決(非真實需求/同業叫賣/逾期/地區明確不符且不可遠端)
qualified --> accepted         : 使用者「加入名單」→ 綁定或建立 Contact
qualified --> dismissed        : 使用者略過
rejected --> qualified         : 使用者手動覆寫(記錄覆寫)
accepted --> (CRM 由 Contact 接手)
  • 硬否決條件(不計分直接 rejected 五問第一問「是不是真實需求」為否;既有分類為 provider_offerannouncementnoise;貼文發布距今 > 14 天。
  • rejected 仍入庫可查(避免誤殺無法回溯),但預設不出現在今日商機頁。
  • 使用者覆寫 intent_band 或把 rejected 拉回 qualified 時,寫入 override(原值、新值、時間、操作者)——這是後續校準判定的素材。

3.3 意向分數與分級

intent_score = 需求真實性 30 + 購買意圖 30 + 地區符合 15 + 需求時效 15 + 服務匹配度 10
band: high >= 80 | mid 5079 | low < 50
  • 每個維度必須輸出分數與人話理由reasons[] 缺任一維度不得入庫。
  • 地區三態:matchmismatchunknownunknown 得部分分(不等同 mismatch),且禁止猜測縣市。ServiceProfile 標記可遠端服務時,mismatch 不觸發硬否決且地區維度給滿分。
  • 時效:距今 ≤ 24h 給滿分2472h 遞減72h14 天低分,> 14 天硬否決。

3.4 Contact CRM 階段

七個互斥階段 一個並存標記畫面上呈現為八格requirements 決策 #5

stage: new_found --> engaged --> dm_sent --> replied --> quoted --> won | lost
  • 允許任意跳轉(含回退、跳級);每次轉移寫一筆 ContactTouch(來源階段、目標階段、時間、操作者)。
  • wonlost 為終態但可重新開啟(轉回任一階段,同樣留痕)。
  • needs_follow_upboolean 標記,可與任何階段並存,非階段值。
  • won 必須由人確認;系統永不自動判定成交

3.5 FollowUp

scheduled --> notified   : 到期 → 站內通知
notified --> done        : 使用者處理(回覆/推進階段/手動關閉)
notified --> snoozed     : 延後 N 天 → 回到 scheduled
notified --> escalated   : 已通知達上限次數 → 建議轉 lost僅建議需人確認
  • 預設:無回應 3 天觸發,最多通知 2 次,天數可由使用者調整。
  • escalated 不自動改階段、不自動關閉。

4. 使用者流程(行為)

4.1 服務檔案P0

  1. 使用者填寫:services[](項目+價格區間)、cases[]forbidden[](不能說的內容)、faq[]service_areas[](縣市代碼;可勾「可遠端」)、availability(可接案空檔文字)、tone_note(語氣備註)。
  2. 服務檔案每會員一份(非多份),可隨時修改;修改不回溯既有商機的判定結果。
  3. 未建立服務檔案時:禁止建立 active 的 RadarWatch並在雷達頁引導先建檔避免判定缺乏依據而產生垃圾名單
  4. forbidden[] 為回覆生成的硬性過濾§4.5)。

4.2 雷達訂閱與每日自動巡P0

  1. 使用者建立 RadarWatchterms[](關鍵字)、exclude_terms[]regions[](可留空=沿用服務檔案)、enabled
  2. 系統可依服務檔案建議關鍵字POST /api/v1/radar/watches/suggest),使用者可全採用或逐條增刪。這是 P0 上手體驗的一部分requirements 開放問題 #1
  3. 每日排程: 每日 UTC 22:00(=台北隔日 06:00為所有 active watch 建立 radar_sweep Job讓使用者早晨打開即有名單。多台 worker 以既有 Redis lock 模式確保只跑一台。時區個人化為 P2。
  4. 巡的路徑沿用既有海巡雙路徑分流:會員 dev_mode_enabled=false 走 API 路徑,true 走瀏覽器工作階段路徑。不新增第三種抓取方式。
  5. 命中 → 逐筆五問判定§4.3)→ 寫入 Opportunity。
  6. 配額截斷: 當日商機數達方案上限時,依 intent_score 由高至低保留,其餘不建立,並在 RadarSweep 記 truncated_count今日頁明確提示「已達今日上限N 筆較低意向未收錄」。不得靜默丟棄。
  7. 使用者可對單一 watch 手動觸發即時巡(POST /api/v1/radar/watches/:id/sweep),受每日配額同一個池子約束。
  8. 降級: 抓取路徑不可用時Sweep 記 failed 與原因並發通知;禁止回成功空資料。

4.3 五問判定P0

  1. 輸入貼文全文與中繼資料作者、發布時間、permalink、ServiceProfile、觸發的 watch 關鍵字。
  2. 沿用既有分類結果(seeking_helpseeking_recommendationprovider_offerdiscussionaskingannouncementnoise)作為第一問的主要依據,不重做分類器
  3. 輸出:intent_scoreintent_bandreasons[](五維度各一條人話理由)、region_detectedregion_matchfreshness_hoursmatched_service(對到哪個服務項目)。
  4. 硬否決者寫 rejectedreject_reason,仍入庫。
  5. 判定計入既有 ai_research metersourceradar.judge§5.5)。

4.4 今日商機頁P0

  1. 頂部統計:今日找到 N 筆高意向 A ・中意向 B ・低意向 C
  2. 卡片欄位:原文摘要、intent_scoreintent_band badge、region_detected、發布距今時間(由 posted_at 前端換算,後端只給 ns 時間)、預設回覆(公開留言版)
  3. 卡片動作:開啟原文permalink 新分頁)、加入名單(→ accepted,綁定或建立 Contact產生其他回覆(→ 生成其他版本)、略過(→ dismissed)、看判定理由(展開 reasons[])、覆寫分級
  4. 空狀態:當日 0 筆時不得顯示空白須給明確原因尚未到巡的時間watch 全部暫停/關鍵字太窄的建議/抓取失敗)與下一步動作。
  5. 低意向預設收合,可展開。

4.5 AI 回覆五版本P0

  1. 版本枚舉:public_commentdmno_salesprofessionalhumorous
  2. 首次判定時只生成 public_comment成本控制requirements 決策 #6其餘按需生成。
  3. 輸入Opportunity 原文、ServiceProfile服務項目、價格區間、案例、FAQ、語氣備註、active Persona若有
  4. forbidden[] 硬性過濾: 生成後檢查,命中則自動重生一次;仍命中則不輸出並回明確錯誤(非 102000不得輸出違規內容。
  5. 回覆生成計入既有 ai_copy metersourceradar.reply
  6. 送出沿用既有管道公開留言版走既有海巡外展送出Outbox私訊版 P0 僅提供複製Threads 無私訊 API複製後由使用者手動送出並回頭標記。
  7. 送出前必經既有 AccountHealth 送出閘warn 帶警示、throttle 拒絕自動送出僅留手動路徑。本 run 不新增繞過 護欄的路徑。

4.6 加入名單與 CRMP0

  1. 「加入名單」時依(source_platformauthor_handleowner_uid)尋找既有 Contact命中則掛上未命中則建立初始 stage=new_found
  2. 同一人多筆商機收斂在同一 Contact 下,時間軸可看到全部接觸歷史。
  3. 跨平台不自動合併;提供手動 mergeunmerge,合併保留兩邊時間軸。
  4. CRM 列表以 Contact 為單位,可依階段、needs_follow_up、意向分數、最後接觸時間篩選排序。
  5. 階段推進、備註、標記待追蹤皆寫 ContactTouch
  6. 成交回報:填金額(選填)與備註 → 階段轉 won寫入既有 OutcomeEventsource_type=radar_opportunity,連 opportunity_idcontact_id),不另建成交帳。可事後修改/刪除並留痕。

4.7 追蹤提醒P0

  1. 商機送出回覆或階段進入 engageddm_sent 後,建立 FollowUpdue_at = 最後接觸 + N 天(預設 3
  2. 日排程 radar_followup_scan 掃到期 → 站內通知(沿用既有 notificationsref_type=contact)。
  3. 通知落地頁為該 Contact 詳情;提供「產生 AI 追蹤訊息」(計入 ai_copysourceradar.followup)。
  4. 階段推進到 replied 以後或使用者手動關閉 → FollowUp done
  5. 通知達 2 次仍無動作 → escalated,在 CRM 顯示「建議轉未成交」,需人確認

4.8 轉換統計P0

  1. 維度:
    • 關鍵字轉換率:以 watch 的 term 為單位,won 數 / accepted 數,附 accepted、replied、won 絕對數。
    • 回覆版本成功率:以 variant 為單位,(replied + won) / used
    • 成交來源radar既有海巡手動匯入 的成交筆數與金額。
  2. 樣本不足不下結論: 任一維度樣本 < 5 時只顯示原始數字並標「樣本不足」,不顯示排名或百分比結論(沿用既有 benchmark 的謹慎原則)。
  3. 金額來源為手動回報P1 起有金額維度P0 先以筆數呈現。

4.9 方案配額P0

  1. 配額維度:max_active_watchesmax_daily_opportunities。AI 判定與回覆另計入既有點數 meter不重複收費。
  2. 建議值plan 階段可調,行為鎖定):
方案 max_active_watches max_daily_opportunities
Free 1 5
Starter 5 30
Pro 20 100
  1. 超限行為:新增 watch 超限 → 明確錯誤並提示升級;當日商機超限 → §4.2 第 6 點截斷並提示,每日巡不因此停止
  2. 點數耗盡時:判定與回覆生成走既有 platform gate 的既有行為BYOK 者不受平台額度限制);每日巡本身不因點數耗盡而刪除 watch

4.10 既有海巡命中升級為商機P0

  1. 既有海巡命中列表新增動作「升級為商機」。
  2. 決策:複製,不共用requirements 開放問題 #5。建立新的 Opportunity 並記 source_scout_post_id 反向連結,兩邊狀態機互不影響,避免 outreach_status 與 Opportunity 狀態互相污染。
  3. 升級後跑同一套五問判定,進同一條 CRM。
  4. 既有海巡三模式(productthemeactivity)與品牌/產品模型原樣保留,不修改其行為。

4.11 P1P2 邊界

能力 波次 行為邊界
手動匯入 P1 貼 ThreadsFacebook 貼文網址或 CSV → 建 Opportunity → 跑同一套判定;來源標 manual_import
報價與成交金額 P1 quotedwon 可填金額幣別預設 TWD寫既有 OutcomeEvent
價格帶校準 P1 依 P0 每會員雷達成本數據決定是否調 StarterPro 價格;本 run 不改價
LINE 官方帳號 P2 私訊建立/更新 Contact進同一 CRM
Google 評論/網站表單 P2 只做自有與公開來源,不碰第三方私有資料
空檔媒合 P2 依 ServiceProfile availability 對高意向商機提示可約時段

5. 介面契約

5.1 共通

  • 沿用 haixun-backend:成功 code=102000pagepageSizepaginationlist;時間 unix nanoseconds UTCuid 數字。
  • AuthBearer JWT資源擁有者 = 登入 uid全部 API 以 owner_uid 隔離。
  • 後端一律 goctlgenerate/api/*.apimake gen-api → 業務只寫 internal/logic/**internal/module/**
  • 禁止未實作回成功空資料。

5.2 API 能力分組

兩個新 group前綴不與既有 /api/v1/scout 衝突。

Group Method Path 用途
radar GET / PUT /api/v1/radar/service-profile 讀/寫服務檔案(每會員一份)
radar GET / POST /api/v1/radar/watches 列表/建立雷達訂閱
radar GET / PUT / DELETE /api/v1/radar/watches/:id 讀/改/封存
radar POST /api/v1/radar/watches/:id/pause/resume 暫停/恢復
radar POST /api/v1/radar/watches/:id/sweep 手動觸發即時巡 → 回 Job
radar POST /api/v1/radar/watches/suggest 依服務檔案建議關鍵字
radar GET /api/v1/radar/today 今日統計+分級筆數+卡片首頁
radar GET /api/v1/radar/opportunities 列表filterbandstatuswatch日期
radar GET /api/v1/radar/opportunities/:id 詳情(含 reasons[]、變體、來源)
radar POST /api/v1/radar/opportunities/:id/accept 加入名單 → 綁定/建立 Contact
radar POST /api/v1/radar/opportunities/:id/dismiss 略過
radar POST /api/v1/radar/opportunities/:id/override 覆寫 band 或把 rejected 拉回
radar POST /api/v1/radar/opportunities/:id/replies 生成指定 variant 回覆
radar GET /api/v1/radar/sweeps 巡的執行紀錄(可觀測性)
radar POST /api/v1/radar/import P1 手動匯入網址CSV
crm GET /api/v1/crm/contacts 名單列表filterstagefollow_upband排序
crm GET /api/v1/crm/contacts/:id 詳情+時間軸
crm POST /api/v1/crm/contacts/:id/stage 推進/回退階段
crm POST /api/v1/crm/contacts/:id/follow-up 設定/解除待追蹤標記與天數
crm POST /api/v1/crm/contacts/:id/notes 新增備註
crm POST /api/v1/crm/contacts/:id/merge 手動合併聯絡人
crm POST /api/v1/crm/contacts/:id/conversion 成交回報(寫既有 OutcomeEvent
crm PUT / DELETE /api/v1/crm/contacts/:id/conversion 改/刪成交(留痕)
crm GET /api/v1/crm/followups 待追蹤清單
crm POST /api/v1/crm/followups/:id/done/snooze 完成/延後
crm GET /api/v1/crm/stats 轉換統計(關鍵字/回覆版本/來源)
scout(既有擴充) POST /api/v1/scout/posts/:id/promote 既有海巡命中升級為商機

5.3 前端頁面

路由 變更
/app/radar 新增 今日商機:統計列+卡片+分級分組+空狀態原因
/app/radar/watches 新增 雷達訂閱管理+關鍵字建議
/app/crm 新增 名單:八格視圖(七階段+待追蹤)、篩選排序
/app/crm/:contactId 新增 聯絡人詳情+時間軸+成交回報
/app/crm/stats 新增 轉換統計(或內嵌 /app/crm 分頁)
/app/brands +「服務檔案」分頁(避免側欄再膨脹)
/app/scout 命中列 +「升級為商機」動作
/app/today +今日商機摘要卡(連向 /app/radar
側欄 nav.ts +新分組「商機」含 radarcrm 兩項;手機底欄以 radar 取代 scout 進主要四格,scout 移入「更多」
  • 沿用既有設計系統:src/components/ui/src/styles/tokens.css,不引入新 UI 框架、不用 emoji 當主 icon。
  • 新頁樣式不再灌入已 6,171 行的 global.css:新增 src/styles/radar.css 並於 main.tsx 匯入,須通過 npm run check:tokens
  • 新增 repository 介面於 src/data/repos.tsradarcrmlive 實作分檔 src/data/live/radarRepos.ts

5.4 Job / Worker

Template 觸發 成功結果
radar_sweep 每日 UTC 22:00 排程(每個 active watch 一筆)/手動觸發 抓取→判定→寫 Opportunity寫 RadarSweep 統計(命中、判定、截斷、失敗原因)
radar_followup_scan 日排程(維護 tickRedis lock 到期 FollowUp → notified +站內通知
(既有)scout_scan 不變 不變;不得改動既有海巡行為
  • 沿用既有 Job guarded 狀態更新與 Redis locklock value = workerID)。
  • radar_sweep 失敗須寫可讀錯誤原因並發通知,不得靜默。

5.5 計費對照(不新增 meter

既有 soft_caps 各分項加總必須等於 monthly_credits新增 meter 會迫使三個方案全部重算。因此本 run 沿用既有四個 meter,僅以 source 標籤區分來源。

行為 Meter source
巡的抓取API 路徑) web_search radar.sweep
五問判定 ai_research radar.judge
回覆生成(各 variant ai_copy radar.reply
AI 追蹤訊息 ai_copy radar.followup
關鍵字建議 ai_copy radar.suggest
  • BYOK 規則不變;平台 gate 行為不變。
  • 用量頁可依 source 前綴 radar. 聚出「雷達花了多少」,供 P1 價格校準使用。

5.6 錯誤語意

情境 行為
未建服務檔案就建 active watch 明確錯誤,非 102000message 指向服務檔案
watch 數超過方案上限 明確錯誤message 含目前上限與升級提示
當日商機達上限 不是錯誤:正常回應並帶 truncated_count 與提示文案
回覆生成兩次都命中 forbidden[] 明確錯誤;不得輸出違規內容
AccountHealth throttle 時嘗試自動送出 沿用既有錯誤語意;僅留手動路徑
抓取路徑不可用 Sweep failed +通知;禁止空成功
合併聯絡人跨不同 owner 明確錯誤(越權)
成交回報金額為負或幣別非法 明確錯誤

6. 與現況對照Retain / Replace / Remove

能力 Retain Replace Remove 備註
海巡三模式productthemeactivity 原樣 不改行為
海巡 BrandProductpain_points 與 ServiceProfile 並存,非取代
海巡抓取雙路徑 復用 不新增第三種抓取
既有貼文分類(seeking_help 等) 復用為第一問依據 不重做分類器
ScoutPost outreach_status 與 Opportunity 狀態不共用
海巡命中列表 「升級為商機」 複製+反向連結
OutcomeEvent 歸因 source_type=radar_opportunity 另建成交帳
AccountHealth 送出閘 強制經過 繞過護欄的新路徑
Outbox 真發送 公開留言版沿用
Usage meter 四分項 source 標籤 新增第五個 meter 避免重算 soft_caps
付費流程Stripe 訂閱結帳portalwebhook 原樣 配額欄位 重做付費流程 金流已存在
方案價格 FreeStarterPro 不改價 校準列 P1
站內通知 ref_type=contact
前端設計系統與 token 守門 radar.css 樣式灌 global.css
lead 指稱銷售線索 禁止 既有語意為主帳號
模擬/空成功 API 禁止 AGENTS.md

7. 非功能

  • 安全/權限: 全部新資源以 owner_uid 隔離Contact 合併需同 ownerAdmin 不預設讀全站商機(如需另開需求)。
  • 隱私: 只處理公開貼文與使用者主動匯入內容Contact 僅存公開作者識別與使用者自填備註,不做跨平台身分推測
  • 合規: 抓取僅走既有雙路徑;dev_mode 爬蟲路徑不擴大;所有自動化保留「複製 → 手動送出 → 標記完成」人工路徑。
  • 可觀測性: RadarSweep 記錄每次巡的命中判定截斷失敗原因與耗用點數FollowUp 掃描寫日誌;日誌不含 token 明文。
  • 效能邊界: 列表 pageSize ≤ 50;單次 sweep 判定筆數以方案每日上限為硬上限;判定為逐筆 AI 呼叫須可中斷並記錄已完成進度Job 失敗不重跑已判定者)。
  • 成本: 每日巡是常駐成本,必須有 §4.9 配額閘;radar. source 聚合是價格校準的資料來源。
  • 語系: 判定理由與回覆文案預設繁體中文台灣語感。

8. 資料保存(邏輯層)

實體 關鍵欄位 生命週期
radar_service_profiles _id=owner_uid, services[], cases[], forbidden[], faq[], service_areas[], remote_ok, availability, tone_note, updated_at 每會員一份,可改
radar_watches id, owner_uid, terms[], exclude_terms[], regions[], status, last_swept_at, created_at CRUD封存
radar_sweeps id, owner_uid, watch_id, job_id, path(api/crawler), hit_count, judged_count, created_count, truncated_count, failed_reason?, credits_used, started_at, ended_at 保留供觀測與成本分析
radar_opportunities id, owner_uid, watch_id?, source(threads/manual/scout_promote), source_scout_post_id?, external_id, permalink, author_handle, text, posted_at, status, intent_score, intent_band, reasons[], region_detected, region_match, freshness_hours, matched_service, reject_reason?, override?, contact_id?, created_at 判定後入庫rejected 亦留
radar_replies id, owner_uid, opportunity_id, variant, text, used_at?, sent_channel?, created_at 按需生成
crm_contacts id, owner_uid, source_platform, author_handle, display_name?, stage, needs_follow_up, follow_up_days, last_touch_at, opportunity_ids[], merged_from[], created_at 唯一鍵owner_uid, source_platform, author_handle
crm_touches id, owner_uid, contact_id, type(stage/reply/note/conversion), from_stage?, to_stage?, body?, actor_uid, created_at 只增不改;成交修改寫新一筆
crm_followups id, owner_uid, contact_id, due_at, status, notified_count, created_at 到期→通知→終態
成交 不新增 collection,寫既有 growth_outcomes source_type=radar_opportunity
  • 索引:owner_uid 為所有查詢前綴;radar_opportunities(owner_uid, created_at)(owner_uid, intent_band, status)(owner_uid, external_id) 去重;crm_contacts 需唯一鍵;crm_followups(status, due_at)
  • 去重:同一 owner_uid 下同 external_id 不重複建立 Opportunity跨 watch 命中同一貼文只留一筆,記錄多個觸發 term

9. 驗收場景Given / When / Then

共通: 成功 envelope 102000;時間 ns UTC未實作 ≠ 空成功。

9.1 服務檔案與雷達訂閱

ID Given When Then
SP-01 新會員無服務檔案 建 active watch 明確錯誤;指向服務檔案
SP-02 已填服務檔案 GET service-profile 欄位完整回傳;forbidden[] 可讀
RW-01 Free 方案已有 1 個 active watch 再建一個 明確錯誤含上限與升級提示
RW-02 active watch pause 不再排入每日巡;既有商機保留
RW-03 有服務檔案 watches/suggest 回關鍵字建議清單,可逐條採用
RW-04 archived watch 列表 不再產生新商機;歷史商機與統計不變

9.2 每日巡與判定

ID Given When Then
SW-01 有 2 個 active watch 排程到 UTC 22:00 各建一筆 radar_sweep Job隔日台北早晨可見結果
SW-02 dev_mode_enabled=false sweep 走 API 路徑;path=api
SW-03 dev_mode_enabled=true 且有工作階段 sweep 走爬蟲路徑;path=crawler
SW-04 抓取路徑不可用 sweep Sweep failed +原因+通知;空成功
SW-05 命中 40 筆、方案上限 30 sweep 依 score 保留 30truncated_count=10;今日頁提示
SW-06 同一貼文被兩個 watch 命中 sweep 只建 1 筆 Opportunity記錄兩個觸發 term
OP-01 貼文為「求推薦台北婚攝」、服務地區台北 判定 qualifiedregion_match=matchreasons[] 五條齊全
OP-02 貼文為同業叫賣(provider_offer 判定 rejected;不出現在今日頁;仍可查
OP-03 貼文發布 20 天前 判定 硬否決 rejected(逾期)
OP-04 貼文未提地區 判定 region_match=unknown;得部分分;不猜測縣市
OP-05 服務檔案標可遠端、貼文在高雄、服務地區台北 判定 不因地區硬否決;地區維度給滿分
OP-06 任一維度缺理由 寫入 拒絕入庫(契約要求 reasons[] 五條齊全)
OP-07 使用者覆寫 band override 生效並記錄原值/新值/時間/操作者

9.3 今日頁與回覆

ID Given When Then
TD-01 當日有 18 筆 GET today 統計為 18 與高/中/低分項;卡片含原文、分數、地區、發布時間、預設回覆
TD-02 當日 0 筆 GET today 非空白:回明確原因與下一步建議
RP-01 商機剛判定完 查 replies 僅存在 public_comment 一個版本
RP-02 使用者要私訊版 生成 dm 產出並計入 ai_copysource=radar.reply
RP-03 服務檔案 forbidden 含「保證錄取」 生成回覆 輸出不含該詞;連兩次命中則明確錯誤且不輸出
RP-04 帳號 AccountHealth throttle 自動送出公開留言 拒絕;僅留複製+標記完成
RP-05 私訊版 送出 P0 僅提供複製;不宣稱已自動送出

9.4 CRM 與追蹤

ID Given When Then
CR-01 商機 qualified accept 建立或綁定 Contactstage=new_found
CR-02 同一作者第二筆商機 accept 掛在同一 Contact 下;時間軸兩筆
CR-03 Contact 在 dm_sent 直接跳 won 允許;寫 ContactTouch 記錄跳轉
CR-04 Contact won 重新開啟為 replied 允許;留痕
CR-05 任一階段 標記待追蹤 needs_follow_up=true 與階段並存,非取代
CR-06 兩個不同平台的 Contact merge 允許手動合併;時間軸保留兩邊
CR-07 跨 owner 的 Contact merge 明確錯誤(越權)
CR-08 回報成交金額 12000 conversion 階段轉 won;寫入既有 growth_outcomessource_type=radar_opportunity);成果頁可見
CR-09 修改/刪除成交 PUTDELETE 明細與成果彙總一致;留痕;非空成功
FU-01 送出回覆後 3 天無動作 followup scan FollowUp notified +站內通知,落地 Contact 詳情
FU-02 通知中 產生 AI 追蹤訊息 產出並計入 ai_copysource=radar.followup
FU-03 已通知 2 次仍無動作 scan escalated +顯示「建議轉未成交」;不自動改階段
FU-04 使用者延後 5 天 snooze due_at 後移;回 scheduled

9.5 統計與配額

ID Given When Then
ST-01 某關鍵字 accepted 8、won 2 GET stats 顯示轉換率與絕對數
ST-02 某關鍵字樣本 3 筆 GET stats 只顯示絕對數並標「樣本不足」,不顯示排名結論
ST-03 有 radarscoutmanual 三種來源成交 GET stats 依來源分列
QT-01 當日已達商機上限 再次 sweep 不新增;回應帶 truncated_count 與提示;非錯誤
QT-02 平台點數耗盡(非 BYOK 判定 沿用既有 platform gate 行為watch 不被刪除
QT-03 用量頁 依 source 聚合 可看出 radar.* 的耗用,供價格校準

9.6 既有海巡橋接與回歸

ID Given When Then
PR-01 既有海巡命中一筆 promote 建立 Opportunity 並記 source_scout_post_id;原 ScoutPost 狀態不變
PR-02 promote 後推進 CRM 操作 不影響原 outreach_status
RG-01 既有海巡三模式 執行 briefscan 行為與現況完全一致
RG-02 既有 Outbox 真發送 送出 仍僅平台成功後才 published
RG-03 既有 growth-loop 成果卡 開啟 既有歸因不受影響radar 成交併入同一彙總
RG-04 既有 Usage soft_caps 檢查 四分項加總仍等於 monthly_credits(未新增 meter
RG-05 全 repo 檢索 無以 lead 指稱銷售線索的新程式碼或契約

10. 開放規格問題

  1. 巡的觸發時段已定:每日 UTC 22:00台北 06:00;個人化時區 P2§4.2)。
  2. 既有海巡命中升級是複製或共用已定:複製+反向連結§4.10)。
  3. 是否新增 usage meter已定:不新增,以 source 標籤區分§5.5)。
  4. 意向分數五維度權重數值 → plan實作可調band 門檻 8050 與硬否決條件鎖定
  5. 地區判定的縣市代碼表來源與比對規則細節 → plan(行為已鎖:三態、不猜測)。
  6. 側欄新增兩項後共 13 項是否需要再收斂資訊架構 → plan 決定;本 spec 已先以分組與手機底欄調整緩解。
  7. 關鍵字建議的產生方式(純 AI 或 AI既有痛點關鍵字工具plan

11. 批准

  • Spec 已批准2026-07-31使用者「好」