thread-master/docs/product/demand-radar/tasks/T527-job-radar-sweep-templa...

64 lines
2.5 KiB
Markdown
Raw Permalink Normal View History

2026-08-03 05:52:02 +00:00
# T527 — job-radar-sweep-template-daily-schedule
> Status: `done`
> Milestone: `M2`
> Kind: `feat`
> Est. change: `~190 lines`
## Goal
完成後系統應:每日 **UTC 22:00** 為每個 active watch 建立一筆 `radar_sweep` Job多台 worker 只有一台建立與執行。
## Depends on
- T512、T526
## Inputs
- Spec`../spec.md` §4.2.3、§5.4
- 既有:`apps/backend/internal/module/job/domain/job.go`template 常數)、`internal/module/job/usecase/service.go`、`cmd/worker/main.go`maintenance tick`redislock`lock value = `workerID`
## Outputs
### 程式變更(預期路徑)
| 路徑 | 動作 | 說明 |
|------|------|------|
| `apps/backend/internal/module/job/domain/job.go` | edit | 新增 `TemplateRadarSweep = "radar_sweep"` |
| `apps/backend/internal/module/job/usecase/service.go` | edit | `ScheduleRadarSweep(owner, watchID, runAt)`guarded 狀態更新沿用 |
| `apps/backend/internal/module/radar/usecase/sweep_schedule.go` | add | 每日排程 tick判斷是否已過當日 UTC 22:00 且未建立過,逐一 active watch 建 Job |
| `apps/backend/cmd/worker/main.go` | edit | `case jobDomain.TemplateRadarSweep` 分派maintenance 內呼叫每日排程 tick |
### 行為變更
- 同一 UTC 日、同一 watch 只建立一筆排程 Job以當日標記或 Job 唯一性防重)。
- 排程與執行皆在既有 Redis lock 保護下lock value = `workerID`;未取得鎖者跳過不報錯。
- 手動觸發T533走**同一條執行路徑**,不另寫一份。
## Out of scope
- 抓取實作T528、判定T529T530
- 個人化時區P2不做
## Acceptance
- [x] SW-012 個 active watch → 排程後各一筆 `radar_sweep` Job
- [x] 兩個 worker 實例同時跑Job 不重複建立、不重複執行RefID=`watchID:YYYY-MM-DD` 去重maintenance Redis lock並行 schedule 測試)
- [x] 指令:
```bash
cd apps/backend && go test ./internal/module/radar/... ./internal/module/job/... -count=1 && make build
```
## Notes
排程時間為固定 UTC 22:00台北 06:00使用者早晨打開就有名單。
### 實作落點
- `job/domain``TemplateRadarSweep`
- `job/usecase``ScheduleRadarSweep``RadarSweepPayload`(同 watch+日去重)
- `radar/usecase/sweep_schedule.go``ScheduleDailySweeps`UTC 22:00 閘)、`BeginSweepRecord`
- `radar` repo`ListAllActiveWatches`
- `cmd/worker`template 分派maintenance tick 呼叫排程;執行體暫明確 fail「fetch not wired (T528)」並寫 Sweep 紀錄