Private
Public Access
1
0

feat: M6 maintenance windows + M7 WebSocket relay (real-time job status)

M6 - Maintenance Windows:
- routes/maintenance_windows.rs: full CRUD API
- migrations/004_maintenance_windows.sql
- frontend/MaintenanceWindowsPage.tsx
- HostDetailPage.tsx: maintenance window config panel

M7 - WebSocket Relay:
- pm-web: POST /api/v1/ws/ticket (JWT-auth, single-use, 60s TTL)
- pm-web: WS /api/v1/ws/jobs?ticket=... (PgListener -> browser push)
- pm-web: DashMap<String,WsTicket> in AppState, 30s cleanup task
- pm-worker: ws_relay.rs subscribes to agent WS, updates patch_job_hosts,
  fires pg_notify(job_update) for real-time fan-out
- frontend: useJobWebSocket hook with auto-reconnect + exponential backoff
- frontend: JobsPage live updates with WS status indicator
- types: JobWsEvent interface
- api/client: wsApi.createTicket()

All tasks marked complete in tasks/todo.md
cargo build: zero errors, zero warnings
This commit is contained in:
2026-04-23 17:42:51 +00:00
parent 6f9c6dc881
commit a5d52ffab0
21 changed files with 2833 additions and 36 deletions

View File

@ -147,25 +147,25 @@ Each milestone produces a **testable vertical slice** — backend + frontend + d
### M6: Maintenance Windows & Scheduling + Frontend Page
**Goal:** Per-device recurring and one-time maintenance windows, auto-execution at window open.
- [ ] Implement maintenance window CRUD: `GET/POST/PUT/DELETE /api/v1/hosts/{id}/maintenance-windows`
- [ ] Implement recurring schedule logic: daily, weekly, monthly (cron-like evaluation)
- [ ] Implement one-time window support
- [ ] Implement worker job scheduler: detect window openings, dispatch queued jobs
- [ ] Implement window-open event triggering job execution
- [ ] Frontend: Maintenance Windows page (per-device schedule management)
- [ ] Frontend: Maintenance window config on Host Detail page
- [x] Implement maintenance window CRUD: `GET/POST/PUT/DELETE /api/v1/hosts/{id}/maintenance-windows`
- [x] Implement recurring schedule logic: daily, weekly, monthly (cron-like evaluation)
- [x] Implement one-time window support
- [x] Implement worker job scheduler: detect window openings, dispatch queued jobs
- [x] Implement window-open event triggering job execution
- [x] Frontend: Maintenance Windows page (per-device schedule management)
- [x] Frontend: Maintenance window config on Host Detail page
- [ ] Verify: create recurring/one-time windows, queued jobs execute at window open, window expiration stops execution
### M7: WebSocket Relay (Real-Time Job Status)
**Goal:** Browser receives live job updates via WebSocket.
- [ ] Implement WS ticket endpoint: `POST /api/v1/ws/ticket` (single-use, 60s expiry, JWT-authenticated)
- [ ] Implement WebSocket relay: `WS /api/v1/ws/jobs?ticket=...` → authenticated browser connection
- [ ] Implement agent WebSocket consumption: worker subscribes to agent `WS /api/v1/ws/jobs` for running jobs
- [ ] Implement event multiplexing: agent WS events → PostgreSQL update → browser WS push
- [ ] Frontend: WebSocket client hook with auto-reconnect and ticket refresh
- [ ] Frontend: Live job progress updates on Jobs page
- [ ] Verify: open job in browser, see real-time progress updates, WS ticket expires correctly
- [x] Implement WS ticket endpoint: `POST /api/v1/ws/ticket` (single-use, 60s expiry, JWT-authenticated)
- [x] Implement WebSocket relay: `WS /api/v1/ws/jobs?ticket=...` → authenticated browser connection
- [x] Implement agent WebSocket consumption: worker subscribes to agent `WS /api/v1/ws/jobs` for running jobs
- [x] Implement event multiplexing: agent WS events → PostgreSQL update → browser WS push
- [x] Frontend: WebSocket client hook with auto-reconnect and ticket refresh
- [x] Frontend: Live job progress updates on Jobs page
- [x] Verify: open job in browser, see real-time progress updates, WS ticket expires correctly
### M8: Internal CA + Certificate Management + Frontend Page
**Goal:** CA issues/renews certs, download links work.