# T830 — review state domain and mapping > Status: `done` > Milestone: `M3` > Est. change: `~180 lines` ## Goal 完成後 backend domain 將 ReviewState 與 OpportunityStatus 分離,並能對舊文件完成安全映射與合法狀態轉移。 ## Depends on - T823(Phase B UX approval) - T800、T802 ## Inputs - `apps/backend/internal/module/radar/domain/opportunity.go` - `apps/backend/internal/module/radar/domain/repository.go` - Spec §3.1–§3.2、驗收 #1–#5 ## Outputs ### 程式變更(預期路徑) | 路徑 | 動作 | 說明 | |------|------|------| | `apps/backend/internal/module/radar/domain/opportunity.go` | edit | review state、reason、previous state、移除欄位與 transition | | `apps/backend/internal/module/radar/domain/opportunity_review.go` | add | review audit/mapping domain | | `apps/backend/internal/module/radar/domain/opportunity_test.go` | edit | 狀態與 legacy table tests | ### 行為變更 - accept 仍是 CRM business status;完成/移除只改 review state。 - dismissed 舊資料映射 removed(legacy_unknown),不可偷偷回 qualified。 ### API / 契約(若有) - domain validation 與 T800 API enum 一致。 ## Out of scope - 不實作 Mongo、HTTP logic、worker。 ## Acceptance - [x] 合法 transition、非法 transition、idempotent update 與 legacy mapping table tests 通過。 - [ ] 指令: ```bash cd apps/backend && go test ./internal/module/radar/domain -run 'Review|Opportunity' -count=1 ``` ## Notes review event 需可 append-only 保存,但本 task 只定義 domain shape。