# Tasks INDEX — demand-radar > Plan:`../plan.md`(**approved** 2026-07-31) > Spec:`../spec.md` §9(SP/RW/SW/OP/TD/RP/CR/FU/ST/QT/PR/RG) > 後端根:`apps/backend`(goctl)· 前端根:`apps/web` > Status:**approved**(2026-07-31 使用者「好」)· phase=`ready-to-implement` > Updated:2026-07-31 · 58/58 done(M0–M6 完成) ## 範圍硬規則 | 規則 | 內容 | |------|------| | 加值層 | 既有海巡三模式/抓取雙路徑/Outbox/付費流程**原樣保留**;新 group、新 collection 並存 | | 橋接單向 | scout → opportunity 只做**複製+反向連結**,狀態機不共用 | | 不新增 meter | 沿用四個既有 meter+`radar.*` source 標籤(RG-04) | | 成交 | 只有人可回報;寫既有 `growth_outcomes`(`source_type=radar_opportunity`),不另建帳 | | 送出 | 公開留言必經既有 AccountHealth 送出閘;私訊 P0 只能複製,UI 不得宣稱自動送出 | | 判定契約 | `reasons[]` 五條齊全否則不入庫;band 門檻 80/50 鎖定,只調權重與 prompt | | 配額 | `max_active_watches`/`max_daily_opportunities`;達上限為**截斷非錯誤** | | 命名紅線 | 全域禁用 `lead` 指稱銷售線索(RG-05) | | 樣式 | 新頁樣式只進 `src/styles/radar.css`,`npm run check:tokens` 為必跑閘 | | 契約 | goctl `.api` → `make gen-api`;業務只寫 `internal/logic/**`、`internal/module/**`;envelope 102000;時間 ns UTC;**禁止未實作回空成功** | ## INDEX | ID | Title | M | Kind | Status | Est | |----|-------|---|------|--------|-----| | T500 | api shells radar crm goctl | M0 | feat | done | ~180 | | T501 | mongo indexes radar crm | M0 | feat | done | ~120 | | T502 | fe domain types and repo interfaces | M0 | feat | done | ~180 | | T503 | fe radar css shell token guard | M0 | chore | done | ~60 | | T510 | service profile model repository | M1 | feat | done | ~170 | | T511 | service profile api get put | M1 | feat | done | ~160 | | T512 | radar watch model repository | M1 | feat | done | ~180 | | T513 | radar watch api crud quota gate | M1 | feat | done | ~200 | | T514 | watch keyword suggest ai | M1 | feat | done | ~160 | | T515 | fe service profile tab brands | M1 | feat | done | ~180 | | T516 | fe radar watches page | M1 | feat | done | ~200 | | T517 | test m1 profile watch quota | M1 | test | done | ~180 | | T525 | opportunity model repository | M2 | feat | done | ~190 | | T526 | radar sweep model repository | M2 | feat | done | ~140 | | T527 | job radar sweep template daily schedule | M2 | feat | done | ~190 | | T528 | sweep fetch reuse dual path | M2 | feat | done | ~170 | | T529 | five question judge scorer | M2 | feat | done | ~200 | | T530 | judge persist reject reasons dedupe | M2 | feat | done | ~170 | | T531 | daily quota truncation and metering | M2 | feat | done | ~160 | | T532 | sweep failure notify and resume | M2 | feat | done | ~160 | | T533 | sweeps list and manual trigger api | M2 | feat | done | ~150 | | T534 | test m2 sweep judge integration | M2 | test | done | ~200 | | T535 | judge accuracy sampling gate | M2 | docs | done | ~120 | | T545 | today api stats and empty reasons | M3 | feat | done | ~180 | | T546 | opportunities list detail api | M3 | feat | done | ~170 | | T547 | opportunity accept dismiss override api | M3 | feat | done | ~160 | | T548 | reply variant model repository | M3 | feat | done | ~130 | | T549 | reply generation forbidden filter | M3 | feat | done | ~200 | | T550 | reply send outbox health gate | M3 | feat | done | ~180 | | T551 | fe radar today page | M3 | feat | done | ~200 | | T552 | fe opportunity actions and reply panel | M3 | feat | done | ~200 | | T553 | fe sidebar ia and today summary | M3 | feat | done | ~150 | | T554 | test m3 today reply integration | M3 | test | done | ~200 | | T565 | contact model repository unique key | M4 | feat | done | ~180 | | T566 | contact touch model timeline repo | M4 | feat | done | ~140 | | T567 | accept binds or creates contact | M4 | feat | done | ~150 | | T568 | contact stage transition engine | M4 | feat | done | ~170 | | T569 | contacts list api filters sort | M4 | feat | done | ~160 | | T570 | contact detail notes followup flag api | M4 | feat | done | ~170 | | T571 | contact merge unmerge owner guard | M4 | feat | done | ~180 | | T572 | conversion report writes growth outcomes | M4 | feat | done | ~180 | | T573 | conversion amend delete audit | M4 | feat | done | ~150 | | T574 | fe crm board eight columns | M4 | feat | done | ~200 | | T575 | fe contact detail timeline conversion | M4 | feat | done | ~200 | | T576 | test m4 crm conversion integration | M4 | test | done | ~200 | | T585 | followup model repository and hooks | M5 | feat | done | ~170 | | T586 | job radar followup scan and notify | M5 | feat | done | ~180 | | T587 | followup api list done snooze escalate | M5 | feat | done | ~170 | | T588 | ai followup message generation | M5 | feat | done | ~140 | | T589 | crm stats api three dimensions | M5 | feat | done | ~200 | | T590 | usage radar source aggregation | M5 | feat | done | ~140 | | T591 | fe followup inbox and stats | M5 | feat | done | ~200 | | T592 | test m5 followup stats integration | M5 | test | done | ~180 | | T600 | scout promote to opportunity | M6 | feat | done | ~170 | | T601 | fe scout promote action | M6 | feat | done | ~100 | | T602 | integration test matrix spec9 | M6 | test | done | ~200 | | T603 | regression scout outbox outcomes naming | M6 | test | done | ~180 | | T604 | docs testing and gaps | M6 | docs | done | ~120 | **合計:58 tasks**(feat 48 · test 7 · docs 2 · chore 1) ## 建議實作順序 ```text T500 → T501 → T502 → T503 → T510 → T511 → T512 → T513 → T514 → T515 → T516 → T517 → T525 → T526 → T527 → T528 → T529 → T530 → T531 → T532 → T533 → T534 → T535 ──【判定準確度閘門:T535 結論為「可進 M3」才往下】 → T545 → T546 → T547 → T548 → T549 → T550 → T551 → T552 → T553 → T554 → T565 → T566 → T567 → T568 → T569 → T570 → T571 → T572 → T573 → T574 → T575 → T576 → T585 → T586 → T587 → T588 → T589 → T590 → T591 → T592 → T600 → T601 → T602 → T603 → T604 ``` 可並行的組合(同 M 內無互相依賴): | 組合 | 說明 | |------|------| | T501 ‖ T500 ‖ T503 | M0 三條互不相依 | | T510+T511 ‖ T512 | 服務檔案與 watch 模型可並行,到 T513 收斂 | | T526 ‖ T525 | sweep 與 opportunity 模型可並行 | | T548 ‖ T545/T546 | 回覆模型與今日頁 API 可並行 | | T565+T566 ‖ T569 | Contact 模型與列表查詢可並行 | | T515 ‖ T516 | 前端兩頁可分頭做(皆需 T502/T503) | ## spec §9 覆蓋對照 | 群組 | 覆蓋 task | |------|-----------| | SP-01~02 | T511、T513、T517 | | RW-01~04 | T513、T514、T516、T517 | | SW-01~06 | T527、T528、T530、T531、T532、T534 | | OP-01~07 | T525、T529、T530、T547、T534 | | TD-01~02 | T545、T551、T554 | | RP-01~05 | T548、T549、T550、T552、T554 | | CR-01~09 | T565~T573、T575、T576 | | FU-01~04 | T585、T586、T587、T588、T592 | | ST-01~03 | T589、T591、T592 | | QT-01~03 | T531、T590、T534、T592 | | PR-01~02 | T600、T601 | | RG-01~05 | T528、T550、T572、T590、T603 | ## 里程碑結案 ### M0(地基)— 2026-07-31 `.api` 殼+mongo 索引+前端型別/repo 介面/`radar.css`。未實作能力一律回 `501010`,前端 live 直接把它丟成 `ApiError`,不做空清單降級。 ### M1(服務檔案與雷達訂閱)— 2026-07-31 - 後端:`ServiceProfile`(每會員一份,`exists` 區分「沒建」與「建了空的」)、`RadarWatch` 狀態機(active/paused/archived,archived 為終點)、配額閘(`max_active_watches`,既有超額者不強制降級)、AI 關鍵字建議(`ai_copy`/`radar.suggest`,失敗退點)。 - 前端:`/app/brands`「服務檔案」分頁、`/app/radar/watches` 訂閱管理+建議面板。側欄項留在 T553。 - 驗收:SP-01、SP-02、RW-01~RW-04 各一個具名 case(`internal/logic/radar/m1_integration_test.go`),已納入 `make test-integration`。 - 跑過:`go test ./... -count=1`、`make test-integration`、`cd apps/web && npm run build && npm run check:tokens && npm run test && npm run lint`。 M1 沒有做(依 plan 排在後面):sweep/判定/商機/回覆/CRM,以及手動觸發即時巡的 UI(T533/T552)。 ### M2–M6 — completed 2026-07-31 - T525:`Opportunity` domain+memory/mongo repo;`UpsertByExternalID` 去重併 term;`reasons[]` 五維度契約;band 80/50。 - T526:`RadarSweep` domain+memory/mongo repo;計數累加、`judged_external_ids` 去重、GetByJobID。 - T527:`TemplateRadarSweep`、UTC 22:00 每日排程、worker maintenance lock 下建 Job、執行殼層(抓取待 T528)。 - 下一個:T528 抓取雙路徑複用。 ## 閘門 - [x] tasks 批准(2026-07-31)→ phase=`ready-to-implement` - 實作時**指定 T###** 才寫碼;一次一題(建議從 **T500** 起) - **M2 → M3 硬閘門**:T535 抽驗報告結論須為「可進 M3」,否則回 T529 調權重/prompt 後重測