# T853 — idempotent judgment metering fixtures

> Status: `done`（2026-08-11）
> Milestone: `M5`
> Est. change: `~180 lines`

## Goal

完成後判定結果保存與 usage commit 具逐筆冪等關聯，重試／中斷不重複扣點，並有完整品質 fixture 集。

## Depends on

- T852、T842

## Inputs

- `apps/backend/internal/module/usage/**`
- `apps/backend/internal/module/radar/usecase/judge_persist.go`
- `apps/backend/internal/module/radar/usecase/testdata/**`
- Spec §5.3、驗收 #16–#18、#21、#23

## Outputs

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

| 路徑 | 動作 | 說明 |
|------|------|------|
| `apps/backend/internal/module/radar/usecase/judgment_metering.go` | add | commit／reuse／failure refund boundary |
| `apps/backend/internal/module/radar/usecase/testdata/opportunity_inbox_cases.json` | add | 口語、純名、公告、重複、未知時間案例 |
| `apps/backend/internal/module/radar/usecase/judgment_metering_test.go` | add | retry／duplicate charge／BYOK tests |

### 行為變更

- AI provider 有效工作才 commit；失敗／無效結構沿用退點規則。
- BYOK credits=0、count/source 可對帳。

### API / 契約（若有）

- source 使用既有 `radar.judge`，不新增 usage meter。

## Out of scope

- 不改 sweep worker 續跑、不做 accuracy report。

## Acceptance

- [x] duplicate judgment／charge count 為 0。
- [x] fixture 可被 T870 evaluation 重用。
- [ ] 指令：

```bash
cd apps/backend && go test ./internal/module/radar/usecase ./internal/module/usage/... -run 'Meter|Judgment' -count=1
```

## Notes

先保存 usage idempotency key，再保存結果，兩者不可只靠整批成功旗標。
