# T802 — legacy mapping and contract guards

> Status: `done`
> Milestone: `M0`
> Est. change: `~160 lines`

## Goal

完成後舊 accepted／dismissed／其他 Opportunity、舊 sort 與未完成新 API 都有可重跑的相容測試與明確錯誤。

## Depends on

- T800、T801

## Inputs

- `apps/backend/internal/module/radar/domain/opportunity.go`
- `apps/web/src/data/live/radarRepos.test.ts`
- Spec §3.2、§7.6、驗收 #1、#11、#12、#24

## Outputs

### 程式變更（預期路徑）

| 路徑 | 動作 | 說明 |
|------|------|------|
| `apps/backend/internal/module/radar/**_test.go` | add/edit | 舊欄位映射與 owner／validation contract tests |
| `apps/web/src/data/live/radarRepos.test.ts` | edit | 舊 sort／today／欄位 mapper 測試 |
| `apps/web/src/data/fixtures/radarLegacy.ts` | edit | 加 legacy review fixtures |

### 行為變更

- accepted→completed、dismissed→removed(legacy_unknown)、其他→pending；score→recommended、posted→newest。

### API / 契約（若有）

- 缺欄位可讀；不完整新操作回 not-ready／validation，不回假成功。

## Out of scope

- 不做資料庫回填、不改既有 status transition。

## Acceptance

- [ ] legacy fixture 在 backend／frontend 都得到相同 review state。
- [ ] unknown time 排序測試固定置底。
- [ ] 指令：

```bash
cd apps/backend && go test ./internal/module/radar/... -run 'Legacy|Contract' -count=1
cd ../web && npm run test -- radarRepos
```

## Notes

測試先鎖定相容行為，再讓後續 task 改 domain。
