CI Pipeline / Rust Format Check (pull_request) Failing after 3s
CI Pipeline / Clippy Lints (pull_request) Failing after 1s
CI Pipeline / Rust Unit Tests (pull_request) Failing after 2s
CI Pipeline / Security Audit (pull_request) Failing after 1s
CI Pipeline / Frontend Lint & Type Check (pull_request) Failing after 4s
CI Pipeline / Build .deb & Release (pull_request) Has been skipped
- Add GET /api/v1/maintenance-windows bulk endpoint to eliminate N+1
per-host API calls (1 request instead of N+1)
- Fix two-phase state update race: setHosts() was called before
setWindowsByHost(), causing React to render hosts with empty windows
- Add AbortController to cancel stale fetch requests on unmount/re-fetch
- Batch state updates atomically (React 18 auto-batching)
- Replace silent catch{} with proper error handling
- Add refreshData() wrapper for mutation handlers and Refresh button
Backend: maintenance_windows.rs - new list_all_windows handler +
all_windows_router(), mounted in main.rs
Frontend: client.ts - new listAll() API method
Frontend: MaintenanceWindowsPage.tsx - rewritten fetchData
The SSO button on the login page was not appearing because the settings
API requires authentication, but the login page cannot authenticate before
the user logs in.
Changes:
- Backend: Add GET /api/v1/auth/sso/config public endpoint that returns
only enabled, display_name, and auth_url (no secrets exposed)
- Backend: Mount sso::public_router() at /api/v1/auth/sso in main.rs
(was previously missing - only azure_compat_router was mounted)
- Frontend: Replace settingsApi.get() call in LoginPage.tsx with
ssoConfigApi.get() which calls the public endpoint
- Frontend: Add SsoConfigResponse interface and ssoConfigApi helper
to client.ts
- Frontend: Use auth_url from config response instead of hardcoded path
- Refactored azure_sso.rs to sso.rs with generic OIDC provider support
- Added OIDC discovery URL lookup with 1hr TTL caching
- Added PKCE for all providers, client_secret optional for public clients
- Added /api/v1/auth/sso/login and /api/v1/auth/sso/callback routes
- Added /api/v1/auth/azure/* backward-compatible routes
- Added POST /settings/sso/discover and POST /settings/sso/test endpoints
- Frontend: Provider dropdown (Keycloak/Azure AD/Custom OIDC)
- Frontend: Auto-fill discovery URL for Keycloak
- Frontend: Discover Endpoints and Test Connection buttons
- Frontend: Dynamic SSO button based on provider display name
- Made migration 014 idempotent with DO blocks and IF NOT EXISTS
- Fixed debian/install to use /usr/local/bin/ for binaries
- Fixed frontend file path in .deb package
- Reset admin password on dev server
- Fixed database permissions for oidc_config table
- Added HealthCheckListResponse type { checks: [...], total: number }
- Updated healthChecksApi.list() return type to HealthCheckListResponse
- Fixed HostDetailPage to use res.data?.checks instead of Array.isArray
- Added Target column to health checks table
- Added git pre-commit/pre-push hooks to prevent format CI failures
- Updated lessons.md
- Added health_check_poller.rs: periodic service/HTTP health checks
- Added pre-patch health gate in job_executor.rs
- Added waiting_health_check job status (migration 008)
- Added health_check_status to HostSummary and hosts API
- Added health check types and API functions to frontend
- Added health check UI section to HostDetailPage
- Added health check status indicators to HostsPage and PatchDeploymentPage
- Added serde default for health_check_poll_interval_secs
- Fixed missing AgentClient import in health_check_poller.rs
- Fixed missing ws_relay import in main.rs
- Fixed missing closing paren in retry_pending_jobs SQL
- Added ReadWritePaths for /etc/patch-manager/keys in systemd services
- Add eslint-plugin-react-hooks to package.json and config
- Fix duplicate imports in HostsPage.tsx
- Remove non-null assertion in main.tsx
- Fix != to !== in HostDetailPage.tsx and MaintenanceWindowsPage.tsx
- Fix unused variable in ReportsPage.tsx
- Change console.debug to console.warn in useJobWebSocket.ts